@kodax-ai/kodax 0.7.63 → 0.7.66

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 (80) hide show
  1. package/CHANGELOG.md +2300 -2204
  2. package/README.md +79 -7
  3. package/README_CN.md +52 -3
  4. package/dist/chunks/{agent-SL444XLN.js → agent-KER4WDNO.js} +1 -1
  5. package/dist/chunks/argument-completer-HK3MHA3K.js +2 -0
  6. package/dist/chunks/{chunk-ARUWXX25.js → chunk-35P7QL2Q.js} +1 -1
  7. package/dist/chunks/chunk-3HKBBY74.js +339 -0
  8. package/dist/chunks/chunk-AKBH2EEE.js +8 -0
  9. package/dist/chunks/{chunk-KCFVGXVK.js → chunk-ALS32RNZ.js} +1 -1
  10. package/dist/chunks/chunk-MHRN2LQV.js +328 -0
  11. package/dist/chunks/{chunk-HP4FXMEM.js → chunk-NBQW7PNZ.js} +2 -2
  12. package/dist/chunks/{chunk-S4GVQO3W.js → chunk-O7N22GJ3.js} +1 -1
  13. package/dist/chunks/chunk-ONUPGMER.js +2 -0
  14. package/dist/chunks/{chunk-ZL5CEANW.js → chunk-PZTG2C33.js} +1 -1
  15. package/dist/chunks/{chunk-4MIHVNB7.js → chunk-QAQ2HNXD.js} +112 -112
  16. package/dist/chunks/{chunk-6OZ5KWG3.js → chunk-QJJKMNZF.js} +1 -1
  17. package/dist/chunks/chunk-QJVZZSEO.js +56 -0
  18. package/dist/chunks/chunk-TLJGOKBT.js +729 -0
  19. package/dist/chunks/{chunk-7MPU7TP6.js → chunk-VS4CDDEF.js} +243 -243
  20. package/dist/chunks/chunk-WBBEJIAY.js +306 -0
  21. package/dist/chunks/{chunk-L3MF5V64.js → chunk-WMIZCY2J.js} +1 -1
  22. package/dist/chunks/{chunk-UA744TZM.js → chunk-YRBNXFHY.js} +1 -1
  23. package/dist/chunks/compaction-config-7GMUFNPB.js +2 -0
  24. package/dist/chunks/{construction-bootstrap-EFZBONTK.js → construction-bootstrap-3XDS2D5K.js} +1 -1
  25. package/dist/chunks/{devtools-4CRULTR2.js → devtools-CD6KSIHE.js} +1 -1
  26. package/dist/chunks/{devtools-YINBSZC7.js → devtools-XR5F2C6T.js} +1 -1
  27. package/dist/chunks/{dist-73L4OYPD.js → dist-4PXB7U22.js} +1 -1
  28. package/dist/chunks/dist-4YAYT2TO.js +2 -0
  29. package/dist/chunks/host-KG3456QP.js +2 -0
  30. package/dist/chunks/{paste-FDYM7SZX.js → paste-C33GZQV5.js} +1 -1
  31. package/dist/chunks/run-manager-6CAH3KTA.js +2 -0
  32. package/dist/chunks/utils-OT5ENFUL.js +2 -0
  33. package/dist/constructed-handler-worker.js +2 -0
  34. package/dist/index.d.ts +21 -10
  35. package/dist/index.js +6 -6
  36. package/dist/kodax_cli.js +1116 -1089
  37. package/dist/runtime-worker.js +2843 -0
  38. package/dist/sdk-agent.d.ts +27 -8
  39. package/dist/sdk-agent.js +1 -1
  40. package/dist/sdk-coding.d.ts +76 -1020
  41. package/dist/sdk-coding.js +1 -1
  42. package/dist/sdk-llm.js +1 -1
  43. package/dist/sdk-mcp.d.ts +2 -1
  44. package/dist/sdk-mcp.js +1 -1
  45. package/dist/sdk-media.js +1 -1
  46. package/dist/sdk-repl.d.ts +197 -183
  47. package/dist/sdk-repl.js +2 -2
  48. package/dist/sdk-runtime.d.ts +982 -0
  49. package/dist/sdk-runtime.js +2 -0
  50. package/dist/sdk-session.d.ts +3 -3
  51. package/dist/sdk-session.js +1 -1
  52. package/dist/sdk-skills.js +1 -1
  53. package/dist/semantic-worker.js +191 -10
  54. package/dist/types-chunks/{bash-prefix-extractor.d-CZW9fRoa.d.ts → bash-prefix-extractor.d-BjkITAva.d.ts} +142 -3
  55. package/dist/types-chunks/{run-manager.d-CYTnWhZY.d.ts → capsule.d-hVhPNkHd.d.ts} +5 -92
  56. package/dist/types-chunks/commands.d-C3B1TdGM.d.ts +213 -0
  57. package/dist/types-chunks/{types.d-1CnTg7Sd.d.ts → guardrail.d-C_Siraua.d.ts} +3 -128
  58. package/dist/types-chunks/{guardrail.d-MR6LwMB2.d.ts → guardrail.d-wk-s0psS.d.ts} +2 -2
  59. package/dist/types-chunks/{manager.d-DBD7SOTT.d.ts → manager.d-Zum9cGHU.d.ts} +3 -173
  60. package/dist/types-chunks/oauth-login.d-Bgb4rdLN.d.ts +174 -0
  61. package/dist/types-chunks/public-api.d-jtREVfEq.d.ts +596 -0
  62. package/dist/types-chunks/run-manager.d-CFknOfo1.d.ts +91 -0
  63. package/dist/types-chunks/{sdk-session-RBSBBKol.d.ts → sdk-session-CLqyfAmf.d.ts} +8 -306
  64. package/dist/types-chunks/types.d-BMLxKV69.d.ts +128 -0
  65. package/dist/types-chunks/types.d-CUN_bZU7.d.ts +975 -0
  66. package/dist/types-chunks/{utils.d-C14jZ9ZM.d.ts → utils.d-C1rpoeDh.d.ts} +84 -72
  67. package/package.json +7 -1
  68. package/dist/chunks/argument-completer-EN63ZVJK.js +0 -2
  69. package/dist/chunks/chunk-KHICMJIR.js +0 -310
  70. package/dist/chunks/chunk-LGR7ACBQ.js +0 -326
  71. package/dist/chunks/chunk-RR7W7UF6.js +0 -341
  72. package/dist/chunks/chunk-UGTK2JIJ.js +0 -731
  73. package/dist/chunks/chunk-V4WSBIXB.js +0 -2
  74. package/dist/chunks/chunk-VSWROENP.js +0 -52
  75. package/dist/chunks/compaction-config-4VIONMFB.js +0 -2
  76. package/dist/chunks/dist-EDF2YUF6.js +0 -2
  77. package/dist/chunks/host-J4HPDLFC.js +0 -2
  78. package/dist/chunks/run-manager-ZVSW2OWM.js +0 -2
  79. package/dist/chunks/utils-5HDLYTZJ.js +0 -2
  80. package/dist/types-chunks/storage.d-C6kkAEch.d.ts +0 -280
@@ -0,0 +1,975 @@
1
+ import { a8 as KodaXWireReasoningEffort, a0 as KodaXToolDefinition, a2 as KodaXToolResultContentItem, j as KodaXMessage } from './types.d-Bp4Lm1jv.js';
2
+ import { K as KodaXBaseProvider } from './base.d-DalIRhbb.js';
3
+ import { C as CapabilityKind, a as CapabilityProvider } from './capability.d-3C62G8Eq.js';
4
+ import { a4 as KodaXJsonValue, U as KodaXExtensionSessionRecord, W as KodaXExtensionStore } from './process.d-CY2g03Mb.js';
5
+ import { aw as KodaXToolExecutionContext, bd as ToolSideEffect } from './bash-prefix-extractor.d-BjkITAva.js';
6
+
7
+ /**
8
+ * KodaX Constructed-World types (FEATURE_087, v0.7.28).
9
+ *
10
+ * Runtime-generated capabilities (tools / agents / skills / ...) live in
11
+ * `.kodax/constructed/` and are loaded into the same registries as builtin
12
+ * primitives. v0.7.28 only ships tool generation (FEATURE_088); other kinds
13
+ * land in FEATURE_089 / FEATURE_090.
14
+ *
15
+ * Cross-references:
16
+ * - DD §14 — lifecycle, security model, registry merge semantics.
17
+ * - docs/features/v0.7.28.md — capability schema, generation flow.
18
+ */
19
+
20
+ /**
21
+ * Handler script source. v0.7.28 limits language to `'javascript'` so that
22
+ * `loadHandler()` can `await import()` the file directly without an
23
+ * intermediate TS → JS compile step (no esbuild / tsx dependency).
24
+ *
25
+ * TypeScript handlers are explicitly out of scope; Coding Agent generates
26
+ * JS strings on the wire.
27
+ */
28
+ interface ScriptSource {
29
+ readonly kind: 'script';
30
+ readonly language: 'javascript';
31
+ readonly code: string;
32
+ }
33
+ /**
34
+ * Capability declaration.
35
+ *
36
+ * v0.7.28 ships the single-dimension form: a whitelist of builtin tool
37
+ * names that the handler may invoke through `ctx.tools.<name>(...)`.
38
+ * All I/O — fs / net / env — must flow through builtin tools (`read` /
39
+ * `write` / `bash` / etc.); handlers do not receive direct `ctx.fs` /
40
+ * `ctx.net` / `ctx.env` entry points.
41
+ *
42
+ * Forward-compatible evolution: if the future demands path/domain-level
43
+ * constraints, this can grow to `(string | { name; constraints })[]`
44
+ * without breaking existing manifests.
45
+ */
46
+ interface Capabilities {
47
+ readonly tools: readonly string[];
48
+ }
49
+ /**
50
+ * Tool-kind artifact body (the `content` of `ConstructionArtifact` when
51
+ * `kind === 'tool'`).
52
+ */
53
+ interface ToolContent {
54
+ readonly description: string;
55
+ readonly inputSchema: Record<string, unknown>;
56
+ readonly capabilities: Capabilities;
57
+ readonly handler: ScriptSource;
58
+ /**
59
+ * Per-tool timeout override. Defaults to {@link DEFAULT_HANDLER_TIMEOUT_MS}
60
+ * when omitted. Bounded by AbortController in `loadHandler()`.
61
+ */
62
+ readonly timeoutMs?: number;
63
+ }
64
+ /**
65
+ * Default handler timeout. Picked to match the historical ceiling on
66
+ * builtin streaming tools (30s); revisit if a constructed tool demands
67
+ * longer-running computation.
68
+ */
69
+ declare const DEFAULT_HANDLER_TIMEOUT_MS = 30000;
70
+ /**
71
+ * Lifecycle state on disk. Drives both the startup glob filter and the
72
+ * `revoke()` semantics. See DD §14.1 — file system is the single source
73
+ * of truth; no separate `_manifest.json` index file (C4 decision).
74
+ */
75
+ type ArtifactStatus = 'staged' | 'active' | 'revoked';
76
+ /**
77
+ * Reference to a tool by stable id. v0.7.31 (FEATURE_089) introduces
78
+ * Agent manifests that bundle tool refs rather than inline tool bodies;
79
+ * the resolver expands these refs to concrete `KodaXToolDefinition`
80
+ * instances at activate time.
81
+ *
82
+ * `ref` shape:
83
+ * - `builtin:<name>` — a tool from the static registry
84
+ * (e.g. `builtin:read`, `builtin:bash`)
85
+ * - `constructed:<name>@<ver>` — a previously-activated constructed tool
86
+ */
87
+ interface ToolRef {
88
+ readonly ref: string;
89
+ }
90
+ /**
91
+ * Reference to a Guardrail by stable id. The Layer A `Guardrail`
92
+ * declaration is name-only (no runtime hooks); resolvers map known
93
+ * names to constructed `ToolGuardrail` / `InputGuardrail` /
94
+ * `OutputGuardrail` instances at activation time.
95
+ */
96
+ interface GuardrailRef {
97
+ readonly kind: 'input' | 'output' | 'tool';
98
+ readonly ref: string;
99
+ }
100
+ /**
101
+ * Reference to a handoff target by stable id (another constructed agent
102
+ * or a builtin role). The resolver expands `target.ref` to the actual
103
+ * `Agent` declaration at admission time so the handoff DAG check
104
+ * (`handoffLegality` invariant) sees the full graph.
105
+ */
106
+ interface AgentHandoffRef {
107
+ readonly target: {
108
+ readonly ref: string;
109
+ };
110
+ readonly kind: 'continuation' | 'as-tool';
111
+ readonly description?: string;
112
+ }
113
+ /**
114
+ * Reasoning profile declaration mirroring the Layer A
115
+ * `AgentReasoningProfile`. Kept structurally identical so the resolver
116
+ * passes the value through without re-shaping.
117
+ */
118
+ interface AgentReasoningRef {
119
+ readonly default: 'quick' | 'balanced' | 'deep';
120
+ readonly max?: 'quick' | 'balanced' | 'deep';
121
+ readonly escalateOnRevise?: boolean;
122
+ }
123
+ /**
124
+ * Sandbox test case. Used by `sandbox_test_agent` to verify a
125
+ * constructed agent before it can activate. Each case feeds `input`
126
+ * to a sandbox Runner instance and grades the agent's final output:
127
+ *
128
+ * - `expectMatch` — final text must match this regex (string form)
129
+ * - `expectNotMatch` — final text must NOT match this regex
130
+ * - `expectFinalText` — exact substring match (case-sensitive)
131
+ *
132
+ * At least one of the three expect-fields must be present; the cases
133
+ * are graded by `runSandboxAgentTest()` (FEATURE_089 Phase 3.5).
134
+ */
135
+ interface AgentTestCase {
136
+ readonly id: string;
137
+ readonly input: string;
138
+ readonly expectMatch?: string;
139
+ readonly expectNotMatch?: string;
140
+ readonly expectFinalText?: string;
141
+ }
142
+ /**
143
+ * Agent-kind artifact body (the `content` of `ConstructionArtifact`
144
+ * when `kind === 'agent'`).
145
+ *
146
+ * FEATURE_089 (v0.7.31): all fields except `instructions` are optional;
147
+ * a minimal "echo agent" can be expressed as `{ instructions: '...' }`.
148
+ * Tool / handoff / guardrail refs are resolved at admission time
149
+ * (Runner.admit's 5-step audit expands them and feeds the resolved
150
+ * Agent through the invariant chain).
151
+ */
152
+ interface AgentContent {
153
+ readonly instructions: string;
154
+ readonly tools?: readonly ToolRef[];
155
+ readonly handoffs?: readonly AgentHandoffRef[];
156
+ readonly reasoning?: AgentReasoningRef;
157
+ readonly guardrails?: readonly GuardrailRef[];
158
+ readonly model?: string;
159
+ readonly provider?: string;
160
+ readonly effort?: KodaXWireReasoningEffort;
161
+ /**
162
+ * FEATURE_191 — one-sentence human-readable summary surfaced in the
163
+ * Worker system prompt's `=== Available specialist agents ===`
164
+ * block (FEATURE_191 A.3) and in `/agents list` UIs. Frontmatter
165
+ * `description` field of `~/.kodax/agents/<name>.md` and the
166
+ * `name`-paired argument of `KodaXExtensionAPI.registerAgent`
167
+ * funnel into this field. Optional for backward compatibility with
168
+ * FEATURE_089 minimal-agent shape (`{ instructions: '...' }`);
169
+ * the SP block renders `(no description)` when absent.
170
+ */
171
+ readonly description?: string;
172
+ /**
173
+ * Optional structured-output schema mirroring `Agent.outputSchema`.
174
+ * Pure pass-through to the runtime — admission does not validate
175
+ * shape semantics here, only well-formed JSON.
176
+ */
177
+ readonly outputSchema?: Record<string, unknown>;
178
+ /**
179
+ * Optional sandbox test cases. When present, `sandbox_test_agent`
180
+ * runs them; when absent, the test step performs only the static
181
+ * checks (manifest schema + admission audit).
182
+ */
183
+ readonly testCases?: readonly AgentTestCase[];
184
+ /**
185
+ * Maximum total budget (iteration count) the agent may consume.
186
+ * Plumbed onto the resolved `AgentManifest.maxBudget` and clamped by
187
+ * `budgetCeiling` invariant during admission.
188
+ */
189
+ readonly maxBudget?: number;
190
+ /**
191
+ * Voluntary additional invariants the LLM declares this agent
192
+ * commits to. Plumbed onto `AgentManifest.declaredInvariants`;
193
+ * unioned on top of the required set during admission.
194
+ */
195
+ readonly declaredInvariants?: readonly string[];
196
+ }
197
+ /**
198
+ * Persisted artifact shape (one JSON file per name/version under
199
+ * `.kodax/constructed/<kind>s/<name>/<version>.json`).
200
+ *
201
+ * Discriminated union over `kind`:
202
+ * - `kind: 'tool'` — v0.7.28 (FEATURE_088) tool generation
203
+ * - `kind: 'agent'` — v0.7.31 (FEATURE_089) agent generation; passes
204
+ * through `Runner.admit()` at activation time
205
+ *
206
+ * Lifecycle fields (status / timestamps / contentHash / sourceAgent /
207
+ * signedBy) are common to all kinds.
208
+ */
209
+ type ConstructionArtifact = ToolArtifact | AgentArtifact;
210
+ interface ConstructionArtifactBase {
211
+ readonly name: string;
212
+ readonly version: string;
213
+ status: ArtifactStatus;
214
+ readonly signedBy?: string;
215
+ readonly createdAt: number;
216
+ readonly sourceAgent?: string;
217
+ testedAt?: number;
218
+ activatedAt?: number;
219
+ revokedAt?: number;
220
+ /**
221
+ * SHA-256 of `JSON.stringify(content)` captured at activate time.
222
+ * `rehydrateActiveArtifacts()` recomputes and compares — a mismatch
223
+ * indicates the manifest was edited between activation and the next
224
+ * boot (naive cross-session tampering, e.g. an LLM rewriting the .json
225
+ * via the Write tool without recomputing the hash). Mismatched
226
+ * artifacts are skipped at rehydrate with a stderr warning. This is
227
+ * NOT a defense against a coordinated attacker who recomputes the
228
+ * hash; the threat model is single-user CLI integrity, not multi-user
229
+ * supply chain.
230
+ */
231
+ contentHash?: string;
232
+ }
233
+ interface ToolArtifact extends ConstructionArtifactBase {
234
+ readonly kind: 'tool';
235
+ readonly content: ToolContent;
236
+ }
237
+ interface AgentArtifact extends ConstructionArtifactBase {
238
+ readonly kind: 'agent';
239
+ readonly content: AgentContent;
240
+ }
241
+ /**
242
+ * Returned by {@link ConstructionRuntime.stage}; opaque handle that
243
+ * downstream `test()` / `activate()` calls bind to.
244
+ */
245
+ interface StagedHandle {
246
+ readonly artifact: ConstructionArtifact;
247
+ readonly stagedAt: number;
248
+ }
249
+ /**
250
+ * Outcome of {@link ConstructionRuntime.test}. `ok=false` blocks
251
+ * activation; `warnings` surface but do not block.
252
+ */
253
+ interface TestResult {
254
+ readonly ok: boolean;
255
+ readonly errors?: readonly string[];
256
+ readonly warnings?: readonly string[];
257
+ }
258
+ /**
259
+ * Policy gate — invoked once per `activate()` before the artifact is
260
+ * registered. Default rejects implicit auto-approval; the REPL surface
261
+ * binds a dialog-based policy in `packages/repl/src/common/construction-
262
+ * bootstrap.ts` so user approval flows through the live askUser channel.
263
+ *
264
+ * Modeled as a function type rather than an interface (D3 decision):
265
+ * keeps the contract surface tiny, no class boilerplate.
266
+ *
267
+ * No declarative `kodax.config.ts` override hatch is provided — see the
268
+ * "Deferred Design Decisions" section in `features/v0.7.28.md` for why
269
+ * a `risk_mode` enum (when truly needed) is preferred over user-authored
270
+ * policy functions.
271
+ */
272
+ type ConstructionPolicy = (artifact: ConstructionArtifact) => Promise<ConstructionPolicyVerdict>;
273
+ type ConstructionPolicyVerdict = 'approve' | 'reject' | 'ask-user';
274
+ /** Default policy: always ask the user; no implicit approvals. */
275
+ declare const defaultPolicy: ConstructionPolicy;
276
+ /**
277
+ * Thrown by `CtxProxy` when handler attempts to access a tool not declared
278
+ * in `capabilities.tools`. Caught in tracer; surfaces as a tool error.
279
+ */
280
+ declare class CapabilityDeniedError extends Error {
281
+ readonly toolName: string;
282
+ readonly declaredTools: readonly string[];
283
+ constructor(toolName: string, declaredTools: readonly string[]);
284
+ }
285
+ /**
286
+ * Thrown when a manifest cannot be parsed / is missing required fields.
287
+ * Surfaces during stage() / startup glob; tracer records details.
288
+ */
289
+ declare class ConstructionManifestError extends Error {
290
+ readonly path?: string;
291
+ constructor(message: string, path?: string);
292
+ }
293
+
294
+ /**
295
+ * KodaX Tool Types
296
+ */
297
+
298
+ /**
299
+ * Progress yield from a streaming (async generator) tool.
300
+ * Each yield appears as a real-time status update in the REPL transcript.
301
+ */
302
+ interface ToolProgress {
303
+ readonly stage: string;
304
+ readonly message: string;
305
+ }
306
+ /**
307
+ * Final result a tool may return. Either a plain string (the default for
308
+ * text-only tools) OR a typed-array form for multimodal returns (e.g.
309
+ * `read` on an image path returns `[{type:'text',...}, {type:'image',...}]`).
310
+ * Providers serialize each shape to their wire format; OpenAI-compat
311
+ * gateways downgrade image items to a placeholder rather than rejecting.
312
+ *
313
+ * The array form mirrors claudecode's FileReadTool image return — Claude
314
+ * Code packs image data into `tool_result` content so the model can
315
+ * re-fetch images via the tool path. See
316
+ * `c:/Works/claudecode/src/tools/FileReadTool/FileReadTool.ts:866-891`.
317
+ */
318
+ type ToolResult = string | readonly KodaXToolResultContentItem[];
319
+ /** Standard tool handler — returns a final result (text or multimodal). */
320
+ type ToolHandlerSync = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => Promise<ToolResult>;
321
+ /** Streaming tool handler — yields progress updates, returns final result. */
322
+ type ToolHandlerStreaming = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => AsyncGenerator<ToolProgress, ToolResult, void>;
323
+ /** Union of both handler types. Existing tools use ToolHandlerSync; new long-running tools may use ToolHandlerStreaming. */
324
+ type ToolHandler = ToolHandlerSync | ToolHandlerStreaming;
325
+
326
+ /**
327
+ * FEATURE_149 (v0.7.38) — interrupt-on-submit policy for in-flight tools.
328
+ *
329
+ * Controls whether submitting a new prompt while THIS tool is mid-execution
330
+ * triggers a fast-abort of the current agent round (so the new prompt starts
331
+ * immediately) or queues the prompt to run after the tool resolves.
332
+ *
333
+ * - `'cancel'` — long-running tools whose work the user is likely to want
334
+ * to abandon when they redirect (e.g., `bash` running a 30s script,
335
+ * `dispatch_child_task` synchronously awaiting a child, sleep-style
336
+ * tools). InkREPL submit handler aborts the round immediately.
337
+ *
338
+ * - `'wait'` (default) — atomic / fast tools (read, grep, glob, write,
339
+ * edit, …) where waiting for completion is cheaper than aborting and
340
+ * redoing.
341
+ *
342
+ * Mirrors Claude Code `interruptBehavior` (`utils/handlePromptSubmit.ts`).
343
+ */
344
+ type ToolInterruptBehavior = 'cancel' | 'wait';
345
+ interface LocalToolDefinition extends KodaXToolDefinition {
346
+ handler: ToolHandler;
347
+ /**
348
+ * v0.7.42 — Required declarative side-effect class. See
349
+ * {@link ToolSideEffect} for category definitions and rationale. Plan
350
+ * mode and SDK embedders' permission brokers consume this; failure to
351
+ * declare is a TypeScript error (by design — `sideEffect` is required,
352
+ * not optional, to prevent silent drift when new tools are added).
353
+ */
354
+ sideEffect: ToolSideEffect;
355
+ /**
356
+ * v0.7.42 — Optional plan-mode override.
357
+ *
358
+ * - `undefined` (default): plan-mode permits only `sideEffect ===
359
+ * 'readonly'` tools.
360
+ * - `true`: explicitly permitted in plan mode even when sideEffect is
361
+ * not `'readonly'`. Reserve for tools whose effect is itself part of
362
+ * the planning loop (`exit_plan_mode`, `task_stop`, `todo_update`,
363
+ * `todo_create`, `ask_user_question`).
364
+ * - `false`: explicitly blocked in plan mode even when sideEffect is
365
+ * `'readonly'`. Rare — useful for read-only tools whose output would
366
+ * leak content the planner should not see.
367
+ */
368
+ planModeAllowed?: boolean;
369
+ /**
370
+ * FEATURE_149 (v0.7.38) — submit-time interrupt policy. See
371
+ * {@link ToolInterruptBehavior}. Default `'wait'` when undefined.
372
+ */
373
+ interruptBehavior?: ToolInterruptBehavior;
374
+ /**
375
+ * Progressive disclosure — when `true`, the tool's full description is
376
+ * replaced with `searchHint` (a one-line summary) in the LLM-visible
377
+ * tool schema until the per-session unlock Set marks the tool name as
378
+ * unlocked. Unlocking happens via the `tool_search` tool: the LLM
379
+ * invokes `tool_search` with a query that selects this tool, and the
380
+ * full description + JSON schema are returned in the tool_result text.
381
+ * The next `getActiveToolDefinitions` call for the same session sees
382
+ * the unlock and emits the full description.
383
+ *
384
+ * Use for tools with rich descriptions (>500 bytes) whose teaching
385
+ * content the model only needs to consume when it actually plans to
386
+ * call the tool. Saves turn-1 context without dropping the tool.
387
+ *
388
+ * Mirrors claudecode `Tool.shouldDefer` — see
389
+ * `c:/Works/claudecode/src/tools/Tool.ts` for the parent design and
390
+ * `c:/Works/claudecode/src/tools/ToolSearchTool/` for the bootstrap.
391
+ */
392
+ shouldDefer?: boolean;
393
+ /**
394
+ * One-line hint shown in place of the full description when this tool
395
+ * is deferred and not yet unlocked. Required when `shouldDefer: true`.
396
+ * Should answer "when would I want to look this up" in ≤ 100 chars
397
+ * so the LLM can decide whether to invoke `tool_search` for the full
398
+ * schema. Example: `'Fetch a specific remote URL — use tool_search to load full schema.'`
399
+ */
400
+ searchHint?: string;
401
+ /**
402
+ * Classifier projection — REQUIRED (FEATURE_092 v0.7.33).
403
+ *
404
+ * Returns a one-line string that the auto-mode classifier sees as the
405
+ * `<action>` to evaluate. The classifier asks: "Given the user's
406
+ * intent + rules, should the agent be allowed to run this?"
407
+ *
408
+ * THREE-TIER STRATEGY (pick by tool's risk profile):
409
+ *
410
+ * 1. ZERO RISK (read-only, structural):
411
+ * → return '' (Tier 1 — classifier is skipped entirely, zero token cost)
412
+ * Examples: read, grep, glob, ask_user_question, exit_plan_mode
413
+ *
414
+ * 2. HIGH RISK (mutates state, network, exec, spawn):
415
+ * → write a CUSTOM projection that surfaces the risk-bearing fields
416
+ * Examples: bash (`Bash: ${i.command}`), web_fetch (`WebFetch ${i.url}`)
417
+ * See `classifier-projection.ts` for examples by category.
418
+ *
419
+ * 3. LOW RISK (structured input, side-effect-capable):
420
+ * → return defaultToClassifierInput(name, input) (one-line helper)
421
+ * Examples: semantic_lookup (refresh: true rebuilds index)
422
+ *
423
+ * KEEP IT SHORT: ≤ 100 chars typical. Variable-length user-provided fields
424
+ * (bash command, URL, dispatch_child_task objective) may legitimately
425
+ * exceed this — the projection's job is to make the risk visible, not to
426
+ * fit a fixed budget at the cost of hiding it.
427
+ *
428
+ * NEVER include: raw file contents, secrets, API keys, full LLM-emitted
429
+ * reasoning, or untrusted text passed through verbatim. Use byte/line
430
+ * counts as proxies (`Write ${path} (${content.length} bytes)`).
431
+ *
432
+ * See `docs/features/v0.7.33.md` "Tool 接口扩展" for design rationale.
433
+ */
434
+ toClassifierInput: (input: unknown) => string;
435
+ }
436
+ interface ToolDefinitionSource {
437
+ /**
438
+ * Origin of the registered tool. `'constructed'` (FEATURE_087, v0.7.28)
439
+ * marks tools materialized at runtime by `ConstructionRuntime` from
440
+ * `.kodax/constructed/tools/<name>/<version>.json` artifacts.
441
+ */
442
+ kind: 'builtin' | 'extension' | 'constructed';
443
+ id?: string;
444
+ label?: string;
445
+ /**
446
+ * Constructed-only: semver of the activated artifact. Used by
447
+ * `findByVersion()` and by `revoke()` to locate a specific stack entry.
448
+ */
449
+ version?: string;
450
+ /**
451
+ * Constructed-only: absolute path to the artifact JSON on disk.
452
+ * Lets revoke / inspect operations round-trip back to the source of
453
+ * truth without re-globbing.
454
+ */
455
+ manifestPath?: string;
456
+ }
457
+ interface RegisteredToolDefinition extends LocalToolDefinition {
458
+ registrationId: string;
459
+ requiredParams: string[];
460
+ source: ToolDefinitionSource;
461
+ }
462
+ interface ToolRegistrationOptions {
463
+ source?: ToolDefinitionSource;
464
+ }
465
+ type ToolRegistry = Map<string, RegisteredToolDefinition[]>;
466
+ type KodaXRetrievalToolName = 'web_search' | 'web_fetch' | 'code_search' | 'semantic_lookup' | 'mcp_search' | 'mcp_describe' | 'mcp_call' | 'mcp_read_resource' | 'mcp_get_prompt';
467
+ type KodaXRetrievalScope = 'workspace' | 'remote';
468
+ type KodaXRetrievalTrust = 'workspace' | 'provider' | 'open-world';
469
+ type KodaXRetrievalFreshness = 'fresh' | 'snapshot' | 'unknown';
470
+ interface KodaXRetrievalArtifact {
471
+ kind: 'url' | 'path' | 'symbol' | 'module' | 'process' | 'provider';
472
+ label: string;
473
+ value: string;
474
+ }
475
+ interface KodaXRetrievalItem {
476
+ title: string;
477
+ locator?: string;
478
+ snippet?: string;
479
+ score?: number;
480
+ metadata?: Record<string, unknown>;
481
+ }
482
+ interface KodaXRetrievalResult {
483
+ tool: KodaXRetrievalToolName;
484
+ query?: string;
485
+ scope: KodaXRetrievalScope;
486
+ trust: KodaXRetrievalTrust;
487
+ freshness: KodaXRetrievalFreshness;
488
+ provider?: string;
489
+ summary: string;
490
+ content?: string;
491
+ items: KodaXRetrievalItem[];
492
+ artifacts?: KodaXRetrievalArtifact[];
493
+ metadata?: Record<string, unknown>;
494
+ }
495
+
496
+ interface ExecOptions {
497
+ /** Extra environment variables to inject (merged with safe base env). */
498
+ readonly env?: Readonly<Record<string, string>>;
499
+ /** Working directory. Defaults to process.cwd(). */
500
+ readonly cwd?: string;
501
+ /** Timeout in milliseconds. Defaults to 30000. */
502
+ readonly timeout?: number;
503
+ /** Shell to use. Defaults to 'bash' on Unix, 'powershell' on Windows. */
504
+ readonly shell?: 'bash' | 'powershell';
505
+ }
506
+ interface ExecResult {
507
+ readonly exitCode: number;
508
+ readonly stdout: string;
509
+ readonly stderr: string;
510
+ }
511
+ /**
512
+ * Run a shell command with a sandboxed environment.
513
+ *
514
+ * SECURITY: Only a whitelist of safe environment variables is passed to the
515
+ * subprocess. API keys and tokens from the parent environment are NOT inherited.
516
+ */
517
+ declare function exec(command: string, options?: ExecOptions): Promise<ExecResult>;
518
+ interface WebhookOptions {
519
+ /** HTTP method. Defaults to 'POST'. */
520
+ readonly method?: 'POST' | 'PUT';
521
+ /** Extra HTTP headers. */
522
+ readonly headers?: Readonly<Record<string, string>>;
523
+ /** Timeout in milliseconds. Defaults to 10000. */
524
+ readonly timeout?: number;
525
+ }
526
+ interface WebhookResult {
527
+ readonly ok: boolean;
528
+ readonly status: number;
529
+ readonly body?: string;
530
+ }
531
+ /**
532
+ * Send an HTTP webhook with timeout support.
533
+ * Returns a result object instead of throwing on errors.
534
+ */
535
+ declare function webhook(url: string, payload: unknown, options?: WebhookOptions): Promise<WebhookResult>;
536
+
537
+ interface ModelProviderRegistration {
538
+ name: string;
539
+ factory: () => KodaXBaseProvider;
540
+ }
541
+ interface ExtensionCommandDefinition {
542
+ name: string;
543
+ aliases?: string[];
544
+ description: string;
545
+ usage?: string;
546
+ metadata?: Record<string, unknown>;
547
+ handler: (args: string[], context: ExtensionCommandContext) => Promise<ExtensionCommandResult | void> | ExtensionCommandResult | void;
548
+ }
549
+ interface ExtensionModelSelection {
550
+ provider?: string;
551
+ model?: string;
552
+ }
553
+ interface ExtensionLogger {
554
+ debug: (...args: unknown[]) => void;
555
+ info: (...args: unknown[]) => void;
556
+ warn: (...args: unknown[]) => void;
557
+ error: (...args: unknown[]) => void;
558
+ }
559
+ interface ExtensionFileContributionSource {
560
+ kind: 'extension';
561
+ id: string;
562
+ label: string;
563
+ path: string;
564
+ }
565
+ interface RuntimeContributionSource {
566
+ kind: 'runtime';
567
+ id: string;
568
+ label: string;
569
+ path?: string;
570
+ }
571
+ type ExtensionContributionSource = ExtensionFileContributionSource | RuntimeContributionSource;
572
+ type ExtensionLoadSource = 'api' | 'cli' | 'config' | 'discovery';
573
+ interface LoadedExtensionDiagnostic {
574
+ path: string;
575
+ label: string;
576
+ loadSource: ExtensionLoadSource;
577
+ sessionStateKeys?: string[];
578
+ sessionRecordCounts?: Record<string, number>;
579
+ }
580
+ interface RegisteredCapabilityProviderDiagnostic {
581
+ id: string;
582
+ kinds: CapabilityKind[];
583
+ source: ExtensionContributionSource;
584
+ metadata?: Record<string, unknown>;
585
+ }
586
+ interface RegisteredCommandDiagnostic {
587
+ name: string;
588
+ aliases?: string[];
589
+ description: string;
590
+ usage?: string;
591
+ metadata?: Record<string, unknown>;
592
+ source: ExtensionContributionSource;
593
+ }
594
+ interface RegisteredToolDiagnostic {
595
+ name: string;
596
+ description: string;
597
+ requiredParams: string[];
598
+ source: RegisteredToolDefinition['source'];
599
+ shadowedSources: RegisteredToolDefinition['source'][];
600
+ }
601
+ interface RegisteredHookDiagnostic {
602
+ hook: keyof ExtensionHookMap;
603
+ order: number;
604
+ source: ExtensionContributionSource;
605
+ }
606
+ type ExtensionFailureStage = 'load' | 'reload' | 'event' | 'hook' | 'persistence';
607
+ interface ExtensionFailureDiagnostic {
608
+ stage: ExtensionFailureStage;
609
+ target: string;
610
+ message: string;
611
+ occurredAt: string;
612
+ source: ExtensionContributionSource;
613
+ }
614
+ interface ExtensionRuntimeDiagnostics {
615
+ loadedExtensions: LoadedExtensionDiagnostic[];
616
+ capabilityProviders: RegisteredCapabilityProviderDiagnostic[];
617
+ commands: RegisteredCommandDiagnostic[];
618
+ tools: RegisteredToolDiagnostic[];
619
+ hooks: RegisteredHookDiagnostic[];
620
+ failures: ExtensionFailureDiagnostic[];
621
+ defaults: {
622
+ activeTools?: string[];
623
+ modelSelection: ExtensionModelSelection;
624
+ thinkingLevel?: KodaXWireReasoningEffort;
625
+ };
626
+ }
627
+ interface ExtensionCommandInvocation {
628
+ prompt: string;
629
+ displayName?: string;
630
+ disableModelInvocation?: boolean;
631
+ allowedTools?: string;
632
+ context?: 'fork';
633
+ model?: string;
634
+ }
635
+ interface ExtensionCommandResult {
636
+ success?: boolean;
637
+ message?: string;
638
+ data?: unknown;
639
+ invocation?: ExtensionCommandInvocation;
640
+ }
641
+ interface ExtensionCommandContext {
642
+ sessionId?: string;
643
+ gitRoot?: string;
644
+ workingDirectory: string;
645
+ reloadExtensions: () => Promise<void>;
646
+ getDiagnostics: () => ExtensionRuntimeDiagnostics;
647
+ logger: ExtensionLogger;
648
+ }
649
+ interface ExtensionToolBeforeHookContext {
650
+ name: string;
651
+ input: Record<string, unknown>;
652
+ toolId?: string;
653
+ executionCwd?: string;
654
+ gitRoot?: string;
655
+ }
656
+ interface ExtensionProviderBeforeHookContext {
657
+ provider: string;
658
+ model?: string;
659
+ reasoningMode?: KodaXWireReasoningEffort;
660
+ systemPrompt: string;
661
+ block: (reason: string) => void;
662
+ replaceProvider: (provider: string) => void;
663
+ replaceModel: (model?: string) => void;
664
+ replaceSystemPrompt: (systemPrompt: string) => void;
665
+ setThinkingLevel: (level: KodaXWireReasoningEffort) => void;
666
+ }
667
+ interface ExtensionTurnSettleHookContext {
668
+ sessionId: string;
669
+ lastText: string;
670
+ hadToolCalls: boolean;
671
+ success: boolean;
672
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
673
+ queueUserMessage: (message: string | KodaXMessage) => void;
674
+ setModelSelection: (next: ExtensionModelSelection) => void;
675
+ setThinkingLevel: (level: KodaXWireReasoningEffort) => void;
676
+ }
677
+ /**
678
+ * FEATURE_184 (v0.7.45) — Stop Hook bridge context for extensions.
679
+ *
680
+ * Fires ONLY when the model terminates a turn text-only (no tool_use)
681
+ * — a strict subset of `turn:settle`, which fires on every turn end
682
+ * including mid-task tool turns. Use this hook for verification or
683
+ * "is the task actually done?" checks. The three-state return surface
684
+ * mirrors `RunOptions.stopHook` at the agent layer; the bridge passes
685
+ * the extension's return through unchanged.
686
+ *
687
+ * Coding-layer first-party consumers (Sidecar Verifier, FEATURE_184
688
+ * Phase D) wire directly to the agent `stopHook`. Third-party
689
+ * extensions write `api.hook('turn:complete', handler)` and the bridge
690
+ * dispatches to them inside the agent's `stopHook` callback. Handlers
691
+ * fire in registration order, first non-`void` return short-circuits
692
+ * the chain (matches `tool:before` semantics).
693
+ *
694
+ * Scope note: this hook fires on the AMA `runner-driven` path only
695
+ * (main loop, B1 retry, V2 worker). SA-path child agents dispatched
696
+ * via `dispatch_child_task` go through `runKodaX` and do NOT trigger
697
+ * this hook — observe their lifecycle via `turn:settle` on the SA
698
+ * path. Extensions wanting "every agent termination" semantics must
699
+ * register both hooks.
700
+ */
701
+ interface ExtensionTurnCompleteHookContext {
702
+ sessionId: string;
703
+ lastAssistantText: string;
704
+ signal: 'natural-end';
705
+ reanimateCount: number;
706
+ reanimateBudget: number;
707
+ }
708
+ /**
709
+ * FEATURE_184 (v0.7.45) — Extension `turn:complete` return surface.
710
+ *
711
+ * - `void` / `undefined` → accept the termination, defer to next
712
+ * handler (or fall through to agent terminal path if none).
713
+ * - `string` → reanimate: synthesize a user message, run another
714
+ * turn. Bounded by Runner's `stopHookReanimateBudget`.
715
+ * - `{ abort: true, reason }` → halt the run, surface reason to
716
+ * caller via `RunResult.output` + `stoppedByHook = true`.
717
+ */
718
+ type ExtensionTurnCompleteHookResult = void | string | {
719
+ readonly abort: true;
720
+ readonly reason: string;
721
+ };
722
+ interface ExtensionSessionHydrateHookContext {
723
+ sessionId: string;
724
+ getState: <T = KodaXJsonValue>(key: string) => T | undefined;
725
+ setState: (key: string, value: KodaXJsonValue | undefined) => void;
726
+ listRecords: (type?: string) => KodaXExtensionSessionRecord[];
727
+ appendRecord: (type: string, data?: KodaXJsonValue, options?: {
728
+ dedupeKey?: string;
729
+ }) => KodaXExtensionSessionRecord | undefined;
730
+ clearRecords: (type?: string) => number;
731
+ }
732
+ interface ExtensionEventMap {
733
+ 'session:start': {
734
+ provider: string;
735
+ sessionId: string;
736
+ };
737
+ 'turn:start': {
738
+ sessionId: string;
739
+ iteration: number;
740
+ maxIter: number;
741
+ };
742
+ 'text:delta': {
743
+ text: string;
744
+ };
745
+ 'thinking:delta': {
746
+ text: string;
747
+ };
748
+ 'thinking:end': {
749
+ thinking: string;
750
+ };
751
+ 'tool:start': {
752
+ name: string;
753
+ id: string;
754
+ input?: Record<string, unknown>;
755
+ };
756
+ 'tool:result': {
757
+ id: string;
758
+ name: string;
759
+ content: string;
760
+ };
761
+ 'provider:selected': {
762
+ provider: string;
763
+ model?: string;
764
+ };
765
+ 'provider:rate-limit': {
766
+ provider: string;
767
+ attempt: number;
768
+ maxRetries: number;
769
+ delayMs: number;
770
+ };
771
+ 'capability:search': {
772
+ providerId: string;
773
+ query: string;
774
+ kind?: CapabilityKind;
775
+ limit?: number;
776
+ };
777
+ 'capability:describe': {
778
+ providerId: string;
779
+ capabilityId: string;
780
+ };
781
+ 'capability:invoke': {
782
+ providerId: string;
783
+ capabilityId: string;
784
+ kind: CapabilityKind;
785
+ };
786
+ 'capability:refresh': {
787
+ providerId: string;
788
+ };
789
+ 'stream:end': undefined;
790
+ 'turn:end': {
791
+ sessionId: string;
792
+ iteration: number;
793
+ lastText: string;
794
+ hadToolCalls: boolean;
795
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
796
+ };
797
+ 'complete': {
798
+ success: boolean;
799
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
800
+ };
801
+ 'error': {
802
+ error: Error;
803
+ };
804
+ 'todo:created': {
805
+ id: string;
806
+ item: KodaXTodoItem;
807
+ source: TodoMutationSource;
808
+ };
809
+ 'todo:updated': {
810
+ id: string;
811
+ before: KodaXTodoItem;
812
+ after: KodaXTodoItem;
813
+ changedFields: readonly (keyof KodaXTodoItem)[];
814
+ source: TodoMutationSource;
815
+ };
816
+ 'todo:deleted': {
817
+ id: string;
818
+ item: KodaXTodoItem;
819
+ source: TodoMutationSource;
820
+ };
821
+ }
822
+ /**
823
+ * FEATURE_170 v0.7.41 — provenance tag for todo:* events / hooks. Lets
824
+ * extension authors distinguish LLM-driven mutations (`tool`) from
825
+ * runner-side automation (`internal`) — e.g. an extension that audits
826
+ * todo churn should ignore `internal` flips to avoid false positives.
827
+ */
828
+ type TodoMutationSource = 'tool' | 'internal';
829
+ /**
830
+ * FEATURE_170 v0.7.41 — seed shape passed to `'todo:before-create'`.
831
+ * Mirrors `TodoAddSeed` from todo-store.ts (kept structurally compatible
832
+ * to avoid coupling extension authors to the internal task-engine type).
833
+ *
834
+ * v0.7.42 — `content` renamed to `subject` + optional `description` to
835
+ * match claudecode V2 `TaskCreateTool` schema. See `TodoItem` JSDoc in
836
+ * packages/coding/src/types.ts.
837
+ */
838
+ interface ExtensionTodoCreateSeed {
839
+ readonly subject: string;
840
+ readonly description?: string;
841
+ readonly activeForm?: string;
842
+ readonly evaluator?: 'build' | 'test' | 'lint';
843
+ readonly owner?: string;
844
+ readonly sourceObligationIndex?: number;
845
+ readonly metadata?: Record<string, unknown>;
846
+ }
847
+ /**
848
+ * FEATURE_170 v0.7.41 — minimal todo item shape exposed to extensions
849
+ * via the todo:* events. Kept structurally identical to the engine's
850
+ * `TodoItem` so the runtime can pass values straight through without
851
+ * conversion, but redeclared here so extension consumers don't import
852
+ * from `packages/coding/src/types.ts` (which is task-engine internal).
853
+ *
854
+ * Drift guard: a compile-time assignability assertion at the bottom of
855
+ * this file fires if `TodoItem` (engine) gains a field that this
856
+ * extension-facing shape does NOT mirror — see `__todoItemParity` below.
857
+ */
858
+ interface KodaXTodoItem {
859
+ readonly id: string;
860
+ /** v0.7.42 — see TodoItem.subject JSDoc in packages/coding/src/types.ts. */
861
+ readonly subject: string;
862
+ readonly description?: string;
863
+ readonly status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'skipped' | 'cancelled';
864
+ readonly owner?: string;
865
+ readonly sourceObligationIndex?: number;
866
+ readonly note?: string;
867
+ readonly evaluator?: 'build' | 'test' | 'lint';
868
+ readonly activeForm?: string;
869
+ readonly metadata?: Record<string, unknown>;
870
+ }
871
+ interface ExtensionHookMap {
872
+ 'tool:before': (context: ExtensionToolBeforeHookContext) => Promise<void | string | false> | void | string | false;
873
+ 'provider:before': (context: ExtensionProviderBeforeHookContext) => Promise<void> | void;
874
+ 'turn:settle': (context: ExtensionTurnSettleHookContext) => Promise<void> | void;
875
+ 'turn:complete': (context: ExtensionTurnCompleteHookContext) => Promise<ExtensionTurnCompleteHookResult> | ExtensionTurnCompleteHookResult;
876
+ 'session:hydrate': (context: ExtensionSessionHydrateHookContext) => Promise<void> | void;
877
+ 'todo:before-create': (context: {
878
+ seed: ExtensionTodoCreateSeed;
879
+ }) => Promise<void | string | false> | void | string | false;
880
+ 'todo:before-complete': (context: {
881
+ id: string;
882
+ item: KodaXTodoItem;
883
+ }) => Promise<void | string | false> | void | string | false;
884
+ }
885
+ interface ExtensionRuntimeController {
886
+ queueUserMessage(message: string | KodaXMessage): void;
887
+ getSessionState<T = KodaXJsonValue>(key: string): T | undefined;
888
+ setSessionState(key: string, value: KodaXJsonValue | undefined): void;
889
+ appendSessionRecord(type: string, data?: KodaXJsonValue, options?: {
890
+ dedupeKey?: string;
891
+ }): KodaXExtensionSessionRecord | undefined;
892
+ listSessionRecords(type?: string): KodaXExtensionSessionRecord[];
893
+ clearSessionRecords(type?: string): number;
894
+ getActiveTools(): string[];
895
+ setActiveTools(toolNames: string[]): void;
896
+ getModelSelection(): ExtensionModelSelection;
897
+ setModelSelection(next: ExtensionModelSelection): void;
898
+ getThinkingLevel(): KodaXWireReasoningEffort | undefined;
899
+ setThinkingLevel(level: KodaXWireReasoningEffort): void;
900
+ }
901
+ interface KodaXExtensionAPI {
902
+ registerTool: (definition: LocalToolDefinition) => () => void;
903
+ getTool: (name: string) => RegisteredToolDefinition | undefined;
904
+ getBuiltinTool: (name: string) => RegisteredToolDefinition | undefined;
905
+ registerModelProvider: (registration: ModelProviderRegistration) => () => void;
906
+ registerCapabilityProvider: (provider: CapabilityProvider) => () => void;
907
+ registerCommand: (command: ExtensionCommandDefinition) => () => void;
908
+ registerSkillPath: (skillPath: string) => () => void;
909
+ /**
910
+ * FEATURE_191 (v0.7.43) — register a constructed agent at extension
911
+ * activate time. The extension supplies the agent name and an
912
+ * `AgentContent` body (instructions + optional tools/handoffs/
913
+ * reasoning/model/description); the runtime threads it through
914
+ * `buildAdmissionManifest` + `Runner.admit` and registers the
915
+ * activated Agent via `registerConstructedAgent({ source:
916
+ * 'extension' })`. The returned dispose fn (also auto-pushed onto
917
+ * the extension's disposables list) unregisters the agent on
918
+ * extension deactivate.
919
+ *
920
+ * Returns `Promise<() => void>` — **you MUST `await` the call**
921
+ * before invoking the dispose function. Unlike sibling
922
+ * `registerTool` (sync), this is async because `Runner.admit` is
923
+ * declared async (FEATURE_101 admission contract — admission may
924
+ * consult disk for handoff-target staged-agent resolution).
925
+ *
926
+ * @example
927
+ * ```ts
928
+ * // CORRECT — await unwraps the Promise to a sync dispose
929
+ * export default async function activate(api: KodaXExtensionAPI) {
930
+ * const dispose = await api.registerAgent('db-reviewer', {
931
+ * instructions: 'You review DB migrations.',
932
+ * description: 'DB migration reviewer',
933
+ * });
934
+ * // dispose() is now callable on demand; the runtime also auto-
935
+ * // disposes via the extension's disposables list at deactivate.
936
+ * }
937
+ * ```
938
+ *
939
+ * @example
940
+ * ```ts
941
+ * // WRONG — TypeScript catches this; .js / @ts-ignore consumers
942
+ * // hit a runtime TypeError because Promise is not a function.
943
+ * export default function activate(api: KodaXExtensionAPI) {
944
+ * const dispose = api.registerAgent('x', { instructions: '...' });
945
+ * dispose(); // TypeError: dispose is not a function
946
+ * }
947
+ * ```
948
+ *
949
+ * Throws on admission rejection (with the verdict reason) so the
950
+ * extension author sees the failure at activate time rather than
951
+ * having a silently-dropped registration. The throw also halts
952
+ * extension loading — the extension's other registrations roll back
953
+ * via `LoadedExtensionRecord.disposables` reverse-iterate.
954
+ */
955
+ registerAgent: (name: string, content: AgentContent) => Promise<() => void>;
956
+ on: <TEvent extends keyof ExtensionEventMap>(event: TEvent, handler: (payload: ExtensionEventMap[TEvent]) => Promise<void> | void) => () => void;
957
+ hook: <THook extends keyof ExtensionHookMap>(hook: THook, handler: ExtensionHookMap[THook]) => () => void;
958
+ logger: ExtensionLogger;
959
+ config: Readonly<Record<string, unknown>>;
960
+ runtime: ExtensionRuntimeController;
961
+ /** Extension-scoped key-value store that persists across sessions. */
962
+ persistence: KodaXExtensionStore;
963
+ /** Run a shell command with sandboxed environment (no API key leakage). */
964
+ exec: (command: string, options?: ExecOptions) => Promise<ExecResult>;
965
+ /** Send an HTTP webhook with timeout support. */
966
+ webhook: (url: string, payload: unknown, options?: WebhookOptions) => Promise<WebhookResult>;
967
+ }
968
+ type KodaXExtensionActivationResult = void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>;
969
+ interface KodaXExtensionModule {
970
+ default?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
971
+ activate?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
972
+ }
973
+
974
+ export { DEFAULT_HANDLER_TIMEOUT_MS as D, defaultPolicy as a1, exec as a2, webhook as a3, CapabilityDeniedError as c, ConstructionManifestError as e };
975
+ export type { WebhookOptions as $, AgentArtifact as A, KodaXRetrievalItem as B, Capabilities as C, ExecOptions as E, KodaXRetrievalResult as F, KodaXRetrievalScope as G, KodaXRetrievalToolName as H, KodaXRetrievalTrust as I, LocalToolDefinition as J, KodaXExtensionAPI as K, LoadedExtensionDiagnostic as L, ModelProviderRegistration as M, RegisteredCommandDiagnostic as N, RegisteredHookDiagnostic as O, RegisteredToolDefinition as P, RegisteredToolDiagnostic as Q, RegisteredCapabilityProviderDiagnostic as R, ScriptSource as S, StagedHandle as T, TestResult as U, ToolContent as V, ToolDefinitionSource as W, ToolHandler as X, ToolHandlerSync as Y, ToolRegistrationOptions as Z, ToolRegistry as _, AgentContent as a, WebhookResult as a0, ArtifactStatus as b, ConstructionArtifact as d, ConstructionPolicy as f, ConstructionPolicyVerdict as g, ExecResult as h, ExtensionCommandContext as i, ExtensionCommandDefinition as j, ExtensionCommandInvocation as k, ExtensionCommandResult as l, ExtensionContributionSource as m, ExtensionEventMap as n, ExtensionFailureDiagnostic as o, ExtensionFailureStage as p, ExtensionHookMap as q, ExtensionLoadSource as r, ExtensionLogger as s, ExtensionRuntimeController as t, ExtensionRuntimeDiagnostics as u, ExtensionToolBeforeHookContext as v, KodaXExtensionActivationResult as w, KodaXExtensionModule as x, KodaXRetrievalArtifact as y, KodaXRetrievalFreshness as z };