Authoring API

The /authoring entry point defines project-owned package intent. It is separate from the finalized manifest.tap.json that the SDK derives for one release.

Define a Package

defineTapMiniapp preserves the inferred TapMiniappDefinition type. Keep the app version in one project-owned value. The executing SDK supplies its own version and derives the release ID, target paths, contribution artifacts, and integrity metadata.

import packageJson from './package.json' with { type: 'json' };
import {
  defineTapMiniapp,
  packageContributionProvider,
  type TapMiniappDefinition,
} from '@theaiplatform/miniapp-sdk/authoring';
import { commandTargetBuilder } from '@theaiplatform/miniapp-sdk/lifecycle';

const definition: TapMiniappDefinition = defineTapMiniapp({
  release: { version: packageJson.version },
  identity: {
    packageId: 'tap_pkg_example_0001',
    publisherId: 'publisher_example',
    namespace: 'example',
    slug: 'example',
  },
  presentation: { name: 'Example', description: 'An example miniapp.' },
  compatibility: { tapHost: '>=0.1.0' },
  targets: {
    desktop: {
      remoteName: 'example_desktop',
      exposes: {
        './ui/desktop': {
          source: './src/surface.tsx',
          runtime: 'webview',
        },
      },
      builder: commandTargetBuilder({
        command: 'pnpm',
        args: ['run', 'build:target'],
      }),
    },
  },
  contributions: [packageContributionProvider()],
});

export default definition;

The returned definition is read-only. The compiler validates identities, targets, paths, providers, hooks, and publishers before a target builder runs.

Provide Generated Content

Use defineContributionProvider when package contributions or generated inputs come from project data. A provider receives one immutable ReleaseContext and returns ContributionProviderOutput containing JSON contributions, GeneratedFile values, or both.

import {
  defineContributionProvider,
  stringifyTapMiniappJson,
  type ContributionProvider,
  type GeneratedFile,
  type LogicalChatBlockDefinition,
  type LogicalSpecialistDefinition,
} from '@theaiplatform/miniapp-sdk/authoring';

const specialist: LogicalSpecialistDefinition = {
  id: 'query-expert',
  displayName: 'Query Expert',
  availability: 'private',
  persona: { purpose: 'Explain query results.' },
  capabilities: { tags: ['queries'], summary: 'Explain query results.' },
  prompts: { spawner: 'Explain the important query results.' },
  privacy: { supportsLocal: false, requiresNetwork: true },
};

const block: LogicalChatBlockDefinition = {
  id: 'query-report',
  specialist: specialist.id,
  primitive: 'report',
  accessibilityLabel: 'Query report',
  fallbackFormat: 'markdown',
};

const provider: ContributionProvider = defineContributionProvider({
  id: 'example.generated-content',
  provide(release) {
    const generatedFile: GeneratedFile = {
      path: 'generated/release.json',
      contents: stringifyTapMiniappJson({ releaseId: release.releaseId }),
      kind: 'module',
    };
    return { files: [generatedFile] };
  },
});

Provider output is confined to staging. Duplicate IDs, unsafe paths, collisions, malformed logical definitions, and nondeterministic repeated output stop compilation.

packageContributionProvider discovers versionless JSON definitions from specialists/*.json and chat-blocks/*.json. It derives versioned specialist names, schema versions, canonical paths, chat block schemas, and descriptor contributions.

Add Project Verification

Use TapMiniappVerificationHooks for product rules that do not belong in generic package verification. Descriptor checks run before builders. Artifact and runtime checks receive the assembled package root after generic verification.

import type {
  TapMiniappVerificationContext,
  TapMiniappVerificationHooks,
} from '@theaiplatform/miniapp-sdk/authoring';

const verify: TapMiniappVerificationHooks = {
  verifyDescriptor(context: TapMiniappVerificationContext) {
    if (context.release.targets.length !== 1) {
      throw new Error('This package supports exactly one target.');
    }
  },
  async verifyArtifacts({ packageRoot }) {
    await verifyProductAssets(packageRoot);
  },
};

Keep package-wide integrity, lock closure, portability, and runtime ABI checks in the SDK lifecycle. Hooks should enforce only application-specific policy.

Connect a Publisher

A separately installed provider supplies a PublisherAdapter. The lifecycle passes one verified PublisherContext containing the immutable release, finalized descriptor, descriptor path, and assembled package root.

import type {
  PublisherAdapter,
  PublisherContext,
} from '@theaiplatform/miniapp-sdk/authoring';

const publisher: PublisherAdapter<{ url: string }> = {
  id: 'example.publisher',
  async publish(context: PublisherContext) {
    return publicationClient.upload({
      releaseId: context.release.releaseId,
      packageRoot: context.packageRoot,
    });
  },
};

Build and check operations never invoke the adapter. Only an explicit publish command can contact it.

Compile Authoring

Most projects use the Package Lifecycle, which calls the compiler automatically. Build tooling can use loadTapMiniappDefinition and compileTapMiniapp directly when it needs the staged descriptor before target compilation.

import {
  compileTapMiniapp,
  isTapMiniappTarget,
  loadTapMiniappDefinition,
  type CompileTapMiniappOptions,
  type CompiledTapMiniapp,
} from '@theaiplatform/miniapp-sdk/authoring';

const root = process.cwd();
await loadTapMiniappDefinition(root);

const options: CompileTapMiniappOptions = {
  root,
  stagingRoot: `${root}/.tap-build/authoring`,
  outputRoot: `${root}/dist`,
};
const compiled: CompiledTapMiniapp = await compileTapMiniapp(options);

if (!compiled.release.targets.every(isTapMiniappTarget)) {
  throw new Error('The compiler returned an unsupported target.');
}

Compilation writes only to the supplied confined staging root. It does not run builders, replace final output, or publish.

Public Export Contract

ExportPurposeInputs and resultLifecycle and errorsWorking example
TapMiniappJsonObjectRepresents immutable JSON object data accepted by authoring contracts.Supplies string-keyed JSON-compatible values to definitions, contributions, and hooks.Type only; non-JSON values fail compiler validation or serialization.Define a package
TapMiniappMaybePromiseAllows provider, builder, publisher, and hook callbacks to be sync or async.Wraps a callback result as either a direct value or a promise of that value.Type only; thrown errors and rejected promises stop the active lifecycle stage.Provide generated content
ReleaseContextCarries the immutable SDK and app release identity resolved by the compiler.Provides versions, package and release IDs, roots, descriptor path, and target list.Created once per lifecycle run and frozen before providers or builders execute.Provide generated content
GeneratedFileDescribes one provider-owned module or asset emitted into confined staging.Contains a safe relative path, string or byte contents, and an optional file kind.Unsafe paths, collisions, symlink escapes, or nondeterministic bytes reject compilation.Provide generated content
ContributionProviderOutputGroups contributions and generated files returned by one provider invocation.Returns optional read-only contribution and generated-file collections.The compiler fingerprints repeated output and rejects malformed or conflicting values.Provide generated content
ContributionProviderDefines a deterministic source of project contributions and generated inputs.Receives a ReleaseContext and returns ContributionProviderOutput.Providers run before target builders and any error stops the lifecycle before publish.Provide generated content
TapMiniappTargetExposeDescribes one project source module exposed by an application target.Selects a runtime and a project source path or generated-source reference.The source must stay inside the project or compiler staging and match the target runtime.Define a package
TargetBuilderContextSupplies one target builder with the resolved release and staging locations.Provides target, release, staged descriptor, staging root, output root, and definition.Created after descriptor verification; builder errors stop assembly and preserve output.Define a package
TargetBuilderDefines the project-owned compiler for one declared target.Receives TargetBuilderContext and completes synchronously or asynchronously.Runs once per selected target before assembly; failures prevent verification and publish.Define a package
TapMiniappTargetDefinitionCombines a remote name, exposed modules, and project-owned target builder.Maps expose names to TapMiniappTargetExpose values and selects a builder.Invalid remote names, empty exposes, or unsupported target combinations reject compile.Define a package
ResolvedTapMiniappTargetExposeDescribes an expose after the compiler resolves its source to an absolute path.Contains the selected runtime and one resolved source path for builder consumption.Produced only after path confinement and generated-file checks pass.Compile authoring
ResolvedTapMiniappTargetDefinitionCarries a target definition with every exposed source fully resolved.Contains the remote name and resolved expose map passed to target builders.Immutable compiler output; builders must not rewrite its release contract.Compile authoring
TapMiniappVerificationContextProvides release, descriptor, and optional package location to policy hooks.Supplies immutable descriptor data and the relevant descriptor or package path.Descriptor hooks run before builders; later hooks receive a verified package root.Add project verification
TapMiniappVerificationHooksDefines typed descriptor, artifact, and runtime checks owned by the project.Accepts optional verification callbacks for the three lifecycle checkpoints.Any thrown or rejected hook stops the lifecycle and prevents output replacement.Add project verification
PublisherContextProvides one publisher with an already verified assembled package.Contains immutable release and descriptor data plus descriptor and package paths.Created only by explicit publication after complete generic and project verification.Connect a publisher
PublisherAdapterDefines one explicit transport for publishing a verified package.Receives PublisherContext and returns provider-specific publication data.Never invoked by build or check; publisher errors leave the assembled package unchanged.Connect a publisher
TapMiniappDefinitionRepresents the complete project-owned authoring configuration.Combines release, identity, presentation, compatibility, targets, contributions, hooks, and publisher.Read-only input; invalid or contradictory fields reject before builders execute.Define a package
CompileTapMiniappOptionsSelects project, staging, output, and optional authoring config paths.Supplies absolute or resolvable roots used by compileTapMiniapp.Staging and output must remain confined, distinct project directories.Compile authoring
CompiledTapMiniappRepresents the fully resolved authoring result ready for lifecycle orchestration.Contains definition, release, descriptor, target definitions, builders, hooks, and publisher.Frozen after compilation; it does not mean target artifacts are built or verified.Compile authoring
LogicalSpecialistDefinitionDescribes a versionless specialist whose release identity belongs to the SDK.Supplies logical ID, specialist behavior, and optional target selection without generated fields.Declaring name, slug, version, or schema version in logical source rejects compile.Provide generated content
LogicalChatBlockDefinitionDescribes a host-rendered chat block attached to one logical specialist.Supplies ID, specialist ID, primitive, accessibility label, and fallback format.Missing specialists, duplicate IDs, or unsupported primitives reject compilation.Provide generated content
defineTapMiniappPreserves precise inference while accepting a typed Miniapp definition.Accepts one TapMiniappDefinition and returns that frozen definition.It performs no build or publication; the compiler validates the returned definition.Define a package
defineContributionProviderFreezes a typed deterministic contribution provider definition.Accepts and returns one ContributionProvider with its ID and callback.It does not invoke the provider; compilation controls execution and validation.Provide generated content
isTapMiniappTargetNarrows an arbitrary string to one supported package target.Accepts a string and returns a TypeScript target predicate result.It has no side effects and returns false for unsupported target names.Compile authoring
stringifyTapMiniappJsonSerializes JSON authoring output with stable formatting and a trailing newline.Accepts a JSON-compatible value and returns deterministic JSON source text.Unsupported values throw during serialization before generated output is written.Provide generated content
loadTapMiniappDefinitionLoads and validates the project's supported authoring config module.Accepts a project root and optional config path and returns a typed definition.Missing, ambiguous, malformed, or unsafe config paths reject before compilation.Compile authoring
compileTapMiniappCompiles project authoring into a staged finalized descriptor and resolved inputs.Accepts CompileTapMiniappOptions and returns CompiledTapMiniapp.Writes only confined staging; validation or determinism failures reject without publish.Compile authoring
packageContributionProviderMaterializes versionless specialist and chat block source definitions.Accepts optional source directories and returns a ContributionProvider.Duplicate, malformed, unsafe, or cross-target definitions reject before builders run.Provide generated content