pi-fabric 0.76.2 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +1 -0
  2. package/dist/agents/bash-worktree-add.d.ts +24 -0
  3. package/dist/agents/bash-worktree-add.d.ts.map +1 -0
  4. package/dist/agents/clone-first-worktree.d.ts +17 -0
  5. package/dist/agents/clone-first-worktree.d.ts.map +1 -0
  6. package/dist/agents/cow-clone.d.ts +8 -0
  7. package/dist/agents/cow-clone.d.ts.map +1 -0
  8. package/dist/agents/worktree-manager.d.ts.map +1 -1
  9. package/dist/agents/worktree-paths.d.ts +5 -0
  10. package/dist/agents/worktree-paths.d.ts.map +1 -0
  11. package/dist/capture/catalog.d.ts +3 -0
  12. package/dist/capture/catalog.d.ts.map +1 -1
  13. package/dist/chunks/{chunk-PAAXKXWT.js → chunk-2AF5ANEB.js} +16 -2
  14. package/dist/chunks/chunk-2AF5ANEB.js.map +7 -0
  15. package/dist/chunks/{chunk-QXB75FLD.js → chunk-2E3CAABA.js} +8 -1
  16. package/dist/chunks/chunk-2E3CAABA.js.map +7 -0
  17. package/dist/chunks/{chunk-6ZKYQW33.js → chunk-3QPTSKDG.js} +139 -29
  18. package/dist/chunks/chunk-3QPTSKDG.js.map +7 -0
  19. package/dist/chunks/{chunk-BT6UELLP.js → chunk-DUIHQAIZ.js} +2 -2
  20. package/dist/chunks/{chunk-6BBFFEPO.js → chunk-DYEOFQ64.js} +15 -1
  21. package/dist/chunks/{chunk-6BBFFEPO.js.map → chunk-DYEOFQ64.js.map} +2 -2
  22. package/dist/chunks/{chunk-F2GKEXGI.js → chunk-PFF3X7OO.js} +272 -146
  23. package/dist/chunks/chunk-PFF3X7OO.js.map +7 -0
  24. package/dist/chunks/{fabric-runtime-state-VCLWTB55.js → fabric-runtime-state-H2NCRJWK.js} +797 -191
  25. package/dist/chunks/fabric-runtime-state-H2NCRJWK.js.map +7 -0
  26. package/dist/chunks/{settings-VEXI347I.js → settings-FUL3U3N4.js} +2 -2
  27. package/dist/commands/fabric.d.ts.map +1 -1
  28. package/dist/config.d.ts +4 -0
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/core/action-registry.d.ts +1 -0
  31. package/dist/core/action-registry.d.ts.map +1 -1
  32. package/dist/core/action-registry.js +1 -1
  33. package/dist/fabric-runtime-state.d.ts +2 -0
  34. package/dist/fabric-runtime-state.d.ts.map +1 -1
  35. package/dist/fabric-state.d.ts +1 -0
  36. package/dist/fabric-state.d.ts.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +218 -8
  39. package/dist/index.js.map +3 -3
  40. package/dist/providers/arg-normalization.d.ts +3 -0
  41. package/dist/providers/arg-normalization.d.ts.map +1 -1
  42. package/dist/providers/memory-provider.js +1 -1
  43. package/dist/providers/pi-tools-provider.d.ts.map +1 -1
  44. package/dist/repairs/active.d.ts +7 -0
  45. package/dist/repairs/active.d.ts.map +1 -0
  46. package/dist/repairs/apply.d.ts +7 -0
  47. package/dist/repairs/apply.d.ts.map +1 -0
  48. package/dist/repairs/catalog-digest.d.ts +5 -0
  49. package/dist/repairs/catalog-digest.d.ts.map +1 -0
  50. package/dist/repairs/classify.d.ts +10 -0
  51. package/dist/repairs/classify.d.ts.map +1 -0
  52. package/dist/repairs/compiler.d.ts +32 -0
  53. package/dist/repairs/compiler.d.ts.map +1 -0
  54. package/dist/repairs/promote.d.ts +4 -0
  55. package/dist/repairs/promote.d.ts.map +1 -0
  56. package/dist/repairs/store.d.ts +9 -0
  57. package/dist/repairs/store.d.ts.map +1 -0
  58. package/dist/repairs/types.d.ts +49 -0
  59. package/dist/repairs/types.d.ts.map +1 -0
  60. package/dist/residency/client.d.ts.map +1 -1
  61. package/dist/residency/host.js +3 -3
  62. package/dist/residency/pi-entry.js +3 -3
  63. package/dist/speculation/store.d.ts +11 -7
  64. package/dist/speculation/store.d.ts.map +1 -1
  65. package/dist/speculation/types.d.ts +2 -1
  66. package/dist/speculation/types.d.ts.map +1 -1
  67. package/docs/agents.md +1 -1
  68. package/docs/architecture.md +3 -1
  69. package/docs/configuration.md +4 -0
  70. package/docs/interface.md +1 -0
  71. package/docs/repairs.md +57 -0
  72. package/package.json +1 -1
  73. package/skills/fabric-exec/references/agents.md +3 -3
  74. package/dist/chunks/chunk-6ZKYQW33.js.map +0 -7
  75. package/dist/chunks/chunk-F2GKEXGI.js.map +0 -7
  76. package/dist/chunks/chunk-PAAXKXWT.js.map +0 -7
  77. package/dist/chunks/chunk-QXB75FLD.js.map +0 -7
  78. package/dist/chunks/fabric-runtime-state-VCLWTB55.js.map +0 -7
  79. /package/dist/chunks/{chunk-BT6UELLP.js.map → chunk-DUIHQAIZ.js.map} +0 -0
  80. /package/dist/chunks/{settings-VEXI347I.js.map → settings-FUL3U3N4.js.map} +0 -0
@@ -448,6 +448,9 @@ var DEFAULT_FABRIC_CONFIG = {
448
448
  regexMaxHaystackBytes: 2 * 1024 * 1024,
449
449
  regexTimeoutMs: 250
450
450
  },
451
+ repairs: {
452
+ enabled: true
453
+ },
451
454
  schema: {
452
455
  mode: "off",
453
456
  certificateTtlMs: 3e4,
@@ -534,6 +537,7 @@ var normalizeFabricConfig = (input) => {
534
537
  const retention = objectValue(input.retention);
535
538
  const mesh = objectValue(input.mesh);
536
539
  const memory = objectValue(input.memory);
540
+ const repairs = objectValue(input.repairs);
537
541
  const modelsSection = objectValue(input.models);
538
542
  const schema = objectValue(input.schema);
539
543
  const schemaMode = schemaModeValue(schema.mode, DEFAULT_FABRIC_CONFIG.schema.mode);
@@ -984,6 +988,9 @@ var normalizeFabricConfig = (input) => {
984
988
  1e4
985
989
  )
986
990
  },
991
+ repairs: {
992
+ enabled: booleanValue(repairs.enabled, DEFAULT_FABRIC_CONFIG.repairs.enabled)
993
+ },
987
994
  schema: {
988
995
  mode: schemaMode,
989
996
  certificateTtlMs: boundedInteger(
@@ -1192,4 +1199,4 @@ export {
1192
1199
  loadFabricConfig,
1193
1200
  saveFabricConfig
1194
1201
  };
1195
- //# sourceMappingURL=chunk-QXB75FLD.js.map
1202
+ //# sourceMappingURL=chunk-2E3CAABA.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/config.ts", "../../src/core/model-resolution.ts", "../../src/config-migrations.ts"],
4
+ "sourcesContent": ["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { renameAtomic } from \"./core/atomic-write.js\";\nimport { normalizeModelAliases } from \"./core/model-resolution.js\";\nimport { PI_CORE_TOOL_NAME_SET } from \"./core/pi-tools.js\";\nimport {\n CURRENT_FABRIC_CONFIG_VERSION,\n migrateFabricConfigDocument,\n} from \"./config-migrations.js\";\nimport type { FabricComponentEntry } from \"./components/types.js\";\nimport type { FabricRisk } from \"./protocol.js\";\nimport { DEFAULT_FABRIC_THINKING, isFabricThinking, type FabricThinking } from \"./thinking.js\";\nimport {\n defaultCodePreviewSettings,\n normalizeCodePreviewSettings,\n type CodePreviewSettings,\n} from \"./ui/code-preview.js\";\n\ntype FabricApprovalMode = \"allow\" | \"ask\" | \"auto\" | \"deny\";\nexport type FabricAgentTransport =\n | \"auto\"\n | \"process\"\n | \"tmux\"\n | \"screen\"\n | \"localterm\"\n | \"herdr\";\nexport type FabricAgentRunner = \"pi\" | \"claude\" | \"veda\";\nexport type FabricUiWidgetMode = \"auto\" | \"always\" | \"hidden\";\ntype FabricToolDisplayMode = \"full\" | \"compact\";\nexport type FabricResultFormat = \"auto\" | \"yaml\" | \"json\" | \"text\";\nexport type FabricPrewalkMode = \"in-place\" | \"trajectory\";\nexport type FabricExecutorRuntime = \"quickjs\" | \"node-process\" | \"bun-process\";\nexport type FabricConfigScope = \"global\" | \"project\";\ntype FabricCompactionEngine = \"pi\" | \"fabric\";\ntype FabricActorScope = \"project\" | \"session\";\n\ninterface FabricExecutorConfig {\n runtime: FabricExecutorRuntime;\n timeoutMs: number;\n /** Policy maximum for any executor deadline, including per-invocation\n * requests and per-ref floors. Values above this are visibly normalized. */\n maxTimeoutMs: number;\n /** Exact-ref deadline floors (ms) for known long-running host calls, e.g.\n * \"extensions.subagent\". Keys are exact refs; no wildcard matching. */\n hostCallTimeouts: Record<string, number>;\n memoryLimitBytes: number;\n maxOutputChars: number;\n maxNestedResultChars: number;\n resultFormat: FabricResultFormat;\n}\n\nexport interface FabricApprovalConfig {\n read: FabricApprovalMode;\n write: FabricApprovalMode;\n execute: FabricApprovalMode;\n network: FabricApprovalMode;\n agent: FabricApprovalMode;\n model?: string;\n}\n\n/** Session-start background revalidation scope for the MCP descriptor cache:\n * \"changed\" lists only added/reconfigured servers, \"all\" re-lists every known\n * server, \"off\" never spawns servers in the background. */\ntype FabricMcpRevalidatePolicy = \"changed\" | \"all\" | \"off\";\n\ninterface FabricMcpCacheConfig {\n /** Serve MCP tool metadata from the on-disk descriptor cache instead of\n * connecting to every configured server on first discovery each session. */\n enabled: boolean;\n revalidate: FabricMcpRevalidatePolicy;\n /** Wall-clock budget for one session-start background revalidation pass. */\n revalidateBudgetMs: number;\n}\n\nexport interface FabricMcpConfig {\n enabled: boolean;\n configPath?: string;\n disableOAuth: boolean;\n allowDynamicServers: boolean;\n callTimeoutMs: number;\n cache: FabricMcpCacheConfig;\n}\n\ninterface FabricClaudeRunnerConfig {\n binary: string;\n model?: string;\n}\n\n/** Veda CLI options for the `veda` agent runner. The Veda CLI wraps external\n * backends (agy, codex, claude-code, droid, pi, and any backend registered by\n * the installed Veda build); the backend is selected here and the persona\n * controls read-only vs write-capable behavior. */\ninterface FabricVedaRunnerConfig {\n binary: string;\n /** Veda backend to drive. Defaults to the Antigravity CLI (agy). */\n backend: string;\n /** Optional backend-specific model or Veda model alias. */\n model?: string;\n /** Veda persona: navigator-plan, navigator-chat, reviewer, or worker. */\n persona: string;\n}\n\ninterface FabricPrewalkConfig {\n // Master switch, persisted by /fabric prewalk --disable|--enable or the\n // settings UI (absent means enabled). Manual arming, session auto-arm, and\n // boundary claims all gate on it.\n enabled?: boolean;\n mode: FabricPrewalkMode;\n model?: string;\n alwaysRearm: boolean;\n // Compact with the configured engine just before restoring Main's boundary\n // model after an in-place continuation settles.\n compactOnReturn: boolean;\n // Filesystem fallback trigger: when an armed boundary ran a successful\n // pi.bash without an audited mutation, claim on stat-manifest drift so\n // shell heredocs / sed -i / formatter writes also hand off.\n detectShellWrites: boolean;\n // Reasoning effort for the trajectory executor; unset inherits agents.thinking.\n thinking?: FabricThinking;\n}\n\nexport interface FabricAgentConfig {\n enabled: boolean;\n runner: FabricAgentRunner;\n transport: FabricAgentTransport;\n model?: string;\n claude: FabricClaudeRunnerConfig;\n veda: FabricVedaRunnerConfig;\n thinking: FabricThinking;\n maxConcurrent: number;\n maxPerExecution: number;\n maxDepth: number;\n timeoutMs: number;\n extensions: boolean;\n defaultTools: string[];\n retainRuns: boolean;\n notifyOnComplete: boolean;\n budgetUsd: number;\n maxTokensPerChild: number;\n /** Write usage-only pi-format session files per agent run for external trackers. */\n sessionExport: boolean;\n /** Export store root override; PI_FABRIC_AGENT_DIR wins. Empty = ~/.pi-fabric/agent. */\n sessionExportDir: string;\n}\n\nexport interface FabricToolCaptureConfig {\n enabled: boolean;\n hideFromModel: boolean;\n keepVisible: string[];\n defaultRisk: FabricRisk;\n risks: Record<string, FabricRisk>;\n}\n\nexport type FabricSchemaMode = \"off\" | \"audit\" | \"enforce\";\n\nexport interface FabricSchemaTrustedCommand {\n command: string;\n args: string[];\n shell: boolean;\n timeoutMs: number;\n}\n\nexport interface FabricSchemaConfig {\n mode: FabricSchemaMode;\n certificateTtlMs: number;\n maxFiles: number;\n maxBytes: number;\n trustedCommands: Record<string, FabricSchemaTrustedCommand>;\n}\n\ninterface FabricUiConfig {\n enabled: boolean;\n widget: FabricUiWidgetMode;\n maxRows: number;\n refreshMs: number;\n eventHistory: number;\n haltOnEscape: boolean;\n showAgentToolPreview: boolean;\n toolDisplay: FabricToolDisplayMode;\n updateDebounceMs: number;\n}\n\ninterface FabricCompactionConfig {\n engine: FabricCompactionEngine;\n targetContextRatio: number;\n thresholds: Record<string, number>;\n tokenThresholds: Record<string, number>;\n}\n\nexport const MIN_COMPACTION_TOKEN_THRESHOLD = 1_000;\nexport const MAX_COMPACTION_TOKEN_THRESHOLD = 100_000_000;\nexport const MIN_COMPACTION_RATIO_THRESHOLD = 0.25;\nexport const MAX_COMPACTION_RATIO_THRESHOLD = 0.95;\n\nexport const clampCompactionTokenThreshold = (value: number): number =>\n Math.min(\n MAX_COMPACTION_TOKEN_THRESHOLD,\n Math.max(MIN_COMPACTION_TOKEN_THRESHOLD, Math.round(value)),\n );\n\nexport const clampCompactionRatioThreshold = (value: number): number =>\n Math.min(\n MAX_COMPACTION_RATIO_THRESHOLD,\n Math.max(MIN_COMPACTION_RATIO_THRESHOLD, value),\n );\n\nexport interface FabricRetentionConfig {\n orphanedTempRunMs: number;\n oneShotRunMs: number;\n actorRunArchiveMs: number;\n}\n\nexport interface FabricMeshConfig {\n enabled: boolean;\n root?: string;\n actorScope: FabricActorScope;\n maxEventBytes: number;\n maxReadEvents: number;\n actorPollMs: number;\n actorQueueLimit: number;\n eventContextChars: number;\n actorContextEntries: number;\n}\n\ninterface FabricRepairsConfig {\n enabled: boolean;\n}\n\nexport interface FabricMemoryConfig {\n enabled: boolean;\n indexDir?: string;\n maxSessions: number;\n maxEntryChars: number;\n indexThinking: boolean;\n indexToolOutput: boolean;\n hotSessions?: number;\n digestTerms?: number;\n maxColdVocabularyBytes?: number;\n maxColdCacheBytes?: number;\n maxSyncSessions?: number;\n maxSyncSourceBytes?: number;\n maxCacheCleanupFiles?: number;\n regexMaxPatternBytes?: number;\n regexMaxHaystackTerms?: number;\n regexMaxHaystackBytes?: number;\n regexTimeoutMs?: number;\n}\n\nexport interface FabricSpeculationConfig {\n /** Master switch for speculative programmatic tool calling during streaming. */\n enabled: boolean;\n /** Maximum simultaneously in-flight speculative calls; excess candidates are dropped. */\n maxConcurrent: number;\n /** Maximum retained unserved speculation entries per turn. */\n maxEntries: number;\n /** Per-stream cap on buffered partial tool-call arguments while extracting the `code` field. */\n maxBufferBytes: number;\n /** Unserved speculation entries older than this are aborted and discarded. */\n entryTtlMs: number;\n /**\n * Tier B: MCP tools that may be speculated despite risk \"network\". Entries\n * are `server.tool` or `server.*` and match the ref after the `mcp.` prefix.\n * Only enable for tools the operator knows are read-only; cached MCP\n * annotations with destructiveHint=true always refuse.\n */\n mcpAllowlist: string[];\n}\n\n\nexport interface FabricModelsConfig {\n /** Alias name \u2192 ordered provider/model fallback chain, first available wins. */\n aliases: Record<string, string[]>;\n}\n\nexport interface FabricConfig {\n fullCodeMode: boolean;\n executor: FabricExecutorConfig;\n approvals: FabricApprovalConfig;\n mcp: FabricMcpConfig;\n prewalk: FabricPrewalkConfig;\n agents: FabricAgentConfig;\n models: FabricModelsConfig;\n components: FabricComponentEntry[];\n capture: FabricToolCaptureConfig;\n ui: FabricUiConfig;\n compaction: FabricCompactionConfig;\n retention: FabricRetentionConfig;\n mesh: FabricMeshConfig;\n memory: FabricMemoryConfig;\n repairs: FabricRepairsConfig;\n schema: FabricSchemaConfig;\n speculation: FabricSpeculationConfig;\n codePreview: CodePreviewSettings;\n}\n\n/** Hard implementation maximum for any executor deadline. Policy ceilings\n * (executor.maxTimeoutMs) may be raised up to this value by administrators. */\nexport const MAX_EXECUTOR_TIMEOUT_MS = 24 * 3_600_000;\n\nexport const MIN_AGENT_TIMEOUT_MS = 1_000;\nconst DEFAULT_AGENT_TIMEOUT_MS = 3_600_000;\nexport const MAX_AGENT_TIMEOUT_MS = 24 * 3_600_000;\nexport const QUICKJS_MAX_MEMORY_LIMIT_BYTES = 0xffff_ffff;\nexport const MAX_EXECUTOR_MEMORY_LIMIT_BYTES = Math.max(\n 8 * 1024 * 1024,\n Math.min(Number.MAX_SAFE_INTEGER, Math.floor(os.totalmem())),\n);\n\nexport const maxExecutorMemoryLimitBytes = (runtime: FabricExecutorRuntime): number =>\n runtime === \"quickjs\"\n ? Math.min(QUICKJS_MAX_MEMORY_LIMIT_BYTES, MAX_EXECUTOR_MEMORY_LIMIT_BYTES)\n : MAX_EXECUTOR_MEMORY_LIMIT_BYTES;\n\nexport const DEFAULT_FABRIC_CONFIG: FabricConfig = {\n fullCodeMode: true,\n executor: {\n runtime: \"quickjs\",\n timeoutMs: 120_000,\n maxTimeoutMs: 900_000,\n hostCallTimeouts: {},\n memoryLimitBytes: 64 * 1024 * 1024,\n maxOutputChars: 50_000,\n maxNestedResultChars: 2_000_000,\n resultFormat: \"auto\",\n },\n approvals: {\n read: \"allow\",\n write: \"allow\",\n execute: \"allow\",\n network: \"allow\",\n agent: \"allow\",\n },\n mcp: {\n enabled: true,\n disableOAuth: true,\n allowDynamicServers: true,\n callTimeoutMs: 120_000,\n cache: {\n enabled: true,\n revalidate: \"changed\",\n revalidateBudgetMs: 60_000,\n },\n },\n prewalk: {\n mode: \"in-place\",\n alwaysRearm: false,\n compactOnReturn: true,\n detectShellWrites: true,\n },\n agents: {\n enabled: true,\n runner: \"pi\",\n transport: \"process\",\n claude: { binary: \"claude\" },\n veda: { binary: \"veda\", backend: \"agy\", persona: \"navigator-chat\" },\n thinking: DEFAULT_FABRIC_THINKING,\n maxConcurrent: 4,\n maxPerExecution: 100,\n maxDepth: 2,\n timeoutMs: DEFAULT_AGENT_TIMEOUT_MS,\n extensions: true,\n defaultTools: [\"read\", \"bash\", \"edit\", \"write\", \"grep\", \"find\", \"ls\"],\n retainRuns: false,\n notifyOnComplete: true,\n budgetUsd: 0,\n maxTokensPerChild: 0,\n sessionExport: true,\n sessionExportDir: \"\",\n },\n components: [],\n capture: {\n enabled: true,\n hideFromModel: true,\n keepVisible: [\"fabric_exec\"],\n defaultRisk: \"execute\",\n risks: {\n read: \"read\",\n grep: \"read\",\n find: \"read\",\n ls: \"read\",\n edit: \"write\",\n write: \"write\",\n bash: \"execute\",\n fovea_sketch: \"read\",\n fovea_focus: \"read\",\n fovea_dwell: \"read\",\n fovea_impact: \"read\",\n },\n },\n ui: {\n enabled: true,\n widget: \"auto\",\n maxRows: 6,\n refreshMs: 500,\n eventHistory: 80,\n haltOnEscape: true,\n showAgentToolPreview: true,\n toolDisplay: \"compact\",\n updateDebounceMs: 100,\n },\n compaction: {\n engine: \"fabric\",\n targetContextRatio: 0.65,\n thresholds: {},\n tokenThresholds: {},\n },\n retention: {\n orphanedTempRunMs: 6 * 60 * 60 * 1_000,\n oneShotRunMs: 24 * 60 * 60 * 1_000,\n actorRunArchiveMs: 7 * 24 * 60 * 60 * 1_000,\n },\n mesh: {\n enabled: true,\n actorScope: \"project\",\n maxEventBytes: 256 * 1024,\n maxReadEvents: 500,\n actorPollMs: 250,\n actorQueueLimit: 32,\n eventContextChars: 40_000,\n actorContextEntries: 14,\n },\n models: {\n aliases: {},\n },\n memory: {\n enabled: true,\n maxSessions: 500,\n maxEntryChars: 2_000,\n indexThinking: false,\n indexToolOutput: true,\n hotSessions: 50,\n digestTerms: 200,\n maxColdVocabularyBytes: 512 * 1024,\n maxColdCacheBytes: 1024 * 1024,\n maxSyncSessions: 10_000,\n maxSyncSourceBytes: 512 * 1024 * 1024,\n maxCacheCleanupFiles: 100_000,\n regexMaxPatternBytes: 1_024,\n regexMaxHaystackTerms: 20_000,\n regexMaxHaystackBytes: 2 * 1024 * 1024,\n regexTimeoutMs: 250,\n },\n repairs: {\n enabled: true,\n },\n schema: {\n mode: \"off\",\n certificateTtlMs: 30_000,\n maxFiles: 100,\n maxBytes: 10 * 1024 * 1024,\n trustedCommands: {},\n },\n speculation: {\n enabled: true,\n maxConcurrent: 4,\n maxEntries: 64,\n maxBufferBytes: 2 * 1024 * 1024,\n entryTtlMs: 180_000,\n mcpAllowlist: [],\n },\n codePreview: defaultCodePreviewSettings(),\n};\n\ninterface JsonObjectFile {\n document: Record<string, unknown>;\n source: string;\n}\n\nconst readJsonObjectFile = (filePath: string): JsonObjectFile | undefined => {\n try {\n const source = fs.readFileSync(filePath, \"utf8\");\n const parsed: unknown = JSON.parse(source);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"configuration root must be an object\");\n }\n return { document: parsed as Record<string, unknown>, source };\n } catch (error) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to read ${filePath}: ${message}`);\n }\n};\n\nconst readJsonObject = (filePath: string): Record<string, unknown> | undefined =>\n readJsonObjectFile(filePath)?.document;\n\nconst mergeObjects = (\n base: Record<string, unknown>,\n override: Record<string, unknown>,\n): Record<string, unknown> => {\n const merged = { ...base };\n for (const [key, value] of Object.entries(override)) {\n const baseValue = merged[key];\n if (\n typeof baseValue === \"object\" &&\n baseValue !== null &&\n !Array.isArray(baseValue) &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n merged[key] = mergeObjects(\n baseValue as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n } else {\n merged[key] = value;\n }\n }\n return merged;\n};\n\nconst approvalMode = (value: unknown, fallback: FabricApprovalMode): FabricApprovalMode =>\n value === \"allow\" || value === \"ask\" || value === \"auto\" || value === \"deny\"\n ? value\n : fallback;\n\nconst booleanValue = (value: unknown, fallback: boolean): boolean =>\n typeof value === \"boolean\" ? value : fallback;\n\nconst boundedInteger = (value: unknown, fallback: number, min: number, max: number): number =>\n typeof value === \"number\" && Number.isInteger(value)\n ? Math.max(min, Math.min(max, value))\n : fallback;\n\nconst boundedFloat = (value: unknown, fallback: number, min: number, max: number): number =>\n typeof value === \"number\" && Number.isFinite(value)\n ? Math.max(min, Math.min(max, value))\n : fallback;\n\nconst stringValue = (value: unknown): string | undefined =>\n typeof value === \"string\" && value.trim() ? value : undefined;\n\nconst runnerValue = (value: unknown, fallback: FabricAgentRunner): FabricAgentRunner =>\n value === \"pi\" || value === \"claude\" || value === \"veda\" ? value : fallback;\n\nconst prewalkModeValue = (\n value: unknown,\n fallback: FabricPrewalkMode,\n): FabricPrewalkMode =>\n value === \"in-place\" || value === \"trajectory\" ? value : fallback;\n\nconst transportValue = (\n value: unknown,\n fallback: FabricAgentTransport,\n): FabricAgentTransport =>\n value === \"auto\" ||\n value === \"process\" ||\n value === \"tmux\" ||\n value === \"screen\" ||\n value === \"localterm\" ||\n value === \"herdr\"\n ? value\n : fallback;\n\nconst thinkingValue = (value: unknown, fallback: FabricThinking): FabricThinking =>\n isFabricThinking(value) ? value : fallback;\n\nconst objectValue = (value: unknown): Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n\nconst widgetModeValue = (value: unknown, fallback: FabricUiWidgetMode): FabricUiWidgetMode =>\n value === \"auto\" || value === \"always\" || value === \"hidden\" ? value : fallback;\n\nconst toolDisplayModeValue = (\n value: unknown,\n fallback: FabricToolDisplayMode,\n): FabricToolDisplayMode => value === \"full\" || value === \"compact\" ? value : fallback;\n\nconst executorRuntimeValue = (\n value: unknown,\n fallback: FabricExecutorRuntime,\n): FabricExecutorRuntime =>\n value === \"quickjs\" || value === \"node-process\" || value === \"bun-process\" ? value : fallback;\n\nconst resultFormatValue = (\n value: unknown,\n fallback: FabricResultFormat,\n): FabricResultFormat =>\n value === \"auto\" || value === \"yaml\" || value === \"json\" || value === \"text\"\n ? value\n : fallback;\n\nconst compactionEngineValue = (\n value: unknown,\n fallback: FabricCompactionEngine,\n): FabricCompactionEngine =>\n value === \"pi\" || value === \"fabric\" ? value : fallback;\n\nconst actorScopeValue = (value: unknown, fallback: FabricActorScope): FabricActorScope =>\n value === \"project\" || value === \"session\" ? value : fallback;\n\nconst schemaModeValue = (value: unknown, fallback: FabricSchemaMode): FabricSchemaMode =>\n value === \"off\" || value === \"audit\" || value === \"enforce\" ? value : fallback;\n\nconst mcpRevalidatePolicyValue = (\n value: unknown,\n fallback: FabricMcpRevalidatePolicy,\n): FabricMcpRevalidatePolicy =>\n value === \"changed\" || value === \"all\" || value === \"off\" ? value : fallback;\n\nconst riskValue = (value: unknown, fallback: FabricRisk): FabricRisk =>\n value === \"read\" ||\n value === \"write\" ||\n value === \"execute\" ||\n value === \"network\" ||\n value === \"agent\"\n ? value\n : fallback;\n\nexport const normalizeFabricConfig = (input: Record<string, unknown>): FabricConfig => {\n const executor = objectValue(input.executor);\n const executorMaxTimeoutMs = boundedInteger(\n executor.maxTimeoutMs,\n DEFAULT_FABRIC_CONFIG.executor.maxTimeoutMs,\n 1_000,\n MAX_EXECUTOR_TIMEOUT_MS,\n );\n const approvals = objectValue(input.approvals);\n const mcp = objectValue(input.mcp);\n const mcpCache = objectValue(mcp.cache);\n const prewalk = objectValue(input.prewalk);\n const agents = objectValue(input.agents);\n const claude = objectValue(agents.claude);\n const veda = objectValue(agents.veda);\n const capture = objectValue(input.capture);\n const ui = objectValue(input.ui);\n const compaction = objectValue(input.compaction);\n const retention = objectValue(input.retention);\n const mesh = objectValue(input.mesh);\n const memory = objectValue(input.memory);\n const repairs = objectValue(input.repairs);\n const modelsSection = objectValue(input.models);\n const schema = objectValue(input.schema);\n const schemaMode = schemaModeValue(schema.mode, DEFAULT_FABRIC_CONFIG.schema.mode);\n const speculation = objectValue(input.speculation);\n const configuredExecutorRuntime = executorRuntimeValue(\n executor.runtime,\n DEFAULT_FABRIC_CONFIG.executor.runtime,\n );\n const executorRuntime = schemaMode === \"enforce\" ? \"quickjs\" : configuredExecutorRuntime;\n const configuredTools = Array.isArray(agents.defaultTools)\n ? agents.defaultTools.filter(\n (tool): tool is string => typeof tool === \"string\" && Boolean(tool),\n )\n : DEFAULT_FABRIC_CONFIG.agents.defaultTools;\n const approvalModel = stringValue(approvals.model);\n const configPath = stringValue(mcp.configPath);\n const meshRoot = stringValue(mesh.root);\n const memoryIndexDir = stringValue(memory.indexDir);\n const compactionThresholds = Object.fromEntries(\n Object.entries(objectValue(compaction.thresholds))\n .filter(([model, threshold]) =>\n model.includes(\"/\")\n && typeof threshold === \"number\"\n && Number.isFinite(threshold),\n )\n .map(([model, threshold]) => [\n model,\n clampCompactionRatioThreshold(threshold as number),\n ]),\n );\n const compactionTokenThresholds = Object.fromEntries(\n Object.entries(objectValue(compaction.tokenThresholds))\n .filter(([model, tokens]) =>\n model.includes(\"/\")\n && typeof tokens === \"number\"\n && Number.isFinite(tokens),\n )\n .map(([model, tokens]) => [\n model,\n clampCompactionTokenThreshold(tokens as number),\n ]),\n );\n const prewalkModel = stringValue(prewalk.model);\n const prewalkThinking = isFabricThinking(prewalk.thinking) ? prewalk.thinking : undefined;\n const agentModel = stringValue(agents.model);\n const claudeBinary = stringValue(claude.binary);\n const claudeModel = stringValue(claude.model);\n const vedaBinary = stringValue(veda.binary);\n const vedaBackend = stringValue(veda.backend);\n const vedaModel = stringValue(veda.model);\n const vedaPersona = stringValue(veda.persona);\n const agentThinking = thinkingValue(agents.thinking, DEFAULT_FABRIC_CONFIG.agents.thinking);\n const configuredComponents: FabricComponentEntry[] = Array.isArray(input.components)\n ? input.components.flatMap((raw) => {\n const componentEntry = objectValue(raw);\n const id = stringValue(componentEntry.id);\n const component = stringValue(componentEntry.component);\n if (!id || !component) return [];\n return [{\n id,\n component,\n ...(Object.prototype.hasOwnProperty.call(componentEntry, \"config\")\n ? { config: componentEntry.config }\n : {}),\n ...(typeof componentEntry.disabled === \"boolean\"\n ? { disabled: componentEntry.disabled }\n : {}),\n }];\n }).slice(0, 256)\n : DEFAULT_FABRIC_CONFIG.components;\n const configuredVisible = Array.isArray(capture.keepVisible)\n ? capture.keepVisible.filter(\n (name): name is string => typeof name === \"string\" && Boolean(name.trim()),\n )\n : DEFAULT_FABRIC_CONFIG.capture.keepVisible;\n const configuredRisks = {\n ...DEFAULT_FABRIC_CONFIG.capture.risks,\n ...objectValue(capture.risks),\n };\n const trustedCommands = Object.fromEntries(\n Object.entries(objectValue(schema.trustedCommands)).flatMap(([name, raw]) => {\n if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/.test(name)) return [];\n const command = objectValue(raw);\n const executable = stringValue(command.command);\n if (!executable) return [];\n const shell = booleanValue(command.shell, false);\n const args = !shell && Array.isArray(command.args)\n ? command.args.filter((arg): arg is string => typeof arg === \"string\").slice(0, 64)\n : [];\n return [[name, {\n command: executable,\n args,\n shell,\n timeoutMs: boundedInteger(command.timeoutMs, 30_000, 1, 300_000),\n } satisfies FabricSchemaTrustedCommand]];\n }),\n );\n const risks = Object.fromEntries(\n Object.entries(configuredRisks)\n .filter(([name]) => Boolean(name.trim()))\n .map(([name, risk]) => [name, riskValue(risk, DEFAULT_FABRIC_CONFIG.capture.defaultRisk)]),\n );\n\n return {\n fullCodeMode: booleanValue(input.fullCodeMode, DEFAULT_FABRIC_CONFIG.fullCodeMode),\n executor: {\n runtime: executorRuntime,\n maxTimeoutMs: boundedInteger(\n executor.maxTimeoutMs,\n DEFAULT_FABRIC_CONFIG.executor.maxTimeoutMs,\n 1_000,\n MAX_EXECUTOR_TIMEOUT_MS,\n ),\n hostCallTimeouts: Object.fromEntries(\n Object.entries(objectValue(executor.hostCallTimeouts))\n .filter(([ref, value]) =>\n typeof ref === \"string\" &&\n Boolean(ref.trim()) &&\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n value >= 1,\n )\n .map(([ref, value]) => [ref, boundedInteger(value, 1_000, 1_000, executorMaxTimeoutMs)]),\n ),\n timeoutMs: boundedInteger(\n executor.timeoutMs,\n DEFAULT_FABRIC_CONFIG.executor.timeoutMs,\n 1_000,\n executorMaxTimeoutMs,\n ),\n memoryLimitBytes: boundedInteger(\n executor.memoryLimitBytes,\n DEFAULT_FABRIC_CONFIG.executor.memoryLimitBytes,\n 8 * 1024 * 1024,\n maxExecutorMemoryLimitBytes(executorRuntime),\n ),\n maxOutputChars: boundedInteger(\n executor.maxOutputChars,\n DEFAULT_FABRIC_CONFIG.executor.maxOutputChars,\n 1_000,\n 1_000_000,\n ),\n maxNestedResultChars: boundedInteger(\n executor.maxNestedResultChars,\n DEFAULT_FABRIC_CONFIG.executor.maxNestedResultChars,\n 10_000,\n 20_000_000,\n ),\n resultFormat: resultFormatValue(\n executor.resultFormat,\n DEFAULT_FABRIC_CONFIG.executor.resultFormat,\n ),\n },\n approvals: {\n read: approvalMode(approvals.read, DEFAULT_FABRIC_CONFIG.approvals.read),\n write: approvalMode(approvals.write, DEFAULT_FABRIC_CONFIG.approvals.write),\n execute: approvalMode(approvals.execute, DEFAULT_FABRIC_CONFIG.approvals.execute),\n network: approvalMode(approvals.network, DEFAULT_FABRIC_CONFIG.approvals.network),\n agent: approvalMode(approvals.agent, DEFAULT_FABRIC_CONFIG.approvals.agent),\n ...(approvalModel ? { model: approvalModel } : {}),\n },\n mcp: {\n enabled: booleanValue(mcp.enabled, DEFAULT_FABRIC_CONFIG.mcp.enabled),\n ...(configPath ? { configPath } : {}),\n disableOAuth: booleanValue(mcp.disableOAuth, DEFAULT_FABRIC_CONFIG.mcp.disableOAuth),\n allowDynamicServers: booleanValue(\n mcp.allowDynamicServers,\n DEFAULT_FABRIC_CONFIG.mcp.allowDynamicServers,\n ),\n callTimeoutMs: boundedInteger(\n mcp.callTimeoutMs,\n DEFAULT_FABRIC_CONFIG.mcp.callTimeoutMs,\n 1_000,\n 900_000,\n ),\n cache: {\n enabled: booleanValue(mcpCache.enabled, DEFAULT_FABRIC_CONFIG.mcp.cache.enabled),\n revalidate: mcpRevalidatePolicyValue(\n mcpCache.revalidate,\n DEFAULT_FABRIC_CONFIG.mcp.cache.revalidate,\n ),\n revalidateBudgetMs: boundedInteger(\n mcpCache.revalidateBudgetMs,\n DEFAULT_FABRIC_CONFIG.mcp.cache.revalidateBudgetMs,\n 1_000,\n 600_000,\n ),\n },\n },\n prewalk: {\n ...(prewalk.enabled === false ? { enabled: false } : {}),\n mode: prewalkModeValue(prewalk.mode, DEFAULT_FABRIC_CONFIG.prewalk.mode),\n ...(prewalkModel ? { model: prewalkModel } : {}),\n ...(prewalkThinking ? { thinking: prewalkThinking } : {}),\n alwaysRearm: booleanValue(\n prewalk.alwaysRearm,\n DEFAULT_FABRIC_CONFIG.prewalk.alwaysRearm,\n ),\n compactOnReturn: booleanValue(\n prewalk.compactOnReturn,\n DEFAULT_FABRIC_CONFIG.prewalk.compactOnReturn,\n ),\n detectShellWrites: booleanValue(\n prewalk.detectShellWrites,\n DEFAULT_FABRIC_CONFIG.prewalk.detectShellWrites,\n ),\n },\n agents: {\n enabled: booleanValue(agents.enabled, DEFAULT_FABRIC_CONFIG.agents.enabled),\n runner: runnerValue(agents.runner, DEFAULT_FABRIC_CONFIG.agents.runner),\n transport: transportValue(agents.transport, DEFAULT_FABRIC_CONFIG.agents.transport),\n ...(agentModel ? { model: agentModel } : {}),\n claude: {\n binary: claudeBinary ?? DEFAULT_FABRIC_CONFIG.agents.claude.binary,\n ...(claudeModel ? { model: claudeModel } : {}),\n },\n veda: {\n binary: vedaBinary ?? DEFAULT_FABRIC_CONFIG.agents.veda.binary,\n backend: vedaBackend ?? DEFAULT_FABRIC_CONFIG.agents.veda.backend,\n ...(vedaModel ? { model: vedaModel } : {}),\n persona: vedaPersona ?? DEFAULT_FABRIC_CONFIG.agents.veda.persona,\n },\n thinking: agentThinking,\n maxConcurrent: boundedInteger(\n agents.maxConcurrent,\n DEFAULT_FABRIC_CONFIG.agents.maxConcurrent,\n 1,\n 32,\n ),\n maxPerExecution: boundedInteger(\n agents.maxPerExecution,\n DEFAULT_FABRIC_CONFIG.agents.maxPerExecution,\n 1,\n 1_000,\n ),\n maxDepth: boundedInteger(\n agents.maxDepth,\n DEFAULT_FABRIC_CONFIG.agents.maxDepth,\n 0,\n Number.MAX_SAFE_INTEGER,\n ),\n timeoutMs: boundedInteger(\n agents.timeoutMs,\n DEFAULT_FABRIC_CONFIG.agents.timeoutMs,\n MIN_AGENT_TIMEOUT_MS,\n MAX_AGENT_TIMEOUT_MS,\n ),\n extensions: booleanValue(agents.extensions, DEFAULT_FABRIC_CONFIG.agents.extensions),\n defaultTools: configuredTools,\n retainRuns: booleanValue(agents.retainRuns, DEFAULT_FABRIC_CONFIG.agents.retainRuns),\n notifyOnComplete: booleanValue(\n agents.notifyOnComplete,\n DEFAULT_FABRIC_CONFIG.agents.notifyOnComplete,\n ),\n budgetUsd: boundedFloat(\n agents.budgetUsd,\n DEFAULT_FABRIC_CONFIG.agents.budgetUsd,\n 0,\n 1_000_000,\n ),\n maxTokensPerChild: boundedInteger(\n agents.maxTokensPerChild,\n DEFAULT_FABRIC_CONFIG.agents.maxTokensPerChild,\n 0,\n 100_000_000,\n ),\n sessionExport: booleanValue(\n agents.sessionExport,\n DEFAULT_FABRIC_CONFIG.agents.sessionExport,\n ),\n sessionExportDir:\n typeof agents.sessionExportDir === \"string\"\n ? agents.sessionExportDir\n : DEFAULT_FABRIC_CONFIG.agents.sessionExportDir,\n },\n components: configuredComponents.map((entry) => structuredClone(entry)),\n capture: {\n enabled: booleanValue(capture.enabled, DEFAULT_FABRIC_CONFIG.capture.enabled),\n hideFromModel: booleanValue(\n capture.hideFromModel,\n DEFAULT_FABRIC_CONFIG.capture.hideFromModel,\n ),\n keepVisible: [...new Set(configuredVisible)],\n defaultRisk: riskValue(capture.defaultRisk, DEFAULT_FABRIC_CONFIG.capture.defaultRisk),\n risks,\n },\n ui: {\n enabled: booleanValue(ui.enabled, DEFAULT_FABRIC_CONFIG.ui.enabled),\n widget: widgetModeValue(ui.widget, DEFAULT_FABRIC_CONFIG.ui.widget),\n maxRows: boundedInteger(ui.maxRows, DEFAULT_FABRIC_CONFIG.ui.maxRows, 1, 20),\n refreshMs: boundedInteger(ui.refreshMs, DEFAULT_FABRIC_CONFIG.ui.refreshMs, 100, 10_000),\n eventHistory: boundedInteger(\n ui.eventHistory,\n DEFAULT_FABRIC_CONFIG.ui.eventHistory,\n 1,\n 500,\n ),\n haltOnEscape: booleanValue(ui.haltOnEscape, DEFAULT_FABRIC_CONFIG.ui.haltOnEscape),\n // Renamed from ui.showNestedToolCalls; the v2 migration rewrites persisted\n // files, and this fallback covers configs normalized without migration.\n showAgentToolPreview: booleanValue(\n ui.showAgentToolPreview ?? ui.showNestedToolCalls,\n DEFAULT_FABRIC_CONFIG.ui.showAgentToolPreview,\n ),\n toolDisplay: toolDisplayModeValue(\n ui.toolDisplay,\n DEFAULT_FABRIC_CONFIG.ui.toolDisplay,\n ),\n // Renamed from ui.nestedToolDebounceMs (v3): the window coalesces every\n // live fabric_exec card update \u2014 nested calls, progress, agent previews.\n updateDebounceMs: boundedInteger(\n ui.updateDebounceMs ?? ui.nestedToolDebounceMs,\n DEFAULT_FABRIC_CONFIG.ui.updateDebounceMs,\n 0,\n 2_000,\n ),\n },\n compaction: {\n engine: compactionEngineValue(compaction.engine, DEFAULT_FABRIC_CONFIG.compaction.engine),\n targetContextRatio: boundedFloat(\n compaction.targetContextRatio,\n DEFAULT_FABRIC_CONFIG.compaction.targetContextRatio,\n 0.25,\n 0.85,\n ),\n thresholds: compactionThresholds,\n tokenThresholds: compactionTokenThresholds,\n },\n retention: {\n orphanedTempRunMs: boundedInteger(\n retention.orphanedTempRunMs,\n DEFAULT_FABRIC_CONFIG.retention.orphanedTempRunMs,\n 60 * 60 * 1_000,\n 365 * 24 * 60 * 60 * 1_000,\n ),\n oneShotRunMs: boundedInteger(\n retention.oneShotRunMs,\n DEFAULT_FABRIC_CONFIG.retention.oneShotRunMs,\n 60 * 60 * 1_000,\n 365 * 24 * 60 * 60 * 1_000,\n ),\n actorRunArchiveMs: boundedInteger(\n retention.actorRunArchiveMs,\n DEFAULT_FABRIC_CONFIG.retention.actorRunArchiveMs,\n 60 * 60 * 1_000,\n 365 * 24 * 60 * 60 * 1_000,\n ),\n },\n mesh: {\n enabled: booleanValue(mesh.enabled, DEFAULT_FABRIC_CONFIG.mesh.enabled),\n ...(meshRoot ? { root: meshRoot } : {}),\n actorScope: actorScopeValue(mesh.actorScope, DEFAULT_FABRIC_CONFIG.mesh.actorScope),\n maxEventBytes: boundedInteger(\n mesh.maxEventBytes,\n DEFAULT_FABRIC_CONFIG.mesh.maxEventBytes,\n 1_024,\n 4 * 1024 * 1024,\n ),\n maxReadEvents: boundedInteger(\n mesh.maxReadEvents,\n DEFAULT_FABRIC_CONFIG.mesh.maxReadEvents,\n 1,\n 10_000,\n ),\n actorPollMs: boundedInteger(\n mesh.actorPollMs,\n DEFAULT_FABRIC_CONFIG.mesh.actorPollMs,\n 50,\n 10_000,\n ),\n actorQueueLimit: boundedInteger(\n mesh.actorQueueLimit,\n DEFAULT_FABRIC_CONFIG.mesh.actorQueueLimit,\n 1,\n 1_000,\n ),\n eventContextChars: boundedInteger(\n mesh.eventContextChars,\n DEFAULT_FABRIC_CONFIG.mesh.eventContextChars,\n 1_000,\n 1_000_000,\n ),\n actorContextEntries: boundedInteger(\n mesh.actorContextEntries,\n DEFAULT_FABRIC_CONFIG.mesh.actorContextEntries,\n 1,\n 100,\n ),\n },\n models: {\n aliases: normalizeModelAliases(modelsSection.aliases),\n },\n memory: {\n enabled: booleanValue(memory.enabled, DEFAULT_FABRIC_CONFIG.memory.enabled),\n ...(memoryIndexDir ? { indexDir: memoryIndexDir } : {}),\n maxSessions: boundedInteger(\n memory.maxSessions,\n DEFAULT_FABRIC_CONFIG.memory.maxSessions,\n 1,\n 100_000,\n ),\n maxEntryChars: boundedInteger(\n memory.maxEntryChars,\n DEFAULT_FABRIC_CONFIG.memory.maxEntryChars,\n 100,\n 1_000_000,\n ),\n indexThinking: booleanValue(\n memory.indexThinking,\n DEFAULT_FABRIC_CONFIG.memory.indexThinking ?? false,\n ),\n indexToolOutput: booleanValue(\n memory.indexToolOutput,\n DEFAULT_FABRIC_CONFIG.memory.indexToolOutput ?? true,\n ),\n hotSessions: boundedInteger(\n memory.hotSessions,\n DEFAULT_FABRIC_CONFIG.memory.hotSessions ?? 50,\n 0,\n 100_000,\n ),\n digestTerms: boundedInteger(\n memory.digestTerms,\n DEFAULT_FABRIC_CONFIG.memory.digestTerms ?? 200,\n 1,\n 10_000,\n ),\n maxColdVocabularyBytes: boundedInteger(\n memory.maxColdVocabularyBytes,\n DEFAULT_FABRIC_CONFIG.memory.maxColdVocabularyBytes ?? 512 * 1024,\n 2,\n 64 * 1024 * 1024,\n ),\n maxColdCacheBytes: boundedInteger(\n memory.maxColdCacheBytes,\n DEFAULT_FABRIC_CONFIG.memory.maxColdCacheBytes ?? 1024 * 1024,\n 512,\n 128 * 1024 * 1024,\n ),\n maxSyncSessions: boundedInteger(\n memory.maxSyncSessions,\n DEFAULT_FABRIC_CONFIG.memory.maxSyncSessions ?? 10_000,\n 1,\n 1_000_000,\n ),\n maxSyncSourceBytes: boundedInteger(\n memory.maxSyncSourceBytes,\n DEFAULT_FABRIC_CONFIG.memory.maxSyncSourceBytes ?? 512 * 1024 * 1024,\n 1_024,\n 8 * 1024 * 1024 * 1024,\n ),\n maxCacheCleanupFiles: boundedInteger(\n memory.maxCacheCleanupFiles,\n DEFAULT_FABRIC_CONFIG.memory.maxCacheCleanupFiles ?? 100_000,\n 1,\n 1_000_000,\n ),\n regexMaxPatternBytes: boundedInteger(\n memory.regexMaxPatternBytes,\n DEFAULT_FABRIC_CONFIG.memory.regexMaxPatternBytes ?? 1_024,\n 1,\n 64 * 1024,\n ),\n regexMaxHaystackTerms: boundedInteger(\n memory.regexMaxHaystackTerms,\n DEFAULT_FABRIC_CONFIG.memory.regexMaxHaystackTerms ?? 20_000,\n 1,\n 1_000_000,\n ),\n regexMaxHaystackBytes: boundedInteger(\n memory.regexMaxHaystackBytes,\n DEFAULT_FABRIC_CONFIG.memory.regexMaxHaystackBytes ?? 2 * 1024 * 1024,\n 1_024,\n 128 * 1024 * 1024,\n ),\n regexTimeoutMs: boundedInteger(\n memory.regexTimeoutMs,\n DEFAULT_FABRIC_CONFIG.memory.regexTimeoutMs ?? 250,\n 10,\n 10_000,\n ),\n },\n repairs: {\n enabled: booleanValue(repairs.enabled, DEFAULT_FABRIC_CONFIG.repairs.enabled),\n },\n schema: {\n mode: schemaMode,\n certificateTtlMs: boundedInteger(\n schema.certificateTtlMs,\n DEFAULT_FABRIC_CONFIG.schema.certificateTtlMs,\n 1_000,\n 10 * 60_000,\n ),\n maxFiles: boundedInteger(\n schema.maxFiles,\n DEFAULT_FABRIC_CONFIG.schema.maxFiles,\n 1,\n 1_000,\n ),\n maxBytes: boundedInteger(\n schema.maxBytes,\n DEFAULT_FABRIC_CONFIG.schema.maxBytes,\n 1_024,\n 100 * 1024 * 1024,\n ),\n trustedCommands,\n },\n speculation: {\n enabled: booleanValue(\n speculation.enabled,\n DEFAULT_FABRIC_CONFIG.speculation.enabled,\n ),\n maxConcurrent: boundedInteger(\n speculation.maxConcurrent,\n DEFAULT_FABRIC_CONFIG.speculation.maxConcurrent,\n 1,\n 32,\n ),\n maxEntries: boundedInteger(\n speculation.maxEntries,\n DEFAULT_FABRIC_CONFIG.speculation.maxEntries,\n 1,\n 1_024,\n ),\n maxBufferBytes: boundedInteger(\n speculation.maxBufferBytes,\n DEFAULT_FABRIC_CONFIG.speculation.maxBufferBytes,\n 64 * 1024,\n 64 * 1024 * 1024,\n ),\n entryTtlMs: boundedInteger(\n speculation.entryTtlMs,\n DEFAULT_FABRIC_CONFIG.speculation.entryTtlMs,\n 5_000,\n 30 * 60_000,\n ),\n mcpAllowlist: [\n ...new Set(\n (Array.isArray(speculation.mcpAllowlist) ? speculation.mcpAllowlist : [])\n .filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.trim().length > 0,\n )\n .map((entry) => entry.trim().slice(0, 256)),\n ),\n ].slice(0, 256),\n },\n codePreview: normalizeCodePreviewSettings(input.codePreview),\n };\n};\n\nexport const effectiveToolCaptureConfig = (\n config: Pick<FabricConfig, \"fullCodeMode\" | \"capture\"> & Partial<Pick<FabricConfig, \"schema\">>,\n): FabricToolCaptureConfig =>\n config.schema?.mode === \"enforce\"\n ? {\n ...config.capture,\n enabled: true,\n hideFromModel: true,\n keepVisible: [\"fabric_exec\"],\n risks: { ...config.capture.risks },\n }\n : config.fullCodeMode\n ? {\n ...config.capture,\n keepVisible: config.capture.keepVisible.filter(\n (name) => !PI_CORE_TOOL_NAME_SET.has(name),\n ),\n risks: { ...config.capture.risks },\n }\n : {\n ...config.capture,\n enabled: false,\n hideFromModel: false,\n keepVisible: [...config.capture.keepVisible],\n risks: { ...config.capture.risks },\n };\n\ninterface FabricConfigFilePlan {\n path: string;\n document: Record<string, unknown>;\n source: string;\n changed: boolean;\n}\n\nconst planConfigFile = (filePath: string): FabricConfigFilePlan | undefined => {\n const input = readJsonObjectFile(filePath);\n if (!input) return undefined;\n const migration = migrateFabricConfigDocument(input.document);\n return {\n path: filePath,\n document: migration.document,\n source: input.source,\n changed: migration.changed,\n };\n};\n\nconst writeJsonAtomic = (\n filePath: string,\n document: Record<string, unknown>,\n expectedSource?: string,\n): void => {\n const resolvedPath = fs.existsSync(filePath) ? fs.realpathSync(filePath) : filePath;\n const directory = path.dirname(resolvedPath);\n if (!fs.existsSync(directory)) fs.mkdirSync(directory, { recursive: true });\n const mode = fs.existsSync(resolvedPath) ? fs.statSync(resolvedPath).mode & 0o777 : 0o600;\n const temporaryPath = path.join(\n directory,\n `.${path.basename(resolvedPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`,\n );\n let descriptor: number | undefined;\n try {\n descriptor = fs.openSync(temporaryPath, \"wx\", mode);\n fs.writeFileSync(descriptor, `${JSON.stringify(document, null, 2)}\\n`, \"utf8\");\n fs.fsyncSync(descriptor);\n fs.closeSync(descriptor);\n descriptor = undefined;\n if (expectedSource !== undefined) {\n let currentSource: string;\n try {\n currentSource = fs.readFileSync(resolvedPath, \"utf8\");\n } catch (error) {\n throw new Error(`Fabric configuration changed while updating ${filePath}`, { cause: error });\n }\n if (currentSource !== expectedSource) {\n throw new Error(`Fabric configuration changed while updating ${filePath}`);\n }\n }\n renameAtomic(temporaryPath, resolvedPath);\n try {\n const directoryDescriptor = fs.openSync(directory, \"r\");\n try {\n fs.fsyncSync(directoryDescriptor);\n } finally {\n fs.closeSync(directoryDescriptor);\n }\n } catch (error) {\n const code = error instanceof Error && \"code\" in error ? error.code : undefined;\n if (code !== \"EINVAL\" && code !== \"ENOTSUP\" && code !== \"EISDIR\" && code !== \"EPERM\") throw error;\n }\n } catch (error) {\n if (descriptor !== undefined) fs.closeSync(descriptor);\n fs.rmSync(temporaryPath, { force: true });\n throw error;\n }\n};\n\nconst resolveFabricConfig = (\n options: {\n cwd: string;\n agentDir: string;\n },\n includeProject: boolean,\n): FabricConfig => {\n let merged = structuredClone(DEFAULT_FABRIC_CONFIG) as unknown as Record<string, unknown>;\n const plans = [\n planConfigFile(path.join(options.agentDir, \"fabric.json\")),\n ...(includeProject\n ? [planConfigFile(path.join(options.cwd, \".pi\", \"fabric.json\"))]\n : []),\n ].filter((plan): plan is FabricConfigFilePlan => plan !== undefined);\n for (const plan of plans) {\n if (plan.changed) writeJsonAtomic(plan.path, plan.document, plan.source);\n merged = mergeObjects(merged, plan.document);\n }\n const inheritedFullCodeMode = process.env.PI_FABRIC_FULL_CODE_MODE;\n if (inheritedFullCodeMode === \"true\" || inheritedFullCodeMode === \"false\") {\n merged.fullCodeMode = inheritedFullCodeMode === \"true\";\n }\n return normalizeFabricConfig(merged);\n};\n\nexport const loadFabricConfigForScope = (\n options: {\n cwd: string;\n agentDir: string;\n projectTrusted: boolean;\n },\n scope: FabricConfigScope,\n): FabricConfig => {\n if (scope === \"project\" && !options.projectTrusted) {\n throw new Error(\"Cannot load project Fabric configuration for an untrusted project\");\n }\n return resolveFabricConfig(options, scope === \"project\");\n};\n\nexport const loadFabricConfig = (options: {\n cwd: string;\n agentDir: string;\n projectTrusted: boolean;\n}): FabricConfig => {\n const config = resolveFabricConfig(options, options.projectTrusted);\n if (config.compaction.engine === \"fabric\") {\n process.env.PI_FABRIC_COMPACTION_ENGINE = \"fabric\";\n } else {\n delete process.env.PI_FABRIC_COMPACTION_ENGINE;\n }\n return config;\n};\n\nexport const saveFabricConfig = (\n options: {\n cwd: string;\n agentDir: string;\n projectTrusted: boolean;\n scope?: FabricConfigScope;\n },\n partial: Record<string, unknown>,\n): { scope: FabricConfigScope; path: string } => {\n const scope = options.scope ?? (options.projectTrusted ? \"project\" : \"global\");\n if (scope === \"project\" && !options.projectTrusted) {\n throw new Error(\"Cannot save project Fabric configuration for an untrusted project\");\n }\n const targetPath = scope === \"project\"\n ? path.join(options.cwd, \".pi\", \"fabric.json\")\n : path.join(options.agentDir, \"fabric.json\");\n if (Object.hasOwn(partial, \"configVersion\") || Object.hasOwn(partial, \"subagents\")) {\n throw new Error(\"Fabric configuration updates must use the current schema\");\n }\n const input = readJsonObjectFile(targetPath);\n const existing = migrateFabricConfigDocument(input?.document ?? {}).document;\n const merged = mergeObjects(existing, partial) as Record<string, unknown>;\n // Never stamp down: preserve version markers written by newer builds.\n merged.configVersion = Math.max(\n typeof merged.configVersion === \"number\" ? merged.configVersion : 0,\n CURRENT_FABRIC_CONFIG_VERSION,\n );\n writeJsonAtomic(targetPath, merged, input?.source);\n return { scope, path: targetPath };\n};\n", "const PROVIDER_MODEL_RE = /^[^\\s/]+\\/[^\\s/]+$/;\n\n/** Minimal model view needed for resolution; satisfied by pi Model entries. */\nexport interface FabricModelCandidate {\n provider: string;\n id: string;\n name?: string;\n}\n\nexport type FabricModelResolution =\n | { kind: \"resolved\"; model: FabricModelCandidate; via?: string }\n | { kind: \"already-active\"; model: FabricModelCandidate }\n | { kind: \"ambiguous\"; query: string; candidates: FabricModelCandidate[] }\n | { kind: \"not-found\"; query: string; tried?: string[] };\n\n/** Markers reported in `via` when an inexact selector is fuzzy-resolved. */\nexport const FUZZY_RESOLUTION_MARKERS = [\"closest\", \"recent\", \"latest\"] as const;\n\nconst modelKey = (model: FabricModelCandidate): string => `${model.provider}/${model.id}`;\n\nconst sameModel = (\n left: FabricModelCandidate,\n right: FabricModelCandidate | undefined,\n): boolean =>\n right !== undefined &&\n left.provider.toLowerCase() === right.provider.toLowerCase() &&\n left.id.toLowerCase() === right.id.toLowerCase();\n\n/**\n * Normalize raw `models.aliases` config into alias name \u2192 ordered targets.\n * String targets degrade to one-element fallback chains. Entries whose name,\n * target list, or any `provider/model` target string is malformed are\n * dropped entirely, matching the lenient fallback style of the other config\n * normalizers (no partial alias survives with a silently missing target).\n */\nexport const normalizeModelAliases = (input: unknown): Record<string, string[]> => {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) return {};\n const aliases: Record<string, string[]> = {};\n for (const [rawName, rawValue] of Object.entries(input as Record<string, unknown>)) {\n const name = rawName.trim();\n if (!name) continue;\n const values = typeof rawValue === \"string\" ? [rawValue] : rawValue;\n if (!Array.isArray(values) || values.length === 0) continue;\n const targets: string[] = [];\n let valid = true;\n for (const candidate of values) {\n if (typeof candidate !== \"string\") {\n valid = false;\n break;\n }\n const target = candidate.trim();\n if (!PROVIDER_MODEL_RE.test(target)) {\n valid = false;\n break;\n }\n if (!targets.includes(target)) targets.push(target);\n }\n if (valid && targets.length > 0) aliases[name] = targets;\n }\n return aliases;\n};\n\nconst FUZZY_MIN_QUERY_LENGTH = 4;\nconst FUZZY_LEVENSHTEIN_MIN_RATIO = 0.55;\n\n/**\n * Span covered when every character of `needle` appears in `haystack` in\n * order (first to last matched index), or Infinity when it does not. A tight\n * span keeps abbreviated selectors honest: \"gmni\" spans 6 chars in\n * \"gemini-2.5-pro\" but 10 in \"gpt-5-mini\", so only the former reads as the\n * same token with letters dropped.\n */\nconst subsequenceSpan = (needle: string, haystack: string): number => {\n let index = 0;\n let first = -1;\n let last = -1;\n for (let i = 0; i < haystack.length && index < needle.length; i += 1) {\n if (haystack[i] === needle[index]) {\n if (first === -1) first = i;\n last = i;\n index += 1;\n }\n }\n return index === needle.length ? last - first + 1 : Number.POSITIVE_INFINITY;\n};\n\n/** Normalized Levenshtein similarity in [0, 1]; 1 means identical. */\nconst levenshteinRatio = (left: string, right: string): number => {\n if (left === right) return 1;\n if (left.length === 0 || right.length === 0) return 0;\n let previous = Array.from({ length: right.length + 1 }, (_, column) => column);\n for (let i = 0; i < left.length; i += 1) {\n const current: number[] = [i + 1];\n for (let j = 0; j < right.length; j += 1) {\n current.push(Math.min(\n previous[j]! + 1,\n current[j]! + 1,\n previous[j]! + (left[i] === right[j] ? 0 : 1),\n ));\n }\n previous = current;\n }\n return 1 - previous[right.length]! / Math.max(left.length, right.length);\n};\n\n/**\n * Closeness score for an inexact selector against one candidate. Tiered so a\n * substring hit always outranks a subsequence hit, which always outranks a\n * typo-level Levenshtein resemblance; coverage bonuses reward selectors that\n * span most of the target id name. Zero means no resemblance at all.\n */\nconst closenessScore = (query: string, model: FabricModelCandidate): number => {\n const id = model.id.toLowerCase();\n const name = model.name?.toLowerCase();\n if (id.startsWith(query)) return 60 + (query.length / id.length) * 20;\n if (id.includes(query)) return 50 + (query.length / id.length) * 15;\n if (name?.startsWith(query) === true) return 45 + (query.length / name.length) * 15;\n if (name?.includes(query) === true) return 40 + (query.length / name.length) * 10;\n if (model.provider.toLowerCase().includes(query)) return 25;\n if (\n query.length >= 3 &&\n query[0] === id[0] &&\n subsequenceSpan(query, id) <= query.length + 2\n ) {\n return 18 + (query.length / id.length) * 6;\n }\n if (query.length >= FUZZY_MIN_QUERY_LENGTH) {\n const idRatio = levenshteinRatio(query, id);\n if (idRatio >= FUZZY_LEVENSHTEIN_MIN_RATIO) return 8 + idRatio * 10;\n if (name !== undefined) {\n const nameRatio = levenshteinRatio(query, name);\n if (nameRatio >= FUZZY_LEVENSHTEIN_MIN_RATIO) return 6 + nameRatio * 8;\n }\n }\n return 0;\n};\n\nexport type FabricModelUsage = Record<string, number>;\n\n/**\n * Pick the closest candidate for an inexact selector. Ranking is closeness\n * first; equal-closeness ties fall to the most recently used model (recency\n * timestamps such as pi-model-sort's extensions/pi-model-sort.json under the\n * agent dir, keyed by provider/id), then to the highest-sorting key, mirroring\n * pi's convention that the newest alias/versioned id sorts last.\n */\nconst pickClosestCandidate = (\n query: string,\n pool: readonly FabricModelCandidate[],\n lastUsed: FabricModelUsage | undefined,\n): { model: FabricModelCandidate; via: \"closest\" | \"recent\" | \"latest\" } | undefined => {\n const usage: FabricModelUsage = {};\n for (const [key, value] of Object.entries(lastUsed ?? {})) {\n usage[key.toLowerCase()] = value;\n }\n const recency = (model: FabricModelCandidate): number =>\n usage[`${model.provider}/${model.id}`.toLowerCase()] ?? 0;\n let best: FabricModelCandidate | undefined;\n let bestScore = 0;\n let tied = false;\n for (const model of pool) {\n const score = closenessScore(query, model);\n if (score <= 0) continue;\n if (best === undefined || score > bestScore) {\n best = model;\n bestScore = score;\n tied = false;\n continue;\n }\n if (score === bestScore) {\n tied = true;\n const bestRecent = recency(best);\n const nextRecent = recency(model);\n if (nextRecent > bestRecent || (nextRecent === bestRecent && modelKey(model) > modelKey(best))) {\n best = model;\n }\n }\n }\n if (best === undefined) return undefined;\n const runnersUp = pool.filter(\n (model) => model !== best && closenessScore(query, model) === bestScore,\n );\n const wonOnRecency = tied\n && runnersUp.some((model) => recency(model) !== recency(best));\n return {\n model: best,\n via: !tied ? \"closest\" : wonOnRecency ? \"recent\" : \"latest\",\n };\n};\n\n/**\n * Resolve a model selector against aliases and the available (authenticated)\n * registry. Order: alias lookup first so a configured name always wins, then\n * exact provider/id, exact id, then fuzzy selection. A lone partial match is\n * returned directly; broader candidate pools are ranked by closeness, with\n * equal-closeness ties falling to the most recently used model (when usage\n * timestamps are supplied, e.g. from pi-model-sort) and then to the\n * highest-sorting key, mirroring pi's newest-alias convention. Only a pool\n * with no resemblance at all stays not-found; `ambiguous` is retained for\n * defensive completeness but the ranker always produces a deterministic pick.\n */\nexport const resolveFabricModel = (\n query: string,\n options: {\n aliases: Record<string, string[]>;\n available: readonly FabricModelCandidate[];\n current?: FabricModelCandidate;\n provider?: string;\n lastUsed?: FabricModelUsage;\n },\n): FabricModelResolution => {\n const normalized = query.trim().toLowerCase();\n if (!normalized) return { kind: \"not-found\", query };\n const providerFilter = options.provider?.trim().toLowerCase();\n const available = providerFilter\n ? options.available.filter((model) => model.provider.toLowerCase() === providerFilter)\n : [...options.available];\n if (available.length === 0) return { kind: \"not-found\", query };\n\n const aliasKey = Object.keys(options.aliases).find(\n (key) => key.toLowerCase() === normalized,\n );\n const tried: string[] = [];\n if (aliasKey !== undefined) {\n const chain = options.aliases[aliasKey] ?? [];\n for (const target of chain) {\n tried.push(target);\n const separator = target.indexOf(\"/\");\n const provider = target.slice(0, separator);\n const id = target.slice(separator + 1);\n const match = available.find(\n (model) =>\n model.provider.toLowerCase() === provider.toLowerCase() &&\n model.id.toLowerCase() === id.toLowerCase(),\n );\n if (match) {\n return sameModel(match, options.current)\n ? { kind: \"already-active\", model: match }\n : { kind: \"resolved\", model: match, via: aliasKey };\n }\n }\n return { kind: \"not-found\", query, tried };\n }\n\n const exact = available.find((model) => modelKey(model).toLowerCase() === normalized)\n ?? available.find((model) => model.id.toLowerCase() === normalized);\n if (exact) {\n return sameModel(exact, options.current)\n ? { kind: \"already-active\", model: exact }\n : { kind: \"resolved\", model: exact };\n }\n\n const candidates = available.filter(\n (model) =>\n model.id.toLowerCase().includes(normalized) ||\n (model.name !== undefined && model.name.toLowerCase().includes(normalized)) ||\n model.provider.toLowerCase().includes(normalized),\n );\n if (candidates.length === 1) {\n const match = candidates[0];\n if (match === undefined) return { kind: \"not-found\", query };\n return sameModel(match, options.current)\n ? { kind: \"already-active\", model: match }\n : { kind: \"resolved\", model: match };\n }\n const pool = candidates.length > 1 ? candidates : available;\n const picked = pickClosestCandidate(normalized, pool, options.lastUsed);\n if (picked) {\n return sameModel(picked.model, options.current)\n ? { kind: \"already-active\", model: picked.model }\n : { kind: \"resolved\", model: picked.model, via: picked.via };\n }\n if (candidates.length > 1) return { kind: \"ambiguous\", query, candidates };\n return { kind: \"not-found\", query };\n};\n", "export const CURRENT_FABRIC_CONFIG_VERSION = 3;\n\nexport interface FabricConfigMigrationResult {\n document: Record<string, unknown>;\n fromVersion: number;\n toVersion: number;\n appliedVersions: number[];\n changed: boolean;\n // True when the document was written by a newer pi-fabric build. The document\n // is accepted as-is (newer builds only add semantics older builds can safely\n // ignore) and is never rewritten or version-stamped down.\n forwardCompatible: boolean;\n}\n\ninterface FabricConfigMigration {\n from: number;\n to: number;\n migrate(document: Readonly<Record<string, unknown>>): Record<string, unknown>;\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst mergeObjects = (\n base: Record<string, unknown>,\n override: Record<string, unknown>,\n): Record<string, unknown> => {\n const merged = { ...base };\n for (const [key, value] of Object.entries(override)) {\n const current = merged[key];\n merged[key] = isObject(current) && isObject(value) ? mergeObjects(current, value) : value;\n }\n return merged;\n};\n\nconst migrations: readonly FabricConfigMigration[] = [\n {\n from: 0,\n to: 1,\n migrate(document) {\n const migrated = { ...document };\n const legacy = migrated.subagents;\n const canonical = migrated.agents;\n if (legacy !== undefined) {\n if (canonical !== undefined && isObject(legacy) !== isObject(canonical)) {\n throw new Error(\n \"Fabric configuration cannot merge legacy subagents with a malformed agents section\",\n );\n }\n migrated.agents = isObject(legacy) && isObject(canonical)\n ? mergeObjects(legacy, canonical)\n : canonical ?? legacy;\n }\n delete migrated.subagents;\n return migrated;\n },\n },\n {\n from: 1,\n to: 2,\n migrate(document) {\n const migrated = { ...document };\n const ui = migrated.ui;\n if (isObject(ui) && Object.hasOwn(ui, \"showNestedToolCalls\")) {\n const renamed = { ...ui };\n if (!Object.hasOwn(renamed, \"showAgentToolPreview\")) {\n renamed.showAgentToolPreview = renamed.showNestedToolCalls;\n }\n delete renamed.showNestedToolCalls;\n migrated.ui = renamed;\n }\n return migrated;\n },\n },\n {\n from: 2,\n to: 3,\n migrate(document) {\n const migrated = { ...document };\n const ui = migrated.ui;\n if (isObject(ui) && Object.hasOwn(ui, \"nestedToolDebounceMs\")) {\n const renamed = { ...ui };\n if (!Object.hasOwn(renamed, \"updateDebounceMs\")) {\n renamed.updateDebounceMs = renamed.nestedToolDebounceMs;\n }\n delete renamed.nestedToolDebounceMs;\n migrated.ui = renamed;\n }\n return migrated;\n },\n },\n];\n\nconst configVersion = (document: Readonly<Record<string, unknown>>): number => {\n const value = document.configVersion;\n if (value === undefined) return 0;\n if (typeof value !== \"number\" || !Number.isInteger(value) || value < 0) {\n throw new Error(\"Fabric configuration configVersion must be a non-negative integer\");\n }\n return value;\n};\n\nexport const migrateFabricConfigDocument = (\n input: Readonly<Record<string, unknown>>,\n): FabricConfigMigrationResult => {\n const fromVersion = configVersion(input);\n if (fromVersion > CURRENT_FABRIC_CONFIG_VERSION) {\n // Written by a newer build: accept as-is instead of bricking the\n // extension. Legacy-shape checks (e.g. the removed subagents key) apply to\n // supported versions only \u2014 newer semantics are unknown here.\n return {\n document: structuredClone(input) as Record<string, unknown>,\n fromVersion,\n toVersion: fromVersion,\n appliedVersions: [],\n changed: false,\n forwardCompatible: true,\n };\n }\n let version = fromVersion;\n let document = structuredClone(input) as Record<string, unknown>;\n const appliedVersions: number[] = [];\n\n while (version < CURRENT_FABRIC_CONFIG_VERSION) {\n const migration = migrations.find((candidate) => candidate.from === version);\n if (!migration || migration.to !== version + 1) {\n throw new Error(`No Fabric configuration migration exists for version ${version}`);\n }\n document = migration.migrate(document);\n version = migration.to;\n document.configVersion = version;\n appliedVersions.push(version);\n }\n\n if (Object.hasOwn(document, \"subagents\")) {\n throw new Error(\"Current Fabric configuration contains removed key subagents\");\n }\n\n return {\n document,\n fromVersion,\n toVersion: version,\n appliedVersions,\n changed: appliedVersions.length > 0,\n forwardCompatible: false,\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["mergeObjects"]
7
+ }
@@ -141,6 +141,18 @@ var repairActionName = (declared, actionName) => {
141
141
  };
142
142
  var formatUnknownActionMessage = (ref, suggestions) => suggestions.length > 0 ? `Unknown Fabric action: ${ref} (did you mean: ${suggestions.slice(0, 3).join(", ")}?)` : `Unknown Fabric action: ${ref}`;
143
143
 
144
+ // src/repairs/active.ts
145
+ var active;
146
+ var setActiveRepairCompiler = (compiler) => {
147
+ active = compiler;
148
+ };
149
+ var clearActiveRepairCompiler = (compiler) => {
150
+ if (compiler && active === compiler) active = void 0;
151
+ };
152
+ var getActiveRepairCompiler = () => active;
153
+ var applyActiveArgRepairs = (ref, args, schema) => active?.applyArgs(ref, args, schema) ?? args;
154
+ var applyActiveActionName = (provider, actionName, declared) => active?.applyActionName(provider, actionName, declared) ?? actionName;
155
+
144
156
  // src/core/provider-bindings.ts
145
157
  import { randomUUID } from "node:crypto";
146
158
  var snapshot = (binding) => ({
@@ -505,6 +517,7 @@ var conflictBetween = (left, right) => {
505
517
  var unexpectedKeys = (schema, value) => {
506
518
  if (schema.type !== "object") return [];
507
519
  if (schema.additionalProperties !== false) return [];
520
+ if (schema.patternProperties !== void 0) return [];
508
521
  const properties = schema.properties;
509
522
  if (!properties) return [];
510
523
  return Object.keys(value).filter((key) => !(key in properties));
@@ -527,9 +540,51 @@ var validationMessage = (schema, value) => {
527
540
  return "Schema validator failed";
528
541
  }
529
542
  };
543
+ var declaredPropertyNames = (schema) => {
544
+ const properties = schema.properties;
545
+ return properties ? Object.keys(properties) : [];
546
+ };
547
+ var repairCatalogInput = (ref, schema, args) => {
548
+ const extras = unexpectedKeys(schema, args).sort();
549
+ const observedUnexpected = extras.length > 0 ? extras.join("\0") : void 0;
550
+ if (extras.length > 0) {
551
+ getActiveRepairCompiler()?.observeInvalidArgs(
552
+ ref,
553
+ args,
554
+ declaredPropertyNames(schema),
555
+ extras.join(","),
556
+ { countError: false, extraKeys: extras }
557
+ );
558
+ }
559
+ return {
560
+ args: applyActiveArgRepairs(ref, args, schema),
561
+ observedUnexpected
562
+ };
563
+ };
564
+ var validateCatalogArgs = (ref, schema, args, observedUnexpected) => {
565
+ const compiler = getActiveRepairCompiler();
566
+ const first = applyActiveArgRepairs(ref, args, schema);
567
+ const invalid = validationMessage(schema, first);
568
+ if (!invalid) return { args: first };
569
+ const extras = unexpectedKeys(schema, first).sort();
570
+ if (observedUnexpected === void 0 || extras.join("\0") !== observedUnexpected) {
571
+ compiler?.observeInvalidArgs(
572
+ ref,
573
+ first,
574
+ declaredPropertyNames(schema),
575
+ invalid,
576
+ { countError: false, extraKeys: extras }
577
+ );
578
+ }
579
+ const second = applyActiveArgRepairs(ref, first, schema);
580
+ const stillInvalid = validationMessage(schema, second);
581
+ if (stillInvalid) compiler?.recordInvocationError();
582
+ return stillInvalid ? { args: second, invalid: stillInvalid } : { args: second };
583
+ };
530
584
  var ActionRegistry = class {
531
585
  constructor(toolResultProxy) {
532
586
  this.toolResultProxy = toolResultProxy;
587
+ this.#providerBindings.subscribe(() => this.#speculation?.reset?.());
533
588
  }
534
589
  #providerBindings = new FabricProviderBindings();
535
590
  #activeEffects = /* @__PURE__ */ new Map();
@@ -879,18 +934,24 @@ var ActionRegistry = class {
879
934
  if (!provider.acquire) {
880
935
  throw new Error(`Fabric provider does not implement scoped acquisition: ${provider.name}`);
881
936
  }
937
+ const catalogInput = repairCatalogInput(action.ref, action.inputSchema, args);
882
938
  const preparedArgs = provider.prepareArguments ? await runAbortable(
883
939
  context.signal,
884
- () => provider.prepareArguments(providerActionName, args, context)
885
- ) : args;
940
+ () => provider.prepareArguments(providerActionName, catalogInput.args, context)
941
+ ) : catalogInput.args;
886
942
  if (typeof preparedArgs !== "object" || preparedArgs === null || Array.isArray(preparedArgs)) {
887
943
  throw new Error(`Argument preparation for ${ref} did not return an object`);
888
944
  }
889
- const invalid = validationMessage(action.inputSchema, preparedArgs);
890
- if (invalid) throw new Error(`Invalid arguments for ${ref}: ${invalid}`);
945
+ const catalog = validateCatalogArgs(
946
+ action.ref,
947
+ action.inputSchema,
948
+ preparedArgs,
949
+ catalogInput.observedUnexpected
950
+ );
951
+ if (catalog.invalid) throw new Error(`Invalid arguments for ${ref}: ${catalog.invalid}`);
891
952
  const acquired = await runAbortable(
892
953
  context.signal,
893
- () => provider.acquire(providerActionName, preparedArgs, context)
954
+ () => provider.acquire(providerActionName, catalog.args, context)
894
955
  );
895
956
  if (!acquired || typeof acquired.dispose !== "function") {
896
957
  throw new Error(`Scoped acquisition ${ref} did not return a disposer`);
@@ -952,25 +1013,33 @@ var ActionRegistry = class {
952
1013
  await runAbortable(context.signal, () => context.authorize(action));
953
1014
  }
954
1015
  failureStage = "prepare";
1016
+ const catalogInput = repairCatalogInput(action.ref, action.inputSchema, args);
955
1017
  const preparedArgs = provider.prepareArguments ? await runAbortable(
956
1018
  context.signal,
957
- () => provider.prepareArguments(providerActionName, args, context)
958
- ) : args;
1019
+ () => provider.prepareArguments(providerActionName, catalogInput.args, context)
1020
+ ) : catalogInput.args;
959
1021
  if (typeof preparedArgs !== "object" || preparedArgs === null || Array.isArray(preparedArgs)) {
960
1022
  throw new FabricTraceSafeError(`Argument preparation for ${ref} did not return an object`);
961
1023
  }
962
- traceOperation?.prepared(preparedArgs);
963
1024
  failureStage = "validate";
964
- const invalid = validationMessage(action.inputSchema, preparedArgs);
965
- if (invalid) throw new FabricTraceSafeError(`Invalid arguments for ${ref}: ${invalid}`);
1025
+ const catalog = validateCatalogArgs(
1026
+ action.ref,
1027
+ action.inputSchema,
1028
+ preparedArgs,
1029
+ catalogInput.observedUnexpected
1030
+ );
1031
+ traceOperation?.prepared(catalog.args);
1032
+ if (catalog.invalid) {
1033
+ throw new FabricTraceSafeError(`Invalid arguments for ${ref}: ${catalog.invalid}`);
1034
+ }
966
1035
  failureStage = "approve";
967
- await runAbortable(context.signal, () => context.approve(action, preparedArgs));
1036
+ await runAbortable(context.signal, () => context.approve(action, catalog.args));
968
1037
  failureStage = "invoke";
969
1038
  const nestedToolCallId = `${NESTED_TOOL_CALL_ID_PREFIX}${randomUUID2()}`;
970
1039
  const effect = action.effect;
971
- const effectConflicts = [...this.#activeEffects.values()].flatMap((active) => {
972
- const conflict = conflictBetween(effect, active.effect);
973
- return conflict ? [{ withRef: active.ref, ...conflict }] : [];
1040
+ const effectConflicts = [...this.#activeEffects.values()].flatMap((active2) => {
1041
+ const conflict = conflictBetween(effect, active2.effect);
1042
+ return conflict ? [{ withRef: active2.ref, ...conflict }] : [];
974
1043
  }).slice(0, 32);
975
1044
  if (effectConflicts.length > 0 && context.effectPolicy === "strict") {
976
1045
  failureStage = "guard";
@@ -982,7 +1051,7 @@ var ActionRegistry = class {
982
1051
  )).join("; ")}`
983
1052
  );
984
1053
  }
985
- const argsPreview = previewArgs(ref, preparedArgs);
1054
+ const argsPreview = previewArgs(ref, catalog.args);
986
1055
  const activeAudit = {
987
1056
  ref,
988
1057
  nestedToolCallId,
@@ -1010,7 +1079,7 @@ var ActionRegistry = class {
1010
1079
  let servedFromSpeculation = false;
1011
1080
  let providerValue;
1012
1081
  if (this.#speculation && effect.kind === "none") {
1013
- const served = await runAbortable(context.signal, () => this.#speculation.tryServe(context.parentToolCallId, ref, preparedArgs));
1082
+ const served = await runAbortable(context.signal, () => this.#speculation.tryServe(context.parentToolCallId, ref, catalog.args, binding.id));
1014
1083
  if (served.hit) {
1015
1084
  servedFromSpeculation = true;
1016
1085
  activeAudit.speculated = true;
@@ -1041,7 +1110,7 @@ var ActionRegistry = class {
1041
1110
  providerInvoked = true;
1042
1111
  providerValue = await runAbortable(
1043
1112
  context.signal,
1044
- () => provider.invoke(providerActionName, preparedArgs, {
1113
+ () => provider.invoke(providerActionName, catalog.args, {
1045
1114
  ...context,
1046
1115
  nestedToolCallId,
1047
1116
  update(message) {
@@ -1095,7 +1164,7 @@ var ActionRegistry = class {
1095
1164
  }
1096
1165
  const value = this.toolResultProxy ? await runAbortable(context.signal, () => this.toolResultProxy.proxy({
1097
1166
  action,
1098
- args: preparedArgs,
1167
+ args: catalog.args,
1099
1168
  toolCallId: nestedToolCallId,
1100
1169
  value: providerValue,
1101
1170
  ...context.signal ? { signal: context.signal } : {}
@@ -1159,25 +1228,38 @@ var ActionRegistry = class {
1159
1228
  async speculate(ref, args, context, replay) {
1160
1229
  if (!this.#speculationEligibility) return void 0;
1161
1230
  try {
1162
- const { binding, provider, actionName } = this.#parseRef(ref, context.capabilityView);
1231
+ const { binding, provider, actionName, expectedDescriptorHash } = this.#parseRef(
1232
+ ref,
1233
+ context.capabilityView
1234
+ );
1163
1235
  const descriptor = await runAbortable(context.signal, () => provider.describe(actionName, context));
1164
1236
  if (!descriptor) return void 0;
1165
1237
  const action = resolveDescriptor(provider, descriptor);
1238
+ if (expectedDescriptorHash && actionDescriptorHash(action) !== expectedDescriptorHash) {
1239
+ return void 0;
1240
+ }
1166
1241
  if (!this.#speculationEligibility(action)) return void 0;
1167
- const preparedArgs = provider.prepareArguments ? await runAbortable(context.signal, () => provider.prepareArguments(actionName, args, context)) : args;
1242
+ const catalogInput = applyActiveArgRepairs(action.ref, args, action.inputSchema);
1243
+ const preparedArgs = provider.prepareArguments ? await runAbortable(context.signal, () => provider.prepareArguments(actionName, catalogInput, context)) : catalogInput;
1168
1244
  if (typeof preparedArgs !== "object" || preparedArgs === null || Array.isArray(preparedArgs)) {
1169
1245
  return void 0;
1170
1246
  }
1171
- if (validationMessage(action.inputSchema, preparedArgs)) return void 0;
1247
+ const repairedArgs = applyActiveArgRepairs(
1248
+ action.ref,
1249
+ preparedArgs,
1250
+ action.inputSchema
1251
+ );
1252
+ if (validationMessage(action.inputSchema, repairedArgs)) return void 0;
1172
1253
  const nestedToolCallId = `${NESTED_TOOL_CALL_ID_PREFIX}spec-${randomUUID2()}`;
1173
1254
  return {
1174
- preparedArgs,
1255
+ preparedArgs: repairedArgs,
1256
+ bindingToken: binding.id,
1175
1257
  execute: async (signal) => {
1176
1258
  const endBindingInvocation = this.#providerBindings.beginInvocation(binding.id);
1177
1259
  try {
1178
1260
  return await runAbortable(
1179
1261
  signal,
1180
- () => provider.invoke(actionName, preparedArgs, {
1262
+ () => provider.invoke(actionName, repairedArgs, {
1181
1263
  ...context,
1182
1264
  signal,
1183
1265
  nestedToolCallId,
@@ -1312,13 +1394,34 @@ var ActionRegistry = class {
1312
1394
  context.signal,
1313
1395
  () => provider.describe(actionName, context)
1314
1396
  );
1315
- if (descriptor) return { action: resolveDescriptor(provider, descriptor), suggestions: [] };
1397
+ if (descriptor) {
1398
+ return {
1399
+ action: resolveDescriptor(provider, descriptor),
1400
+ suggestions: []
1401
+ };
1402
+ }
1316
1403
  if (!allowRepair) return { suggestions: [] };
1317
- const repair = repairActionName(
1318
- await this.#declaredActionNames(provider, context),
1319
- actionName
1320
- );
1404
+ const declared = await this.#declaredActionNames(provider, context);
1405
+ const catalogName = applyActiveActionName(provider.name, actionName, declared);
1406
+ if (catalogName !== actionName) {
1407
+ const catalogDescriptor = await runAbortable(
1408
+ context.signal,
1409
+ () => provider.describe(catalogName, context)
1410
+ );
1411
+ if (catalogDescriptor) {
1412
+ return {
1413
+ action: resolveDescriptor(provider, catalogDescriptor),
1414
+ suggestions: [],
1415
+ repairedFrom: actionName
1416
+ };
1417
+ }
1418
+ }
1419
+ const repair = repairActionName(declared, actionName);
1420
+ const compiler = getActiveRepairCompiler();
1321
1421
  if (repair.repaired !== void 0) {
1422
+ compiler?.observeUnknownAction(provider.name, actionName, declared, {
1423
+ countError: false
1424
+ });
1322
1425
  const repairedDescriptor = await runAbortable(
1323
1426
  context.signal,
1324
1427
  () => provider.describe(repair.repaired, context)
@@ -1330,6 +1433,9 @@ var ActionRegistry = class {
1330
1433
  repairedFrom: actionName
1331
1434
  };
1332
1435
  }
1436
+ compiler?.recordInvocationError();
1437
+ } else {
1438
+ compiler?.observeUnknownAction(provider.name, actionName, declared);
1333
1439
  }
1334
1440
  return {
1335
1441
  suggestions: repair.suggestions.map((name) => `${provider.name}.${name}`)
@@ -1379,7 +1485,11 @@ var ActionRegistry = class {
1379
1485
  };
1380
1486
 
1381
1487
  export {
1488
+ repairActionName,
1489
+ setActiveRepairCompiler,
1490
+ clearActiveRepairCompiler,
1491
+ getActiveRepairCompiler,
1382
1492
  NESTED_TOOL_CALL_ID_PREFIX,
1383
1493
  ActionRegistry
1384
1494
  };
1385
- //# sourceMappingURL=chunk-6ZKYQW33.js.map
1495
+ //# sourceMappingURL=chunk-3QPTSKDG.js.map