indusagi-coding-agent 0.2.8 → 0.2.9
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/package.json +2 -1
- package/src/_decls/entry.ts +18 -0
- package/src/_decls/guardrails.ts +35 -0
- package/src/_decls/index.ts +26 -0
- package/src/addons/contract.ts +236 -0
- package/src/addons/dispatch/event-dispatcher.ts +164 -0
- package/src/addons/dispatch/index.ts +25 -0
- package/src/addons/dispatch/tool-interceptor.ts +208 -0
- package/src/addons/host.ts +225 -0
- package/src/addons/index.ts +112 -0
- package/src/addons/manifest.ts +158 -0
- package/src/addons/sandbox.ts +170 -0
- package/src/addons/surface.ts +78 -0
- package/src/boot/auth-vault.ts +195 -0
- package/src/boot/boot.ts +138 -0
- package/src/boot/contract.ts +238 -0
- package/src/boot/heap.ts +59 -0
- package/src/boot/index.ts +28 -0
- package/src/boot/invocation.ts +93 -0
- package/src/boot/runners/addon-wiring.ts +153 -0
- package/src/boot/runners/checkpoint.ts +169 -0
- package/src/boot/runners/delegate-runner.ts +294 -0
- package/src/boot/runners/index.ts +13 -0
- package/src/boot/runners/link-runner.ts +45 -0
- package/src/boot/runners/memdir.ts +168 -0
- package/src/boot/runners/oneshot-runner.ts +58 -0
- package/src/boot/runners/read-state.ts +90 -0
- package/src/boot/runners/registry.ts +42 -0
- package/src/boot/runners/repl-runner.ts +143 -0
- package/src/boot/runners/server-mode.ts +121 -0
- package/src/boot/runners/session.ts +641 -0
- package/src/boot/server-token.ts +148 -0
- package/src/boot/stages.ts +167 -0
- package/src/boot/upgrade/apply.ts +94 -0
- package/src/boot/upgrade/index.ts +13 -0
- package/src/boot/upgrade/upgrades.ts +289 -0
- package/src/briefing/compose.ts +150 -0
- package/src/briefing/context-docs.ts +19 -0
- package/src/briefing/contract.ts +717 -0
- package/src/briefing/index.ts +31 -0
- package/src/briefing/macros.ts +97 -0
- package/src/briefing/skills.ts +47 -0
- package/src/capability-deck/bridge-ledger/index.ts +27 -0
- package/src/capability-deck/bridge-ledger/key.ts +67 -0
- package/src/capability-deck/bridge-ledger/ledger.ts +131 -0
- package/src/capability-deck/bridge-ledger/network.ts +117 -0
- package/src/capability-deck/builtin-bridge.ts +312 -0
- package/src/capability-deck/cards/bg-process-card.ts +335 -0
- package/src/capability-deck/cards/index.ts +115 -0
- package/src/capability-deck/cards/memory-card.ts +146 -0
- package/src/capability-deck/cards/plan-file.ts +97 -0
- package/src/capability-deck/cards/plan-tools.ts +185 -0
- package/src/capability-deck/cards/saas-card.ts +183 -0
- package/src/capability-deck/cards/task-card.ts +207 -0
- package/src/capability-deck/cards/todo-card.ts +168 -0
- package/src/capability-deck/cards/workflow-card.ts +247 -0
- package/src/capability-deck/contract.ts +388 -0
- package/src/capability-deck/index.ts +48 -0
- package/src/capability-deck/manifest.ts +109 -0
- package/src/capability-deck/provision.ts +169 -0
- package/src/channels/contract.ts +191 -0
- package/src/channels/framer.ts +50 -0
- package/src/channels/index.ts +101 -0
- package/src/channels/link/dialog.ts +129 -0
- package/src/channels/link/driver.ts +190 -0
- package/src/channels/link/index.ts +34 -0
- package/src/channels/link/server.ts +134 -0
- package/src/channels/oneshot.ts +90 -0
- package/src/channels/ops.ts +65 -0
- package/src/channels/session-ops.ts +81 -0
- package/src/conductor/bash-guard.ts +599 -0
- package/src/conductor/catalog/catalog.ts +116 -0
- package/src/conductor/catalog/index.ts +8 -0
- package/src/conductor/catalog/matcher.ts +134 -0
- package/src/conductor/conductor.ts +234 -0
- package/src/conductor/contract.ts +842 -0
- package/src/conductor/diagnostics.ts +227 -0
- package/src/conductor/index.ts +33 -0
- package/src/conductor/permissions.ts +588 -0
- package/src/conductor/quota-error.ts +49 -0
- package/src/conductor/signal-hub/hub.ts +46 -0
- package/src/conductor/signal-hub/index.ts +2 -0
- package/src/conductor/signal-hub/translate.test.ts +81 -0
- package/src/conductor/signal-hub/translate.ts +74 -0
- package/src/conductor/skill-parse/index.ts +2 -0
- package/src/conductor/skill-parse/parse.ts +108 -0
- package/src/conductor/transcript-store/index.ts +22 -0
- package/src/conductor/transcript-store/serialize.ts +116 -0
- package/src/conductor/transcript-store/store.ts +205 -0
- package/src/console/auth-status.ts +56 -0
- package/src/console/components/AgentsView.ts +165 -0
- package/src/console/components/BackgroundAgents.ts +155 -0
- package/src/console/components/Banner.ts +334 -0
- package/src/console/components/Composer.ts +94 -0
- package/src/console/components/StatusBar.ts +49 -0
- package/src/console/components/TerminalConsole.ts +1090 -0
- package/src/console/components/WorkingIndicator.ts +98 -0
- package/src/console/components/banner-sweep.ts +24 -0
- package/src/console/components/welcome.ts +74 -0
- package/src/console/contract.ts +630 -0
- package/src/console/index.ts +34 -0
- package/src/console/input/complete.ts +127 -0
- package/src/console/input/dir-reader.ts +34 -0
- package/src/console/input/index.ts +23 -0
- package/src/console/input/keymap.ts +159 -0
- package/src/console/input/paste.ts +104 -0
- package/src/console/mount.ts +56 -0
- package/src/console/overlays/approval-queue.ts +57 -0
- package/src/console/overlays/approval.ts +130 -0
- package/src/console/overlays/auth.ts +342 -0
- package/src/console/overlays/boards.ts +308 -0
- package/src/console/overlays/host.ts +36 -0
- package/src/console/overlays/index.ts +26 -0
- package/src/console/overlays/pickers.ts +258 -0
- package/src/console/overlays/sessions.ts +190 -0
- package/src/console/reducer.ts +182 -0
- package/src/console/slash/builtins.ts +81 -0
- package/src/console/slash/commands/dynamic.ts +83 -0
- package/src/console/slash/commands/integrations.ts +695 -0
- package/src/console/slash/commands/shared.ts +75 -0
- package/src/console/slash/commands/transcript.ts +263 -0
- package/src/console/slash/commands/workbench.ts +246 -0
- package/src/console/slash/index.ts +15 -0
- package/src/console/slash/registry.ts +70 -0
- package/src/console/slash/resolve.ts +63 -0
- package/src/console/startup.ts +209 -0
- package/src/console/theme/adapter.ts +45 -0
- package/src/console/theme/index.ts +7 -0
- package/src/console/theme/palette.ts +68 -0
- package/src/console/theme/resolve.ts +39 -0
- package/src/console/theme/tokens.ts +71 -0
- package/src/entry.ts +55 -0
- package/src/guardrails.ts +37 -0
- package/src/index.ts +18 -0
- package/src/insight/channel.ts +88 -0
- package/src/insight/contract.ts +185 -0
- package/src/insight/index.ts +110 -0
- package/src/insight/recorder.ts +213 -0
- package/src/insight/redaction.ts +157 -0
- package/src/insight/replay.ts +158 -0
- package/src/insight/sampling.ts +70 -0
- package/src/insight/serialize.ts +50 -0
- package/src/insight/sinks/console.ts +64 -0
- package/src/insight/sinks/file.ts +40 -0
- package/src/insight/sinks/index.ts +24 -0
- package/src/insight/sinks/stream.ts +54 -0
- package/src/integrations/sarvam/attach.ts +239 -0
- package/src/integrations/sarvam/config.ts +156 -0
- package/src/integrations/sarvam/index.ts +25 -0
- package/src/integrations/sarvam/sarvam.test.ts +60 -0
- package/src/integrations/sarvam/types.ts +27 -0
- package/src/integrations/zoho/attach.ts +342 -0
- package/src/integrations/zoho/config.ts +125 -0
- package/src/integrations/zoho/index.ts +27 -0
- package/src/integrations/zoho/types.ts +21 -0
- package/src/integrations/zoho/zoho.test.ts +50 -0
- package/src/kit/clipboard-image.ts +107 -0
- package/src/kit/external-editor.ts +48 -0
- package/src/kit/image.ts +59 -0
- package/src/kit/index.ts +51 -0
- package/src/kit/shell.ts +19 -0
- package/src/kit/tool-fetch.ts +85 -0
- package/src/launch/catalog.ts +148 -0
- package/src/launch/contract.ts +187 -0
- package/src/launch/credentials.ts +625 -0
- package/src/launch/index.ts +98 -0
- package/src/launch/invocation/attachments.ts +179 -0
- package/src/launch/invocation/flags.ts +196 -0
- package/src/launch/invocation/index.ts +25 -0
- package/src/launch/invocation/read.ts +260 -0
- package/src/launch/invocation/usage.ts +67 -0
- package/src/launch/login.ts +324 -0
- package/src/launch/oauth.test.ts +18 -0
- package/src/launch/oauth.ts +203 -0
- package/src/launch/packages.ts +194 -0
- package/src/launch/pickers.ts +189 -0
- package/src/runtime-bridge/bridges/_drive.ts +96 -0
- package/src/runtime-bridge/bridges/builtins.ts +68 -0
- package/src/runtime-bridge/bridges/claude-cli.ts +123 -0
- package/src/runtime-bridge/bridges/codex-cli.ts +142 -0
- package/src/runtime-bridge/bridges/index.ts +33 -0
- package/src/runtime-bridge/bridges/indusagi-cli.ts +155 -0
- package/src/runtime-bridge/broker.ts +227 -0
- package/src/runtime-bridge/contract.ts +122 -0
- package/src/runtime-bridge/index.ts +79 -0
- package/src/runtime-bridge/sink.ts +180 -0
- package/src/sessions/contract.ts +81 -0
- package/src/sessions/index.ts +13 -0
- package/src/sessions/library.ts +229 -0
- package/src/settings/contract.ts +114 -0
- package/src/settings/index.ts +32 -0
- package/src/settings/manager.ts +117 -0
- package/src/transcript-export/index.ts +45 -0
- package/src/transcript-export/publish.ts +260 -0
- package/src/transcript-export/sgr.ts +315 -0
- package/src/transcript-export/template.ts +272 -0
- package/src/transcript-export/theme-bridge.ts +150 -0
- package/src/window-budget/budget/estimate.ts +135 -0
- package/src/window-budget/budget/gate.ts +33 -0
- package/src/window-budget/budget/index.ts +16 -0
- package/src/window-budget/budget/slice.ts +56 -0
- package/src/window-budget/condenser.ts +58 -0
- package/src/window-budget/contract.ts +184 -0
- package/src/window-budget/index.ts +19 -0
- package/src/window-budget/microcompact.ts +95 -0
- package/src/window-budget/rehydrate.ts +136 -0
- package/src/window-budget/summarize/condense.ts +103 -0
- package/src/window-budget/summarize/index.ts +14 -0
- package/src/window-budget/summarize/prompt.ts +149 -0
- package/src/workflow-engine/agent-runner.ts +181 -0
- package/src/workflow-engine/display.ts +224 -0
- package/src/workflow-engine/engine.ts +294 -0
- package/src/workflow-engine/index.ts +23 -0
- package/src/workflow-engine/parse.ts +172 -0
- package/src/workflow-engine/structured-output.ts +35 -0
- package/src/workspace/brand.ts +29 -0
- package/src/workspace/index.ts +18 -0
- package/src/workspace/locator.ts +103 -0
- package/src/workspace/runtime-detect.ts +64 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow capability — orchestrate a deterministic fan-out of subagents.
|
|
3
|
+
*
|
|
4
|
+
* App-novel wiring, sibling to (and UNRELATED to) the {@link "./task-card"}
|
|
5
|
+
* delegate card. The `workflow` tool runs a deterministic JavaScript workflow
|
|
6
|
+
* script that calls `agent()`, `parallel()`, and `pipeline()` to fan work out
|
|
7
|
+
* across many fresh subagents and fan their results back in, all under a live
|
|
8
|
+
* `◆ Workflow:` progress tree streamed into the tool result.
|
|
9
|
+
*
|
|
10
|
+
* The actual subagent runner is NOT owned by this card — it is a framework /
|
|
11
|
+
* boot concern injected through {@link DeckContext.framework} under the
|
|
12
|
+
* {@link WORKFLOW_HANDLE_KEY} key. When that handle is present the capability
|
|
13
|
+
* really runs the workflow (via the pure {@link runWorkflow} engine); when it is
|
|
14
|
+
* absent (tests, headless tooling, a host that has not wired the runner) the
|
|
15
|
+
* capability degrades gracefully to a clearly-typed {@link STUB_NOTE} result
|
|
16
|
+
* rather than throwing, exactly like the task card's `readDelegateRunner` path.
|
|
17
|
+
*
|
|
18
|
+
* Recursion guard: this card is registered all-profile-only in
|
|
19
|
+
* {@link "../cards/index"} (`APP_NOVEL_CARDS`), so the `'authoring'` deck a
|
|
20
|
+
* workflow subagent runs against EXCLUDES it — a subagent cannot call `workflow`.
|
|
21
|
+
*
|
|
22
|
+
* Live UI: each engine lifecycle callback mutates a {@link WorkflowSnapshot} and
|
|
23
|
+
* calls the framework `onUpdate` with the snapshot rendered through
|
|
24
|
+
* {@link renderWorkflowText} (the v1 string renderer). Updates are coalesced to
|
|
25
|
+
* status transitions (phase / agent start / agent end), not every log line, to
|
|
26
|
+
* avoid render thrash. The conductor re-projects the framework
|
|
27
|
+
* `tool_execution_update` event to a `tool_update` product signal (stage 3).
|
|
28
|
+
*/
|
|
29
|
+
import { Type, type Static } from "@sinclair/typebox";
|
|
30
|
+
import { capabilityId, type Capability, type CapabilityCard, type DeckContext } from "../contract.js";
|
|
31
|
+
import {
|
|
32
|
+
createWorkflowSnapshot,
|
|
33
|
+
preview,
|
|
34
|
+
recomputeWorkflowSnapshot,
|
|
35
|
+
renderWorkflowText,
|
|
36
|
+
runWorkflow,
|
|
37
|
+
type WorkflowSnapshot,
|
|
38
|
+
} from "../../workflow-engine";
|
|
39
|
+
|
|
40
|
+
/** Key under which a host wires a live workflow agent runner into the context. */
|
|
41
|
+
export const WORKFLOW_HANDLE_KEY = "workflow" as const;
|
|
42
|
+
|
|
43
|
+
const WorkflowParams = Type.Object(
|
|
44
|
+
{
|
|
45
|
+
script: Type.String({
|
|
46
|
+
description: [
|
|
47
|
+
"Required raw JavaScript workflow script, with no Markdown fences.",
|
|
48
|
+
"First statement: export const meta = { name: 'short_snake_case', description: 'non-empty description' }.",
|
|
49
|
+
"Use phase(title), agent(prompt, opts), parallel(arrayOfFunctions), pipeline(items, ...stages), log(message), args, and budget. The workflow must call agent() at least once.",
|
|
50
|
+
"parallel() requires functions, not promises: await parallel(items.map(item => () => agent(...))).",
|
|
51
|
+
"Plain JavaScript only \u2014 no imports, require(), fs, Date.now(), Math.random(), or new Date().",
|
|
52
|
+
].join(" "),
|
|
53
|
+
}),
|
|
54
|
+
args: Type.Optional(
|
|
55
|
+
Type.Any({
|
|
56
|
+
description: "Optional JSON value exposed to the workflow script as global `args`.",
|
|
57
|
+
}),
|
|
58
|
+
),
|
|
59
|
+
},
|
|
60
|
+
{ additionalProperties: false },
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
/** Statically-inferred parameter type the capability's `execute` receives. */
|
|
64
|
+
export type WorkflowParamsType = Static<typeof WorkflowParams>;
|
|
65
|
+
|
|
66
|
+
/** Structured detail returned alongside the model-facing content (the snapshot). */
|
|
67
|
+
export type WorkflowDetails = WorkflowSnapshot;
|
|
68
|
+
|
|
69
|
+
const DESCRIPTION = [
|
|
70
|
+
"Execute a deterministic JavaScript workflow that orchestrates multiple subagents with agent(), parallel(), and pipeline().",
|
|
71
|
+
"Use it for decomposable work \u2014 repository inspection, independent research/checks, multi-perspective review, or fan-out/fan-in synthesis.",
|
|
72
|
+
"script is required raw JavaScript; it must start with `export const meta = { name, description }` and must call agent() at least once.",
|
|
73
|
+
].join(" ");
|
|
74
|
+
|
|
75
|
+
const STUB_NOTE =
|
|
76
|
+
"Workflow orchestration is not wired in this environment, so the script was not run. Wire a WorkflowAgentRunner into the deck context to enable it, or perform the work inline with the other tools.";
|
|
77
|
+
|
|
78
|
+
/** Read the optional workflow runner handle from the deck context. */
|
|
79
|
+
function readWorkflowRunner(ctx: DeckContext) {
|
|
80
|
+
const handle = ctx.framework?.[WORKFLOW_HANDLE_KEY];
|
|
81
|
+
if (handle && typeof (handle as { run?: unknown }).run === "function") {
|
|
82
|
+
return handle;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Detect an abort/cancellation error from the workflow engine. */
|
|
88
|
+
function isAbortError(error: unknown): boolean {
|
|
89
|
+
if (!(error instanceof Error)) return false;
|
|
90
|
+
return /\babort(?:ed)?\b/i.test(error.message);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Build the workflow capability.
|
|
95
|
+
*
|
|
96
|
+
* If a workflow runner is present on the context it is bound and the tool
|
|
97
|
+
* truly orchestrates; otherwise the tool builds anyway and returns a typed,
|
|
98
|
+
* non-throwing stub so the deck stays assemblable in every environment.
|
|
99
|
+
*
|
|
100
|
+
* @param ctx the deck context; an optional runner is read from
|
|
101
|
+
* `ctx.framework[WORKFLOW_HANDLE_KEY]`.
|
|
102
|
+
*/
|
|
103
|
+
export function buildWorkflowCapability(ctx: DeckContext): Capability<typeof WorkflowParams, WorkflowDetails> {
|
|
104
|
+
const runner = readWorkflowRunner(ctx);
|
|
105
|
+
return {
|
|
106
|
+
name: "workflow",
|
|
107
|
+
label: "Workflow",
|
|
108
|
+
description: DESCRIPTION,
|
|
109
|
+
parameters: WorkflowParams,
|
|
110
|
+
async execute(_toolCallId, params, signal, onUpdate) {
|
|
111
|
+
if (!runner) {
|
|
112
|
+
const stub = createWorkflowSnapshot({ name: "workflow", description: STUB_NOTE });
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: "text", text: STUB_NOTE }],
|
|
115
|
+
details: stub,
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
let snapshot = createWorkflowSnapshot({
|
|
120
|
+
name: "workflow",
|
|
121
|
+
description: "",
|
|
122
|
+
});
|
|
123
|
+
const emit = (completed = false) => {
|
|
124
|
+
snapshot = recomputeWorkflowSnapshot(snapshot);
|
|
125
|
+
onUpdate?.({
|
|
126
|
+
content: [{ type: "text", text: renderWorkflowText(snapshot, completed) }],
|
|
127
|
+
details: snapshot,
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
const recordPhase = (title: string) => {
|
|
131
|
+
if (!title) return;
|
|
132
|
+
if (!snapshot.phases.includes(title)) snapshot.phases.push(title);
|
|
133
|
+
};
|
|
134
|
+
const agentById = (id: string) => snapshot.agents.find((item) => item.id === id);
|
|
135
|
+
const ticker = setInterval(() => {
|
|
136
|
+
if (snapshot.agents.some((item) => item.status === "running")) emit();
|
|
137
|
+
}, 1_000);
|
|
138
|
+
if (typeof ticker.unref === "function") ticker.unref();
|
|
139
|
+
try {
|
|
140
|
+
let result;
|
|
141
|
+
try {
|
|
142
|
+
result = await runWorkflow(params.script, {
|
|
143
|
+
agentRunner: runner,
|
|
144
|
+
cwd: ctx.cwd,
|
|
145
|
+
args: params.args,
|
|
146
|
+
signal,
|
|
147
|
+
onLog(message: string) {
|
|
148
|
+
snapshot.logs.push(message);
|
|
149
|
+
},
|
|
150
|
+
onPhase(title: string) {
|
|
151
|
+
snapshot.currentPhase = title;
|
|
152
|
+
recordPhase(title);
|
|
153
|
+
emit();
|
|
154
|
+
},
|
|
155
|
+
onAgentStart(event) {
|
|
156
|
+
recordPhase(event.phase);
|
|
157
|
+
snapshot.agents.push({
|
|
158
|
+
id: event.id,
|
|
159
|
+
label: event.label,
|
|
160
|
+
phase: event.phase,
|
|
161
|
+
prompt: event.prompt,
|
|
162
|
+
status: "running",
|
|
163
|
+
startedAt: Date.now(),
|
|
164
|
+
});
|
|
165
|
+
emit();
|
|
166
|
+
},
|
|
167
|
+
onAgentActivity(id: string, metrics) {
|
|
168
|
+
const agent = agentById(id);
|
|
169
|
+
if (!agent) return;
|
|
170
|
+
agent.tokensIn = metrics.tokensIn;
|
|
171
|
+
agent.tokensOut = metrics.tokensOut;
|
|
172
|
+
agent.toolCount = metrics.toolCount;
|
|
173
|
+
agent.currentTool = metrics.currentTool;
|
|
174
|
+
agent.lastTool = metrics.lastTool;
|
|
175
|
+
},
|
|
176
|
+
onAgentEnd(event) {
|
|
177
|
+
const agent =
|
|
178
|
+
agentById(event.id) ??
|
|
179
|
+
[...snapshot.agents]
|
|
180
|
+
.reverse()
|
|
181
|
+
.find(
|
|
182
|
+
(item) => item.label === event.label && item.status === "running",
|
|
183
|
+
);
|
|
184
|
+
if (agent) {
|
|
185
|
+
agent.status = event.result === null ? "error" : "done";
|
|
186
|
+
agent.resultPreview = preview(event.result);
|
|
187
|
+
agent.endedAt = Date.now();
|
|
188
|
+
agent.currentTool = undefined;
|
|
189
|
+
}
|
|
190
|
+
emit();
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
} catch (error) {
|
|
194
|
+
if (signal?.aborted || isAbortError(error)) {
|
|
195
|
+
for (const agent of snapshot.agents) {
|
|
196
|
+
if (agent.status === "running") {
|
|
197
|
+
agent.status = "skipped";
|
|
198
|
+
agent.error = "aborted";
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
snapshot = recomputeWorkflowSnapshot(snapshot);
|
|
202
|
+
emit(true);
|
|
203
|
+
return {
|
|
204
|
+
content: [{ type: "text", text: renderWorkflowText(snapshot, true) }],
|
|
205
|
+
details: snapshot,
|
|
206
|
+
isError: true,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
210
|
+
snapshot = recomputeWorkflowSnapshot(snapshot);
|
|
211
|
+
return {
|
|
212
|
+
content: [{ type: "text", text: `Workflow failed: ${message}` }],
|
|
213
|
+
details: snapshot,
|
|
214
|
+
isError: true,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
snapshot.name = result.meta.name;
|
|
218
|
+
snapshot.description = result.meta.description;
|
|
219
|
+
snapshot.result = result.result;
|
|
220
|
+
snapshot.durationMs = result.durationMs;
|
|
221
|
+
snapshot = recomputeWorkflowSnapshot(snapshot);
|
|
222
|
+
emit(true);
|
|
223
|
+
const noAgents = result.agentCount === 0;
|
|
224
|
+
const body = noAgents
|
|
225
|
+
? "workflow scripts must call agent() at least once; this workflow declared phases but did not run any subagents"
|
|
226
|
+
: `Workflow ${result.meta.name} completed with ${result.agentCount} agent(s).\n\n${renderWorkflowText(snapshot, true)}\n\nResult:\n${JSON.stringify(result.result, null, 2)}`;
|
|
227
|
+
return {
|
|
228
|
+
content: [{ type: "text", text: body }],
|
|
229
|
+
details: snapshot,
|
|
230
|
+
isError: noAgents ? true : undefined,
|
|
231
|
+
};
|
|
232
|
+
} finally {
|
|
233
|
+
clearInterval(ticker);
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Catalog row for the workflow capability. */
|
|
240
|
+
export const workflowCard: CapabilityCard = {
|
|
241
|
+
id: capabilityId("workflow"),
|
|
242
|
+
title: "Workflow",
|
|
243
|
+
summary: "Run a deterministic JavaScript workflow that fans work out across many subagents.",
|
|
244
|
+
// Erase the precisely-typed builder to the `Capability` card surface (through
|
|
245
|
+
// `unknown`, as TypeBox tools are invariant in their parameter schema).
|
|
246
|
+
build: (ctx) => buildWorkflowCapability(ctx),
|
|
247
|
+
};
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-deck contract — the FROZEN type surface of the tooling layer.
|
|
3
|
+
*
|
|
4
|
+
* This module is the single typed seam between the coding-agent *product* and
|
|
5
|
+
* the set of callable capabilities the agent runtime executes — file ops, the
|
|
6
|
+
* shell, search, the web, the delegate/subagent action, the checklist, the
|
|
7
|
+
* background-process proxy, SaaS connector actions, and dynamically-grafted MCP
|
|
8
|
+
* server tools. It declares *only* shapes plus a handful of tiny inert helpers
|
|
9
|
+
* (an id brand, a key minter, a fault factory, and a pure ledger reducer) — no
|
|
10
|
+
* I/O, no provisioning, no orchestration. Every later deck module (the manifest
|
|
11
|
+
* catalog, the builtin bridge, the per-concern provisioners, the bridge network,
|
|
12
|
+
* and the assembled `ToolDeck`) is written against the names declared here, so
|
|
13
|
+
* the file is intentionally small, append-mostly, and stable.
|
|
14
|
+
*
|
|
15
|
+
* Design stance:
|
|
16
|
+
* - A {@link Capability} is exactly the framework `AgentTool` shape. The deck
|
|
17
|
+
* does not invent a parallel descriptor type; it *manages* AgentTools so the
|
|
18
|
+
* conductor can consume the deck's output directly as `options.tools`.
|
|
19
|
+
* - The catalog is a single source of truth: {@link CapabilityCard} rows live
|
|
20
|
+
* in one `CAPABILITY_CARDS` array (built by the manifest module), and every
|
|
21
|
+
* index/lookup is derived *from* that array rather than hand-maintained in a
|
|
22
|
+
* second parallel map.
|
|
23
|
+
* - Profiles replace a trio of near-identical build functions: one
|
|
24
|
+
* data-driven provisioner walks a {@link DeckProfile} ("authoring" |
|
|
25
|
+
* "survey" | "all") to assemble the right capability set for a session.
|
|
26
|
+
* - MCP enrollment is **event-sourced**: a {@link BridgeLedger} is the fold of
|
|
27
|
+
* an append-only stream of {@link BridgeEntry} events (`enroll` / `retire`),
|
|
28
|
+
* keyed by a content-hash / ULID {@link BridgeKey} rather than a path digest.
|
|
29
|
+
* The current view is a {@link LedgerSnapshot} reduced from that stream.
|
|
30
|
+
*
|
|
31
|
+
* Framework anchors (all from the `indusagi` package — the sibling rebuilt
|
|
32
|
+
* framework this app targets):
|
|
33
|
+
* - `AgentTool`, `AgentToolResult` ← `indusagi/agent`
|
|
34
|
+
* - `ToolBox` ← `indusagi/runtime`
|
|
35
|
+
* - `TSchema`, `Static` ← `@sinclair/typebox`
|
|
36
|
+
*
|
|
37
|
+
* The deck never re-declares these; it composes them.
|
|
38
|
+
*/
|
|
39
|
+
// Local aliases for framework vocabulary that is not exported from the
|
|
40
|
+
// `indusagi` package. Kept loose (`unknown` payload) so deck consumers can
|
|
41
|
+
// thread framework-supplied values through without a parallel descriptor type.
|
|
42
|
+
/** The framework `AgentTool` shape (name, description, parameters, execute). */
|
|
43
|
+
import type { Static, TSchema } from "@sinclair/typebox";
|
|
44
|
+
export type AgentTool<TParameters = unknown, TDetails = unknown> = {
|
|
45
|
+
name: string;
|
|
46
|
+
label?: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
parameters?: TParameters;
|
|
49
|
+
readOnly?: boolean;
|
|
50
|
+
execute?: (...args: unknown[]) => unknown;
|
|
51
|
+
[k: string]: unknown;
|
|
52
|
+
};
|
|
53
|
+
/** The framework `AgentToolResult` (content parts + details). */
|
|
54
|
+
export type AgentToolResult<TDetails = unknown> = {
|
|
55
|
+
content: readonly unknown[];
|
|
56
|
+
details?: TDetails;
|
|
57
|
+
[k: string]: unknown;
|
|
58
|
+
};
|
|
59
|
+
/** Opaque handle to a framework tool box. */
|
|
60
|
+
export type ToolBox = { [k: string]: unknown };
|
|
61
|
+
|
|
62
|
+
/** Re-exported framework vocabulary that deck consumers routinely need. */
|
|
63
|
+
export type { TSchema, Static };
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A single callable tool the deck manages.
|
|
67
|
+
*
|
|
68
|
+
* Deliberately an alias of the framework `AgentTool` rather than a fresh shape:
|
|
69
|
+
* the conductor and the framework agent loop both expect `AgentTool` objects, so
|
|
70
|
+
* the deck's whole job is to *assemble* them, not to wrap them in a parallel
|
|
71
|
+
* descriptor. A `Capability` therefore carries the framework contract verbatim —
|
|
72
|
+
* `name`, `label`, `description`, a TypeBox `parameters` schema, and an
|
|
73
|
+
* async `execute` — while the deck owns only the catalog, profiles, and
|
|
74
|
+
* dynamic-bridge layers around it.
|
|
75
|
+
*
|
|
76
|
+
* `TParameters` is left open (`TSchema`) so heterogeneous capabilities with
|
|
77
|
+
* different parameter schemas coexist in one `Capability[]`.
|
|
78
|
+
*/
|
|
79
|
+
export type Capability<TParameters extends TSchema = TSchema, TDetails = unknown> =
|
|
80
|
+
AgentTool<TParameters, TDetails>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* A capability whose parameter/detail types are erased — the element type of a
|
|
84
|
+
* heterogeneous deck.
|
|
85
|
+
*
|
|
86
|
+
* A `Capability[]` array of mixed schemas widens to `AnyCapability[]`; this is
|
|
87
|
+
* the shape the conductor consumes as `options.tools` and the type the deck's
|
|
88
|
+
* {@link ToolDeck.tools} / {@link ToolDeck.box} surface in.
|
|
89
|
+
*/
|
|
90
|
+
export type AnyCapability = Capability<TSchema, unknown>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* String-branded stable identifier for a capability.
|
|
94
|
+
*
|
|
95
|
+
* The wire-facing tool `name` the model sees (e.g. `"read"`, `"bash"`,
|
|
96
|
+
* `"composio_execute"`, a qualified `"<server>__<tool>"`); branded so an
|
|
97
|
+
* arbitrary string cannot be passed where a vetted capability id is required.
|
|
98
|
+
* Mint one with {@link capabilityId}.
|
|
99
|
+
*/
|
|
100
|
+
export type CapabilityId = string & {
|
|
101
|
+
readonly __capability: unique symbol;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Brand a raw string as a {@link CapabilityId}. The single sanctioned way to
|
|
106
|
+
* produce one, so id provenance stays uniform across the catalog and bridge.
|
|
107
|
+
*
|
|
108
|
+
* @param raw the wire-facing tool name to brand
|
|
109
|
+
*/
|
|
110
|
+
export function capabilityId(raw: string): CapabilityId {
|
|
111
|
+
return raw as CapabilityId;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* One row of the static capability catalog — the deck's single source of truth.
|
|
116
|
+
*
|
|
117
|
+
* A card is *metadata plus a builder*: it advertises the capability's identity
|
|
118
|
+
* (`id`, `title`, `summary`) for help/introspection and slash-command listings,
|
|
119
|
+
* and carries a {@link CapabilityCard.build} factory that mints the live
|
|
120
|
+
* {@link Capability} for a given {@link DeckContext}. The catalog array
|
|
121
|
+
* (`CAPABILITY_CARDS`, owned by the manifest module) is the only hand-maintained
|
|
122
|
+
* list; every index, profile membership, and lookup is derived from it.
|
|
123
|
+
*/
|
|
124
|
+
export interface CapabilityCard {
|
|
125
|
+
/** Stable, wire-facing identifier of the capability this card builds. */
|
|
126
|
+
readonly id: CapabilityId;
|
|
127
|
+
/** Short human-facing title for catalogs and help text. */
|
|
128
|
+
readonly title: string;
|
|
129
|
+
/** One-line description of what the capability does, in the deck's own voice. */
|
|
130
|
+
readonly summary: string;
|
|
131
|
+
/**
|
|
132
|
+
* Build the live capability for a working context.
|
|
133
|
+
*
|
|
134
|
+
* Pure with respect to the deck: it reads the injected backends from `ctx`
|
|
135
|
+
* and returns a configured {@link Capability}; it performs no enrollment and
|
|
136
|
+
* mutates no shared state.
|
|
137
|
+
*
|
|
138
|
+
* @param ctx the working context (cwd + injectable backends) to bind to
|
|
139
|
+
*/
|
|
140
|
+
build(ctx: DeckContext): Capability;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The set of capabilities a card is eligible for, by profile.
|
|
145
|
+
*
|
|
146
|
+
* A card declares which {@link DeckProfile}s it participates in; the
|
|
147
|
+
* data-driven provisioner intersects this with the requested profile instead of
|
|
148
|
+
* branching through separate per-profile build functions. `"all"` is implied for
|
|
149
|
+
* every card and need not be listed.
|
|
150
|
+
*/
|
|
151
|
+
export type CardProfiles = readonly DeckProfile[];
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The named capability sets a session can be provisioned with — the profile
|
|
155
|
+
* table that replaces a trio of near-identical build functions.
|
|
156
|
+
*
|
|
157
|
+
* - `authoring` — the READ-ONLY built-in subset: read/ls/search/web/
|
|
158
|
+
* checklist-read. No filesystem mutation, no shell, no app-novel cards —
|
|
159
|
+
* the deck sub-agents (task/workflow) are provisioned with (see
|
|
160
|
+
* {@link "./provision"}'s PROFILE_TABLE, the authoritative mapping).
|
|
161
|
+
* - `survey` — every built-in (mutating ones included), no app-novel cards.
|
|
162
|
+
* - `all` — every registered capability, nothing withheld. What an
|
|
163
|
+
* interactive coding session runs with.
|
|
164
|
+
*/
|
|
165
|
+
export type DeckProfile = "authoring" | "survey" | "all";
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The working context handed to {@link CapabilityCard.build}.
|
|
169
|
+
*
|
|
170
|
+
* Bundles the workspace root with the injectable backends a capability binds to,
|
|
171
|
+
* so capabilities stay framework-agnostic and testable: a test passes fake
|
|
172
|
+
* `fs` / `shell` ports, production passes the Node-backed ones. Every field
|
|
173
|
+
* beyond `cwd` is optional — the manifest supplies framework defaults when a
|
|
174
|
+
* backend is not injected.
|
|
175
|
+
*/
|
|
176
|
+
export interface DeckContext {
|
|
177
|
+
/** Absolute working directory the session's capabilities are scoped to. */
|
|
178
|
+
readonly cwd: string;
|
|
179
|
+
/** Injectable filesystem port; framework Node backend is the default. */
|
|
180
|
+
readonly fs?: DeckFsBackend;
|
|
181
|
+
/** Injectable shell port; framework Node backend is the default. */
|
|
182
|
+
readonly shell?: DeckShellBackend;
|
|
183
|
+
/** Opaque framework handles a capability may need (model registry, stores). */
|
|
184
|
+
readonly framework?: DeckFrameworkHandles;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Filesystem backend port a capability may bind to.
|
|
189
|
+
*
|
|
190
|
+
* Intentionally opaque at the contract layer: the concrete port shape is owned
|
|
191
|
+
* by the framework capabilities kernel. The deck only needs to *thread* it from
|
|
192
|
+
* a host into a card's builder, so the contract treats it as a branded handle —
|
|
193
|
+
* threaded, not interpreted, here.
|
|
194
|
+
*/
|
|
195
|
+
export type DeckFsBackend = {
|
|
196
|
+
readonly __deckFsBackend: unique symbol;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Shell backend port a capability may bind to. Opaque for the same reason as
|
|
201
|
+
* {@link DeckFsBackend}: a branded handle the contract threads but never reads.
|
|
202
|
+
*/
|
|
203
|
+
export type DeckShellBackend = {
|
|
204
|
+
readonly __deckShellBackend: unique symbol;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* A bag of opaque framework handles the novel capabilities wire to — the
|
|
209
|
+
* subagent/delegate manager, the checklist ledger, the background-process
|
|
210
|
+
* controller, the SaaS gateway. Each is optional and keyed by name; a card that
|
|
211
|
+
* needs one reads it from here, and the manifest fills in defaults.
|
|
212
|
+
*/
|
|
213
|
+
export interface DeckFrameworkHandles {
|
|
214
|
+
readonly [name: string]: unknown;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* The stable key of an enrolled bridge capability.
|
|
219
|
+
*
|
|
220
|
+
* Minted from the capability's identity rather than from a working-directory
|
|
221
|
+
* digest, so the same external tool grafted from two sessions collapses to one
|
|
222
|
+
* key and re-enrolling is idempotent. In practice a content hash of the
|
|
223
|
+
* qualified `<server>__<tool>` name (and its schema) or a fresh ULID; branded so
|
|
224
|
+
* a raw string cannot stand in for a vetted key.
|
|
225
|
+
*/
|
|
226
|
+
export type BridgeKey = string & {
|
|
227
|
+
readonly __bridgeKey: unique symbol;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/** Brand a raw string as a {@link BridgeKey}. */
|
|
231
|
+
export function bridgeKey(raw: string): BridgeKey {
|
|
232
|
+
return raw as BridgeKey;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* The operations the MCP enrollment stream records.
|
|
237
|
+
*
|
|
238
|
+
* - `enroll` — a bridge capability became available and was grafted in (an
|
|
239
|
+
* upsert: re-enrolling the same {@link BridgeKey} replaces its entry).
|
|
240
|
+
* - `retire` — a bridge capability (or a whole server's set) was withdrawn (a
|
|
241
|
+
* splice: the keyed entry is removed from the reduced view).
|
|
242
|
+
*/
|
|
243
|
+
export type BridgeOp = "enroll" | "retire";
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* A single append-only event in the MCP enrollment stream.
|
|
247
|
+
*
|
|
248
|
+
* The ledger is never mutated in place; every change is one of these entries
|
|
249
|
+
* appended to an ordered log, and the live view is the fold of that log. An
|
|
250
|
+
* `enroll` entry carries the grafted {@link Capability} and the owning server;
|
|
251
|
+
* a `retire` entry need only name the {@link BridgeKey} (and server) to remove.
|
|
252
|
+
* Field names are the deck's own, not the framework's registry schema.
|
|
253
|
+
*/
|
|
254
|
+
export interface BridgeEntry {
|
|
255
|
+
/** The operation this event records. */
|
|
256
|
+
readonly op: BridgeOp;
|
|
257
|
+
/** Stable key of the bridge capability the event concerns. */
|
|
258
|
+
readonly key: BridgeKey;
|
|
259
|
+
/** Id of the external MCP server that owns the capability. */
|
|
260
|
+
readonly server: string;
|
|
261
|
+
/** The grafted capability — present on `enroll`, omitted on `retire`. */
|
|
262
|
+
readonly capability?: AnyCapability;
|
|
263
|
+
/** Monotonic sequence number; the append order, used to break upsert ties. */
|
|
264
|
+
readonly seq: number;
|
|
265
|
+
/** ISO-8601 timestamp the event was appended. */
|
|
266
|
+
readonly at: string;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* The reduced, current view of the MCP enrollment ledger.
|
|
271
|
+
*
|
|
272
|
+
* A pure projection of the {@link BridgeEntry} stream: the set of bridge
|
|
273
|
+
* capabilities live *right now*, keyed by {@link BridgeKey}, alongside the
|
|
274
|
+
* highest sequence number folded and a per-server tool count for status
|
|
275
|
+
* rendering. Produced by {@link reduceLedger}; consumers read it, never mutate.
|
|
276
|
+
*/
|
|
277
|
+
export interface LedgerSnapshot {
|
|
278
|
+
/** Currently-enrolled bridge capabilities, keyed by their stable key. */
|
|
279
|
+
readonly live: ReadonlyMap<BridgeKey, AnyCapability>;
|
|
280
|
+
/** Number of live capabilities grafted from each server, keyed by server id. */
|
|
281
|
+
readonly byServer: ReadonlyMap<string, number>;
|
|
282
|
+
/** The highest {@link BridgeEntry.seq} folded into this snapshot. */
|
|
283
|
+
readonly highWater: number;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Fold an append-only {@link BridgeEntry} stream into its current
|
|
288
|
+
* {@link LedgerSnapshot}.
|
|
289
|
+
*
|
|
290
|
+
* Pure and total: `enroll` upserts the keyed capability (later `seq` wins on a
|
|
291
|
+
* repeated key), `retire` removes it, and entries are applied in `seq` order so
|
|
292
|
+
* the result is independent of array order. This is the single sanctioned
|
|
293
|
+
* reducer, so the event-sourced view stays consistent across every producer.
|
|
294
|
+
*
|
|
295
|
+
* @param entries the enrollment events to fold, in any order
|
|
296
|
+
*/
|
|
297
|
+
export function reduceLedger(entries: readonly BridgeEntry[]): LedgerSnapshot {
|
|
298
|
+
const ordered = [...entries].sort((a, b) => a.seq - b.seq);
|
|
299
|
+
const live = new Map<BridgeKey, AnyCapability>();
|
|
300
|
+
let highWater = 0;
|
|
301
|
+
for (const entry of ordered) {
|
|
302
|
+
if (entry.seq > highWater) highWater = entry.seq;
|
|
303
|
+
if (entry.op === "enroll") {
|
|
304
|
+
if (entry.capability !== undefined) live.set(entry.key, entry.capability);
|
|
305
|
+
} else {
|
|
306
|
+
live.delete(entry.key);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const keyServer = new Map<BridgeKey, string>();
|
|
310
|
+
for (const entry of ordered) keyServer.set(entry.key, entry.server);
|
|
311
|
+
const byServer = new Map<string, number>();
|
|
312
|
+
for (const key of live.keys()) {
|
|
313
|
+
const server = keyServer.get(key);
|
|
314
|
+
if (server === undefined) continue;
|
|
315
|
+
byServer.set(server, (byServer.get(server) ?? 0) + 1);
|
|
316
|
+
}
|
|
317
|
+
return { live, byServer, highWater };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* The assembled capability deck a session runs against.
|
|
322
|
+
*
|
|
323
|
+
* The product of provisioning a {@link DeckProfile} against a
|
|
324
|
+
* {@link DeckContext}, optionally with bridge capabilities grafted on. It
|
|
325
|
+
* exposes exactly two reads: the flat capability list (for inspection, naming,
|
|
326
|
+
* and `--tools` style selection) and the consumable box the conductor wires in.
|
|
327
|
+
*
|
|
328
|
+
* `box()` returns an `AnyCapability[]` — the same `AgentTool[]` the conductor's
|
|
329
|
+
* session options accept directly — so a deck drops straight into
|
|
330
|
+
* `SessionConductorOptions.tools`. The {@link DeckBox} alias also admits the
|
|
331
|
+
* framework `ToolBox` for hosts that drive the lower-level runtime contract
|
|
332
|
+
* instead of the conductor.
|
|
333
|
+
*/
|
|
334
|
+
export interface ToolDeck {
|
|
335
|
+
/** The flat list of live capabilities, for inspection and selection. */
|
|
336
|
+
tools(): AnyCapability[];
|
|
337
|
+
/** The consumable surface the conductor (or runtime) wires in as its tools. */
|
|
338
|
+
box(): DeckBox;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* What {@link ToolDeck.box} hands to a consumer.
|
|
343
|
+
*
|
|
344
|
+
* Primarily an `AnyCapability[]` (= `AgentTool[]`), which the conductor accepts
|
|
345
|
+
* verbatim as `options.tools`. Also admits the framework {@link ToolBox} so a
|
|
346
|
+
* host wiring the raw runtime contract — or grafting MCP tools through the
|
|
347
|
+
* protocol bridge, which yields a `ToolBox` — can consume the deck the same way.
|
|
348
|
+
*/
|
|
349
|
+
export type DeckBox = AnyCapability[] | ToolBox;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* The closed set of failure categories the deck can surface during
|
|
353
|
+
* provisioning or bridge enrollment.
|
|
354
|
+
*
|
|
355
|
+
* - `unknown_capability` — a requested id is not in the catalog.
|
|
356
|
+
* - `build_failed` — a card's `build` threw while minting a capability.
|
|
357
|
+
* - `bridge` — connecting/listing/grafting an MCP server failed.
|
|
358
|
+
* - `backend` — a required injected backend was missing or invalid.
|
|
359
|
+
*/
|
|
360
|
+
export type DeckFaultKind = "unknown_capability" | "build_failed" | "bridge" | "backend";
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* A typed, discriminated failure raised by the deck.
|
|
364
|
+
*
|
|
365
|
+
* `kind` selects the category; `message` is a human-readable summary; the
|
|
366
|
+
* optional `cause` carries the underlying error for logging without forcing
|
|
367
|
+
* consumers to parse the message. Construct one with {@link deckFault}.
|
|
368
|
+
*/
|
|
369
|
+
export interface DeckFault {
|
|
370
|
+
/** Failure category — the discriminant consumers switch on. */
|
|
371
|
+
readonly kind: DeckFaultKind;
|
|
372
|
+
/** Human-readable, single-line summary of what went wrong. */
|
|
373
|
+
readonly message: string;
|
|
374
|
+
/** Underlying error or structured detail, if any. */
|
|
375
|
+
readonly cause?: unknown;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Construct a {@link DeckFault}. The single sanctioned way to mint one, so the
|
|
380
|
+
* shape stays uniform across every producer.
|
|
381
|
+
*
|
|
382
|
+
* @param kind the failure category
|
|
383
|
+
* @param message a human-readable, single-line summary
|
|
384
|
+
* @param cause optional underlying error or structured detail
|
|
385
|
+
*/
|
|
386
|
+
export function deckFault(kind: DeckFaultKind, message: string, cause?: unknown): DeckFault {
|
|
387
|
+
return cause === undefined ? { kind, message } : { kind, message, cause };
|
|
388
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Type declarations recovered from dist/types (no runtime body)
|
|
3
|
+
/**
|
|
4
|
+
* Capability-deck subsystem — public barrel.
|
|
5
|
+
*
|
|
6
|
+
* Re-exports the FROZEN tooling-layer contract: the {@link Capability} alias
|
|
7
|
+
* over the framework `AgentTool`, the branded {@link CapabilityId}, the
|
|
8
|
+
* catalog row ({@link CapabilityCard}) that is the deck's single source of
|
|
9
|
+
* truth, the {@link DeckProfile} table and {@link DeckContext} injection bag,
|
|
10
|
+
* the event-sourced MCP enrollment model ({@link BridgeEntry}, {@link BridgeOp},
|
|
11
|
+
* {@link LedgerSnapshot} + the pure {@link reduceLedger} fold), the assembled
|
|
12
|
+
* {@link ToolDeck} the conductor consumes, and the typed {@link DeckFault}.
|
|
13
|
+
*
|
|
14
|
+
* Behavior modules (the manifest catalog, the builtin bridge, the per-concern
|
|
15
|
+
* provisioners, the bridge network, and the deck assembler) are added to this
|
|
16
|
+
* barrel as they land; consumers import the deck surface from
|
|
17
|
+
* `src/capability-deck` rather than reaching into individual modules.
|
|
18
|
+
*/
|
|
19
|
+
export type { Capability, AnyCapability, CapabilityId, CapabilityCard, CardProfiles, DeckProfile, DeckContext, DeckFsBackend, DeckShellBackend, DeckFrameworkHandles, BridgeKey, BridgeOp, BridgeEntry, LedgerSnapshot, ToolDeck, DeckBox, DeckFaultKind, DeckFault, AgentTool, AgentToolResult, ToolBox, TSchema, Static, } from "./contract.js";
|
|
20
|
+
export { capabilityId, bridgeKey, reduceLedger, deckFault, } from "./contract.js";
|
|
21
|
+
/**
|
|
22
|
+
* Built-in bridge — the single seam re-exposing the framework's native tools
|
|
23
|
+
* (read/write/edit/ls/grep/find/bash/process/checklist/web) as capabilities.
|
|
24
|
+
*/
|
|
25
|
+
export { BUILTIN_BRIDGE, BUILTIN_IDS, BUILTIN_PROFILES, builtinDescriptors, buildBuiltin, buildBuiltinsForProfile, type BridgeBuilder, type BuiltinDescriptor, } from "./builtin-bridge.js";
|
|
26
|
+
/**
|
|
27
|
+
* Capability catalog — the single `CAPABILITY_CARDS` source of truth plus the
|
|
28
|
+
* lookups/profile filters derived from it.
|
|
29
|
+
*/
|
|
30
|
+
export { CAPABILITY_CARDS, CAPABILITY_INDEX, CARD_PROFILES, capabilityIds, hasCapability, findCard, cardsForProfile, } from "./manifest.js";
|
|
31
|
+
/**
|
|
32
|
+
* App-novel capability cards — the in-house tools the deck builds itself
|
|
33
|
+
* (checklist, background-process proxy, delegate/sub-agent, SaaS connector,
|
|
34
|
+
* working memory) plus their builders, stores, and injection-handle types.
|
|
35
|
+
*/
|
|
36
|
+
export { APP_NOVEL_CARDS, todoCard, buildTodoCapability, TodoLedger, type TodoItem, type TodoState, type TodoWeight, type TodoParamsType, type TodoDetails, daemonCard, buildDaemonCapability, DaemonTable, type DaemonState, type DaemonParamsType, type DaemonDetails, taskCard, buildTaskCapability, DELEGATE_HANDLE_KEY, type DelegateRunner, type DelegateRequest, type DelegateResult, type TaskParamsType, type TaskDetails, workflowCard, buildWorkflowCapability, WORKFLOW_HANDLE_KEY, type WorkflowParamsType, type WorkflowDetails, saasCard, buildSaasCapability, SAAS_GATEWAY_KEY, type SaasGatewayPort, type RemoteToolSummary, type RemoteExecution, type SaasParamsType, type SaasDetails, memoryCard, buildMemoryCapability, InMemoryStore, MEMORY_HANDLE_KEY, type MemoryStore, type MemoryParamsType, type MemoryDetails, enterPlanModeCard, exitPlanModeCard, buildEnterPlanModeCapability, buildExitPlanModeCapability, PLAN_HANDLE_KEY, planSlug, planFilePath, writePlan, readPlan, PLANS_DIRNAME, type PlanController, type EnterPlanParamsType, type EnterPlanDetails, type ExitPlanParamsType, type ExitPlanDetails, } from "./cards/index";
|
|
37
|
+
/**
|
|
38
|
+
* Bridge ledger — event-sourced enrollment of dynamically grafted MCP tools:
|
|
39
|
+
* content-hash / ULID key minting, the immutable {@link BridgeLedger} value with
|
|
40
|
+
* its pure enroll/retire/withdraw transitions and live projections, and the
|
|
41
|
+
* side-effecting mount/adapt/detach network operations.
|
|
42
|
+
*/
|
|
43
|
+
export { qualifyBridgeName, bridgeContentKey, bridgeUlidKey, emptyBridgeLedger, bridgeLedgerFromLog, enrollBridgeCard, retire, withdrawServer, liveCapabilities, liveCapabilitiesForServer, type BridgeLedger, type EnrollRequest, attachBridgeCapabilities, detachBridge, bridgeBoxToCapabilities, bridgeCapabilityCard, bridgeConfig, type AttachResult, } from "./bridge-ledger/index";
|
|
44
|
+
/**
|
|
45
|
+
* Deck provisioning — the single data-driven {@link provisionDeck} assembler over
|
|
46
|
+
* the profile table, plus the profile-to-cards selection it walks.
|
|
47
|
+
*/
|
|
48
|
+
export { provisionDeck, cardsForDeckProfile, } from "./provision.js";
|