@code-yeongyu/senpi 2026.7.29-6 → 2026.7.30
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.
- package/CHANGELOG.md +29 -0
- package/dist/bun-global-launcher.d.ts +7 -0
- package/dist/bun-global-launcher.d.ts.map +1 -0
- package/dist/bun-global-launcher.js +21 -0
- package/dist/bun-global-launcher.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -6
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +31 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/btw/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/btw/index.js +1 -0
- package/dist/core/extensions/builtin/btw/index.js.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.js +10 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/auth-lane.js.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/errors.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/errors.js +14 -0
- package/dist/core/extensions/builtin/claude-agent-sdk/errors.js.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/options.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/options.js +2 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/options.js.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/tools.d.ts +3 -0
- package/dist/core/extensions/builtin/claude-agent-sdk/tools.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-agent-sdk/tools.js +19 -0
- package/dist/core/extensions/builtin/claude-agent-sdk/tools.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts +1 -2
- package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-engine.js +1 -8
- package/dist/core/extensions/builtin/config-reload/watch-engine.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts +15 -0
- package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts.map +1 -0
- package/dist/core/extensions/builtin/config-reload/watch-event-source.js +114 -0
- package/dist/core/extensions/builtin/config-reload/watch-event-source.js.map +1 -0
- package/dist/core/extensions/builtin/goal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/prompt.js +2 -1
- package/dist/core/extensions/builtin/goal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js +1 -1
- package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
- package/dist/core/extensions/builtin/rules/rules/project-root.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/rules/project-root.js +8 -1
- package/dist/core/extensions/builtin/rules/rules/project-root.js.map +1 -1
- package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
- package/dist/core/extensions/builtin/service-tier.js +20 -1
- package/dist/core/extensions/builtin/service-tier.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/normalize.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/normalize.js +14 -3
- package/dist/core/extensions/builtin/todotools/normalize.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +23 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/session-log.d.ts +12 -0
- package/dist/core/session-log.d.ts.map +1 -0
- package/dist/core/session-log.js +101 -0
- package/dist/core/session-log.js.map +1 -0
- package/dist/modes/interactive/compaction-queue-transfer.d.ts +6 -0
- package/dist/modes/interactive/compaction-queue-transfer.d.ts.map +1 -1
- package/dist/modes/interactive/compaction-queue-transfer.js +1 -1
- package/dist/modes/interactive/compaction-queue-transfer.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +24 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/normalize.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TodoOpEntry, TodoOperation, TodoPhase } from \"./todo-types.ts\";\n\nexport type TodoNormalization = {\n\tentry?: TodoOpEntry;\n\tcorrections: string[];\n\terror?: string;\n};\n\ntype Alias = \"init\" | \"append\";\n\nconst CONFLICTING_SHAPES =\n\t'conflicting shapes. Use {\"op\":\"init\",\"list\":[...]} to replace the list or {\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]} to add tasks.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isOperation(value: unknown): value is TodoOperation {\n\tswitch (value) {\n\t\tcase \"init\":\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"rm\":\n\t\tcase \"drop\":\n\t\tcase \"append\":\n\t\tcase \"view\":\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction strings(value: unknown): string[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst parsed: string[] = [];\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\") return undefined;\n\t\tparsed.push(item);\n\t}\n\treturn parsed;\n}\n\nfunction list(value: unknown): TodoOpEntry[\"list\"] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst parsed: NonNullable<TodoOpEntry[\"list\"]> = [];\n\tfor (const item of value) {\n\t\tif (!isRecord(item) || typeof item.phase !== \"string\") return undefined;\n\t\tconst items = strings(item.items);\n\t\tif (!items) return undefined;\n\t\tparsed.push({ phase: item.phase, items });\n\t}\n\treturn parsed;\n}\n\nfunction nonBlank(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\nfunction isBlank(value: unknown): boolean {\n\treturn typeof value === \"string\" && value.trim() === \"\";\n}\n\nfunction error(message: string): TodoNormalization {\n\treturn { corrections: [], error: message };\n}\n\nfunction aliasCorrection(alias: Alias, inferred: boolean): string {\n\tconst form =\n\t\talias === \"init\" ? '{\"op\":\"init\",\"items\":[...]}' : '{\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]}';\n\tif (inferred) {\n\t\treturn `[auto-corrected] \"op\" was missing; interpreted as \"${alias}\" because \"${alias}\" was provided as an items alias. Always pass op explicitly: ${form}`;\n\t}\n\treturn `[auto-corrected] \"${alias}\" was used as an items alias and folded into \"items\". Use: ${form}`;\n}\n\nfunction inferredCorrection(op: \"init\" | \"append\", reason: string, form: string): string {\n\treturn `[auto-corrected] \"op\" was missing; interpreted as \"${op}\" because ${reason}. Always pass op explicitly: ${form}`;\n}\n\nfunction hasTasks(phases: readonly TodoPhase[]): boolean {\n\treturn phases.some((phase) => phase.tasks.length > 0);\n}\n\nexport function normalizeTodoParams(\n\traw: Record<string, unknown>,\n\tcurrentPhases: readonly TodoPhase[],\n): TodoNormalization {\n\tconst rawOp = raw.op;\n\tif (rawOp === \"view\") return { entry: { op: \"view\" }, corrections: [] };\n\tif (rawOp !== undefined && !isOperation(rawOp)) return error('Invalid \"op\".');\n\n\tconst op = isOperation(rawOp) ? rawOp : undefined;\n\tconst task = nonBlank(raw.task);\n\tconst phase = nonBlank(raw.phase);\n\tif (op === \"start\" || op === \"done\" || op === \"drop\" || op === \"rm\") {\n\t\tif (isBlank(raw.task) && !phase) {\n\t\t\treturn error('Blank \"task\" — pass the exact task text, or omit the field entirely for a bulk operation.');\n\t\t}\n\t\tif (isBlank(raw.phase) && !task) {\n\t\t\treturn error('Blank \"phase\" — pass the exact phase text, or omit the field entirely for a bulk operation.');\n\t\t}\n\t}\n\n\tconst rawItems = strings(raw.items);\n\tconst aliases: Array<{ name: Alias; items: string[] }> = [];\n\tfor (const name of [\"init\", \"append\"] as const) {\n\t\tconst items = strings(raw[name]);\n\t\tif (items && items.length > 0) aliases.push({ name, items });\n\t}\n\tif (aliases.length > 1) return error(CONFLICTING_SHAPES);\n\tif (aliases.length === 1 && rawItems && rawItems.length > 0) return error(CONFLICTING_SHAPES);\n\n\tconst alias = aliases[0];\n\tlet effectiveItems = rawItems && rawItems.length > 0 ? rawItems : undefined;\n\tlet candidate: Alias | undefined;\n\tconst corrections: string[] = [];\n\tif (alias) {\n\t\tif (op && op !== alias.name) return error(CONFLICTING_SHAPES);\n\t\teffectiveItems = alias.items;\n\t\tcandidate = op ? undefined : alias.name;\n\t\tcorrections.push(aliasCorrection(alias.name, !op));\n\t}\n\n\tconst effectiveList = list(raw.list);\n\tconst hasList = Boolean(effectiveList && effectiveList.length > 0);\n\tconst hasItems = Boolean(effectiveItems && effectiveItems.length > 0);\n\tif (hasList && hasItems) return error(CONFLICTING_SHAPES);\n\n\tlet effectiveOp = op;\n\tif (!effectiveOp) {\n\t\tif (candidate) {\n\t\t\teffectiveOp = candidate;\n\t\t} else if (hasList) {\n\t\t\teffectiveOp = \"init\";\n\t\t\tcorrections.push(inferredCorrection(\"init\", '\"list\" was provided', '{\"op\":\"init\",\"list\":[...]}'));\n\t\t} else if (hasItems && phase) {\n\t\t\teffectiveOp = \"append\";\n\t\t\tcorrections.push(\n\t\t\t\tinferredCorrection(\n\t\t\t\t\t\"append\",\n\t\t\t\t\t'\"items\" and \"phase\" were provided',\n\t\t\t\t\t'{\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]}',\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (hasItems && !hasTasks(currentPhases)) {\n\t\t\teffectiveOp = \"init\";\n\t\t\tcorrections.push(\n\t\t\t\tinferredCorrection(\"init\", '\"items\" was provided to an empty todo list', '{\"op\":\"init\",\"items\":[...]}'),\n\t\t\t);\n\t\t} else if (hasItems) {\n\t\t\treturn error(\n\t\t\t\t'Missing \"op\": use {\"op\":\"init\",\"list\":[...]} to replace the list, or {\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]} to add tasks.',\n\t\t\t);\n\t\t} else {\n\t\t\treturn error('Missing \"op\". Example: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"...\"]}]}');\n\t\t}\n\t}\n\n\tswitch (effectiveOp) {\n\t\tcase \"init\": {\n\t\t\tif (task || (effectiveList && effectiveList.length === 0 && hasItems)) return error(CONFLICTING_SHAPES);\n\t\t\tconst entry: TodoOpEntry = { op: \"init\" };\n\t\t\tif (effectiveList) entry.list = effectiveList;\n\t\t\tif (effectiveItems) entry.items = effectiveItems;\n\t\t\tif (phase) entry.phase = phase;\n\t\t\treturn { entry, corrections };\n\t\t}\n\t\tcase \"start\":\n\t\t\tif (phase || hasList || hasItems) return error(CONFLICTING_SHAPES);\n\t\t\treturn { entry: task ? { op: \"start\", task } : { op: \"start\" }, corrections };\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\tcase \"rm\": {\n\t\t\tif (hasList || hasItems) return error(CONFLICTING_SHAPES);\n\t\t\tconst entry: TodoOpEntry = { op: effectiveOp };\n\t\t\tif (task) entry.task = task;\n\t\t\tif (phase) entry.phase = phase;\n\t\t\treturn { entry, corrections };\n\t\t}\n\t\tcase \"append\":\n\t\t\tif (task || hasList) return error(CONFLICTING_SHAPES);\n\t\t\treturn {\n\t\t\t\tentry: { op: \"append\", ...(phase ? { phase } : {}), ...(effectiveItems ? { items: effectiveItems } : {}) },\n\t\t\t\tcorrections,\n\t\t\t};\n\t\tcase \"view\":\n\t\t\treturn { entry: { op: \"view\" }, corrections: [] };\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/todotools/normalize.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TodoOpEntry, TodoOperation, TodoPhase } from \"./todo-types.ts\";\n\nexport type TodoNormalization = {\n\tentry?: TodoOpEntry;\n\tcorrections: string[];\n\terror?: string;\n};\n\ntype Alias = \"init\" | \"append\";\n\nconst CONFLICTING_SHAPES =\n\t'conflicting shapes. Use {\"op\":\"init\",\"list\":[...]} to replace the list or {\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]} to add tasks.';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isOperation(value: unknown): value is TodoOperation {\n\tswitch (value) {\n\t\tcase \"init\":\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"rm\":\n\t\tcase \"drop\":\n\t\tcase \"append\":\n\t\tcase \"view\":\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\nfunction strings(value: unknown): string[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst parsed: string[] = [];\n\tfor (const item of value) {\n\t\tif (typeof item !== \"string\") return undefined;\n\t\tparsed.push(item);\n\t}\n\treturn parsed;\n}\n\nfunction list(value: unknown): TodoOpEntry[\"list\"] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst parsed: NonNullable<TodoOpEntry[\"list\"]> = [];\n\tfor (const item of value) {\n\t\tif (!isRecord(item) || typeof item.phase !== \"string\") return undefined;\n\t\tconst items = strings(item.items);\n\t\tif (!items) return undefined;\n\t\tparsed.push({ phase: item.phase, items });\n\t}\n\treturn parsed;\n}\n\nfunction nonBlank(value: unknown): string | undefined {\n\treturn typeof value === \"string\" && value.trim() !== \"\" ? value : undefined;\n}\n\nfunction isBlank(value: unknown): boolean {\n\treturn typeof value === \"string\" && value.trim() === \"\";\n}\n\nfunction error(message: string): TodoNormalization {\n\treturn { corrections: [], error: message };\n}\n\nfunction aliasCorrection(alias: Alias, inferred: boolean): string {\n\tconst form =\n\t\talias === \"init\" ? '{\"op\":\"init\",\"items\":[...]}' : '{\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]}';\n\tif (inferred) {\n\t\treturn `[auto-corrected] \"op\" was missing; interpreted as \"${alias}\" because \"${alias}\" was provided as an items alias. Always pass op explicitly: ${form}`;\n\t}\n\treturn `[auto-corrected] \"${alias}\" was used as an items alias and folded into \"items\". Use: ${form}`;\n}\n\nfunction inferredCorrection(op: \"init\" | \"append\", reason: string, form: string): string {\n\treturn `[auto-corrected] \"op\" was missing; interpreted as \"${op}\" because ${reason}. Always pass op explicitly: ${form}`;\n}\n\nfunction hasTasks(phases: readonly TodoPhase[]): boolean {\n\treturn phases.some((phase) => phase.tasks.length > 0);\n}\n\nexport function normalizeTodoParams(\n\traw: Record<string, unknown>,\n\tcurrentPhases: readonly TodoPhase[],\n): TodoNormalization {\n\tconst rawOp = raw.op;\n\tif (rawOp === \"view\") return { entry: { op: \"view\" }, corrections: [] };\n\tif (rawOp !== undefined && !isOperation(rawOp)) return error('Invalid \"op\".');\n\n\tconst op = isOperation(rawOp) ? rawOp : undefined;\n\tconst task = nonBlank(raw.task);\n\tconst phase = nonBlank(raw.phase);\n\tconst corrections: string[] = [];\n\tif (op === \"start\" || op === \"done\" || op === \"drop\" || op === \"rm\") {\n\t\t// GPT-5.x-style function calling serializes every schema property and pads\n\t\t// omitted strings with \"\". When BOTH targets arrive blank on rm, the only\n\t\t// documented no-target rm form is a bulk clear, so the padding is\n\t\t// unambiguous — drop it instead of demanding a field omission the\n\t\t// serializer cannot express. Single-blank targets and the destructive-bulk\n\t\t// ops (start/done/drop) still error, so a truncated single target never\n\t\t// widens into a bulk action.\n\t\tif (op === \"rm\" && isBlank(raw.task) && isBlank(raw.phase)) {\n\t\t\tcorrections.push(\n\t\t\t\t'[auto-corrected] \"task\" and \"phase\" were both blank; treated as a bulk clear. ' +\n\t\t\t\t\t'For a single target pass the exact text: {\"op\":\"rm\",\"task\":\"<exact task content>\"}.',\n\t\t\t);\n\t\t} else if (isBlank(raw.task) && !phase) {\n\t\t\treturn error('Blank \"task\" — pass the exact task text, or omit the field entirely for a bulk operation.');\n\t\t} else if (isBlank(raw.phase) && !task) {\n\t\t\treturn error('Blank \"phase\" — pass the exact phase text, or omit the field entirely for a bulk operation.');\n\t\t}\n\t}\n\n\tconst rawItems = strings(raw.items);\n\tconst aliases: Array<{ name: Alias; items: string[] }> = [];\n\tfor (const name of [\"init\", \"append\"] as const) {\n\t\tconst items = strings(raw[name]);\n\t\tif (items && items.length > 0) aliases.push({ name, items });\n\t}\n\tif (aliases.length > 1) return error(CONFLICTING_SHAPES);\n\tif (aliases.length === 1 && rawItems && rawItems.length > 0) return error(CONFLICTING_SHAPES);\n\n\tconst alias = aliases[0];\n\tlet effectiveItems = rawItems && rawItems.length > 0 ? rawItems : undefined;\n\tlet candidate: Alias | undefined;\n\tif (alias) {\n\t\tif (op && op !== alias.name) return error(CONFLICTING_SHAPES);\n\t\teffectiveItems = alias.items;\n\t\tcandidate = op ? undefined : alias.name;\n\t\tcorrections.push(aliasCorrection(alias.name, !op));\n\t}\n\n\tconst effectiveList = list(raw.list);\n\tconst hasList = Boolean(effectiveList && effectiveList.length > 0);\n\tconst hasItems = Boolean(effectiveItems && effectiveItems.length > 0);\n\tif (hasList && hasItems) return error(CONFLICTING_SHAPES);\n\n\tlet effectiveOp = op;\n\tif (!effectiveOp) {\n\t\tif (candidate) {\n\t\t\teffectiveOp = candidate;\n\t\t} else if (hasList) {\n\t\t\teffectiveOp = \"init\";\n\t\t\tcorrections.push(inferredCorrection(\"init\", '\"list\" was provided', '{\"op\":\"init\",\"list\":[...]}'));\n\t\t} else if (hasItems && phase) {\n\t\t\teffectiveOp = \"append\";\n\t\t\tcorrections.push(\n\t\t\t\tinferredCorrection(\n\t\t\t\t\t\"append\",\n\t\t\t\t\t'\"items\" and \"phase\" were provided',\n\t\t\t\t\t'{\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]}',\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (hasItems && !hasTasks(currentPhases)) {\n\t\t\teffectiveOp = \"init\";\n\t\t\tcorrections.push(\n\t\t\t\tinferredCorrection(\"init\", '\"items\" was provided to an empty todo list', '{\"op\":\"init\",\"items\":[...]}'),\n\t\t\t);\n\t\t} else if (hasItems) {\n\t\t\treturn error(\n\t\t\t\t'Missing \"op\": use {\"op\":\"init\",\"list\":[...]} to replace the list, or {\"op\":\"append\",\"phase\":\"<active phase>\",\"items\":[...]} to add tasks.',\n\t\t\t);\n\t\t} else {\n\t\t\treturn error('Missing \"op\". Example: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"...\"]}]}');\n\t\t}\n\t}\n\n\tswitch (effectiveOp) {\n\t\tcase \"init\": {\n\t\t\tif (task || (effectiveList && effectiveList.length === 0 && hasItems)) return error(CONFLICTING_SHAPES);\n\t\t\tconst entry: TodoOpEntry = { op: \"init\" };\n\t\t\tif (effectiveList) entry.list = effectiveList;\n\t\t\tif (effectiveItems) entry.items = effectiveItems;\n\t\t\tif (phase) entry.phase = phase;\n\t\t\treturn { entry, corrections };\n\t\t}\n\t\tcase \"start\":\n\t\t\tif (phase || hasList || hasItems) return error(CONFLICTING_SHAPES);\n\t\t\treturn { entry: task ? { op: \"start\", task } : { op: \"start\" }, corrections };\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\tcase \"rm\": {\n\t\t\tif (hasList || hasItems) return error(CONFLICTING_SHAPES);\n\t\t\tconst entry: TodoOpEntry = { op: effectiveOp };\n\t\t\tif (task) entry.task = task;\n\t\t\tif (phase) entry.phase = phase;\n\t\t\treturn { entry, corrections };\n\t\t}\n\t\tcase \"append\":\n\t\t\tif (task || hasList) return error(CONFLICTING_SHAPES);\n\t\t\treturn {\n\t\t\t\tentry: { op: \"append\", ...(phase ? { phase } : {}), ...(effectiveItems ? { items: effectiveItems } : {}) },\n\t\t\t\tcorrections,\n\t\t\t};\n\t\tcase \"view\":\n\t\t\treturn { entry: { op: \"view\" }, corrections: [] };\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-config-value.d.ts","sourceRoot":"","sources":["../../src/core/resolve-config-value.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"resolve-config-value.d.ts","sourceRoot":"","sources":["../../src/core/resolve-config-value.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwHH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAGlE;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAEvG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAE7F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAQnG;AAsFD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAM3G;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAsBnH;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAUpC;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC3C,WAAW,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAOpC;AAED,kEAAkE;AAClE,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -6,6 +6,14 @@ import { execSync, spawnSync } from "child_process";
|
|
|
6
6
|
import { getShellConfig } from "../utils/shell.js";
|
|
7
7
|
// Cache for shell command results (persists for process lifetime)
|
|
8
8
|
const commandResultCache = new Map();
|
|
9
|
+
// Credential helper commands (auth brokers like `omp token …`) are cold-started on
|
|
10
|
+
// every invocation and can fail transiently — broker lock contention, a slow spawn
|
|
11
|
+
// under load, an OAuth refresh racing another process. A single failed attempt must
|
|
12
|
+
// not read as "credential gone": callers escalate an unresolved API key to a
|
|
13
|
+
// hard-error provider ejection, so one blip would kick the session off its model
|
|
14
|
+
// without any retry. Retry with a short backoff before giving up.
|
|
15
|
+
const COMMAND_EXECUTION_MAX_ATTEMPTS = 3;
|
|
16
|
+
const COMMAND_EXECUTION_BACKOFF_MS = [250, 1000];
|
|
9
17
|
const ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
10
18
|
const ENV_VAR_NAME_PREFIX_RE = /^[A-Za-z_][A-Za-z0-9_]*/;
|
|
11
19
|
function appendLiteral(parts, value) {
|
|
@@ -173,7 +181,10 @@ function executeWithDefaultShell(command, env) {
|
|
|
173
181
|
return undefined;
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
|
-
function
|
|
184
|
+
function sleepBlocking(milliseconds) {
|
|
185
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
|
|
186
|
+
}
|
|
187
|
+
function executeCommandOnce(commandConfig, env) {
|
|
177
188
|
const command = commandConfig.slice(1);
|
|
178
189
|
return process.platform === "win32"
|
|
179
190
|
? (() => {
|
|
@@ -182,6 +193,17 @@ function executeCommandUncached(commandConfig, env) {
|
|
|
182
193
|
})()
|
|
183
194
|
: executeWithDefaultShell(command, env);
|
|
184
195
|
}
|
|
196
|
+
function executeCommandUncached(commandConfig, env) {
|
|
197
|
+
for (let attempt = 0; attempt < COMMAND_EXECUTION_MAX_ATTEMPTS; attempt++) {
|
|
198
|
+
const value = executeCommandOnce(commandConfig, env);
|
|
199
|
+
if (value !== undefined)
|
|
200
|
+
return value;
|
|
201
|
+
const backoffMs = COMMAND_EXECUTION_BACKOFF_MS[attempt];
|
|
202
|
+
if (backoffMs !== undefined)
|
|
203
|
+
sleepBlocking(backoffMs);
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
185
207
|
function executeCommand(commandConfig) {
|
|
186
208
|
if (commandResultCache.has(commandConfig)) {
|
|
187
209
|
return commandResultCache.get(commandConfig);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-config-value.js","sourceRoot":"","sources":["../../src/core/resolve-config-value.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Resolve configuration values that may be shell commands, environment variables, or literals.\n * Used by auth-storage.ts and model-registry.ts.\n */\n\nimport { execSync, spawnSync } from \"child_process\";\nimport { getShellConfig } from \"../utils/shell.ts\";\n\n// Cache for shell command results (persists for process lifetime)\nconst commandResultCache = new Map<string, string | undefined>();\nconst ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;\nconst ENV_VAR_NAME_PREFIX_RE = /^[A-Za-z_][A-Za-z0-9_]*/;\n\ntype TemplatePart = { type: \"literal\"; value: string } | { type: \"env\"; name: string };\n\ntype ConfigValueReference = { type: \"command\"; config: string } | { type: \"template\"; parts: TemplatePart[] };\n\nfunction appendLiteral(parts: TemplatePart[], value: string): void {\n\tif (!value) return;\n\tconst previousPart = parts[parts.length - 1];\n\tif (previousPart?.type === \"literal\") {\n\t\tpreviousPart.value += value;\n\t\treturn;\n\t}\n\tparts.push({ type: \"literal\", value });\n}\n\nfunction parseConfigValueTemplate(config: string): TemplatePart[] {\n\tconst parts: TemplatePart[] = [];\n\tlet index = 0;\n\n\twhile (index < config.length) {\n\t\tconst dollarIndex = config.indexOf(\"$\", index);\n\t\tif (dollarIndex < 0) {\n\t\t\tappendLiteral(parts, config.slice(index));\n\t\t\tbreak;\n\t\t}\n\n\t\tappendLiteral(parts, config.slice(index, dollarIndex));\n\t\tconst nextChar = config[dollarIndex + 1];\n\n\t\tif (nextChar === \"$\" || nextChar === \"!\") {\n\t\t\tappendLiteral(parts, nextChar);\n\t\t\tindex = dollarIndex + 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nextChar === \"{\") {\n\t\t\tconst endIndex = config.indexOf(\"}\", dollarIndex + 2);\n\t\t\tif (endIndex < 0) {\n\t\t\t\tappendLiteral(parts, \"$\");\n\t\t\t\tindex = dollarIndex + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst name = config.slice(dollarIndex + 2, endIndex);\n\t\t\tif (ENV_VAR_NAME_RE.test(name)) {\n\t\t\t\tparts.push({ type: \"env\", name });\n\t\t\t} else {\n\t\t\t\tappendLiteral(parts, config.slice(dollarIndex, endIndex + 1));\n\t\t\t}\n\t\t\tindex = endIndex + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst match = config.slice(dollarIndex + 1).match(ENV_VAR_NAME_PREFIX_RE);\n\t\tif (match) {\n\t\t\tparts.push({ type: \"env\", name: match[0] });\n\t\t\tindex = dollarIndex + 1 + match[0].length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tappendLiteral(parts, \"$\");\n\t\tindex = dollarIndex + 1;\n\t}\n\n\treturn parts;\n}\n\nfunction parseConfigValueReference(config: string): ConfigValueReference {\n\tif (config.startsWith(\"!\")) {\n\t\treturn { type: \"command\", config };\n\t}\n\n\treturn { type: \"template\", parts: parseConfigValueTemplate(config) };\n}\n\nfunction resolveEnvConfigValue(name: string, env?: Record<string, string>): string | undefined {\n\treturn env?.[name] || process.env[name] || undefined;\n}\n\nfunction getTemplateEnvVarNames(parts: TemplatePart[]): string[] {\n\tconst names: string[] = [];\n\tfor (const part of parts) {\n\t\tif (part.type !== \"env\" || names.includes(part.name)) continue;\n\t\tnames.push(part.name);\n\t}\n\treturn names;\n}\n\nfunction resolveTemplate(parts: TemplatePart[], env?: Record<string, string>): string | undefined {\n\tlet resolved = \"\";\n\tfor (const part of parts) {\n\t\tif (part.type === \"literal\") {\n\t\t\tresolved += part.value;\n\t\t\tcontinue;\n\t\t}\n\t\tconst envValue = resolveEnvConfigValue(part.name, env);\n\t\tif (envValue === undefined) return undefined;\n\t\tresolved += envValue;\n\t}\n\treturn resolved;\n}\n\nexport function getConfigValueEnvVarName(config: string): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type !== \"template\") return undefined;\n\treturn reference.parts.length === 1 && reference.parts[0]?.type === \"env\" ? reference.parts[0].name : undefined;\n}\n\nexport function getConfigValueEnvVarNames(config: string): string[] {\n\tconst reference = parseConfigValueReference(config);\n\treturn reference.type === \"template\" ? getTemplateEnvVarNames(reference.parts) : [];\n}\n\nexport function getMissingConfigValueEnvVarNames(config: string, env?: Record<string, string>): string[] {\n\treturn getConfigValueEnvVarNames(config).filter((name) => resolveEnvConfigValue(name, env) === undefined);\n}\n\nexport function isCommandConfigValue(config: string): boolean {\n\treturn parseConfigValueReference(config).type === \"command\";\n}\n\nexport function isConfigValueConfigured(config: string, env?: Record<string, string>): boolean {\n\treturn getMissingConfigValueEnvVarNames(config, env).length === 0;\n}\n\n/**\n * Resolve a config value (API key, header value, etc.) to an actual value.\n * - If starts with \"!\", executes the rest as a shell command and uses stdout (cached)\n * - Interpolates \"$ENV_VAR\" or \"${ENV_VAR}\" references with the named environment variable\n * - In non-command values, \"$$\" escapes a literal \"$\" and \"$!\" escapes a literal \"!\"\n * - Otherwise treats the value as a literal\n */\nexport function resolveConfigValue(config: string, env?: Record<string, string>): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\t// Credentials can carry a per-session environment. Those commands must not\n\t\t// reuse a process-wide result produced under another session's environment.\n\t\treturn env === undefined ? executeCommand(reference.config) : executeCommandUncached(reference.config, env);\n\t}\n\treturn resolveTemplate(reference.parts, env);\n}\n\nfunction executeWithConfiguredShell(\n\tcommand: string,\n\tenv?: Record<string, string>,\n): { executed: boolean; value: string | undefined } {\n\ttry {\n\t\tconst { shell, args, commandTransport } = getShellConfig();\n\t\tconst commandFromStdin = commandTransport === \"stdin\";\n\t\tconst result = spawnSync(shell, commandFromStdin ? args : [...args, command], {\n\t\t\tencoding: \"utf-8\",\n\t\t\tinput: commandFromStdin ? command : undefined,\n\t\t\ttimeout: 10000,\n\t\t\tstdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"ignore\"],\n\t\t\tshell: false,\n\t\t\twindowsHide: true,\n\t\t\t...(env === undefined ? {} : { env: { ...process.env, ...env } }),\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tconst error = result.error as NodeJS.ErrnoException;\n\t\t\tif (error.code === \"ENOENT\") {\n\t\t\t\treturn { executed: false, value: undefined };\n\t\t\t}\n\t\t\treturn { executed: true, value: undefined };\n\t\t}\n\n\t\tif (result.status !== 0) {\n\t\t\treturn { executed: true, value: undefined };\n\t\t}\n\n\t\tconst value = (result.stdout ?? \"\").trim();\n\t\treturn { executed: true, value: value || undefined };\n\t} catch {\n\t\treturn { executed: false, value: undefined };\n\t}\n}\n\nfunction executeWithDefaultShell(command: string, env?: Record<string, string>): string | undefined {\n\ttry {\n\t\tconst output = execSync(command, {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 10000,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t...(env === undefined ? {} : { env: { ...process.env, ...env } }),\n\t\t});\n\t\treturn output.trim() || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction executeCommandUncached(commandConfig: string, env?: Record<string, string>): string | undefined {\n\tconst command = commandConfig.slice(1);\n\treturn process.platform === \"win32\"\n\t\t? (() => {\n\t\t\t\tconst configuredResult = executeWithConfiguredShell(command, env);\n\t\t\t\treturn configuredResult.executed ? configuredResult.value : executeWithDefaultShell(command, env);\n\t\t\t})()\n\t\t: executeWithDefaultShell(command, env);\n}\n\nfunction executeCommand(commandConfig: string): string | undefined {\n\tif (commandResultCache.has(commandConfig)) {\n\t\treturn commandResultCache.get(commandConfig);\n\t}\n\n\tconst result = executeCommandUncached(commandConfig);\n\tcommandResultCache.set(commandConfig, result);\n\treturn result;\n}\n\n/**\n * Resolve all header values using the same resolution logic as API keys.\n */\nexport function resolveConfigValueUncached(config: string, env?: Record<string, string>): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\treturn executeCommandUncached(reference.config, env);\n\t}\n\treturn resolveTemplate(reference.parts, env);\n}\n\nexport function resolveConfigValueOrThrow(config: string, description: string, env?: Record<string, string>): string {\n\tconst resolvedValue = resolveConfigValueUncached(config, env);\n\tif (resolvedValue !== undefined) {\n\t\treturn resolvedValue;\n\t}\n\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\tthrow new Error(`Failed to resolve ${description} from shell command: ${reference.config.slice(1)}`);\n\t}\n\n\tif (reference.type === \"template\") {\n\t\tconst missingEnvVars = getMissingConfigValueEnvVarNames(config, env);\n\t\tif (missingEnvVars.length === 1) {\n\t\t\tthrow new Error(`Failed to resolve ${description} from environment variable: ${missingEnvVars[0]}`);\n\t\t}\n\t\tif (missingEnvVars.length > 1) {\n\t\t\tthrow new Error(`Failed to resolve ${description} from environment variables: ${missingEnvVars.join(\", \")}`);\n\t\t}\n\t}\n\n\tthrow new Error(`Failed to resolve ${description}`);\n}\n\n/**\n * Resolve all header values using the same resolution logic as API keys.\n */\nexport function resolveHeaders(\n\theaders: Record<string, string> | undefined,\n\tenv?: Record<string, string>,\n): Record<string, string> | undefined {\n\tif (!headers) return undefined;\n\tconst resolved: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tconst resolvedValue = resolveConfigValue(value, env);\n\t\tif (resolvedValue) {\n\t\t\tresolved[key] = resolvedValue;\n\t\t}\n\t}\n\treturn Object.keys(resolved).length > 0 ? resolved : undefined;\n}\n\nexport function resolveHeadersOrThrow(\n\theaders: Record<string, string> | undefined,\n\tdescription: string,\n\tenv?: Record<string, string>,\n): Record<string, string> | undefined {\n\tif (!headers) return undefined;\n\tconst resolved: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tresolved[key] = resolveConfigValueOrThrow(value, `${description} header \"${key}\"`, env);\n\t}\n\treturn Object.keys(resolved).length > 0 ? resolved : undefined;\n}\n\n/** Clear the config value command cache. Exported for testing. */\nexport function clearConfigValueCache(): void {\n\tcommandResultCache.clear();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resolve-config-value.js","sourceRoot":"","sources":["../../src/core/resolve-config-value.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA8B,CAAC;AAEjE,mFAAmF;AACnF,mFAAmF;AACnF,oFAAoF;AACpF,6EAA6E;AAC7E,iFAAiF;AACjF,kEAAkE;AAClE,MAAM,8BAA8B,GAAG,CAAC,CAAC;AACzC,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,IAAI,CAAU,CAAC;AAC1D,MAAM,eAAe,GAAG,0BAA0B,CAAC;AACnD,MAAM,sBAAsB,GAAG,yBAAyB,CAAC;AAMzD,SAAS,aAAa,CAAC,KAAqB,EAAE,KAAa;IAC1D,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,YAAY,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;QACtC,YAAY,CAAC,KAAK,IAAI,KAAK,CAAC;QAC5B,OAAO;IACR,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,wBAAwB,CAAC,MAAc;IAC/C,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/C,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACrB,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1C,MAAM;QACP,CAAC;QAED,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAEzC,IAAI,QAAQ,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YAC1C,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC/B,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;YACxB,SAAS;QACV,CAAC;QAED,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;YACtD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBAClB,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC1B,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;gBACxB,SAAS;YACV,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;YACrD,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACP,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,KAAK,GAAG,QAAQ,GAAG,CAAC,CAAC;YACrB,SAAS;QACV,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1E,IAAI,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5C,KAAK,GAAG,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1C,SAAS;QACV,CAAC;QAED,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC1B,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAc;IAChD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,GAA4B;IACxE,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;AACtD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAqB;IACpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,KAAqB,EAAE,GAA4B;IAC3E,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC;YACvB,SAAS;QACV,CAAC;QACD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACvD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC7C,QAAQ,IAAI,QAAQ,CAAC;IACtB,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACtD,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACpD,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACjH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACvD,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,SAAS,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,sBAAsB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,gCAAgC,CAAC,MAAc,EAAE,GAA4B;IAC5F,OAAO,yBAAyB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC;AAC3G,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IAClD,OAAO,yBAAyB,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc,EAAE,GAA4B;IACnF,OAAO,gCAAgC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,GAA4B;IAC9E,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,2EAA2E;QAC3E,4EAA4E;QAC5E,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,eAAe,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,0BAA0B,CAClC,OAAe,EACf,GAA4B;IAE5B,IAAI,CAAC;QACJ,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,CAAC;QAC3D,MAAM,gBAAgB,GAAG,gBAAgB,KAAK,OAAO,CAAC;QACtD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE;YAC7E,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YAC7C,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YAC/D,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,IAAI;YACjB,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;SACjE,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM,CAAC,KAA8B,CAAC;YACpD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YAC9C,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC7C,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC9C,CAAC;AACF,CAAC;AAED,SAAS,uBAAuB,CAAC,OAAe,EAAE,GAA4B;IAC7E,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,EAAE;YAChC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;SACjE,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,aAAa,CAAC,YAAoB;IAC1C,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;AAC5E,CAAC;AAED,SAAS,kBAAkB,CAAC,aAAqB,EAAE,GAA4B;IAC9E,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO;QAClC,CAAC,CAAC,CAAC,GAAG,EAAE;YACN,MAAM,gBAAgB,GAAG,0BAA0B,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAClE,OAAO,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACnG,CAAC,CAAC,EAAE;QACL,CAAC,CAAC,uBAAuB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAAC,aAAqB,EAAE,GAA4B;IAClF,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,8BAA8B,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAG,kBAAkB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACtC,MAAM,SAAS,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,SAAS,KAAK,SAAS;YAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,aAAqB;IAC5C,IAAI,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAC3C,OAAO,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACrD,kBAAkB,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc,EAAE,GAA4B;IACtF,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,sBAAsB,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,eAAe,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,WAAmB,EAAE,GAA4B;IAC1G,MAAM,aAAa,GAAG,0BAA0B,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9D,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,aAAa,CAAC;IACtB,CAAC;IAED,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,wBAAwB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,gCAAgC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACrE,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,+BAA+B,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrG,CAAC;QACD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,gCAAgC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9G,CAAC;IACF,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC7B,OAA2C,EAC3C,GAA4B;IAE5B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,aAAa,EAAE,CAAC;YACnB,QAAQ,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;QAC/B,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,OAA2C,EAC3C,WAAmB,EACnB,GAA4B;IAE5B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,QAAQ,CAAC,GAAG,CAAC,GAAG,yBAAyB,CAAC,KAAK,EAAE,GAAG,WAAW,YAAY,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAChE,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,qBAAqB;IACpC,kBAAkB,CAAC,KAAK,EAAE,CAAC;AAC5B,CAAC","sourcesContent":["/**\n * Resolve configuration values that may be shell commands, environment variables, or literals.\n * Used by auth-storage.ts and model-registry.ts.\n */\n\nimport { execSync, spawnSync } from \"child_process\";\nimport { getShellConfig } from \"../utils/shell.ts\";\n\n// Cache for shell command results (persists for process lifetime)\nconst commandResultCache = new Map<string, string | undefined>();\n\n// Credential helper commands (auth brokers like `omp token …`) are cold-started on\n// every invocation and can fail transiently — broker lock contention, a slow spawn\n// under load, an OAuth refresh racing another process. A single failed attempt must\n// not read as \"credential gone\": callers escalate an unresolved API key to a\n// hard-error provider ejection, so one blip would kick the session off its model\n// without any retry. Retry with a short backoff before giving up.\nconst COMMAND_EXECUTION_MAX_ATTEMPTS = 3;\nconst COMMAND_EXECUTION_BACKOFF_MS = [250, 1000] as const;\nconst ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;\nconst ENV_VAR_NAME_PREFIX_RE = /^[A-Za-z_][A-Za-z0-9_]*/;\n\ntype TemplatePart = { type: \"literal\"; value: string } | { type: \"env\"; name: string };\n\ntype ConfigValueReference = { type: \"command\"; config: string } | { type: \"template\"; parts: TemplatePart[] };\n\nfunction appendLiteral(parts: TemplatePart[], value: string): void {\n\tif (!value) return;\n\tconst previousPart = parts[parts.length - 1];\n\tif (previousPart?.type === \"literal\") {\n\t\tpreviousPart.value += value;\n\t\treturn;\n\t}\n\tparts.push({ type: \"literal\", value });\n}\n\nfunction parseConfigValueTemplate(config: string): TemplatePart[] {\n\tconst parts: TemplatePart[] = [];\n\tlet index = 0;\n\n\twhile (index < config.length) {\n\t\tconst dollarIndex = config.indexOf(\"$\", index);\n\t\tif (dollarIndex < 0) {\n\t\t\tappendLiteral(parts, config.slice(index));\n\t\t\tbreak;\n\t\t}\n\n\t\tappendLiteral(parts, config.slice(index, dollarIndex));\n\t\tconst nextChar = config[dollarIndex + 1];\n\n\t\tif (nextChar === \"$\" || nextChar === \"!\") {\n\t\t\tappendLiteral(parts, nextChar);\n\t\t\tindex = dollarIndex + 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (nextChar === \"{\") {\n\t\t\tconst endIndex = config.indexOf(\"}\", dollarIndex + 2);\n\t\t\tif (endIndex < 0) {\n\t\t\t\tappendLiteral(parts, \"$\");\n\t\t\t\tindex = dollarIndex + 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst name = config.slice(dollarIndex + 2, endIndex);\n\t\t\tif (ENV_VAR_NAME_RE.test(name)) {\n\t\t\t\tparts.push({ type: \"env\", name });\n\t\t\t} else {\n\t\t\t\tappendLiteral(parts, config.slice(dollarIndex, endIndex + 1));\n\t\t\t}\n\t\t\tindex = endIndex + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst match = config.slice(dollarIndex + 1).match(ENV_VAR_NAME_PREFIX_RE);\n\t\tif (match) {\n\t\t\tparts.push({ type: \"env\", name: match[0] });\n\t\t\tindex = dollarIndex + 1 + match[0].length;\n\t\t\tcontinue;\n\t\t}\n\n\t\tappendLiteral(parts, \"$\");\n\t\tindex = dollarIndex + 1;\n\t}\n\n\treturn parts;\n}\n\nfunction parseConfigValueReference(config: string): ConfigValueReference {\n\tif (config.startsWith(\"!\")) {\n\t\treturn { type: \"command\", config };\n\t}\n\n\treturn { type: \"template\", parts: parseConfigValueTemplate(config) };\n}\n\nfunction resolveEnvConfigValue(name: string, env?: Record<string, string>): string | undefined {\n\treturn env?.[name] || process.env[name] || undefined;\n}\n\nfunction getTemplateEnvVarNames(parts: TemplatePart[]): string[] {\n\tconst names: string[] = [];\n\tfor (const part of parts) {\n\t\tif (part.type !== \"env\" || names.includes(part.name)) continue;\n\t\tnames.push(part.name);\n\t}\n\treturn names;\n}\n\nfunction resolveTemplate(parts: TemplatePart[], env?: Record<string, string>): string | undefined {\n\tlet resolved = \"\";\n\tfor (const part of parts) {\n\t\tif (part.type === \"literal\") {\n\t\t\tresolved += part.value;\n\t\t\tcontinue;\n\t\t}\n\t\tconst envValue = resolveEnvConfigValue(part.name, env);\n\t\tif (envValue === undefined) return undefined;\n\t\tresolved += envValue;\n\t}\n\treturn resolved;\n}\n\nexport function getConfigValueEnvVarName(config: string): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type !== \"template\") return undefined;\n\treturn reference.parts.length === 1 && reference.parts[0]?.type === \"env\" ? reference.parts[0].name : undefined;\n}\n\nexport function getConfigValueEnvVarNames(config: string): string[] {\n\tconst reference = parseConfigValueReference(config);\n\treturn reference.type === \"template\" ? getTemplateEnvVarNames(reference.parts) : [];\n}\n\nexport function getMissingConfigValueEnvVarNames(config: string, env?: Record<string, string>): string[] {\n\treturn getConfigValueEnvVarNames(config).filter((name) => resolveEnvConfigValue(name, env) === undefined);\n}\n\nexport function isCommandConfigValue(config: string): boolean {\n\treturn parseConfigValueReference(config).type === \"command\";\n}\n\nexport function isConfigValueConfigured(config: string, env?: Record<string, string>): boolean {\n\treturn getMissingConfigValueEnvVarNames(config, env).length === 0;\n}\n\n/**\n * Resolve a config value (API key, header value, etc.) to an actual value.\n * - If starts with \"!\", executes the rest as a shell command and uses stdout (cached)\n * - Interpolates \"$ENV_VAR\" or \"${ENV_VAR}\" references with the named environment variable\n * - In non-command values, \"$$\" escapes a literal \"$\" and \"$!\" escapes a literal \"!\"\n * - Otherwise treats the value as a literal\n */\nexport function resolveConfigValue(config: string, env?: Record<string, string>): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\t// Credentials can carry a per-session environment. Those commands must not\n\t\t// reuse a process-wide result produced under another session's environment.\n\t\treturn env === undefined ? executeCommand(reference.config) : executeCommandUncached(reference.config, env);\n\t}\n\treturn resolveTemplate(reference.parts, env);\n}\n\nfunction executeWithConfiguredShell(\n\tcommand: string,\n\tenv?: Record<string, string>,\n): { executed: boolean; value: string | undefined } {\n\ttry {\n\t\tconst { shell, args, commandTransport } = getShellConfig();\n\t\tconst commandFromStdin = commandTransport === \"stdin\";\n\t\tconst result = spawnSync(shell, commandFromStdin ? args : [...args, command], {\n\t\t\tencoding: \"utf-8\",\n\t\t\tinput: commandFromStdin ? command : undefined,\n\t\t\ttimeout: 10000,\n\t\t\tstdio: [commandFromStdin ? \"pipe\" : \"ignore\", \"pipe\", \"ignore\"],\n\t\t\tshell: false,\n\t\t\twindowsHide: true,\n\t\t\t...(env === undefined ? {} : { env: { ...process.env, ...env } }),\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tconst error = result.error as NodeJS.ErrnoException;\n\t\t\tif (error.code === \"ENOENT\") {\n\t\t\t\treturn { executed: false, value: undefined };\n\t\t\t}\n\t\t\treturn { executed: true, value: undefined };\n\t\t}\n\n\t\tif (result.status !== 0) {\n\t\t\treturn { executed: true, value: undefined };\n\t\t}\n\n\t\tconst value = (result.stdout ?? \"\").trim();\n\t\treturn { executed: true, value: value || undefined };\n\t} catch {\n\t\treturn { executed: false, value: undefined };\n\t}\n}\n\nfunction executeWithDefaultShell(command: string, env?: Record<string, string>): string | undefined {\n\ttry {\n\t\tconst output = execSync(command, {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 10000,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t...(env === undefined ? {} : { env: { ...process.env, ...env } }),\n\t\t});\n\t\treturn output.trim() || undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction sleepBlocking(milliseconds: number): void {\n\tAtomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);\n}\n\nfunction executeCommandOnce(commandConfig: string, env?: Record<string, string>): string | undefined {\n\tconst command = commandConfig.slice(1);\n\treturn process.platform === \"win32\"\n\t\t? (() => {\n\t\t\t\tconst configuredResult = executeWithConfiguredShell(command, env);\n\t\t\t\treturn configuredResult.executed ? configuredResult.value : executeWithDefaultShell(command, env);\n\t\t\t})()\n\t\t: executeWithDefaultShell(command, env);\n}\n\nfunction executeCommandUncached(commandConfig: string, env?: Record<string, string>): string | undefined {\n\tfor (let attempt = 0; attempt < COMMAND_EXECUTION_MAX_ATTEMPTS; attempt++) {\n\t\tconst value = executeCommandOnce(commandConfig, env);\n\t\tif (value !== undefined) return value;\n\t\tconst backoffMs = COMMAND_EXECUTION_BACKOFF_MS[attempt];\n\t\tif (backoffMs !== undefined) sleepBlocking(backoffMs);\n\t}\n\treturn undefined;\n}\n\nfunction executeCommand(commandConfig: string): string | undefined {\n\tif (commandResultCache.has(commandConfig)) {\n\t\treturn commandResultCache.get(commandConfig);\n\t}\n\n\tconst result = executeCommandUncached(commandConfig);\n\tcommandResultCache.set(commandConfig, result);\n\treturn result;\n}\n\n/**\n * Resolve all header values using the same resolution logic as API keys.\n */\nexport function resolveConfigValueUncached(config: string, env?: Record<string, string>): string | undefined {\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\treturn executeCommandUncached(reference.config, env);\n\t}\n\treturn resolveTemplate(reference.parts, env);\n}\n\nexport function resolveConfigValueOrThrow(config: string, description: string, env?: Record<string, string>): string {\n\tconst resolvedValue = resolveConfigValueUncached(config, env);\n\tif (resolvedValue !== undefined) {\n\t\treturn resolvedValue;\n\t}\n\n\tconst reference = parseConfigValueReference(config);\n\tif (reference.type === \"command\") {\n\t\tthrow new Error(`Failed to resolve ${description} from shell command: ${reference.config.slice(1)}`);\n\t}\n\n\tif (reference.type === \"template\") {\n\t\tconst missingEnvVars = getMissingConfigValueEnvVarNames(config, env);\n\t\tif (missingEnvVars.length === 1) {\n\t\t\tthrow new Error(`Failed to resolve ${description} from environment variable: ${missingEnvVars[0]}`);\n\t\t}\n\t\tif (missingEnvVars.length > 1) {\n\t\t\tthrow new Error(`Failed to resolve ${description} from environment variables: ${missingEnvVars.join(\", \")}`);\n\t\t}\n\t}\n\n\tthrow new Error(`Failed to resolve ${description}`);\n}\n\n/**\n * Resolve all header values using the same resolution logic as API keys.\n */\nexport function resolveHeaders(\n\theaders: Record<string, string> | undefined,\n\tenv?: Record<string, string>,\n): Record<string, string> | undefined {\n\tif (!headers) return undefined;\n\tconst resolved: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tconst resolvedValue = resolveConfigValue(value, env);\n\t\tif (resolvedValue) {\n\t\t\tresolved[key] = resolvedValue;\n\t\t}\n\t}\n\treturn Object.keys(resolved).length > 0 ? resolved : undefined;\n}\n\nexport function resolveHeadersOrThrow(\n\theaders: Record<string, string> | undefined,\n\tdescription: string,\n\tenv?: Record<string, string>,\n): Record<string, string> | undefined {\n\tif (!headers) return undefined;\n\tconst resolved: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tresolved[key] = resolveConfigValueOrThrow(value, `${description} header \"${key}\"`, env);\n\t}\n\treturn Object.keys(resolved).length > 0 ? resolved : undefined;\n}\n\n/** Clear the config value command cache. Exported for testing. */\nexport function clearConfigValueCache(): void {\n\tcommandResultCache.clear();\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SessionLogger {
|
|
2
|
+
debug(event: string, data?: Record<string, unknown>): void;
|
|
3
|
+
info(event: string, data?: Record<string, unknown>): void;
|
|
4
|
+
warn(event: string, data?: Record<string, unknown>): void;
|
|
5
|
+
}
|
|
6
|
+
export interface SessionLoggerOptions {
|
|
7
|
+
sink?: (line: string) => void;
|
|
8
|
+
mirrorToStderr?: boolean;
|
|
9
|
+
maxBytes?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function createSessionLogger(agentDir: string | undefined, options?: SessionLoggerOptions): SessionLogger;
|
|
12
|
+
//# sourceMappingURL=session-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-log.d.ts","sourceRoot":"","sources":["../../src/core/session-log.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC7B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA6BnH"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { chmodSync, closeSync, mkdirSync, openSync, renameSync, rmSync, statSync, writeSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
const DEFAULT_MAX_BYTES = 5 * 1024 * 1024;
|
|
4
|
+
const MAX_STRING_LENGTH = 200;
|
|
5
|
+
const DEBUG_PREFIX = "[senpi-session]";
|
|
6
|
+
const BLOCKED_KEY = /^(?:__proto__|constructor|prototype|headers?|env(?:ironment)?|authorization|credential(?:s)?|password|secret|token|api_?key|client_?secret)$/i;
|
|
7
|
+
const ALLOWED_DATA_KEY = /^(?:disposition|stage|error|mode|count|willRetry|deferAdmission|delivered|restored|cause|accepted|rejectionCause|reason|durationMs|kind|retryable|phase|op|bytes|generation|requestId|tokens|contextWindow|attempt|aborted)$/;
|
|
8
|
+
const SENSITIVE_TEXT = /((?:authorization\s*[:=]\s*(?:bearer|basic)\s+)|(?:bearer\s+)|(?:[?&](?:api[_-]?key|token|secret|password|auth(?:orization)?)=))[^\s&,"'}\]]+/gi;
|
|
9
|
+
export function createSessionLogger(agentDir, options = {}) {
|
|
10
|
+
if (typeof agentDir !== "string" || agentDir.length === 0) {
|
|
11
|
+
return { debug: () => { }, info: () => { }, warn: () => { } };
|
|
12
|
+
}
|
|
13
|
+
const filePath = join(agentDir, "logs", "session.log");
|
|
14
|
+
const maxBytes = validMaxBytes(options.maxBytes);
|
|
15
|
+
let reportedWriteFailure = false;
|
|
16
|
+
function log(level, event, data) {
|
|
17
|
+
try {
|
|
18
|
+
const line = formatLine(level, event, data);
|
|
19
|
+
options.sink?.(line);
|
|
20
|
+
writeLine(filePath, line, maxBytes);
|
|
21
|
+
if (options.mirrorToStderr ?? process.env.SENPI_SESSION_DEBUG === "1") {
|
|
22
|
+
console.error(DEBUG_PREFIX, line);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (!reportedWriteFailure) {
|
|
27
|
+
reportedWriteFailure = true;
|
|
28
|
+
console.error("Unable to write session log", error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
debug: (event, data) => log("debug", event, data),
|
|
34
|
+
info: (event, data) => log("info", event, data),
|
|
35
|
+
warn: (event, data) => log("warn", event, data),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function validMaxBytes(value) {
|
|
39
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : DEFAULT_MAX_BYTES;
|
|
40
|
+
}
|
|
41
|
+
function formatLine(level, event, data) {
|
|
42
|
+
const entry = {
|
|
43
|
+
ts: new Date().toISOString(),
|
|
44
|
+
level,
|
|
45
|
+
event: safeText(event),
|
|
46
|
+
};
|
|
47
|
+
if (data !== undefined) {
|
|
48
|
+
for (const [key, value] of Object.entries(data)) {
|
|
49
|
+
if (ALLOWED_DATA_KEY.test(key) && !BLOCKED_KEY.test(key)) {
|
|
50
|
+
const safeValue = serializeValue(value);
|
|
51
|
+
if (safeValue !== undefined)
|
|
52
|
+
entry[key] = safeValue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return JSON.stringify(entry);
|
|
57
|
+
}
|
|
58
|
+
function writeLine(filePath, line, maxBytes) {
|
|
59
|
+
mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });
|
|
60
|
+
const text = `${line}\n`;
|
|
61
|
+
if (fileExceedsCap(filePath, Buffer.byteLength(text), maxBytes)) {
|
|
62
|
+
rmSync(`${filePath}.1`, { force: true });
|
|
63
|
+
renameSync(filePath, `${filePath}.1`);
|
|
64
|
+
chmodSync(`${filePath}.1`, 0o600);
|
|
65
|
+
}
|
|
66
|
+
const descriptor = openSync(filePath, "a", 0o600);
|
|
67
|
+
try {
|
|
68
|
+
writeSync(descriptor, text);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
closeSync(descriptor);
|
|
72
|
+
}
|
|
73
|
+
chmodSync(filePath, 0o600);
|
|
74
|
+
}
|
|
75
|
+
function fileExceedsCap(filePath, incomingBytes, maxBytes) {
|
|
76
|
+
try {
|
|
77
|
+
return statSync(filePath).size + incomingBytes > maxBytes;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (isMissingFileError(error))
|
|
81
|
+
return false;
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function isMissingFileError(error) {
|
|
86
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
87
|
+
}
|
|
88
|
+
function serializeValue(value) {
|
|
89
|
+
if (typeof value === "string")
|
|
90
|
+
return safeText(value);
|
|
91
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null)
|
|
92
|
+
return value;
|
|
93
|
+
if (typeof value === "bigint")
|
|
94
|
+
return value.toString();
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
function safeText(value) {
|
|
98
|
+
const redacted = value.replace(SENSITIVE_TEXT, "$1[redacted]");
|
|
99
|
+
return redacted.length <= MAX_STRING_LENGTH ? redacted : `${redacted.slice(0, MAX_STRING_LENGTH - 3)}...`;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=session-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-log.js","sourceRoot":"","sources":["../../src/core/session-log.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, closeSync, mkdirSync, openSync, renameSync, rmSync, statSync, writeSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nconst DEFAULT_MAX_BYTES = 5 * 1024 * 1024;\nconst MAX_STRING_LENGTH = 200;\nconst DEBUG_PREFIX = \"[senpi-session]\";\nconst BLOCKED_KEY =\n\t/^(?:__proto__|constructor|prototype|headers?|env(?:ironment)?|authorization|credential(?:s)?|password|secret|token|api_?key|client_?secret)$/i;\nconst ALLOWED_DATA_KEY =\n\t/^(?:disposition|stage|error|mode|count|willRetry|deferAdmission|delivered|restored|cause|accepted|rejectionCause|reason|durationMs|kind|retryable|phase|op|bytes|generation|requestId|tokens|contextWindow|attempt|aborted)$/;\nconst SENSITIVE_TEXT =\n\t/((?:authorization\\s*[:=]\\s*(?:bearer|basic)\\s+)|(?:bearer\\s+)|(?:[?&](?:api[_-]?key|token|secret|password|auth(?:orization)?)=))[^\\s&,\"'}\\]]+/gi;\n\nexport interface SessionLogger {\n\tdebug(event: string, data?: Record<string, unknown>): void;\n\tinfo(event: string, data?: Record<string, unknown>): void;\n\twarn(event: string, data?: Record<string, unknown>): void;\n}\n\nexport interface SessionLoggerOptions {\n\tsink?: (line: string) => void;\n\tmirrorToStderr?: boolean;\n\tmaxBytes?: number;\n}\n\nexport function createSessionLogger(agentDir: string | undefined, options: SessionLoggerOptions = {}): SessionLogger {\n\tif (typeof agentDir !== \"string\" || agentDir.length === 0) {\n\t\treturn { debug: () => {}, info: () => {}, warn: () => {} };\n\t}\n\tconst filePath = join(agentDir, \"logs\", \"session.log\");\n\tconst maxBytes = validMaxBytes(options.maxBytes);\n\tlet reportedWriteFailure = false;\n\n\tfunction log(level: \"debug\" | \"info\" | \"warn\", event: string, data?: Record<string, unknown>): void {\n\t\ttry {\n\t\t\tconst line = formatLine(level, event, data);\n\t\t\toptions.sink?.(line);\n\t\t\twriteLine(filePath, line, maxBytes);\n\t\t\tif (options.mirrorToStderr ?? process.env.SENPI_SESSION_DEBUG === \"1\") {\n\t\t\t\tconsole.error(DEBUG_PREFIX, line);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!reportedWriteFailure) {\n\t\t\t\treportedWriteFailure = true;\n\t\t\t\tconsole.error(\"Unable to write session log\", error);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tdebug: (event, data) => log(\"debug\", event, data),\n\t\tinfo: (event, data) => log(\"info\", event, data),\n\t\twarn: (event, data) => log(\"warn\", event, data),\n\t};\n}\n\nfunction validMaxBytes(value: number | undefined): number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0 ? Math.floor(value) : DEFAULT_MAX_BYTES;\n}\n\nfunction formatLine(\n\tlevel: \"debug\" | \"info\" | \"warn\",\n\tevent: string,\n\tdata: Record<string, unknown> | undefined,\n): string {\n\tconst entry: Record<string, unknown> = {\n\t\tts: new Date().toISOString(),\n\t\tlevel,\n\t\tevent: safeText(event),\n\t};\n\tif (data !== undefined) {\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (ALLOWED_DATA_KEY.test(key) && !BLOCKED_KEY.test(key)) {\n\t\t\t\tconst safeValue = serializeValue(value);\n\t\t\t\tif (safeValue !== undefined) entry[key] = safeValue;\n\t\t\t}\n\t\t}\n\t}\n\treturn JSON.stringify(entry);\n}\n\nfunction writeLine(filePath: string, line: string, maxBytes: number): void {\n\tmkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });\n\tconst text = `${line}\\n`;\n\tif (fileExceedsCap(filePath, Buffer.byteLength(text), maxBytes)) {\n\t\trmSync(`${filePath}.1`, { force: true });\n\t\trenameSync(filePath, `${filePath}.1`);\n\t\tchmodSync(`${filePath}.1`, 0o600);\n\t}\n\tconst descriptor = openSync(filePath, \"a\", 0o600);\n\ttry {\n\t\twriteSync(descriptor, text);\n\t} finally {\n\t\tcloseSync(descriptor);\n\t}\n\tchmodSync(filePath, 0o600);\n}\n\nfunction fileExceedsCap(filePath: string, incomingBytes: number, maxBytes: number): boolean {\n\ttry {\n\t\treturn statSync(filePath).size + incomingBytes > maxBytes;\n\t} catch (error) {\n\t\tif (isMissingFileError(error)) return false;\n\t\tthrow error;\n\t}\n}\n\nfunction isMissingFileError(error: unknown): boolean {\n\treturn typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n\nfunction serializeValue(value: unknown): unknown {\n\tif (typeof value === \"string\") return safeText(value);\n\tif (typeof value === \"number\" || typeof value === \"boolean\" || value === null) return value;\n\tif (typeof value === \"bigint\") return value.toString();\n\treturn undefined;\n}\n\nfunction safeText(value: string): string {\n\tconst redacted = value.replace(SENSITIVE_TEXT, \"$1[redacted]\");\n\treturn redacted.length <= MAX_STRING_LENGTH ? redacted : `${redacted.slice(0, MAX_STRING_LENGTH - 3)}...`;\n}\n"]}
|
|
@@ -5,6 +5,12 @@ export type CompactionQueuedMessage = {
|
|
|
5
5
|
export type PromptDisposition = "handled" | "queued" | "started";
|
|
6
6
|
type TransferOptions = {
|
|
7
7
|
readonly willRetry?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Deliver prompts through the native steer/followUp queues instead of
|
|
10
|
+
* prompt admission. Used after an unsuccessful compaction so queued input
|
|
11
|
+
* is never dropped and never force-admitted into an over-budget context.
|
|
12
|
+
*/
|
|
13
|
+
readonly deferAdmission?: boolean;
|
|
8
14
|
};
|
|
9
15
|
type TransferDependencies = {
|
|
10
16
|
readonly takeBatch: () => CompactionQueuedMessage[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction-queue-transfer.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/compaction-queue-transfer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjE,KAAK,eAAe,GAAG;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"compaction-queue-transfer.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/compaction-queue-transfer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjE,KAAK,eAAe,GAAG;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,uBAAuB,EAAE,CAAC;IACpD,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC;IACvE,QAAQ,CAAC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,KAAK,MAAM,CAAC;IACtF,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC;IAClE,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9F,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3E,CAAC;AAEF,wBAAsB,uBAAuB,CAC5C,YAAY,EAAE,oBAAoB,EAClC,OAAO,GAAE,eAAoB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED,wBAAgB,wBAAwB,CACvC,WAAW,EAAE,CACZ,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,EAC3C,iBAAiB,EAAE,CAAC,WAAW,EAAE,iBAAiB,KAAK,IAAI,KACvD,OAAO,CAAC,IAAI,CAAC,EAClB,2BAA2B,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACnD,OAAO,CAAC,iBAAiB,CAAC,CAsC5B"}
|
|
@@ -4,7 +4,7 @@ export async function transferCompactionQueue(dependencies, options = {}) {
|
|
|
4
4
|
return;
|
|
5
5
|
let acceptedCount = 0;
|
|
6
6
|
try {
|
|
7
|
-
if (options.willRetry) {
|
|
7
|
+
if (options.willRetry || options.deferAdmission) {
|
|
8
8
|
for (const message of batch) {
|
|
9
9
|
if (dependencies.isCommand(message)) {
|
|
10
10
|
await dependencies.deliverCommand(message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction-queue-transfer.js","sourceRoot":"","sources":["../../../src/modes/interactive/compaction-queue-transfer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compaction-queue-transfer.js","sourceRoot":"","sources":["../../../src/modes/interactive/compaction-queue-transfer.ts"],"names":[],"mappings":"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","sourcesContent":["export type CompactionQueuedMessage = {\n\treadonly text: string;\n\treadonly mode: \"steer\" | \"followUp\";\n};\n\nexport type PromptDisposition = \"handled\" | \"queued\" | \"started\";\n\ntype TransferOptions = {\n\treadonly willRetry?: boolean;\n\t/**\n\t * Deliver prompts through the native steer/followUp queues instead of\n\t * prompt admission. Used after an unsuccessful compaction so queued input\n\t * is never dropped and never force-admitted into an over-budget context.\n\t */\n\treadonly deferAdmission?: boolean;\n};\n\ntype TransferDependencies = {\n\treadonly takeBatch: () => CompactionQueuedMessage[];\n\treadonly commitAccepted: (message: CompactionQueuedMessage) => boolean;\n\treadonly restoreUndelivered: (messages: readonly CompactionQueuedMessage[]) => number;\n\treadonly isCommand: (message: CompactionQueuedMessage) => boolean;\n\treadonly deliverCommand: (message: CompactionQueuedMessage) => Promise<void>;\n\treadonly deliverFirstPrompt: (message: CompactionQueuedMessage) => Promise<PromptDisposition>;\n\treadonly deliverQueued: (message: CompactionQueuedMessage) => Promise<void>;\n\treadonly reportFailure: (error: unknown, undeliveredCount: number) => void;\n};\n\nexport async function transferCompactionQueue(\n\tdependencies: TransferDependencies,\n\toptions: TransferOptions = {},\n): Promise<void> {\n\tconst batch = dependencies.takeBatch();\n\tif (batch.length === 0) return;\n\n\tlet acceptedCount = 0;\n\ttry {\n\t\tif (options.willRetry || options.deferAdmission) {\n\t\t\tfor (const message of batch) {\n\t\t\t\tif (dependencies.isCommand(message)) {\n\t\t\t\t\tawait dependencies.deliverCommand(message);\n\t\t\t\t} else {\n\t\t\t\t\tawait dependencies.deliverQueued(message);\n\t\t\t\t}\n\t\t\t\tif (!dependencies.commitAccepted(message)) return;\n\t\t\t\tacceptedCount += 1;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tlet promptWorkOwned = false;\n\t\tfor (const message of batch) {\n\t\t\tif (dependencies.isCommand(message)) {\n\t\t\t\tawait dependencies.deliverCommand(message);\n\t\t\t} else if (!promptWorkOwned) {\n\t\t\t\tconst disposition = await dependencies.deliverFirstPrompt(message);\n\t\t\t\tpromptWorkOwned = disposition !== \"handled\";\n\t\t\t} else {\n\t\t\t\tawait dependencies.deliverQueued(message);\n\t\t\t}\n\t\t\tif (!dependencies.commitAccepted(message)) return;\n\t\t\tacceptedCount += 1;\n\t\t}\n\t} catch (error) {\n\t\tconst failure = error instanceof Error ? error : new Error(String(error));\n\t\tconst undelivered = batch.slice(acceptedCount);\n\t\tconst restoredCount = dependencies.restoreUndelivered(undelivered);\n\t\tif (restoredCount > 0) {\n\t\t\tdependencies.reportFailure(failure, restoredCount);\n\t\t}\n\t}\n}\n\nexport function waitForPromptDisposition(\n\tstartPrompt: (\n\t\tpreflightResult: (success: boolean) => void,\n\t\tpromptDisposition: (disposition: PromptDisposition) => void,\n\t) => Promise<void>,\n\treportPostAcceptanceFailure: (error: unknown) => void,\n): Promise<PromptDisposition> {\n\treturn new Promise<PromptDisposition>((resolve, reject) => {\n\t\tlet accepted = false;\n\t\tlet rejectedAtPreflight = false;\n\t\tlet disposition: PromptDisposition | undefined;\n\t\tconst resolveAcceptedDisposition = (): void => {\n\t\t\tif (accepted && disposition) resolve(disposition);\n\t\t};\n\t\tconst prompt = startPrompt(\n\t\t\t(success) => {\n\t\t\t\tif (success) {\n\t\t\t\t\taccepted = true;\n\t\t\t\t\tresolveAcceptedDisposition();\n\t\t\t\t} else {\n\t\t\t\t\trejectedAtPreflight = true;\n\t\t\t\t}\n\t\t\t},\n\t\t\t(nextDisposition) => {\n\t\t\t\tdisposition = nextDisposition;\n\t\t\t\tresolveAcceptedDisposition();\n\t\t\t},\n\t\t);\n\n\t\tvoid prompt.then(\n\t\t\t() => {\n\t\t\t\tif (rejectedAtPreflight && !accepted) {\n\t\t\t\t\treject(new Error(\"Queued prompt was rejected before acceptance\"));\n\t\t\t\t}\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tif (accepted) {\n\t\t\t\t\treportPostAcceptanceFailure(error);\n\t\t\t\t} else {\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t});\n}\n"]}
|
|
@@ -46,6 +46,7 @@ export declare class InteractiveMode {
|
|
|
46
46
|
private shortcutOverlay;
|
|
47
47
|
private lastEditorText;
|
|
48
48
|
private lastInputWasPaste;
|
|
49
|
+
private sessionLogger;
|
|
49
50
|
private readonly turnWorkingTip;
|
|
50
51
|
private hookStatusContainer;
|
|
51
52
|
private defaultEditor;
|
|
@@ -309,6 +310,7 @@ export declare class InteractiveMode {
|
|
|
309
310
|
private showExtensionError;
|
|
310
311
|
private setupKeyHandlers;
|
|
311
312
|
private handleClipboardPaste;
|
|
313
|
+
private getSessionLogger;
|
|
312
314
|
private setupEditorSubmitHandler;
|
|
313
315
|
private subscribeToAgent;
|
|
314
316
|
private handleEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAoB,YAAY,EAA+B,MAAM,8BAA8B,CAAC;AA+ChH,OAAO,EAAE,KAAK,mBAAmB,EAAkC,MAAM,qCAAqC,CAAC;AAC/G,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive-mode.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
|
22
22
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScope, } from "../../core/model-resolver.js";
|
|
23
23
|
import { detectOmoNativeInstall } from "../../core/omo-native-detect.js";
|
|
24
24
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
25
|
+
import { createSessionLogger } from "../../core/session-log.js";
|
|
25
26
|
import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
|
|
26
27
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
27
28
|
import { isInstallTelemetryEnabled } from "../../core/telemetry.js";
|
|
@@ -2605,10 +2606,16 @@ export class InteractiveMode {
|
|
|
2605
2606
|
this.ui.requestRender();
|
|
2606
2607
|
}
|
|
2607
2608
|
}
|
|
2608
|
-
catch {
|
|
2609
|
-
|
|
2609
|
+
catch (error) {
|
|
2610
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2611
|
+
this.getSessionLogger().warn("clipboard_error", { op: "paste", error: message });
|
|
2612
|
+
this.showStatus(`Clipboard paste failed: ${sanitizeTuiErrorMessage(message)}`);
|
|
2610
2613
|
}
|
|
2611
2614
|
}
|
|
2615
|
+
getSessionLogger() {
|
|
2616
|
+
this.sessionLogger ??= createSessionLogger(this.runtimeHost.services.agentDir);
|
|
2617
|
+
return this.sessionLogger;
|
|
2618
|
+
}
|
|
2612
2619
|
setupEditorSubmitHandler() {
|
|
2613
2620
|
this.defaultEditor.onSubmit = async (text) => {
|
|
2614
2621
|
this.hideShortcutOverlay();
|
|
@@ -3117,12 +3124,21 @@ export class InteractiveMode {
|
|
|
3117
3124
|
this.chatContainer.addChild(new Text(theme.fg("error", message), 1, 0));
|
|
3118
3125
|
}
|
|
3119
3126
|
}
|
|
3120
|
-
//
|
|
3121
|
-
//
|
|
3122
|
-
//
|
|
3123
|
-
|
|
3124
|
-
|
|
3127
|
+
// Every terminal compaction_end flushes the TUI compaction queue.
|
|
3128
|
+
// Accepted compactions deliver through prompt admission; unsuccessful
|
|
3129
|
+
// ones route through the native steer/followUp queues so submitted
|
|
3130
|
+
// input is never silently parked (field bug: messages typed during a
|
|
3131
|
+
// failing compaction were held forever and lost on session switch).
|
|
3132
|
+
const compactionSucceeded = event.accepted === true || event.result !== undefined;
|
|
3133
|
+
const heldCount = this.compactionQueuedMessages.length;
|
|
3134
|
+
if (!compactionSucceeded && heldCount > 0) {
|
|
3135
|
+
this.getSessionLogger().warn("compaction_queue_deferred", {
|
|
3136
|
+
count: heldCount,
|
|
3137
|
+
cause: event.errorMessage ?? event.rejectionCause ?? (event.aborted ? "aborted" : "no-result"),
|
|
3138
|
+
});
|
|
3139
|
+
this.showStatus(`${heldCount} queued message${heldCount === 1 ? "" : "s"} will send with the next turn (compaction did not complete)`);
|
|
3125
3140
|
}
|
|
3141
|
+
void this.flushCompactionQueue({ willRetry: event.willRetry, deferAdmission: !compactionSucceeded });
|
|
3126
3142
|
this.ui.requestRender();
|
|
3127
3143
|
break;
|
|
3128
3144
|
}
|
|
@@ -3983,6 +3999,7 @@ export class InteractiveMode {
|
|
|
3983
3999
|
}
|
|
3984
4000
|
queueCompactionMessage(text, mode) {
|
|
3985
4001
|
this.compactionQueuedMessages.push({ text, mode });
|
|
4002
|
+
this.getSessionLogger().debug("compaction_queue_enqueue", { mode, count: this.compactionQueuedMessages.length });
|
|
3986
4003
|
this.editor.addToHistory?.(text);
|
|
3987
4004
|
this.editor.setText("");
|
|
3988
4005
|
this.updatePendingMessagesDisplay();
|