@skaile/forge-app-actions 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +61 -2
  2. package/dist/module.d.mts +23 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +37 -0
  5. package/dist/runtime/chat/index.d.ts +52 -0
  6. package/dist/runtime/chat/index.js +100 -0
  7. package/dist/runtime/chat/server.d.ts +36 -0
  8. package/dist/runtime/chat/server.js +27 -0
  9. package/dist/runtime/chat/types.d.ts +10 -0
  10. package/dist/runtime/chat/types.js +0 -0
  11. package/dist/runtime/client-capabilities.d.ts +29 -0
  12. package/dist/runtime/client-capabilities.js +25 -0
  13. package/dist/runtime/components-nuxt-ui/ForgeCapabilityApproval.d.vue.ts +2 -0
  14. package/dist/runtime/components-nuxt-ui/ForgeCapabilityApproval.vue +125 -0
  15. package/dist/runtime/components-nuxt-ui/ForgeCapabilityApproval.vue.d.ts +2 -0
  16. package/dist/runtime/components-nuxt-ui/ForgeCommandPalette.d.vue.ts +2 -0
  17. package/dist/runtime/components-nuxt-ui/ForgeCommandPalette.vue +218 -0
  18. package/dist/runtime/components-nuxt-ui/ForgeCommandPalette.vue.d.ts +2 -0
  19. package/dist/runtime/composables/defineClientCapability.d.ts +64 -0
  20. package/dist/runtime/composables/defineClientCapability.js +40 -0
  21. package/dist/runtime/composables/defineForgeAction.d.ts +82 -0
  22. package/dist/runtime/composables/defineForgeAction.js +147 -0
  23. package/dist/runtime/composables/useAgentCapabilities.d.ts +78 -0
  24. package/dist/runtime/composables/useAgentCapabilities.js +94 -0
  25. package/dist/runtime/composables/useCapabilityApproval.d.ts +109 -0
  26. package/dist/runtime/composables/useCapabilityApproval.js +74 -0
  27. package/dist/runtime/composables/useCapabilityInvocations.d.ts +150 -0
  28. package/dist/runtime/composables/useCapabilityInvocations.js +118 -0
  29. package/dist/runtime/composables/useCommandPalette.d.ts +28 -0
  30. package/dist/runtime/composables/useCommandPalette.js +49 -0
  31. package/dist/runtime/composables/usePaletteArgStep.d.ts +47 -0
  32. package/dist/runtime/composables/usePaletteArgStep.js +51 -0
  33. package/dist/runtime/internal/describe-error.d.ts +10 -0
  34. package/dist/runtime/internal/describe-error.js +12 -0
  35. package/dist/runtime/server/index.d.ts +7 -0
  36. package/dist/runtime/server/index.js +2 -0
  37. package/dist/runtime/server/utils/capability-registry.d.ts +35 -0
  38. package/dist/runtime/server/utils/capability-registry.js +24 -0
  39. package/dist/runtime/server/utils/client-capability-bridge.d.ts +647 -0
  40. package/dist/runtime/server/utils/client-capability-bridge.js +755 -0
  41. package/dist/runtime/shims-vue.d.ts +8 -0
  42. package/dist/runtime/types/client-capability.d.ts +159 -0
  43. package/dist/runtime/types/client-capability.js +0 -0
  44. package/dist/runtime/types/command-palette.d.ts +75 -0
  45. package/dist/runtime/types/command-palette.js +0 -0
  46. package/dist/runtime/types/forge-action.d.ts +152 -0
  47. package/dist/runtime/types/forge-action.js +0 -0
  48. package/dist/runtime/types/index.d.ts +3 -0
  49. package/dist/runtime/types/index.js +0 -0
  50. package/dist/types.d.mts +9 -0
  51. package/package.json +94 -4
  52. package/src/runtime/chat/index.ts +190 -0
  53. package/src/runtime/chat/server.ts +64 -0
  54. package/src/runtime/chat/types.ts +13 -0
  55. package/src/runtime/client-capabilities.ts +82 -0
  56. package/src/runtime/components-nuxt-ui/ForgeCapabilityApproval.vue +240 -0
  57. package/src/runtime/components-nuxt-ui/ForgeCommandPalette.vue +363 -0
  58. package/src/runtime/composables/defineClientCapability.ts +119 -0
  59. package/src/runtime/composables/defineForgeAction.ts +278 -0
  60. package/src/runtime/composables/useAgentCapabilities.ts +215 -0
  61. package/src/runtime/composables/useCapabilityApproval.ts +219 -0
  62. package/src/runtime/composables/useCapabilityInvocations.ts +325 -0
  63. package/src/runtime/composables/useCommandPalette.ts +97 -0
  64. package/src/runtime/composables/usePaletteArgStep.ts +110 -0
  65. package/src/runtime/internal/describe-error.ts +21 -0
  66. package/src/runtime/server/index.ts +8 -0
  67. package/src/runtime/server/utils/capability-registry.ts +66 -0
  68. package/src/runtime/server/utils/client-capability-bridge.ts +1201 -0
  69. package/src/runtime/shims-vue.d.ts +8 -0
  70. package/src/runtime/types/client-capability.ts +178 -0
  71. package/src/runtime/types/command-palette.ts +78 -0
  72. package/src/runtime/types/forge-action.ts +166 -0
  73. package/src/runtime/types/index.ts +24 -0
@@ -0,0 +1,8 @@
1
+ // Ambient module declaration so `tsc --noEmit` resolves `*.vue` imports.
2
+ // Runtime resolution is handled by Vite / @vitejs/plugin-vue at build time.
3
+ declare module "*.vue" {
4
+ import type { DefineComponent } from "vue";
5
+ // biome-ignore lint/suspicious/noExplicitAny: catch-all for SFC components
6
+ const component: DefineComponent<object, object, any>;
7
+ export default component;
8
+ }
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Types for the **forge app channel** — capabilities that are declared in the
3
+ * browser, announced upward through Nitro, and (from ticket 04 onward) invoked
4
+ * by the agent with the handler running where the state actually lives.
5
+ *
6
+ * The authoring shape deliberately mirrors `@skaile/workspaces/app-sdk`'s
7
+ * `defineAppCapability` field-for-field, so that a second transport (registering
8
+ * into the *platform's* session agent when a forge app is embedded as a
9
+ * `protocol: true` preview app) becomes a transport swap rather than a rewrite.
10
+ * See `docs/superpowers/specs/2026-08-22-forge-app-channel-design.md` §2.1.
11
+ *
12
+ * Two deliberate divergences from `defineAppCapability`, both forced by the
13
+ * protocol version forge pins:
14
+ *
15
+ * - `side` is `"client"`, not `"app"`. The `Capability.side` union in the
16
+ * `@skaile/workspaces` releases forge pins (0.13.0 … 0.48.1) is
17
+ * `"client" | "agent"`; `"app"` only exists on the 3.x line that also ships
18
+ * `app-sdk`. Forge's own agent treats the browser as the *client* side, which
19
+ * is what `"client"` already means on the wire.
20
+ * - `origin` is not authored here. `defineAppCapability` has the SDK stamp it at
21
+ * registration time because only the SDK knows the `appId`; forge has no
22
+ * `appId`, so {@link ClientCapabilityBridge} stamps `{ kind: "client" }` when
23
+ * the announcement reaches Nitro. Same split, different stamper.
24
+ */
25
+
26
+ import type {
27
+ CapabilityAudience,
28
+ CapabilityOrigin,
29
+ RenderSpec,
30
+ } from "@skaile/workspaces/sdk/types";
31
+ import type * as z from "zod";
32
+
33
+ /**
34
+ * Logger handed to a client capability handler. Structural subset of `console`
35
+ * (and of consola), so either can be passed without an adapter.
36
+ */
37
+ export interface ClientCapabilityLogger {
38
+ info(message: string, ...args: unknown[]): void;
39
+ warn(message: string, ...args: unknown[]): void;
40
+ error(message: string, ...args: unknown[]): void;
41
+ }
42
+
43
+ /**
44
+ * Per-invocation context passed to a client capability handler.
45
+ *
46
+ * The analogue of `app-sdk`'s `AppHandlerContext`. It carries the bridge's
47
+ * opaque {@link ClientCapabilityContext.sessionKey} instead of a platform
48
+ * `sessionId`, and has no `appId` (forge apps are not registered platform apps).
49
+ */
50
+ export interface ClientCapabilityContext {
51
+ /**
52
+ * The opaque session key this invocation was routed under — the same string
53
+ * the SPA announced with. See the bridge's session-key contract.
54
+ */
55
+ sessionKey: string;
56
+ /** Correlation token of the originating `capability_invoked` event. */
57
+ callId: string;
58
+ /** The capability name as invoked (useful when one handler serves aliases). */
59
+ name: string;
60
+ /** Logger to emit through; defaults to `console`. */
61
+ log: ClientCapabilityLogger;
62
+ }
63
+
64
+ /**
65
+ * Author-facing arguments to `defineClientCapability`.
66
+ *
67
+ * Field names are identical to `app-sdk`'s `DefineAppCapabilityArgs`, minus
68
+ * `side` (fixed) and `origin` (stamped by the bridge).
69
+ */
70
+ export interface DefineClientCapabilityArgs<
71
+ T extends z.ZodType,
72
+ R extends z.ZodType | undefined = undefined,
73
+ > {
74
+ /**
75
+ * Stable, session-unique name. Convention: `app.<sector>.<verb>` — e.g.
76
+ * `app.workspace.open_file`. The platform rejects registrations outside the
77
+ * `app.` namespace; forge's own agent does not, but the convention is adopted
78
+ * now so a later embed costs no rename.
79
+ */
80
+ name: string;
81
+ /** Human-readable label for user-facing surfaces; falls back to `name`. */
82
+ displayName?: string;
83
+ /** Human/LLM-readable summary; shown to the agent at tool registration. */
84
+ description: string;
85
+ /** Zod schema validating the invocation arguments. Converted to JSON Schema. */
86
+ input: T;
87
+ /** Optional Zod schema for the return value. */
88
+ output?: R;
89
+ /** Lifetime: `session` survives the whole session, `turn` is dropped at end-of-turn. */
90
+ scope?: "session" | "turn";
91
+ /**
92
+ * When true, the invocation must be confirmed before the handler runs. Forge
93
+ * has no platform approval gate — spec §L7 puts the confirm in the browser
94
+ * wrapper. Declared here so the field survives a transport swap.
95
+ */
96
+ requiresApproval?: boolean;
97
+ /** Documentation hint: side-effect, render, or pure query. */
98
+ kind?: "effect" | "render" | "query";
99
+ /** Audience scoping. Omit for the wire default (`['llm','user']`). */
100
+ audience?: CapabilityAudience[];
101
+ /** Appended to the system prompt's `<CAPABILITIES>` section. */
102
+ promptFragment?: string;
103
+ /** Per-capability override for the result round-trip timeout. */
104
+ callTimeoutMs?: number;
105
+ /** Render contract for capabilities that produce a UI surface. */
106
+ render?: RenderSpec;
107
+ /**
108
+ * The handler — runs in the browser. Receives validated input plus a
109
+ * {@link ClientCapabilityContext}.
110
+ *
111
+ * Not invoked by this ticket: the announce half only makes the agent's tool
112
+ * list truthful. Dispatch lands in ticket 04.
113
+ */
114
+ handler: (
115
+ args: z.infer<T>,
116
+ ctx: ClientCapabilityContext,
117
+ ) => Promise<R extends z.ZodType ? z.infer<R> : unknown>;
118
+ }
119
+
120
+ /**
121
+ * A defined client capability: the wire fields the bridge announces, plus the
122
+ * Zod schemas and type-erased handler kept browser-side for runtime validation
123
+ * and inbound dispatch.
124
+ *
125
+ * `inputZod` / `outputZod` / `handler` never cross the wire — see
126
+ * {@link ClientCapabilityDescriptor}.
127
+ */
128
+ export interface DefinedClientCapability {
129
+ name: string;
130
+ displayName?: string;
131
+ description: string;
132
+ /** Derived from `input` via `z.toJSONSchema()` — never hand-written. */
133
+ inputSchema: Record<string, unknown>;
134
+ /** Derived from `output` via `z.toJSONSchema()` when `output` is declared. */
135
+ outputSchema?: Record<string, unknown>;
136
+ /** Always `"client"` — the handler runs in the browser. */
137
+ side: "client";
138
+ scope?: "session" | "turn";
139
+ requiresApproval?: boolean;
140
+ kind?: "effect" | "render" | "query";
141
+ audience?: CapabilityAudience[];
142
+ promptFragment?: string;
143
+ callTimeoutMs?: number;
144
+ render?: RenderSpec;
145
+ /** Original Zod schema for runtime input validation. Not serialized. */
146
+ readonly inputZod: z.ZodType;
147
+ /** Original Zod schema for the optional output, if declared. Not serialized. */
148
+ readonly outputZod?: z.ZodType;
149
+ /** Type-erased handler, dispatched on an inbound `capability_invoked`. */
150
+ handler: (args: unknown, ctx: ClientCapabilityContext) => Promise<unknown>;
151
+ }
152
+
153
+ /**
154
+ * The JSON-serialisable half of a {@link DefinedClientCapability} — exactly what
155
+ * the SPA POSTs upward in an announcement. `origin` is absent: the bridge stamps
156
+ * it (see the module docblock).
157
+ */
158
+ export type ClientCapabilityDescriptor = Omit<
159
+ DefinedClientCapability,
160
+ "inputZod" | "outputZod" | "handler"
161
+ >;
162
+
163
+ /**
164
+ * Body of an upward announcement POST, minus whatever session-identifying
165
+ * fields the consuming app's route adds (forge-workspace adds `mode`).
166
+ */
167
+ export interface ClientCapabilityAnnouncement {
168
+ /**
169
+ * Stable per-tab token. The bridge records it as the session's owner so
170
+ * spec §L4's last-writer-wins routing has something to compare (ticket 05).
171
+ */
172
+ subscriberId?: string;
173
+ /** The full registry, always sent whole — announcements are not deltas. */
174
+ capabilities: ClientCapabilityDescriptor[];
175
+ }
176
+
177
+ /** Origin kind a client capability always carries once stamped by the bridge. */
178
+ export type ClientCapabilityOrigin = Extract<CapabilityOrigin, { kind: "client" }>;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Types for the forge command palette (Cmd+K / Ctrl+K global action menu).
3
+ */
4
+
5
+ /** One candidate value offered while the palette collects an action's argument. */
6
+ export interface PaletteArgOption {
7
+ /** The value handed to the action's handler when this row is picked. */
8
+ value: string;
9
+ /** Display label shown in the list. */
10
+ label: string;
11
+ /** Optional secondary line. */
12
+ description?: string;
13
+ /** Iconify icon name, e.g. `"lucide:file"`. */
14
+ icon?: string;
15
+ }
16
+
17
+ /**
18
+ * Declares that an action needs **one string argument** before it can run, and
19
+ * how the palette should collect it.
20
+ *
21
+ * Selecting such an action does not close the palette: it switches into an
22
+ * argument step (breadcrumb + a fresh input), and only the second Enter runs
23
+ * the handler. Escape returns to the action list.
24
+ *
25
+ * This exists because {@link https://github.com/skaile-ai/forge-app-actions | forge}
26
+ * actions are declared once for two audiences (see `defineForgeAction`): the
27
+ * agent supplies `{ path }` as structured input, and the user needs somewhere
28
+ * to type it. Without this seam a palette entry for an action with required
29
+ * input could only ever fail on Enter.
30
+ */
31
+ export interface PaletteArgPrompt {
32
+ /** Breadcrumb shown during the argument step. Defaults to the action label. */
33
+ label?: string;
34
+ /** Placeholder for the argument input. */
35
+ placeholder?: string;
36
+ /**
37
+ * Candidate values for the current query — a file search, a list of models,
38
+ * whatever the argument ranges over. Omit for a free-text argument.
39
+ *
40
+ * Called on every keystroke; implementations should debounce or abort their
41
+ * own I/O (see `useFileSearch`). A rejected promise is treated as "no
42
+ * candidates", never as a palette error.
43
+ */
44
+ options?: (query: string) => PaletteArgOption[] | Promise<PaletteArgOption[]>;
45
+ /**
46
+ * Accept a value the user typed that is not among `options`. Defaults to
47
+ * `true` when `options` is absent (free text), `false` when it is present
48
+ * (pick-from-list).
49
+ */
50
+ allowCustom?: boolean;
51
+ }
52
+
53
+ export interface PaletteAction {
54
+ /** Unique stable identifier, e.g. `"workspace.open-file"`. */
55
+ id: string;
56
+ /** Display label shown in the list. */
57
+ label: string;
58
+ /** Optional secondary line (hint, shortcut, description). */
59
+ description?: string;
60
+ /** Iconify icon name, e.g. `"lucide:file"`. */
61
+ icon?: string;
62
+ /**
63
+ * Called when the user selects this action.
64
+ *
65
+ * Receives the collected string when {@link PaletteAction.arg} is declared,
66
+ * and nothing otherwise — a zero-argument handler stays valid.
67
+ */
68
+ handler: (arg?: string) => void | Promise<void>;
69
+ /** Extra search terms that do not appear in the UI. */
70
+ keywords?: string[];
71
+ /** Display group header (e.g. `"Files"`, `"Agent"`). Optional. */
72
+ group?: string;
73
+ /**
74
+ * When present, the palette collects one string before calling
75
+ * {@link PaletteAction.handler}. See {@link PaletteArgPrompt}.
76
+ */
77
+ arg?: PaletteArgPrompt;
78
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Types for **forge actions** — one declaration that serves both the Cmd+K
3
+ * command palette and the agent.
4
+ *
5
+ * See `docs/superpowers/specs/2026-08-22-forge-app-channel-design.md` §2.3.
6
+ * The short version: forge already had two registries for what is really one
7
+ * concept. `useCommandPalette()` holds things a *user* can trigger;
8
+ * `useAgentCapabilities()` holds things an *agent* can trigger. A capability is
9
+ * a palette action with a typed input and a different audience, so a
10
+ * {@link ForgeAction} is authored once and *written through* to whichever of
11
+ * those two registries its `audience` names. There is no third registry.
12
+ */
13
+
14
+ import type * as z from "zod";
15
+ import type {
16
+ ClientCapabilityLogger,
17
+ DefineClientCapabilityArgs,
18
+ DefinedClientCapability,
19
+ } from "./client-capability";
20
+ import type { PaletteAction, PaletteArgPrompt } from "./command-palette";
21
+
22
+ /** Who may trigger an action. `'user'` → Cmd+K, `'llm'` → agent capability. */
23
+ export type ForgeActionAudience = "user" | "llm";
24
+
25
+ /**
26
+ * Per-run context handed to a forge action's `run`.
27
+ *
28
+ * A superset of `ClientCapabilityContext`: the agent path fills every field,
29
+ * the palette path fills what it can. `source` is what an action checks when it
30
+ * genuinely needs to behave differently — most do not.
31
+ */
32
+ export interface ForgeActionContext {
33
+ /** Which surface triggered this run. */
34
+ source: ForgeActionAudience;
35
+ /** The capability name as invoked (a deprecated alias reports the alias). */
36
+ name: string;
37
+ /** Opaque session key. Empty string on the palette path. */
38
+ sessionKey: string;
39
+ /** Correlation token of the agent's call. `undefined` on the palette path. */
40
+ callId?: string;
41
+ /** Logger to emit through; defaults to `console`. */
42
+ log: ClientCapabilityLogger;
43
+ }
44
+
45
+ /**
46
+ * How Cmd+K collects the single string an action needs before it can run, plus
47
+ * how to turn that string into the action's declared input.
48
+ */
49
+ export interface ForgeActionArg<T extends z.ZodType> extends PaletteArgPrompt {
50
+ /**
51
+ * Turn the collected string into the action's input. Its result is parsed
52
+ * through the action's zod schema exactly like the agent's input is, so a
53
+ * mistake here fails the same way and in the same place.
54
+ */
55
+ toInput: (value: string) => z.input<T>;
56
+ }
57
+
58
+ /**
59
+ * Author-facing arguments to `defineForgeAction`.
60
+ *
61
+ * The palette-shaped fields (`id`, `label`, `icon`, `keywords`, `group`) are
62
+ * exactly `PaletteAction`'s. The agent-shaped fields (`kind`, `promptFragment`,
63
+ * `requiresApproval`, `callTimeoutMs`, `scope`, `render`) are exactly
64
+ * `defineClientCapability`'s, which in turn mirror `@skaile/workspaces/app-sdk`
65
+ * field-for-field (spec §2.1). Nothing is renamed on the way through.
66
+ */
67
+ export interface DefineForgeActionArgs<T extends z.ZodType>
68
+ extends Pick<
69
+ DefineClientCapabilityArgs<z.ZodType>,
70
+ "kind" | "promptFragment" | "requiresApproval" | "callTimeoutMs" | "scope" | "render"
71
+ > {
72
+ /**
73
+ * Palette id, **without** the `app.` prefix — e.g. `workspace.open_file`.
74
+ *
75
+ * The capability name is derived from it as `app.<id>`, because the platform
76
+ * rejects any registration outside the `app.` namespace (spec §2.2) while the
77
+ * palette has always used bare ids. One id, two namespaces, no drift. Pass
78
+ * {@link DefineForgeActionArgs.name} to override the derived name; passing an
79
+ * id that already starts with `app.` throws.
80
+ */
81
+ id: string;
82
+ /** Display label for the palette row. Also the capability's `displayName`. */
83
+ label: string;
84
+ /**
85
+ * Secondary line in the palette **and** the description the model reads at
86
+ * tool registration. Required when the audience includes `'llm'` — a tool
87
+ * with no description is a tool the model cannot use correctly.
88
+ */
89
+ description?: string;
90
+ /**
91
+ * Short secondary line for the palette row. Defaults to
92
+ * {@link DefineForgeActionArgs.description}, which is written for the model
93
+ * and is usually far too long for a list row — an action visible on both
94
+ * surfaces normally wants both.
95
+ */
96
+ hint?: string;
97
+ /** Iconify icon name for the palette row, e.g. `"lucide:file"`. */
98
+ icon?: string;
99
+ /** Extra palette search terms that do not appear in the UI. */
100
+ keywords?: string[];
101
+ /** Palette group header (e.g. `"Files"`, `"Agent"`). */
102
+ group?: string;
103
+ /**
104
+ * Who may trigger this. Defaults to **both** (`['user', 'llm']`) — that
105
+ * default is the point of the whole helper: agent-controllability is what you
106
+ * get unless you opt out. Narrow to `['user']` for something the model has no
107
+ * business driving, `['llm']` for something with no sensible UI affordance.
108
+ */
109
+ audience?: ForgeActionAudience[];
110
+ /** Zod schema for the run arguments. Defaults to `z.object({})`. */
111
+ input?: T;
112
+ /** Optional zod schema for the return value. Validated advisory-only. */
113
+ output?: z.ZodType;
114
+ /**
115
+ * Override the derived capability name. Only for a name that cannot be
116
+ * expressed as `app.<palette id>`; prefer letting it derive.
117
+ */
118
+ name?: string;
119
+ /**
120
+ * Old capability names to keep answering, registered as deprecated aliases
121
+ * sharing this action's handler instance (spec §2.2). Agent-side only — a
122
+ * deprecated duplicate has no business appearing in Cmd+K.
123
+ */
124
+ deprecatedNames?: string[];
125
+ /**
126
+ * How Cmd+K collects the input. Required when the audience includes `'user'`
127
+ * and the input schema does not accept `{}` — otherwise the palette row would
128
+ * exist only to fail on Enter, and `defineForgeAction` throws at define time
129
+ * rather than letting you ship that.
130
+ */
131
+ arg?: ForgeActionArg<T>;
132
+ /** The implementation. One function, both surfaces. */
133
+ run: (input: z.infer<T>, ctx: ForgeActionContext) => unknown | Promise<unknown>;
134
+ }
135
+
136
+ /**
137
+ * A defined forge action: the two registry-shaped projections of one
138
+ * declaration, plus the pieces a caller may want directly.
139
+ *
140
+ * `paletteAction` is `undefined` when the audience omits `'user'`;
141
+ * `capability` is `undefined` when it omits `'llm'`. That absence *is* the
142
+ * enforcement — a user-only action has nothing to announce upward, and an
143
+ * llm-only action has nothing to put in the palette.
144
+ */
145
+ export interface ForgeAction {
146
+ /** The palette id, as authored. */
147
+ id: string;
148
+ /** The derived (or overridden) `app.`-namespaced capability name. */
149
+ name: string;
150
+ label: string;
151
+ audience: ForgeActionAudience[];
152
+ /** The input schema, defaulted to `z.object({})` when none was declared. */
153
+ readonly inputZod: z.ZodType;
154
+ /** The Cmd+K projection. Absent unless the audience includes `'user'`. */
155
+ paletteAction?: PaletteAction;
156
+ /** The agent projection. Absent unless the audience includes `'llm'`. */
157
+ capability?: DefinedClientCapability;
158
+ /** Deprecated-alias capabilities, if any. Empty when none were declared. */
159
+ aliases: DefinedClientCapability[];
160
+ /**
161
+ * Run the action directly, bypassing both surfaces. Input is parsed through
162
+ * the declared schema first, so this is not a way around validation. Handy
163
+ * for a button that triggers the same behaviour as its palette entry.
164
+ */
165
+ run(input?: unknown, ctx?: Partial<ForgeActionContext>): Promise<unknown>;
166
+ }
@@ -0,0 +1,24 @@
1
+ // ── Browser-side agent capabilities ─────────────────────────────────────────
2
+ export type {
3
+ ClientCapabilityAnnouncement,
4
+ ClientCapabilityContext,
5
+ ClientCapabilityDescriptor,
6
+ ClientCapabilityLogger,
7
+ ClientCapabilityOrigin,
8
+ DefineClientCapabilityArgs,
9
+ DefinedClientCapability,
10
+ } from "./client-capability";
11
+ // ── Command palette ─────────────────────────────────────────────────────────
12
+ export type {
13
+ PaletteAction,
14
+ PaletteArgOption,
15
+ PaletteArgPrompt,
16
+ } from "./command-palette";
17
+ // ── Unified action API ──────────────────────────────────────────────────────
18
+ export type {
19
+ DefineForgeActionArgs,
20
+ ForgeAction,
21
+ ForgeActionArg,
22
+ ForgeActionAudience,
23
+ ForgeActionContext,
24
+ } from "./forge-action";