/** * `defineCapability` — author-friendly factory that builds a {@link DefinedCapability} * from a Zod-typed input/output schema. * * Authors declare a capability with Zod schemas; this factory derives the * wire-format `inputSchema` / `outputSchema` (JSON Schema) and packages the * handler so it can be invoked uniformly through {@link CapabilityRegistry}. * * The runtime per-handler logger (`ctx.log`) is wired by the registry at * invocation time — handlers MUST NOT construct their own logger; all output * goes through `ctx.log` so it lands under the * `capability::` slice (see protocol-v2 carry-forward L2). * * @category Capabilities * @since 2.0.0 */ import type { Capability, CapabilityAudience, CapabilityOrigin, Logger, RenderSpec } from "@skaile/workspaces/types"; import * as z from "zod"; /** * Per-invocation context passed to a capability handler. The registry builds * a fresh context for each call and fills in `log` from * `createLogger({kind: 'capability', subkind: , instance: })`. * * Additional runtime hooks (cancellation signal, store accessors, etc.) can * be threaded in by the bridge layer in later phases; the minimum contract is * `sessionId` + `log`. * * @category Capabilities * @since 2.0.0 * @docLink packages/runner/capabilities#handlercontext-log-convention-carry-forward-l2 */ export type HandlerContext = { /** Cooperative cancellation, including cancellation while awaiting approval. */ signal?: AbortSignal; /** Session this invocation belongs to. */ sessionId: string; /** * Per-capability logger pre-configured as * `createLogger({kind: 'capability', subkind: , instance: })`. * Handlers MUST emit through this logger so invocations land under the * `capability::` slice and stay queryable from the debug * panel and `skaile session logs`. */ log: Logger; }; /** * Arguments to {@link defineCapability}. Mirrors the wire-format * {@link Capability} fields plus the Zod schemas (input + optional output) * and the handler. * * @category Capabilities * @since 2.0.0 * @docLink packages/runner/capabilities#registry-surface */ export type DefineCapabilityArgs = { /** Stable, session-unique name. Convention: `.`. */ name: string; /** * Human-readable label for user-facing surfaces (cmdK action palette, * debug panels). Falls back to `name` when omitted. */ displayName?: string; /** Human/LLM-readable summary; shown to the LLM at tool registration. */ description: string; /** Zod schema validating `args` at invocation time. Converted to JSON Schema. */ input: T; /** Optional Zod schema for the return value. Converted to JSON Schema when present. */ output?: R; /** Where the handler runs. */ side: "client" | "agent"; /** Discriminated tag identifying who registered the capability. */ origin: CapabilityOrigin; /** Lifetime: `session` survives the whole session, `turn` is dropped at end-of-turn. */ scope?: "session" | "turn"; /** When true, the bridge auto-resolves with `{}` immediately and runs the handler in the background. */ fireAndForget?: boolean; /** When true, the platform shows a confirm UI before dispatch. */ requiresApproval?: boolean; /** Documentation hint: side-effect, render, or pure query. */ kind?: "effect" | "render" | "query"; /** * Whether this capability should be exposed in user-facing surfaces * (cmdK / capability menus). Defers to `isUserInvokable` inference rules * when omitted. See `@skaile/workspaces/types#isUserInvokable`. * * @deprecated Set {@link audience} instead. Kept for v2.x compatibility * with skill authors that haven't migrated. */ userInvokable?: boolean; /** * Audience scoping for this capability. When omitted, consumers treat * the capability as `['llm', 'user']` (v2.x default). Host RPCs and * `runner.*` capabilities MUST set this to `['runtime']` so they never * reach the LLM tool list or the user-facing command palette. * * @since 3.0.0 */ audience?: CapabilityAudience[]; /** Appended to the system prompt's `` section. */ promptFragment?: string; /** * Per-capability override for the runner's `capability_result` round-trip * timeout. Omit to use `DEFAULT_CAPABILITY_CALL_TIMEOUT_MS` (60s). Set a * larger value for capabilities that block longer than a normal tool call * (e.g. `platform.ask_session`). */ callTimeoutMs?: number; /** Render contract for capabilities that produce a UI surface. */ render?: RenderSpec; /** * The handler. Receives validated input plus a {@link HandlerContext}. * When `output` is declared, the return type is inferred from the schema; * otherwise the handler may return any value (including `void` for pure * effects). */ handler: (args: z.infer, ctx: HandlerContext) => Promise : unknown>; }; /** * A registered capability. Carries the wire-format {@link Capability} fields * plus the original Zod schemas and the type-erased handler. The registry * stores `DefinedCapability`s; serialization to the wire (for replay or * remote registration) drops the runtime fields. * * @category Capabilities * @since 2.0.0 * @docLink packages/runner/capabilities#registry-surface */ export type DefinedCapability = Capability & { /** Original Zod schema for runtime input validation. Not serialized to the wire. */ readonly inputZod: z.ZodTypeAny; /** Original Zod schema for the optional output, if declared. Not serialized. */ readonly outputZod?: z.ZodTypeAny; /** Type-erased handler invoked through {@link CapabilityRegistry.invoke}. */ handler: (args: unknown, ctx: HandlerContext) => Promise; }; /** * Build a {@link DefinedCapability} from author-friendly Zod-typed args. * * The resulting `inputSchema` / `outputSchema` on the capability are JSON * Schema records (per the wire contract); the original Zod schemas are kept * on `inputZod` / `outputZod` for runtime validation in * {@link CapabilityRegistry.invoke}. * * @example * ```ts * const reactCap = defineCapability({ * name: 'platform.react', * description: 'Acknowledge a user message with a Unicode emoji.', * side: 'client', * origin: { kind: 'client' }, * fireAndForget: true, * input: z.object({ emoji: z.string(), targetSeq: z.number().optional() }), * handler: async ({ emoji }, ctx) => { ctx.log.info('reacted', { emoji }) }, * }); * ``` * * @category Capabilities * @since 2.0.0 * @docLink packages/runner/capabilities#registry-surface */ export declare function defineCapability(args: DefineCapabilityArgs): DefinedCapability; //# sourceMappingURL=define-capability.d.ts.map