@wrongstack/core 0.291.0 → 0.291.2

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 (52) hide show
  1. package/dist/boot.d.ts.map +1 -1
  2. package/dist/chronicle/index.js +20 -1
  3. package/dist/chronicle/index.js.map +2 -2
  4. package/dist/chronicle/tool-adapter.d.ts.map +1 -1
  5. package/dist/coordination/director.d.ts +18 -0
  6. package/dist/coordination/director.d.ts.map +1 -1
  7. package/dist/coordination/fleet-spawn.d.ts.map +1 -1
  8. package/dist/coordination/index.js +37 -15
  9. package/dist/coordination/index.js.map +2 -2
  10. package/dist/core/agent-response.d.ts.map +1 -1
  11. package/dist/defaults/index.js +660 -391
  12. package/dist/defaults/index.js.map +4 -4
  13. package/dist/execution/index.js +61 -12
  14. package/dist/execution/index.js.map +3 -3
  15. package/dist/execution/tool-executor.d.ts.map +1 -1
  16. package/dist/hq/index.js +17 -0
  17. package/dist/hq/index.js.map +2 -2
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1304 -882
  21. package/dist/index.js.map +4 -4
  22. package/dist/infrastructure/index.js +15 -10
  23. package/dist/infrastructure/index.js.map +2 -2
  24. package/dist/kernel/events/tool-events.d.ts +24 -0
  25. package/dist/kernel/events/tool-events.d.ts.map +1 -1
  26. package/dist/plugins/auto-review-plugin.d.ts +10 -0
  27. package/dist/plugins/auto-review-plugin.d.ts.map +1 -1
  28. package/dist/security/index.js +148 -0
  29. package/dist/security/index.js.map +3 -3
  30. package/dist/security/permission-policy.d.ts +8 -1
  31. package/dist/security/permission-policy.d.ts.map +1 -1
  32. package/dist/storage/config-loader.d.ts +8 -0
  33. package/dist/storage/config-loader.d.ts.map +1 -1
  34. package/dist/storage/index.js +457 -379
  35. package/dist/storage/index.js.map +4 -4
  36. package/dist/storage/provider-config-watcher.d.ts +6 -0
  37. package/dist/storage/provider-config-watcher.d.ts.map +1 -1
  38. package/dist/types/permission.d.ts +38 -0
  39. package/dist/types/permission.d.ts.map +1 -1
  40. package/dist/utils/config-backup.d.ts +20 -0
  41. package/dist/utils/config-backup.d.ts.map +1 -0
  42. package/dist/utils/index.d.ts +2 -1
  43. package/dist/utils/index.d.ts.map +1 -1
  44. package/dist/utils/index.js +172 -106
  45. package/dist/utils/index.js.map +4 -4
  46. package/dist/utils/message-invariants.d.ts +12 -9
  47. package/dist/utils/message-invariants.d.ts.map +1 -1
  48. package/dist/utils/term.d.ts +6 -0
  49. package/dist/utils/term.d.ts.map +1 -1
  50. package/dist/utils/wstack-paths.d.ts +10 -0
  51. package/dist/utils/wstack-paths.d.ts.map +1 -1
  52. package/package.json +2 -2
@@ -8,6 +8,12 @@ import type { SecretVault } from '../types/secret-vault.js';
8
8
  */
9
9
  export interface ProviderConfigSnapshot {
10
10
  providers: Record<string, ProviderConfig>;
11
+ /** True when the config file actually had a `providers` key. The watcher
12
+ * callback uses this to avoid clearing in-memory providers during hot-reload
13
+ * when the profile config file simply doesn't define any — without this
14
+ * guard, reading a profile config that has no `providers` key would set
15
+ * `appConfig.providers = {}` and wipe all configured providers. */
16
+ snapshotHasProviders: boolean;
11
17
  apiKey?: string;
12
18
  baseUrl?: string;
13
19
  /** Display language (Config.uiLocale), surfaced so a cross-process change
@@ -1 +1 @@
1
- {"version":3,"file":"provider-config-watcher.d.ts","sourceRoot":"","sources":["../../src/storage/provider-config-watcher.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;0EACsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;yEACqE;IACrE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yBAAyB,CAAC,EAAE,OAAO,wCAAwC,EAAE,iBAAiB,EAAE,CAAC;CAClG;AAED,MAAM,WAAW,0BAA0B;IACzC,mDAAmD;IACnD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC3B,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAgD7C;AAmBD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,EACpD,IAAI,GAAE,0BAA+B,GACpC;IAAE,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAgEvB"}
1
+ {"version":3,"file":"provider-config-watcher.d.ts","sourceRoot":"","sources":["../../src/storage/provider-config-watcher.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C;;;;wEAIoE;IACpE,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;0EACsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;yEACqE;IACrE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yBAAyB,CAAC,EAAE,OAAO,wCAAwC,EAAE,iBAAiB,EAAE,CAAC;CAClG;AAED,MAAM,WAAW,0BAA0B;IACzC,mDAAmD;IACnD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC3B,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAiD7C;AAmBD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,EACpD,IAAI,GAAE,0BAA+B,GACpC;IAAE,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAgEvB"}
@@ -16,8 +16,46 @@ export interface PermissionDecision {
16
16
  /** Risk tier of the tool, if classified. */
17
17
  riskTier?: 'safe' | 'standard' | 'destructive' | undefined;
18
18
  }
19
+ /**
20
+ * A single evaluation step in the permission explainer trace.
21
+ * Each step records a rule that was checked, whether it matched,
22
+ * and what the effective decision would be if that rule wins.
23
+ */
24
+ export interface PermissionTraceStep {
25
+ /** Label identifying the rule, e.g. "session soft deny", "trust deny", "yolo". */
26
+ rule: string;
27
+ /** Whether this rule's condition matched the tool+input pair. */
28
+ matched: boolean;
29
+ /** The permission decision if this rule were the winner. */
30
+ decision: 'auto' | 'deny' | 'confirm';
31
+ /** The source label associated with this step. */
32
+ source: string;
33
+ /** Human-readable explanation of the outcome. */
34
+ detail: string;
35
+ }
36
+ /**
37
+ * Structured trace of a permission evaluation for debugging and CLI
38
+ * explainer output. Contains every step that was checked and the
39
+ * winning decision.
40
+ */
41
+ export interface PermissionTrace {
42
+ toolName: string;
43
+ subject: string | null | undefined;
44
+ /** The ordered list of rules checked, in evaluation priority order. */
45
+ steps: PermissionTraceStep[];
46
+ /** Index into `steps` of the winning rule. */
47
+ winnerIndex: number;
48
+ /** The final effective permission decision. */
49
+ decision: PermissionDecision;
50
+ }
19
51
  export interface PermissionPolicy {
20
52
  evaluate(tool: Tool, input: unknown, ctx: Context): Promise<PermissionDecision>;
53
+ /**
54
+ * Side-effect-free permission evaluation trace. Returns the same
55
+ * logical result as `evaluate()` without prompting the user,
56
+ * writing to trust files, or mutating session state.
57
+ */
58
+ explain?(tool: Tool, input: unknown, ctx: Context): Promise<PermissionTrace>;
21
59
  trust(rule: {
22
60
  tool: string;
23
61
  pattern: string;
@@ -1 +1 @@
1
- {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/types/permission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,CAAC,iBAAiB,EAAE,MAAM,GAAG;QAC3B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC7B,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC3B,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACnC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACnC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,CAAC;IAC3G,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;CAC5D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChF,KAAK,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,6EAA6E;IAC7E,OAAO,CAAC,IAAI,OAAO,CAAC;IACpB,8EAA8E;IAC9E,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,2EAA2E;IAC3E,kBAAkB,CAAC,IAAI,OAAO,CAAC;IAC/B,4EAA4E;IAC5E,kBAAkB,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,mEAAmE;IACnE,qBAAqB,CAAC,IAAI,OAAO,CAAC;IAClC,oFAAoF;IACpF,qBAAqB,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/C,0CAA0C;IAC1C,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC;CACvJ"}
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../../src/types/permission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Minimal paths object needed for config backup — just the global root
3
+ * from which we derive the backup history directory.
4
+ */
5
+ export interface ConfigBackupPaths {
6
+ globalRoot: string;
7
+ }
8
+ /**
9
+ * Backup directory for config file history.
10
+ * Every config write creates a timestamped snapshot here so the user can
11
+ * recover from accidental changes. Backups are never cleaned up automatically.
12
+ */
13
+ export declare function configHistoryDir(globalRoot: string): string;
14
+ /**
15
+ * Before overwriting a config file, save its current content to the
16
+ * config-history directory with a timestamp. Best-effort: failures are
17
+ * silently ignored so they never block the config write itself.
18
+ */
19
+ export declare function backupConfigFile(filePath: string, paths: ConfigBackupPaths): Promise<void>;
20
+ //# sourceMappingURL=config-backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-backup.d.ts","sourceRoot":"","sources":["../../src/utils/config-backup.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAcD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -2,6 +2,7 @@ export * from './assert-never.js';
2
2
  export * from './atomic-write.js';
3
3
  export * from './child-env.js';
4
4
  export * from './color.js';
5
+ export * from './config-backup.js';
5
6
  export * from './config-json.js';
6
7
  export { buildCompletedWorkLedgerBlock, buildContextEvidenceDigest, COMPLETED_WORK_LEDGER_MARKER, createContextEvidenceState, formatCompletedWorkLedger, markAssistantReferencedEvidence, type RecordCompletedWorkInput, type RecordToolOutputEvidenceInput, recordCompletedWorkEvidence, recordToolOutputEvidence, recordUserIntentEvidence, repeatedReadPressure, syncCompletedWorkLedgerBlock, } from './context-evidence.js';
7
8
  export { type DeepMergeOptions, deepMerge, FORBIDDEN_PROTO_KEYS, isPrimitiveArray, } from './deep-merge.js';
@@ -33,7 +34,7 @@ export { applyToolDescriptionModes, applyToolDescriptionModeToTool, DEFAULT_TOOL
33
34
  export { createToolOutputSerializer, type ToolOutputSerializerOptions, } from './tool-output-serializer.js';
34
35
  export { applyToolResultRenderModes, DEFAULT_TOOL_RESULT_RENDER_MODE, getToolResultRenderMode, normalizeToolResultRenderMode, resolveToolResultRenderMode, setToolResultRenderMode, type ToolResultRenderModeRegistryLike, } from './tool-result-render-mode.js';
35
36
  export * from './tool-subject.js';
36
- export { type CompactToolDefinitionForWireOptions, type CompactWireToolDefinition, compactSchemaDescriptions, compactToolDefinitionForWire, type ToolWireDefinitionLike, } from './tool-wire-compact.js';
37
+ export { type CompactToolDefinitionForWireOptions, type CompactWireToolDefinition, compactSchemaDescriptions, compactToolDefinitionForWire, normalizeTopLevelToolSchema, type ToolWireDefinitionLike, } from './tool-wire-compact.js';
37
38
  export { isUlid, ulid } from './ulid.js';
38
39
  export * from './wstack-paths.js';
39
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
@@ -492,6 +492,12 @@ var TerminalLifecycle = class {
492
492
  * raw mode. Null when `acquire()` has never been called.
493
493
  */
494
494
  _wasRaw = null;
495
+ /**
496
+ * Whether stdin was paused before the TUI took ownership. Readline closes
497
+ * its interface by pausing the shared process stream, so raw mode alone is
498
+ * not enough to make Ink receive bytes during the boot-prompt -> TUI handoff.
499
+ */
500
+ _wasPaused = null;
495
501
  /**
496
502
  * Request the process to exit. Set the flag, trigger any registered
497
503
  * `onRequestExit` callback (typically Ink's `unmount()`), and arm a
@@ -543,8 +549,10 @@ var TerminalLifecycle = class {
543
549
  if (stdin?.isTTY !== true) return false;
544
550
  if (typeof stdin.setRawMode !== "function") return false;
545
551
  this._wasRaw = stdin.isRaw ?? false;
552
+ this._wasPaused = stdin.isPaused();
546
553
  this._stdin = stdin;
547
554
  stdin.setRawMode(true);
555
+ stdin.resume();
548
556
  this._active = true;
549
557
  if (process.platform === "win32") {
550
558
  setImmediate(() => {
@@ -573,9 +581,11 @@ var TerminalLifecycle = class {
573
581
  const stdin = this._stdin;
574
582
  if (stdin?.isTTY === true) {
575
583
  stdin.setRawMode?.(this._wasRaw ?? false);
584
+ if (this._wasPaused) stdin.pause();
576
585
  }
577
586
  this._stdin = void 0;
578
587
  this._wasRaw = null;
588
+ this._wasPaused = null;
579
589
  }
580
590
  /**
581
591
  * Synchronously reset all terminal state written by the TUI layer:
@@ -686,11 +696,42 @@ function stripAnsi(s) {
686
696
  return s.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "");
687
697
  }
688
698
 
689
- // src/utils/config-json.ts
699
+ // src/utils/config-backup.ts
690
700
  import * as fs2 from "node:fs/promises";
701
+ import * as path2 from "node:path";
702
+ function configHistoryDir(globalRoot) {
703
+ return path2.join(globalRoot, "config-history");
704
+ }
705
+ function configSlug(absolutePath, globalRoot) {
706
+ const rel = path2.relative(globalRoot, absolutePath);
707
+ const normalized = rel.replace(/\\/g, "/").replace(/\.json$/i, "");
708
+ return normalized.replace(/\//g, "-");
709
+ }
710
+ async function backupConfigFile(filePath, paths) {
711
+ let currentContent;
712
+ try {
713
+ currentContent = await fs2.readFile(filePath, "utf8");
714
+ if (!currentContent.trim()) return;
715
+ } catch {
716
+ return;
717
+ }
718
+ const now = /* @__PURE__ */ new Date();
719
+ const ts = now.toISOString().replace(/[:.]/g, "-").replace(/Z$/, "");
720
+ const slug = configSlug(filePath, paths.globalRoot);
721
+ const backupDir = configHistoryDir(paths.globalRoot);
722
+ const backupFile = path2.join(backupDir, `${slug}-${ts}.json`);
723
+ try {
724
+ await fs2.mkdir(backupDir, { recursive: true });
725
+ await fs2.writeFile(backupFile, currentContent, { mode: 384, encoding: "utf8" });
726
+ } catch {
727
+ }
728
+ }
729
+
730
+ // src/utils/config-json.ts
731
+ import * as fs3 from "node:fs/promises";
691
732
  async function readJsonObjectFile(filePath) {
692
733
  try {
693
- const parsed = JSON.parse(await fs2.readFile(filePath, "utf8"));
734
+ const parsed = JSON.parse(await fs3.readFile(filePath, "utf8"));
694
735
  return isJsonObject(parsed) ? parsed : {};
695
736
  } catch {
696
737
  return {};
@@ -698,7 +739,7 @@ async function readJsonObjectFile(filePath) {
698
739
  }
699
740
  async function jsonObjectFileExists(filePath) {
700
741
  try {
701
- await fs2.access(filePath);
742
+ await fs3.access(filePath);
702
743
  return true;
703
744
  } catch {
704
745
  return false;
@@ -714,9 +755,9 @@ async function updateJsonObjectFile(filePath, mutator) {
714
755
  await writeJsonObjectFile(filePath, next);
715
756
  return next;
716
757
  }
717
- function getJsonPath(root, path5) {
758
+ function getJsonPath(root, path6) {
718
759
  let current = root;
719
- for (const segment of path5) {
760
+ for (const segment of path6) {
720
761
  if (typeof segment === "number") {
721
762
  if (!Array.isArray(current)) return void 0;
722
763
  current = current[segment];
@@ -727,13 +768,13 @@ function getJsonPath(root, path5) {
727
768
  }
728
769
  return current;
729
770
  }
730
- function setJsonPath(root, path5, value) {
731
- if (path5.length === 0) {
771
+ function setJsonPath(root, path6, value) {
772
+ if (path6.length === 0) {
732
773
  if (!isJsonObject(value)) throw new Error("Root config value must be an object");
733
774
  return value;
734
775
  }
735
- const parent = ensureJsonParent(root, path5);
736
- const leaf = lastPathSegment(path5);
776
+ const parent = ensureJsonParent(root, path6);
777
+ const leaf = lastPathSegment(path6);
737
778
  if (typeof leaf === "number") {
738
779
  if (!Array.isArray(parent)) throw new Error(`Cannot set numeric segment ${leaf} on non-array parent`);
739
780
  parent[leaf] = value;
@@ -743,10 +784,10 @@ function setJsonPath(root, path5, value) {
743
784
  }
744
785
  return root;
745
786
  }
746
- function removeJsonPath(root, path5) {
747
- if (path5.length === 0) return false;
748
- const parent = getJsonPath(root, path5.slice(0, -1));
749
- const leaf = lastPathSegment(path5);
787
+ function removeJsonPath(root, path6) {
788
+ if (path6.length === 0) return false;
789
+ const parent = getJsonPath(root, path6.slice(0, -1));
790
+ const leaf = lastPathSegment(path6);
750
791
  if (typeof leaf === "number") {
751
792
  if (!Array.isArray(parent) || leaf < 0 || leaf >= parent.length) return false;
752
793
  parent.splice(leaf, 1);
@@ -756,27 +797,27 @@ function removeJsonPath(root, path5) {
756
797
  delete parent[leaf];
757
798
  return true;
758
799
  }
759
- async function setJsonPathInFile(filePath, path5, value) {
760
- return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path5, value));
800
+ async function setJsonPathInFile(filePath, path6, value) {
801
+ return updateJsonObjectFile(filePath, (config) => setJsonPath(config, path6, value));
761
802
  }
762
- async function removeJsonPathInFile(filePath, path5) {
803
+ async function removeJsonPathInFile(filePath, path6) {
763
804
  return updateJsonObjectFile(filePath, (config) => {
764
- removeJsonPath(config, path5);
805
+ removeJsonPath(config, path6);
765
806
  });
766
807
  }
767
808
  function isJsonObject(value) {
768
809
  return typeof value === "object" && value !== null && !Array.isArray(value);
769
810
  }
770
- function lastPathSegment(path5) {
771
- const segment = path5[path5.length - 1];
811
+ function lastPathSegment(path6) {
812
+ const segment = path6[path6.length - 1];
772
813
  if (segment === void 0) throw new Error("Invalid empty JSON path");
773
814
  return segment;
774
815
  }
775
- function ensureJsonParent(root, path5) {
816
+ function ensureJsonParent(root, path6) {
776
817
  let current = root;
777
- for (let i = 0; i < path5.length - 1; i += 1) {
778
- const segment = path5[i];
779
- const nextSegment = path5[i + 1];
818
+ for (let i = 0; i < path6.length - 1; i += 1) {
819
+ const segment = path6[i];
820
+ const nextSegment = path6[i + 1];
780
821
  if (segment === void 0) throw new Error("Invalid empty JSON path segment");
781
822
  const nextContainer = typeof nextSegment === "number" ? [] : {};
782
823
  if (typeof segment === "number") {
@@ -793,7 +834,7 @@ function ensureJsonParent(root, path5) {
793
834
  }
794
835
 
795
836
  // src/utils/context-evidence.ts
796
- import * as path2 from "node:path";
837
+ import * as path3 from "node:path";
797
838
  var MAX_TOOL_CALLS = 80;
798
839
  var MAX_FACTS = 40;
799
840
  var MAX_ERRORS = 20;
@@ -1033,10 +1074,10 @@ function addPath(ctx, out, raw) {
1033
1074
  if (!clean || clean.length > 260) return;
1034
1075
  let normalized = clean.replace(/\\/g, "/");
1035
1076
  try {
1036
- const abs = path2.isAbsolute(clean) ? path2.resolve(clean) : null;
1077
+ const abs = path3.isAbsolute(clean) ? path3.resolve(clean) : null;
1037
1078
  if (abs) {
1038
- const rel = path2.relative(ctx.projectRoot, abs);
1039
- if (!rel.startsWith("..") && !path2.isAbsolute(rel)) {
1079
+ const rel = path3.relative(ctx.projectRoot, abs);
1080
+ if (!rel.startsWith("..") && !path3.isAbsolute(rel)) {
1040
1081
  normalized = rel.replace(/\\/g, "/");
1041
1082
  }
1042
1083
  }
@@ -1154,7 +1195,7 @@ function implicitFactFor(metadata) {
1154
1195
  function metadataReferencedByText(metadata, haystack) {
1155
1196
  for (const file of metadata.files) {
1156
1197
  const f = file.toLowerCase();
1157
- const base = path2.basename(file).toLowerCase();
1198
+ const base = path3.basename(file).toLowerCase();
1158
1199
  if (f && haystack.includes(f)) return true;
1159
1200
  if (base && haystack.includes(base)) return true;
1160
1201
  }
@@ -1860,10 +1901,10 @@ function validateAgainstSchema(value, schema) {
1860
1901
  return { ok: errors.length === 0, errors };
1861
1902
  }
1862
1903
  var MAX_SCHEMA_DEPTH = 64;
1863
- function walk(value, schema, path5, errors, depth) {
1904
+ function walk(value, schema, path6, errors, depth) {
1864
1905
  if (depth > MAX_SCHEMA_DEPTH) {
1865
1906
  errors.push({
1866
- path: path5 || "<root>",
1907
+ path: path6 || "<root>",
1867
1908
  message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`
1868
1909
  });
1869
1910
  return;
@@ -1871,7 +1912,7 @@ function walk(value, schema, path5, errors, depth) {
1871
1912
  if (schema.enum !== void 0) {
1872
1913
  if (!enumIncludes(schema.enum, value)) {
1873
1914
  errors.push({
1874
- path: path5 || "<root>",
1915
+ path: path6 || "<root>",
1875
1916
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
1876
1917
  });
1877
1918
  return;
@@ -1880,7 +1921,7 @@ function walk(value, schema, path5, errors, depth) {
1880
1921
  if (typeof schema.type === "string") {
1881
1922
  if (!checkType(value, schema.type)) {
1882
1923
  errors.push({
1883
- path: path5 || "<root>",
1924
+ path: path6 || "<root>",
1884
1925
  message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`
1885
1926
  });
1886
1927
  return;
@@ -1892,7 +1933,7 @@ function walk(value, schema, path5, errors, depth) {
1892
1933
  if (!(req in obj)) {
1893
1934
  const expected = schema.properties?.[req]?.type;
1894
1935
  errors.push({
1895
- path: joinPath(path5, req),
1936
+ path: joinPath(path6, req),
1896
1937
  message: `required property missing${typeof expected === "string" ? ` (expected ${expected})` : ""}`
1897
1938
  });
1898
1939
  }
@@ -1900,14 +1941,14 @@ function walk(value, schema, path5, errors, depth) {
1900
1941
  if (schema.properties) {
1901
1942
  for (const [key, subSchema] of Object.entries(schema.properties)) {
1902
1943
  if (key in obj) {
1903
- walk(obj[key], subSchema, joinPath(path5, key), errors, depth + 1);
1944
+ walk(obj[key], subSchema, joinPath(path6, key), errors, depth + 1);
1904
1945
  }
1905
1946
  }
1906
1947
  }
1907
1948
  }
1908
1949
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
1909
1950
  for (let i = 0; i < value.length; i++) {
1910
- walk(value[i], schema.items, `${path5}[${i}]`, errors, depth + 1);
1951
+ walk(value[i], schema.items, `${path6}[${i}]`, errors, depth + 1);
1911
1952
  }
1912
1953
  }
1913
1954
  }
@@ -2118,16 +2159,6 @@ function stripUndefined(obj) {
2118
2159
  }
2119
2160
 
2120
2161
  // src/utils/message-invariants.ts
2121
- function hasMeaningfulContent(content) {
2122
- if (typeof content === "string") return content.trim().length > 0;
2123
- return content.some((block) => {
2124
- if (block.type === "text") return block.text.trim().length > 0;
2125
- if (block.type === "thinking") {
2126
- return block.thinking.trim().length > 0 || Boolean(block.signature);
2127
- }
2128
- return true;
2129
- });
2130
- }
2131
2162
  function repairToolUseAdjacency(messages) {
2132
2163
  const removedToolUses = [];
2133
2164
  const removedToolResults = [];
@@ -2214,6 +2245,21 @@ function mapContent(msg, fn) {
2214
2245
  }
2215
2246
  return { ...msg, content: next };
2216
2247
  }
2248
+ function hasMeaningfulContent(content) {
2249
+ if (typeof content === "string") return content.trim().length > 0;
2250
+ for (const block of content) {
2251
+ if (block.type === "text") {
2252
+ if (block.text.trim().length > 0) return true;
2253
+ continue;
2254
+ }
2255
+ if (block.type === "thinking") {
2256
+ if (block.thinking.trim().length > 0 || block.signature) return true;
2257
+ continue;
2258
+ }
2259
+ return true;
2260
+ }
2261
+ return false;
2262
+ }
2217
2263
  function isEmptyMessage(msg) {
2218
2264
  return !hasMeaningfulContent(msg.content);
2219
2265
  }
@@ -2426,14 +2472,14 @@ function stripJsonComments(s) {
2426
2472
  }
2427
2473
 
2428
2474
  // src/utils/session-scoped-path.ts
2429
- import * as path3 from "node:path";
2475
+ import * as path4 from "node:path";
2430
2476
  function sessionScopedPath(dir, sessionId, suffix) {
2431
2477
  if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
2432
2478
  throw invalid(sessionId);
2433
2479
  }
2434
- const resolved = path3.resolve(dir, `${sessionId}${suffix}`);
2435
- const rel = path3.relative(path3.resolve(dir), resolved);
2436
- if (rel.startsWith("..") || path3.isAbsolute(rel)) {
2480
+ const resolved = path4.resolve(dir, `${sessionId}${suffix}`);
2481
+ const rel = path4.relative(path4.resolve(dir), resolved);
2482
+ if (rel.startsWith("..") || path4.isAbsolute(rel)) {
2437
2483
  throw invalid(sessionId);
2438
2484
  }
2439
2485
  return resolved;
@@ -3776,23 +3822,23 @@ function isUlid(value) {
3776
3822
 
3777
3823
  // src/utils/wstack-paths.ts
3778
3824
  import { createHash } from "node:crypto";
3779
- import * as fs3 from "node:fs";
3825
+ import * as fs4 from "node:fs";
3780
3826
  import * as os from "node:os";
3781
- import * as path4 from "node:path";
3827
+ import * as path5 from "node:path";
3782
3828
  function canonicalProjectRoot(absRoot) {
3783
- const checkoutRoot = path4.resolve(absRoot);
3784
- const dotGit = path4.join(checkoutRoot, ".git");
3829
+ const checkoutRoot = path5.resolve(absRoot);
3830
+ const dotGit = path5.join(checkoutRoot, ".git");
3785
3831
  try {
3786
- if (!fs3.statSync(dotGit).isFile()) return checkoutRoot;
3787
- const gitDirLine = fs3.readFileSync(dotGit, "utf8").trim();
3832
+ if (!fs4.statSync(dotGit).isFile()) return checkoutRoot;
3833
+ const gitDirLine = fs4.readFileSync(dotGit, "utf8").trim();
3788
3834
  const match = /^gitdir:\s*(.+)$/i.exec(gitDirLine);
3789
3835
  if (!match?.[1]) return checkoutRoot;
3790
- const gitDir = path4.resolve(checkoutRoot, match[1].trim());
3791
- const commonDirFile = path4.join(gitDir, "commondir");
3792
- if (!fs3.statSync(commonDirFile).isFile()) return checkoutRoot;
3793
- const commonDir = path4.resolve(gitDir, fs3.readFileSync(commonDirFile, "utf8").trim());
3794
- if (path4.basename(commonDir).toLowerCase() !== ".git") return checkoutRoot;
3795
- return path4.dirname(commonDir);
3836
+ const gitDir = path5.resolve(checkoutRoot, match[1].trim());
3837
+ const commonDirFile = path5.join(gitDir, "commondir");
3838
+ if (!fs4.statSync(commonDirFile).isFile()) return checkoutRoot;
3839
+ const commonDir = path5.resolve(gitDir, fs4.readFileSync(commonDirFile, "utf8").trim());
3840
+ if (path5.basename(commonDir).toLowerCase() !== ".git") return checkoutRoot;
3841
+ return path5.dirname(commonDir);
3796
3842
  } catch {
3797
3843
  return checkoutRoot;
3798
3844
  }
@@ -3802,7 +3848,7 @@ function projectHash(absRoot) {
3802
3848
  }
3803
3849
  function projectSlug(absRoot) {
3804
3850
  const identityRoot = canonicalProjectRoot(absRoot);
3805
- const base = slugify2(path4.basename(identityRoot));
3851
+ const base = slugify2(path5.basename(identityRoot));
3806
3852
  const hash = createHash("sha256").update(identityRoot).digest("hex").slice(0, 6);
3807
3853
  return `${base}-${hash}`;
3808
3854
  }
@@ -3811,66 +3857,83 @@ function slugify2(name) {
3811
3857
  }
3812
3858
  function wstackGlobalRoot() {
3813
3859
  const fromEnv = process.env["WRONGSTACK_HOME"];
3814
- if (fromEnv && fromEnv.trim().length > 0) return path4.resolve(fromEnv);
3815
- return path4.join(os.homedir(), ".wrongstack");
3860
+ if (fromEnv && fromEnv.trim().length > 0) return path5.resolve(fromEnv);
3861
+ return path5.join(os.homedir(), ".wrongstack");
3816
3862
  }
3817
3863
  function resolveWstackPaths(opts) {
3818
- const globalRoot = opts.globalRoot ?? (opts.userHome ? path4.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
3864
+ const globalRoot = opts.globalRoot ?? (opts.userHome ? path5.join(opts.userHome, ".wrongstack") : wstackGlobalRoot());
3819
3865
  const homeDir = opts.userHome ?? os.homedir();
3820
3866
  const hash = projectHash(opts.projectRoot);
3821
3867
  const slug = projectSlug(opts.projectRoot);
3822
- const projectDir = path4.join(globalRoot, "projects", slug);
3868
+ const projectDir = path5.join(globalRoot, "projects", slug);
3823
3869
  return {
3824
3870
  globalRoot,
3825
3871
  projectRoot: opts.projectRoot,
3826
3872
  homeDir,
3827
3873
  configDir: globalRoot,
3828
- globalConfig: path4.join(globalRoot, "config.json"),
3829
- profilesDir: path4.join(globalRoot, "profiles"),
3874
+ globalConfig: path5.join(globalRoot, "config.json"),
3875
+ profilesDir: path5.join(globalRoot, "profiles"),
3830
3876
  profileConfig: (name) => {
3831
3877
  const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3832
- return path4.join(globalRoot, "profiles", safe || "default", "config.json");
3878
+ return path5.join(globalRoot, "profiles", safe || "default", "config.json");
3879
+ },
3880
+ profileStatuslineConfig: (name) => {
3881
+ const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3882
+ return path5.join(globalRoot, "profiles", safe || "default", "statusline.json");
3883
+ },
3884
+ profileModeConfig: (name) => {
3885
+ const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3886
+ return path5.join(globalRoot, "profiles", safe || "default", "mode.json");
3887
+ },
3888
+ profileProviderStatus: (name) => {
3889
+ const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3890
+ return path5.join(globalRoot, "profiles", safe || "default", "provider-status.json");
3891
+ },
3892
+ profileUpdateCache: (name) => {
3893
+ const safe = name.replace(/[/\\:]/g, "_").replace(/\.\./g, "_");
3894
+ return path5.join(globalRoot, "profiles", safe || "default", "update-cache.json");
3833
3895
  },
3834
- secretsKey: path4.join(globalRoot, ".key"),
3835
- globalMemory: path4.join(globalRoot, "memory.md"),
3836
- globalSkills: path4.join(globalRoot, "skills"),
3837
- globalClaudeSkills: path4.join(homeDir, ".claude", "skills"),
3838
- globalDesignKits: path4.join(globalRoot, "design-kits"),
3839
- globalPrompts: path4.join(globalRoot, "prompts"),
3840
- globalInstructions: path4.join(globalRoot, "instructions"),
3841
- promptUsage: path4.join(globalRoot, "prompt-usage.json"),
3842
- cacheDir: path4.join(globalRoot, "cache"),
3843
- modelsCache: path4.join(globalRoot, "cache", "models.dev.json"),
3844
- modelsOverlayCache: path4.join(globalRoot, "cache", "models-overlay.json"),
3845
- historyFile: path4.join(globalRoot, "history"),
3846
- logFile: path4.join(globalRoot, "logs", "wrongstack.log"),
3896
+ secretsKey: path5.join(globalRoot, ".key"),
3897
+ globalMemory: path5.join(globalRoot, "memory.md"),
3898
+ globalSkills: path5.join(globalRoot, "skills"),
3899
+ globalClaudeSkills: path5.join(homeDir, ".claude", "skills"),
3900
+ globalDesignKits: path5.join(globalRoot, "design-kits"),
3901
+ globalPrompts: path5.join(globalRoot, "prompts"),
3902
+ globalInstructions: path5.join(globalRoot, "instructions"),
3903
+ promptUsage: path5.join(globalRoot, "prompt-usage.json"),
3904
+ cacheDir: path5.join(globalRoot, "cache"),
3905
+ modelsCache: path5.join(globalRoot, "cache", "models.dev.json"),
3906
+ modelsOverlayCache: path5.join(globalRoot, "cache", "models-overlay.json"),
3907
+ historyFile: path5.join(globalRoot, "history"),
3908
+ logFile: path5.join(globalRoot, "logs", "wrongstack.log"),
3847
3909
  projectDir,
3848
- projectCodebaseIndex: path4.join(projectDir, "codebase-index"),
3849
- projectMemory: path4.join(projectDir, "memory.md"),
3850
- projectSessions: path4.join(projectDir, "sessions"),
3851
- projectTrust: path4.join(projectDir, "trust.json"),
3852
- projectMeta: path4.join(projectDir, "meta.json"),
3853
- projectLocalConfig: path4.join(projectDir, "config.local.json"),
3854
- inProjectConfig: path4.join(opts.projectRoot, ".wrongstack", "config.json"),
3855
- inProjectAgentsFile: path4.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
3856
- inProjectSkills: path4.join(opts.projectRoot, ".wrongstack", "skills"),
3857
- inProjectClaudeSkills: path4.join(opts.projectRoot, ".claude", "skills"),
3858
- inProjectPrompts: path4.join(opts.projectRoot, ".wrongstack", "prompts"),
3859
- inProjectInstructions: path4.join(opts.projectRoot, ".wrongstack", "instructions"),
3860
- inProjectDesignKits: path4.join(opts.projectRoot, ".wrongstack", "design-kits"),
3861
- inProjectWorktrees: path4.join(opts.projectRoot, ".wrongstack", "worktrees"),
3910
+ projectCodebaseIndex: path5.join(projectDir, "codebase-index"),
3911
+ projectMemory: path5.join(projectDir, "memory.md"),
3912
+ projectSessions: path5.join(projectDir, "sessions"),
3913
+ projectTrust: path5.join(projectDir, "trust.json"),
3914
+ projectMeta: path5.join(projectDir, "meta.json"),
3915
+ projectLocalConfig: path5.join(projectDir, "config.local.json"),
3916
+ inProjectConfig: path5.join(opts.projectRoot, ".wrongstack", "config.json"),
3917
+ inProjectAgentsFile: path5.join(opts.projectRoot, ".wrongstack", "AGENTS.md"),
3918
+ inProjectSkills: path5.join(opts.projectRoot, ".wrongstack", "skills"),
3919
+ inProjectClaudeSkills: path5.join(opts.projectRoot, ".claude", "skills"),
3920
+ inProjectPrompts: path5.join(opts.projectRoot, ".wrongstack", "prompts"),
3921
+ inProjectInstructions: path5.join(opts.projectRoot, ".wrongstack", "instructions"),
3922
+ inProjectDesignKits: path5.join(opts.projectRoot, ".wrongstack", "design-kits"),
3923
+ inProjectWorktrees: path5.join(opts.projectRoot, ".wrongstack", "worktrees"),
3862
3924
  projectHash: hash,
3863
3925
  projectSlug: slug,
3864
- projectGoal: path4.join(projectDir, "goal.json"),
3865
- projectInputHistory: path4.join(projectDir, "input-history.json"),
3866
- projectSpecs: path4.join(projectDir, "specs"),
3867
- projectTaskGraphs: path4.join(projectDir, "task-graphs"),
3868
- projectSddSession: path4.join(projectDir, "sdd-session.json"),
3869
- projectPlan: path4.join(projectDir, "plan.json"),
3870
- projectAutophase: path4.join(projectDir, "autophase"),
3871
- projectSddBoards: path4.join(projectDir, "sdd-boards"),
3872
- syncConfig: path4.join(globalRoot, "sync.json"),
3873
- projectStatus: (projectHash2) => path4.join(globalRoot, "projects", projectHash2, "status.json")
3926
+ projectGoal: path5.join(projectDir, "goal.json"),
3927
+ projectInputHistory: path5.join(projectDir, "input-history.json"),
3928
+ projectSpecs: path5.join(projectDir, "specs"),
3929
+ projectTaskGraphs: path5.join(projectDir, "task-graphs"),
3930
+ projectSddSession: path5.join(projectDir, "sdd-session.json"),
3931
+ projectPlan: path5.join(projectDir, "plan.json"),
3932
+ projectAutophase: path5.join(projectDir, "autophase"),
3933
+ projectSddBoards: path5.join(projectDir, "sdd-boards"),
3934
+ syncConfig: path5.join(globalRoot, "sync.json"),
3935
+ configHistoryDir: path5.join(globalRoot, "config-history"),
3936
+ projectStatus: (projectHash2) => path5.join(globalRoot, "projects", projectHash2, "status.json")
3874
3937
  };
3875
3938
  }
3876
3939
  export {
@@ -3889,6 +3952,7 @@ export {
3889
3952
  assertNever,
3890
3953
  assertNotPrivateHost,
3891
3954
  atomicWrite,
3955
+ backupConfigFile,
3892
3956
  buildChildEnv,
3893
3957
  buildCompletedWorkLedgerBlock,
3894
3958
  buildContextEvidenceDigest,
@@ -3905,6 +3969,7 @@ export {
3905
3969
  completePartialObject,
3906
3970
  computeMessageTokens,
3907
3971
  computeTaskItemProgress,
3972
+ configHistoryDir,
3908
3973
  configureChildEnvGitIdentity,
3909
3974
  createContextEvidenceState,
3910
3975
  createToolOutputSerializer,
@@ -3950,6 +4015,7 @@ export {
3950
4015
  normalizeToLf,
3951
4016
  normalizeToolDescriptionMode,
3952
4017
  normalizeToolResultRenderMode,
4018
+ normalizeTopLevelToolSchema,
3953
4019
  parseIncomingImages,
3954
4020
  projectHash,
3955
4021
  projectSlug,