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