@kodax-ai/kodax 0.7.76 → 0.7.78

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 (130) hide show
  1. package/CHANGELOG.md +758 -371
  2. package/LICENSE +158 -158
  3. package/README.md +1702 -1508
  4. package/README_CN.md +1019 -869
  5. package/config-templates/config.example.jsonc +86 -4
  6. package/config-templates/integrations/a2a.example.jsonc +98 -98
  7. package/config-templates/integrations/extensions.example.jsonc +7 -7
  8. package/config-templates/integrations/mcp.example.jsonc +16 -16
  9. package/dist/builtin/code-review/SKILL.md +22 -22
  10. package/dist/builtin/skill-creator/scripts/aggregate-benchmark.d.ts +46 -46
  11. package/dist/builtin/skill-creator/scripts/analyze-benchmark.d.ts +46 -46
  12. package/dist/builtin/skill-creator/scripts/compare-runs.d.ts +62 -62
  13. package/dist/builtin/skill-creator/scripts/generate-review.d.ts +33 -33
  14. package/dist/builtin/skill-creator/scripts/grade-evals.d.ts +73 -73
  15. package/dist/builtin/skill-creator/scripts/improve-description.d.ts +23 -23
  16. package/dist/builtin/skill-creator/scripts/init-skill.d.ts +14 -14
  17. package/dist/builtin/skill-creator/scripts/install-skill.d.ts +29 -29
  18. package/dist/builtin/skill-creator/scripts/package-skill.d.ts +38 -38
  19. package/dist/builtin/skill-creator/scripts/quick-validate.d.ts +8 -8
  20. package/dist/builtin/skill-creator/scripts/run-eval.d.ts +66 -66
  21. package/dist/builtin/skill-creator/scripts/run-loop.d.ts +49 -49
  22. package/dist/builtin/skill-creator/scripts/run-trigger-eval.d.ts +58 -58
  23. package/dist/chunks/agent-ASP4MS3X.js +2 -0
  24. package/dist/chunks/argument-completer-JYQ7FX3W.js +2 -0
  25. package/dist/chunks/chunk-2CFHBKRE.js +5 -0
  26. package/dist/chunks/chunk-35PPHOQ2.js +292 -0
  27. package/dist/chunks/chunk-43QNNDHR.js +29 -0
  28. package/dist/chunks/chunk-5BNQXXGY.js +1 -0
  29. package/dist/chunks/chunk-5GO6FH7L.js +458 -0
  30. package/dist/chunks/chunk-5NDCSFOP.js +78 -0
  31. package/dist/chunks/chunk-6FOJVETH.js +22 -0
  32. package/dist/chunks/chunk-6XM4B6K2.js +48 -0
  33. package/dist/chunks/chunk-6YZUE6NC.js +240 -0
  34. package/dist/chunks/{chunk-RDXRM3UI.js → chunk-7OEBJGHK.js} +1 -1
  35. package/dist/chunks/chunk-KQLQYHWU.js +386 -0
  36. package/dist/chunks/chunk-NXO6GWSY.js +46 -0
  37. package/dist/chunks/chunk-T2XZTLYE.js +316 -0
  38. package/dist/chunks/chunk-TQDBTTIM.js +348 -0
  39. package/dist/chunks/{chunk-SMT2JSM3.js → chunk-UID7BLAB.js} +9 -9
  40. package/dist/chunks/chunk-VAT2QYXM.js +765 -0
  41. package/dist/chunks/chunk-YAZQTC2L.js +5 -0
  42. package/dist/chunks/chunk-YVRYHC4C.js +655 -0
  43. package/dist/chunks/{chunk-PXKSE54E.js → chunk-Z3KFRTSB.js} +1 -1
  44. package/dist/chunks/compaction-config-BQSSIWK5.js +2 -0
  45. package/dist/chunks/{construction-bootstrap-5F5KF2BZ.js → construction-bootstrap-VQLQGWPY.js} +1 -1
  46. package/dist/chunks/dist-BFT5YIGU.js +2 -0
  47. package/dist/chunks/dist-PCFE24YP.js +2 -0
  48. package/dist/chunks/host-UTFXCYYM.js +2 -0
  49. package/dist/chunks/run-manager-PJU3WIFJ.js +2 -0
  50. package/dist/chunks/utils-SID4HW2Q.js +2 -0
  51. package/dist/index.d.ts +21 -19
  52. package/dist/index.js +6 -6
  53. package/dist/kodax_bootstrap.js +25 -25
  54. package/dist/kodax_cli.js +1787 -1341
  55. package/dist/kodax_resume.js +17 -17
  56. package/dist/provider-capabilities.json +392 -362
  57. package/dist/runtime-worker.js +1707 -1279
  58. package/dist/sandbox-workspace-session.js +563 -0
  59. package/dist/sdk-a2a.d.ts +18 -17
  60. package/dist/sdk-a2a.js +8 -8
  61. package/dist/sdk-agent.d.ts +320 -70
  62. package/dist/sdk-agent.js +1 -1
  63. package/dist/sdk-coding.d.ts +135 -168
  64. package/dist/sdk-coding.js +1 -1
  65. package/dist/sdk-experimental-memory.d.ts +14 -597
  66. package/dist/sdk-experimental-memory.js +1 -1
  67. package/dist/sdk-llm.d.ts +219 -6
  68. package/dist/sdk-llm.js +1 -1
  69. package/dist/sdk-mcp.js +1 -1
  70. package/dist/sdk-media.d.ts +1 -1
  71. package/dist/sdk-media.js +1 -1
  72. package/dist/sdk-repl.d.ts +70 -27
  73. package/dist/sdk-repl.js +2 -2
  74. package/dist/sdk-runtime.d.ts +212 -149
  75. package/dist/sdk-runtime.js +1 -1
  76. package/dist/sdk-sandbox.d.ts +93 -0
  77. package/dist/sdk-sandbox.js +2 -0
  78. package/dist/sdk-session.d.ts +8 -8
  79. package/dist/sdk-session.js +1 -1
  80. package/dist/sdk-skills.d.ts +2 -2
  81. package/dist/sdk-skills.js +1 -1
  82. package/dist/semantic-worker.js +15 -15
  83. package/dist/types-chunks/{base.d-ChvpaKjZ.d.ts → base.d-4e74xDdy.d.ts} +13 -1
  84. package/dist/types-chunks/{bash-prefix-extractor.d-r1beOESM.d.ts → bash-prefix-extractor.d-uAe2Oqda.d.ts} +319 -9
  85. package/dist/types-chunks/{capability-learning.d-DPrYxRjF.d.ts → capability-learning.d-CVsdHw4j.d.ts} +1 -1
  86. package/dist/types-chunks/{capsule.d-zeqV4IQX.d.ts → capsule.d-BlSv9l3V.d.ts} +2 -2
  87. package/dist/types-chunks/{guardrail.d-CWYD1bdL.d.ts → guardrail.d-BRE_ErEj.d.ts} +1 -1
  88. package/dist/types-chunks/{guardrail.d-qjuKJZ31.d.ts → guardrail.d-CXDYRgZ3.d.ts} +201 -35
  89. package/dist/types-chunks/{history-retrieval.d-BKTJIrVd.d.ts → history-retrieval.d-DtCy7x64.d.ts} +2 -2
  90. package/dist/types-chunks/{integration-config.d-ojG4swOP.d.ts → integration-config.d-BNowXE8k.d.ts} +23 -8
  91. package/dist/types-chunks/{public-api.d-CX4B11qY.d.ts → public-api.d-B3AohsxN.d.ts} +37 -8
  92. package/dist/types-chunks/{commands.d-DUxnK2TU.d.ts → repl.d-Ie_ZXb_U.d.ts} +89 -78
  93. package/dist/types-chunks/{side-query.d-DWTMsndP.d.ts → resolver.d-iAQ9ocLB.d.ts} +23 -74
  94. package/dist/types-chunks/{run-manager.d-B9fEIjZk.d.ts → run-manager.d-D1twIhF9.d.ts} +1 -1
  95. package/dist/types-chunks/{sdk-session-B0fhAOPa.d.ts → sdk-session-DB9KksIx.d.ts} +3 -3
  96. package/dist/types-chunks/side-query.d-DTuLPcC5.d.ts +77 -0
  97. package/dist/types-chunks/types-D3g6XUQr.d.ts +662 -0
  98. package/dist/types-chunks/{types.d-sRLugmjy.d.ts → types.d-BA-Jwpfs.d.ts} +506 -11
  99. package/dist/types-chunks/{types.d-DEctY20M.d.ts → types.d-BH0ZkTGf.d.ts} +2 -2
  100. package/dist/types-chunks/{types.d-DCQVBqVn.d.ts → types.d-BbtGlKZu.d.ts} +25 -3
  101. package/dist/types-chunks/{types.d-CSmF0t0n.d.ts → types.d-DIpZJKUl.d.ts} +15 -0
  102. package/dist/types-chunks/{types.d-Bm_y6YuM.d.ts → types.d-DVDTIfB_.d.ts} +4 -4
  103. package/dist/types-chunks/{utils.d-D0wPxz8y.d.ts → utils.d-CVp6bFl9.d.ts} +23 -7
  104. package/docs/SDK_EMBEDDER_GUIDE.md +592 -119
  105. package/package.json +9 -1
  106. package/scripts/kodax-bin.cjs +28 -28
  107. package/scripts/production-env.cjs +25 -25
  108. package/dist/chunks/agent-7X5CFET2.js +0 -2
  109. package/dist/chunks/argument-completer-3NHIKB4N.js +0 -2
  110. package/dist/chunks/chunk-4PWPNCNK.js +0 -158
  111. package/dist/chunks/chunk-7FJNLJLF.js +0 -369
  112. package/dist/chunks/chunk-COQYLD4U.js +0 -5
  113. package/dist/chunks/chunk-D3T24FJW.js +0 -78
  114. package/dist/chunks/chunk-EI4JBQKL.js +0 -46
  115. package/dist/chunks/chunk-HGT6WQ24.js +0 -321
  116. package/dist/chunks/chunk-HS3XHF3R.js +0 -622
  117. package/dist/chunks/chunk-IDCGNQ4H.js +0 -5
  118. package/dist/chunks/chunk-KAY2XLCP.js +0 -74
  119. package/dist/chunks/chunk-OD6LVXU6.js +0 -329
  120. package/dist/chunks/chunk-OSF3H4RR.js +0 -22
  121. package/dist/chunks/chunk-TGMBHGZO.js +0 -427
  122. package/dist/chunks/chunk-VWSLC2WO.js +0 -770
  123. package/dist/chunks/chunk-Y3AMP22L.js +0 -37
  124. package/dist/chunks/compaction-config-7J2XE35D.js +0 -2
  125. package/dist/chunks/dist-2RA7LSH3.js +0 -2
  126. package/dist/chunks/dist-URKXBOC6.js +0 -2
  127. package/dist/chunks/host-RKZ2OGFT.js +0 -2
  128. package/dist/chunks/run-manager-7RM4HEH6.js +0 -2
  129. package/dist/chunks/utils-X3TEH6IO.js +0 -2
  130. package/dist/types-chunks/center-types.d-BBT122uJ.d.ts +0 -91
@@ -1,8 +1,10 @@
1
1
  import { b as McpServersConfig, M as McpConnectMode, a as McpServerConfig, c as McpTransportKind } from './config.d-CJy1WENT.js';
2
- import { K as KodaXBaseProvider } from './base.d-ChvpaKjZ.js';
2
+ import { K as KodaXBaseProvider } from './base.d-4e74xDdy.js';
3
3
  import { a as CostTracker } from './cost-tracker.d-BeaenODW.js';
4
- import { d6 as RunnerToolCall } from './types.d-sRLugmjy.js';
5
- import { d as ToolGuardrail } from './guardrail.d-CWYD1bdL.js';
4
+ import { dT as RunnerToolCall } from './types.d-BA-Jwpfs.js';
5
+ import { d as ToolGuardrail } from './guardrail.d-BRE_ErEj.js';
6
+ import { k as KodaXMessage } from './types.d-DIpZJKUl.js';
7
+ import { S as SideQueryDiagnostics } from './side-query.d-DTuLPcC5.js';
6
8
 
7
9
  /**
8
10
  * FEATURE_200 Phase F (v0.7.45) — MCP domain types extracted from types.ts.
@@ -241,6 +243,157 @@ interface SignalCollector {
241
243
  */
242
244
  declare function collectAllSignals(call: RunnerToolCall, projectRoot: string, collectors: readonly SignalCollector[], executionCwd?: string): readonly ToolCallSignal[];
243
245
 
246
+ interface PermissionIntentEvidence {
247
+ readonly status: 'complete' | 'targeted' | 'missing';
248
+ /** Latest genuine user request, kept separate as the authoritative intent. */
249
+ readonly currentUserContent?: string;
250
+ readonly currentUserContentTruncated?: boolean;
251
+ readonly content: string;
252
+ readonly sourceBytes: number;
253
+ readonly includedBytes: number;
254
+ readonly omittedBytes: number;
255
+ readonly sha256: string;
256
+ }
257
+
258
+ /**
259
+ * Classifier Projection Helpers — FEATURE_092 (v0.7.33)
260
+ *
261
+ * Typed tools implement `toClassifierInput(input): string` to project their
262
+ * input into a compact action the auto-mode classifier evaluates. Runtime
263
+ * registration supplies a fail-closed semantic fallback for legacy JavaScript,
264
+ * extension, and constructed tools that lack a trusted projector.
265
+ *
266
+ * ============== EXAMPLES BY CATEGORY ==============
267
+ *
268
+ * --- FILE OPERATIONS (path + size, never raw contents) ---
269
+ * write.ts: (i) => `Write ${i.path} (${i.content.length} bytes)`
270
+ * edit.ts: (i) => `Edit ${i.path} [${describeEdit(i)}]`
271
+ * multi-edit: (i) => `MultiEdit ${i.path}: ${i.edits.length} edits`
272
+ *
273
+ * --- SHELL / EXEC (command verbatim, ignore noise fields) ---
274
+ * bash.ts: (i) => `Bash: ${i.command}`
275
+ *
276
+ * --- NETWORK (URL is THE risk surface) ---
277
+ * web_fetch: (i) => `WebFetch ${i.url}`
278
+ *
279
+ * --- CHILD AGENT SPAWN (routing + execution controls) ---
280
+ * spawn_agent: objective size + scope/read_only/isolation/provider/model
281
+ *
282
+ * --- MCP CALLS (semantic fields + shape-only unknowns) ---
283
+ * mcp_call: (i) => mcpToClassifierInput(i.server, i.tool, i.input)
284
+ *
285
+ * --- READ-ONLY (Tier 1 — fully skipped) ---
286
+ * read.ts: () => ''
287
+ * grep.ts: () => ''
288
+ * glob.ts: () => ''
289
+ *
290
+ * --- UNKNOWN / CONSTRUCTED (semantic fail-closed fallback) ---
291
+ * extension: (i) => safeFallbackToClassifierInput(name, i)
292
+ *
293
+ * ============== ANTI-PATTERNS ==============
294
+ *
295
+ * ❌ JSON.stringify(input) as default
296
+ * → leaks raw content; hard for LLM to scan
297
+ *
298
+ * ❌ Returning input.description / input.rationale verbatim
299
+ * → these are LLM-emitted, manipulable; classifier should see facts
300
+ *
301
+ * ❌ Including raw file contents in Write/Edit projections
302
+ * → privacy + token cost; use bytes/line count as proxy
303
+ *
304
+ * ❌ Returning '' for a high-risk tool to "skip the classifier"
305
+ * → defeats Tier 1's "safe-only" semantics
306
+ *
307
+ * ❌ Truncating without indicating it ('foo' instead of 'foo…')
308
+ * → classifier may make decisions on false-complete information
309
+ */
310
+ type ClassifierToolProjectionResolver = (toolName: string) => ((input: unknown) => string) | undefined;
311
+
312
+ /**
313
+ * Auto-Mode Classifier Orchestrator — FEATURE_092 Phase 2b.3 (v0.7.33).
314
+ *
315
+ * Wires the classifier prompt + sideQuery + output parser into a single
316
+ * `classify(...)` call. Caller supplies the rules, transcript, and the
317
+ * tool-call action being classified; gets back a `ClassifyDecision`.
318
+ *
319
+ * Failure → decision mapping:
320
+ *
321
+ * sideQuery.stopReason parsedOutput → ClassifyDecision
322
+ * ───────────────────────────────────────────────────────
323
+ * end_turn / max_tokens block → confirm (with reason)
324
+ * end_turn / max_tokens allow → allow
325
+ * end_turn / max_tokens unparseable → retry, then failure
326
+ * end_turn / max_tokens + tool_use → retry, then failure
327
+ * (sideQuery returns stopReason='error' here)
328
+ * timeout — → retry, then failure
329
+ * aborted — → throw AbortError to caller
330
+ * error — → retry, then failure
331
+ *
332
+ * Every non-abort failure receives one immediate retry. The caller applies
333
+ * its configured safety fallback after the second failure; a valid model
334
+ * concern always means "ask the user", never a direct hard block.
335
+ */
336
+
337
+ interface ClassifyOptions {
338
+ readonly provider: KodaXBaseProvider;
339
+ readonly model: string;
340
+ readonly rules: AutoRules;
341
+ readonly claudeMd?: string;
342
+ readonly transcript: readonly KodaXMessage[];
343
+ readonly action: string;
344
+ readonly intentEvidence?: PermissionIntentEvidence;
345
+ /** Resolve canonical per-tool projections for safe historical context. */
346
+ readonly getToolProjection?: ClassifierToolProjectionResolver;
347
+ /**
348
+ * FEATURE_158 (v0.7.39): static-analysis signals forwarded to the
349
+ * classifier prompt. Empty / undefined preserves the FEATURE_092 prompt
350
+ * shape (no `<signals>` block emitted). When supplied, the classifier
351
+ * sees signals between `<transcript>` and `<action>` as informational
352
+ * input — not verdicts.
353
+ */
354
+ readonly signals?: readonly ToolCallSignal[];
355
+ readonly timeoutMs?: number;
356
+ readonly abortSignal?: AbortSignal;
357
+ readonly costTracker?: CostTracker;
358
+ /**
359
+ * Optional setter — invoked once after `sideQuery` returns when the
360
+ * classifier successfully recorded its token usage. The CostTracker is
361
+ * immutable, so `sideQuery` produces a fresh tracker copy with the new
362
+ * record; without this setter the recorded call is silently dropped.
363
+ * Wired by the AutoModeToolGuardrail so the agent's tracker accumulates
364
+ * classifier calls under role='auto_mode'.
365
+ */
366
+ readonly setCostTracker?: (next: CostTracker) => void;
367
+ }
368
+ type ClassifierFailureKind = 'timeout' | 'provider_error' | 'contract_error' | 'input_budget';
369
+ type ClassifierAttemptOutcome = 'allow' | 'confirm' | ClassifierFailureKind;
370
+ interface ClassifierAttemptDiagnostics {
371
+ readonly attempt: number;
372
+ readonly outcome: ClassifierAttemptOutcome;
373
+ readonly diagnostics?: SideQueryDiagnostics;
374
+ }
375
+ interface ClassifyDecisionDetails {
376
+ readonly reason: string;
377
+ /** Structured request metadata only; never includes prompt or response text. */
378
+ readonly diagnostics?: SideQueryDiagnostics;
379
+ readonly attempts: readonly ClassifierAttemptDiagnostics[];
380
+ }
381
+ type ClassifyDecision = ({
382
+ readonly kind: 'allow';
383
+ } & ClassifyDecisionDetails) | ({
384
+ readonly kind: 'confirm';
385
+ } & ClassifyDecisionDetails) | ({
386
+ readonly kind: 'failure';
387
+ readonly failureKind: ClassifierFailureKind;
388
+ } & ClassifyDecisionDetails);
389
+ /**
390
+ * The deadline includes connection setup, provider-side queueing, inference,
391
+ * and any Retry-After/backoff handled by the provider adapter. Keep it bounded
392
+ * so infrastructure failure degrades to an explicit user decision.
393
+ */
394
+ declare const DEFAULT_CLASSIFIER_TIMEOUT_MS = 20000;
395
+ declare function classify(opts: ClassifyOptions): Promise<ClassifyDecision>;
396
+
244
397
  /**
245
398
  * Denial Tracker — FEATURE_092 Phase 2b.4 (v0.7.33).
246
399
  *
@@ -365,18 +518,19 @@ declare function checkAbsoluteDeny(call: RunnerToolCall, projectRoot: string, ex
365
518
  *
366
519
  * Decision flow (per design doc "三层权限金字塔"):
367
520
  *
368
- * 1. Tier-0 deterministic deny block
369
- * 2. Tool projection is '' (Tier 1) → allow (zero token cost)
370
- * 3. Engine is rules → deterministic Tier 2, otherwise user confirms
371
- * 4. denial/circuit threshold engine downgrade, then escalate
372
- * 5. classify(...) sideQuery
373
- * allow → allow (record allow → reset consecutive)
374
- * block block + reason (record block)
375
- * escalate escalate + reason (record error)
376
- * AbortError thrown re-throw (propagate user cancel)
521
+ * 1. Tier-0 deterministic critical match user confirmation
522
+ * 2. exact safe read/workspace-temp effect → allow (zero token cost)
523
+ * 3. Tool projection is '' (Tier 1) → allow
524
+ * 4. Engine is rules deterministic Tier 2, otherwise user confirms
525
+ * 5. degraded classifier infrastructure → Accept-edits fallback
526
+ * 6. classify(...) sideQuery
527
+ * allow allow (record allow → reset consecutive)
528
+ * confirm user confirmation (record concern)
529
+ * failure Accept-edits fallback (record error)
530
+ * AbortError thrown → re-throw (propagate user cancel)
377
531
  *
378
532
  * State (mutable, session-scoped):
379
- * - engine: 'llm' | 'rules' (starts at 'llm', downgrades on threshold)
533
+ * - engine: 'llm' | 'rules' (user-selected; classifier health never changes it)
380
534
  * - denialTracker (immutable type, swapped on each event)
381
535
  * - circuitBreaker (immutable type, swapped on each event)
382
536
  *
@@ -402,15 +556,20 @@ interface AutoModeSharedState {
402
556
  * User answer for an escalated tool-call. The guardrail translates this into
403
557
  * the actual `GuardrailVerdict` returned to the Runner. `'block'` preserves
404
558
  * the original escalation reason as the verdict reason so downstream consumers
405
- * see why the tool was blocked.
559
+ * see why the tool was blocked. `'timeout'` reports that the action was not
560
+ * executed and gives the main model a bounded recovery instruction.
406
561
  */
407
- type AutoModeAskUserVerdict = 'allow' | 'block';
562
+ type AutoModeAskUserVerdict = 'allow' | 'block' | 'timeout';
563
+ interface AutoModeDecisionDiagnostics {
564
+ readonly source: 'classifier_confirm' | 'classifier_failure' | 'classifier_circuit_breaker' | 'configuration';
565
+ readonly classifierFailureKind?: ClassifierFailureKind;
566
+ readonly classifierAttempts?: readonly ClassifierAttemptDiagnostics[];
567
+ }
408
568
  /**
409
- * Optional REPL-supplied prompt callback for the 6 escalate paths in
410
- * `beforeTool` (engine-downgraded, denial-threshold-just-crossed,
411
- * breaker-just-tripped, classifier-error, classifier-decision-escalate,
412
- * provider-not-configured). When supplied, the guardrail calls this and
413
- * translates the user's answer into `'allow'` or `'block'`. When NOT
569
+ * Optional REPL-supplied prompt callback for calls that require a human
570
+ * decision (rules escalation, classifier concern/failure, or configuration
571
+ * failure). When supplied, the guardrail calls this and
572
+ * translates the user's answer into allow/block/timeout semantics. When NOT
414
573
  * supplied, the guardrail returns `'escalate'` as before — the Runner will
415
574
  * then throw `GuardrailEscalateError` (preserves backward compat with
416
575
  * SDK-side guardrail consumers that have no askUser surface).
@@ -425,7 +584,7 @@ type AutoModeAskUser = (call: RunnerToolCall, reason: string,
425
584
  * keep working. REPL uses these to render Scope/Risk labels on the
426
585
  * confirm dialog (replacing the input-marker path from FEATURE_066).
427
586
  */
428
- signals?: readonly ToolCallSignal[]) => Promise<AutoModeAskUserVerdict>;
587
+ signals?: readonly ToolCallSignal[], diagnostics?: AutoModeDecisionDiagnostics) => Promise<AutoModeAskUserVerdict>;
429
588
  interface AutoModeRulesContext {
430
589
  readonly projectRoot: string;
431
590
  readonly executionCwd: string;
@@ -498,6 +657,15 @@ interface AutoModeGuardrailConfig {
498
657
  * paths. See `AutoModeAskUser` for semantics.
499
658
  */
500
659
  readonly askUser?: AutoModeAskUser;
660
+ /**
661
+ * Runtime-owned Accept-edits fallback used only when classifier
662
+ * infrastructure or its response contract fails.
663
+ */
664
+ readonly allowOnClassifierFailure?: (call: RunnerToolCall) => boolean | Promise<boolean>;
665
+ /** Whether ordinary bash calls can be enforced by an OS workspace sandbox. */
666
+ readonly workspaceShellSandboxAvailable?: boolean;
667
+ /** Mint one exact bash call for workspace-sandboxed execution. */
668
+ readonly admitWorkspaceSandboxCall?: (call: RunnerToolCall, review: AutoModePermissionReview) => void;
501
669
  /**
502
670
  * Runtime-owned deterministic Tier-2 evaluator. It is injected rather than
503
671
  * implemented in @kodax/coding because canonical path and shell-AST helpers
@@ -544,12 +712,11 @@ interface AutoModeGuardrailConfig {
544
712
  */
545
713
  readonly getCostTracker?: () => CostTracker | undefined;
546
714
  readonly setCostTracker?: (t: CostTracker) => void;
547
- /** Optional logger for engine-downgrade and config warnings. */
715
+ /** Optional logger for classifier-health and configuration warnings. */
548
716
  readonly log?: (level: 'info' | 'warn', msg: string) => void;
549
717
  /**
550
- * Fired whenever the active engine changes both on automatic downgrades
551
- * (denial threshold / circuit breaker) AND on manual `setEngine(...)`
552
- * calls. UI surfaces (status bar engine indicator, slash-command
718
+ * Fired whenever the active engine changes through `setEngine(...)`.
719
+ * UI surfaces (status bar engine indicator, slash-command
553
720
  * confirmations) subscribe here so the displayed engine stays in sync
554
721
  * with the guardrail's internal state without the user having to trigger
555
722
  * another mode toggle just to refresh the bar.
@@ -558,8 +725,8 @@ interface AutoModeGuardrailConfig {
558
725
  /**
559
726
  * Optional shared state for subagent threshold-bypass defense
560
727
  * (design doc "防绕阈值"). When supplied, the parent and child
561
- * guardrails reference the SAME object — engine downgrades and
562
- * tracker advances are visible across the session boundary.
728
+ * guardrails reference the SAME object — engine changes and tracker
729
+ * advances are visible across the session boundary.
563
730
  */
564
731
  readonly sharedState?: AutoModeSharedState;
565
732
  /**
@@ -625,8 +792,8 @@ interface AutoModeGuardrailConfig {
625
792
  * (late-verdict adoption). The window therefore only controls "fast path
626
793
  * vs wait", never "dialog vs no dialog": an `allow` never surfaces a
627
794
  * confirm dialog regardless of how long the classifier takes, and only an
628
- * `escalate` verdict (explicit LLM escalation, classifier timeout, or infra
629
- * error — all mapped to `escalate` by classify()) reaches the user.
795
+ * confirmation/failure verdict reaches the configured user or Accept-edits
796
+ * fallback path.
630
797
  * The background classifier's cost is settled exactly once inside
631
798
  * classify(), so awaiting it after window expiry does not double-count.
632
799
  *
@@ -645,6 +812,7 @@ interface AutoModeGuardrailConfig {
645
812
  */
646
813
  interface AutoModeStats {
647
814
  readonly engine: AutoModeEngine;
815
+ readonly classifierHealth: 'healthy' | 'degraded';
648
816
  readonly classifierModel?: string;
649
817
  readonly denials: DenialTracker;
650
818
  readonly breaker: CircuitBreaker;
@@ -656,19 +824,17 @@ interface AutoModeToolGuardrail extends ToolGuardrail {
656
824
  getStats(): AutoModeStats;
657
825
  /**
658
826
  * Manually set the engine. Used by `/auto-engine` slash command to flip
659
- * back to 'llm' after an automatic downgrade or to flip to 'rules' for
660
- * manual testing. The downgrade thresholds still operate normally — a
661
- * subsequent threshold cross will downgrade again.
827
+ * between 'llm' and 'rules' after an explicit user or host choice.
662
828
  */
663
829
  setEngine(engine: AutoModeEngine): void;
664
830
  /** Test-only alias for getEngine(). Backward-compat for test files. */
665
831
  getEngineForTest(): AutoModeEngine;
666
832
  /** Test-only alias for getStats(). Backward-compat for test files. */
667
833
  getStatsForTest(): AutoModeStats;
668
- /** Test-only override: swap the provider mid-test (for downgrade scenarios). */
834
+ /** Test-only override: swap the provider mid-test. */
669
835
  setProviderForTest(provider: KodaXBaseProvider): void;
670
836
  }
671
837
  declare function createAutoModeToolGuardrail(config: AutoModeGuardrailConfig): AutoModeToolGuardrail;
672
838
 
673
- export { recordBlock as $, CONSECUTIVE_THRESHOLD as C, ERROR_THRESHOLD as E, checkAbsoluteDeny as I, collectAllSignals as J, computeRulesFingerprint as M, createAutoModeToolGuardrail as N, createCircuitBreaker as O, createDenialTracker as P, formatAgentsForPrompt as Q, getKodaxGlobalDir as U, loadAgentsFiles as V, WINDOW_MS as W, loadAutoRules as X, parseAutoRules as Y, readTrustState as Z, recordAllow as _, recordError as a0, shouldFallback$1 as a1, shouldFallback as a2, trustProjectRules as a3, CUMULATIVE_THRESHOLD as u };
674
- export type { AbsoluteDenyCheck as A, RulesLoadResult as B, DenialTracker as D, SkippedRulesSource as F, ToolCallSignal as G, TrustState as H, KodaXMcpConnectMode as K, LoadAgentsOptions as L, RulesLoadError as R, SignalCollector as S, TierZeroPatternId as T, AbsoluteDenyMatch as a, AbsoluteDenyMiss as b, AbsoluteDenyResult as c, AgentsFile as d, AutoModeAskUser as e, AutoModeAskUserVerdict as f, AutoModeCallAnalyzer as g, AutoModeEngine as h, AutoModeGuardrailConfig as i, AutoModePermissionBoundary as j, AutoModePermissionOperation as k, AutoModePermissionReview as l, AutoModePermissionTarget as m, AutoModeRulesContext as n, AutoModeRulesDecision as o, AutoModeRulesEvaluator as p, AutoModeSharedState as q, AutoModeStats as r, AutoModeToolGuardrail as s, AutoRules as t, CircuitBreaker as v, KodaXMcpServerConfig as w, KodaXMcpServersConfig as x, KodaXMcpTransport as y, LoadedRulesSource as z };
839
+ export { createAutoModeToolGuardrail as $, CONSECUTIVE_THRESHOLD as C, DEFAULT_CLASSIFIER_TIMEOUT_MS as F, ERROR_THRESHOLD as H, WINDOW_MS as W, checkAbsoluteDeny as X, classify as Y, collectAllSignals as Z, computeRulesFingerprint as _, createCircuitBreaker as a0, createDenialTracker as a1, formatAgentsForPrompt as a2, getKodaxGlobalDir as a3, loadAgentsFiles as a4, loadAutoRules as a5, parseAutoRules as a6, readTrustState as a7, recordAllow as a8, recordBlock as a9, recordError as aa, shouldFallback$1 as ab, shouldFallback as ac, trustProjectRules as ad, CUMULATIVE_THRESHOLD as v };
840
+ export type { AbsoluteDenyCheck as A, ClassifierToolProjectionResolver as B, ClassifyDecision as D, ClassifyOptions as E, DenialTracker as G, KodaXMcpServerConfig as I, KodaXMcpServersConfig as J, KodaXMcpConnectMode as K, KodaXMcpTransport as L, LoadAgentsOptions as M, LoadedRulesSource as N, RulesLoadResult as O, PermissionIntentEvidence as P, SkippedRulesSource as Q, RulesLoadError as R, SignalCollector as S, TierZeroPatternId as T, ToolCallSignal as U, TrustState as V, AbsoluteDenyMatch as a, AbsoluteDenyMiss as b, AbsoluteDenyResult as c, AgentsFile as d, AutoModeAskUser as e, AutoModeAskUserVerdict as f, AutoModeCallAnalyzer as g, AutoModeDecisionDiagnostics as h, AutoModeEngine as i, AutoModeGuardrailConfig as j, AutoModePermissionBoundary as k, AutoModePermissionOperation as l, AutoModePermissionReview as m, AutoModePermissionTarget as n, AutoModeRulesContext as o, AutoModeRulesDecision as p, AutoModeRulesEvaluator as q, AutoModeSharedState as r, AutoModeStats as s, AutoModeToolGuardrail as t, AutoRules as u, CircuitBreaker as w, ClassifierAttemptDiagnostics as x, ClassifierAttemptOutcome as y, ClassifierFailureKind as z };
@@ -1,5 +1,5 @@
1
- import { k as KodaXMessage } from './types.d-CSmF0t0n.js';
2
- import { bM as KodaXSessionLineage } from './types.d-sRLugmjy.js';
1
+ import { k as KodaXMessage } from './types.d-DIpZJKUl.js';
2
+ import { bU as KodaXSessionLineage } from './types.d-BA-Jwpfs.js';
3
3
 
4
4
  type KodaXSessionHistoryScope = 'compacted' | 'all';
5
5
  type KodaXSessionHistorySource = 'user' | 'assistant' | 'system' | 'tool' | 'child_task';
@@ -1,7 +1,7 @@
1
1
  import { b as McpServersConfig } from './config.d-CJy1WENT.js';
2
2
 
3
- type IntegrationDomain = 'mcp' | 'a2a' | 'extensions';
4
- type IntegrationConfigSource = 'user' | 'legacy-user' | 'default';
3
+ type IntegrationDomain = "mcp" | "a2a" | "extensions";
4
+ type IntegrationConfigSource = "user" | "legacy-user" | "default";
5
5
  interface McpIntegrationDocument {
6
6
  readonly version: 1;
7
7
  readonly servers: McpServersConfig;
@@ -19,7 +19,7 @@ interface IntegrationConfigSnapshot<T extends object> {
19
19
  readonly loadedAt: string;
20
20
  }
21
21
  interface IntegrationConfigDiagnostic {
22
- readonly code: 'invalid-config' | 'activation-failed' | 'watcher-degraded';
22
+ readonly code: "invalid-config" | "activation-failed" | "watcher-degraded";
23
23
  readonly message: string;
24
24
  readonly time: string;
25
25
  }
@@ -33,7 +33,7 @@ interface IntegrationConfigStatus {
33
33
  readonly watching: boolean;
34
34
  }
35
35
  interface LegacyIntegrationMigrationDomainPlan {
36
- readonly action: 'create' | 'none';
36
+ readonly action: "create" | "none";
37
37
  readonly entries: number;
38
38
  readonly destination: string;
39
39
  readonly reason?: string;
@@ -44,9 +44,12 @@ interface LegacyIntegrationMigrationPlan {
44
44
  readonly warnings: readonly string[];
45
45
  }
46
46
  interface LegacyIntegrationMigrationResult extends LegacyIntegrationMigrationPlan {
47
- readonly applied: readonly ('mcp' | 'extensions')[];
47
+ readonly applied: readonly ("mcp" | "extensions")[];
48
48
  readonly cleanedLegacy: boolean;
49
49
  }
50
+ declare class IntegrationConfigConflictError extends Error {
51
+ constructor(file: string, expected: string | undefined, actual: string | undefined);
52
+ }
50
53
  type IntegrationDocumentValidator<T extends object> = (value: unknown) => T;
51
54
  type IntegrationConfigListener<T extends object> = (snapshot: IntegrationConfigSnapshot<T>, previous: IntegrationConfigSnapshot<T> | undefined) => Promise<void> | void;
52
55
  type IntegrationReloadResult<T extends object> = {
@@ -71,7 +74,8 @@ declare function writeIntegrationDocument<T extends object>(input: {
71
74
  readonly configHome: string;
72
75
  readonly document: T;
73
76
  readonly validate: IntegrationDocumentValidator<T>;
74
- readonly expectedRevision?: string;
77
+ /** `null` means the destination must still be absent when committed. */
78
+ readonly expectedRevision?: string | null;
75
79
  }): IntegrationConfigSnapshot<T>;
76
80
  declare class IntegrationConfigController<T extends object> {
77
81
  #private;
@@ -80,6 +84,17 @@ declare class IntegrationConfigController<T extends object> {
80
84
  readonly configHome: string;
81
85
  readonly validate: IntegrationDocumentValidator<T>;
82
86
  readonly read: () => IntegrationConfigSnapshot<T>;
87
+ /**
88
+ * Optional legacy source consulted only while the split domain file is
89
+ * absent. It participates in both filesystem watching and polling.
90
+ */
91
+ readonly fallbackPath?: string;
92
+ /**
93
+ * Explicit fail-closed document used only when the first disk read is
94
+ * invalid. The diagnostic remains visible and a later valid file replaces
95
+ * this snapshot through the normal reload path.
96
+ */
97
+ readonly coldStartDefault?: T;
83
98
  });
84
99
  initialize(): Promise<IntegrationConfigSnapshot<T>>;
85
100
  snapshot(): IntegrationConfigSnapshot<T> | undefined;
@@ -91,5 +106,5 @@ declare class IntegrationConfigController<T extends object> {
91
106
  close(): void;
92
107
  }
93
108
 
94
- export { IntegrationConfigController as I, parseMcpIntegrationDocument as j, planLegacyIntegrationMigration as k, readMcpIntegration as l, migrateLegacyIntegrationConfig as m, resolveIntegrationConfigPath as n, parseExtensionsIntegrationDocument as p, readExtensionsIntegration as r, writeIntegrationDocument as w };
95
- export type { ExtensionsIntegrationDocument as E, LegacyIntegrationMigrationDomainPlan as L, McpIntegrationDocument as M, IntegrationConfigDiagnostic as a, IntegrationConfigListener as b, IntegrationConfigSnapshot as c, IntegrationConfigSource as d, IntegrationConfigStatus as e, IntegrationDocumentValidator as f, IntegrationDomain as g, LegacyIntegrationMigrationPlan as h, LegacyIntegrationMigrationResult as i };
109
+ export { IntegrationConfigConflictError as I, IntegrationConfigController as a, parseMcpIntegrationDocument as k, planLegacyIntegrationMigration as l, migrateLegacyIntegrationConfig as m, readMcpIntegration as n, resolveIntegrationConfigPath as o, parseExtensionsIntegrationDocument as p, readExtensionsIntegration as r, writeIntegrationDocument as w };
110
+ export type { ExtensionsIntegrationDocument as E, LegacyIntegrationMigrationDomainPlan as L, McpIntegrationDocument as M, IntegrationConfigDiagnostic as b, IntegrationConfigListener as c, IntegrationConfigSnapshot as d, IntegrationConfigSource as e, IntegrationConfigStatus as f, IntegrationDocumentValidator as g, IntegrationDomain as h, LegacyIntegrationMigrationPlan as i, LegacyIntegrationMigrationResult as j };
@@ -1,7 +1,6 @@
1
- import { a as BashPrefixExtractor, t as KodaXAgentMode } from './bash-prefix-extractor.d-r1beOESM.js';
2
- import { F as KodaXReasoningMode, k as KodaXMessage, S as KodaXTaskResultMetadata } from './types.d-CSmF0t0n.js';
3
- import { p as LearningSurfaceSnapshot$1, n as LearningQuery, m as LearningPage, b as LearnedCapabilityRecord, j as LearningEvent, o as LearningSubscribeOptions } from './center-types.d-BBT122uJ.js';
4
- import { bH as KodaXSessionData, bM as KodaXSessionLineage, bR as KodaXSessionNavigationOptions, bT as KodaXSessionRuntimeInfo, bV as KodaXSessionStorage, i as AgentActorSnapshot, aQ as CompactionReport, by as KodaXJsonValue } from './types.d-sRLugmjy.js';
1
+ import { a as BashPrefixExtractor, t as KodaXAgentMode } from './bash-prefix-extractor.d-uAe2Oqda.js';
2
+ import { F as KodaXReasoningMode, k as KodaXMessage, S as KodaXTaskResultMetadata } from './types.d-DIpZJKUl.js';
3
+ import { cP as LearningSurfaceSnapshot$1, cK as LearningQuery, cJ as LearningPage, cm as LearnedCapabilityRecord, cF as LearningEvent, cO as LearningSubscribeOptions, bP as KodaXSessionData, bU as KodaXSessionLineage, bZ as KodaXSessionNavigationOptions, b$ as KodaXSessionRuntimeInfo, c1 as KodaXSessionStorage, j as AgentActorSnapshot, aU as CompactionReport, bF as KodaXJsonValue } from './types.d-BA-Jwpfs.js';
5
4
 
6
5
  /**
7
6
  * TextBuffer - Text buffer management class - 文本缓冲区管理类
@@ -904,6 +903,7 @@ declare function createMemorySessionStorage(): SessionStorage;
904
903
 
905
904
  declare class FileSessionStorage implements KodaXSessionStorage {
906
905
  private readonly sessionsDir;
906
+ private readonly configHome;
907
907
  /**
908
908
  * v0.7.46 — optional explicit project cwd for in-process embedders
909
909
  * (KodaX Space) serving multiple projects from a single runtime.
@@ -927,6 +927,7 @@ declare class FileSessionStorage implements KodaXSessionStorage {
927
927
  private readonly emitMismatchWarnings;
928
928
  constructor(opts?: {
929
929
  sessionsDir?: string;
930
+ configHome?: string;
930
931
  cwd?: string;
931
932
  emitMismatchWarnings?: boolean;
932
933
  });
@@ -934,6 +935,7 @@ declare class FileSessionStorage implements KodaXSessionStorage {
934
935
  getSessionsDir(): string;
935
936
  private writeQueues;
936
937
  private serializedWrite;
938
+ private sessionWriteLockPath;
937
939
  private appendState;
938
940
  private sessionDirCache;
939
941
  private projectJsonWritten;
@@ -969,9 +971,13 @@ declare class FileSessionStorage implements KodaXSessionStorage {
969
971
  private shouldRunMaintenance;
970
972
  private runMaintenance;
971
973
  save(id: string, data: SessionData): Promise<void>;
974
+ mutateLineage(id: string, mutation: (lineage: KodaXSessionLineage) => KodaXSessionLineage): Promise<boolean>;
972
975
  /** F270/F269 owner mutation: CAS-update only the Actor section of a session snapshot. */
973
976
  saveActorSnapshot(id: string, snapshot: AgentActorSnapshot, expectedRevision: number): Promise<void>;
977
+ /** Read Session data without recovery writes or append-watermark mutation. */
978
+ peek(id: string): Promise<SessionData | null>;
974
979
  load(id: string): Promise<SessionData | null>;
980
+ isArchived(id: string): Promise<boolean>;
975
981
  getLineage(id: string): Promise<KodaXSessionLineage | null>;
976
982
  loadFullLineage(id: string): Promise<KodaXSessionLineage | null>;
977
983
  setActiveEntry(id: string, selector: string, options?: {
@@ -1016,26 +1022,43 @@ declare class FileSessionStorage implements KodaXSessionStorage {
1016
1022
  * (never orphans the sidecar). No-op + returns false for a missing session.
1017
1023
  */
1018
1024
  archive(id: string): Promise<boolean>;
1025
+ archiveOwned(id: string, ownerId: string): Promise<boolean>;
1026
+ private archiveWithActorOwner;
1019
1027
  /** Restore an archived session back into its project directory. */
1020
1028
  unarchive(id: string): Promise<boolean>;
1029
+ unarchiveOwned(id: string, ownerId: string): Promise<boolean>;
1030
+ private unarchiveWithActorOwner;
1021
1031
  /**
1022
1032
  * Move a session + its island sidecar between two directories. Propagates a
1023
1033
  * non-ENOENT rename error (e.g. Windows file-in-use) so a partial move is
1024
1034
  * surfaced as a failure instead of silently splitting main + sidecar.
1025
1035
  */
1026
1036
  private movePair;
1037
+ /**
1038
+ * Remove a complete Session file set without exposing a partial failure.
1039
+ * Every canonical path is first renamed to an ignored tombstone. A staging
1040
+ * failure rolls all prior renames back; only after the full set is hidden do
1041
+ * we unlink tombstones. A locked tombstone is recoverable and no longer
1042
+ * represents a live Session, so cleanup failure is diagnostic rather than a
1043
+ * failed logical deletion.
1044
+ */
1045
+ private removeFileSetAtomically;
1046
+ private assertActorFileOwner;
1027
1047
  delete(id: string): Promise<void>;
1048
+ /** Strict deletion path for the Runtime that already owns the Actor tree. */
1049
+ deleteOwned(id: string, ownerId: string): Promise<void>;
1050
+ private deleteWithActorOwner;
1028
1051
  deleteAll(gitRoot?: string): Promise<void>;
1029
1052
  /**
1030
- * Auto-retention: delete session files (`.jsonl` + `.archive.jsonl`) whose
1053
+ * Auto-retention: delete a complete Session file set when its main file
1031
1054
  * mtime is older than `retentionDays`. Modeled on claudecode's
1032
1055
  * `cleanup.ts` (`unlinkIfOld`). Bounds the sessions directory so it never
1033
1056
  * accumulates unboundedly — which is what keeps `list()`'s head-read pass
1034
1057
  * fast (its cost scales with file COUNT, not size). A non-positive /
1035
1058
  * non-finite `retentionDays` disables cleanup (no-op). Best-effort: per-file
1036
- * errors are swallowed so a single locked/racing file never aborts the
1037
- * sweep. Returns the number of files removed. mtime-based, so the session
1038
- * currently being written/resumed (fresh mtime) is never eligible.
1059
+ * errors are isolated so a single locked/racing file never aborts the
1060
+ * sweep. Durable Actor owners and non-terminal turns are never eligible.
1061
+ * Returns the number of files removed.
1039
1062
  */
1040
1063
  cleanupOldSessions(retentionDays: number): Promise<number>;
1041
1064
  }
@@ -1308,6 +1331,10 @@ type DeleteSessionResult = {
1308
1331
  startedAt: number;
1309
1332
  };
1310
1333
  };
1334
+ } | {
1335
+ error: {
1336
+ code: 'delete_failed';
1337
+ };
1311
1338
  };
1312
1339
  /**
1313
1340
  * Delete a session by ID.
@@ -1347,9 +1374,11 @@ declare function watchSessions(cb: WatchSessionsCallback): {
1347
1374
  * that directory instead of the module-load-frozen `KODAX_SESSIONS_DIR`.
1348
1375
  * `listRunningSessions` still consults the agent-config-home instances
1349
1376
  * directory (sibling-process awareness is not scoped per sessions dir).
1377
+ * `configHome` binds rewind/setActive review fencing to the same Runtime owner.
1350
1378
  */
1351
1379
  declare function createSessionManager(opts?: {
1352
1380
  sessionsDir?: string;
1381
+ configHome?: string;
1353
1382
  }): SessionManager;
1354
1383
 
1355
1384
  export { KeypressHandlerPriority as B, DEFAULT_UI_STATE as D, FILE_MODIFICATION_TOOLS as F, MemorySessionStorage as M, PERMISSION_MODES as P, StreamingState as a0, TOOL_STATUS_ICONS as a2, TextBuffer as a3, ToolCallStatus as a9, appendClientNotice as ag, archiveSession as ah, compactSession as ai, computeConfirmTools as aj, createMemorySessionStorage as ak, createSessionManager as al, deleteSession as am, forkSession as an, isPermissionMode as ao, listRunningSessions as ap, listSessions as aq, loadFullTranscript as ar, loadSession as as, normalizePermissionMode as at, permissionModeDisplayName as au, rewindSession as av, setActiveEntry as aw, unarchiveSession as ax, watchSessions as ay, FileSessionStorage as j };