@caupulican/pi-adaptative 0.84.1 → 0.85.3

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 (214) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +14 -8
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +14 -8
  6. package/dist/bundled-resources/runtimes/pi-shell-engine/arithmetic.py +364 -0
  7. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +2 -1
  8. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +16 -0
  9. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +137 -14
  10. package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +23 -2
  11. package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +134 -6
  12. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +25 -2
  13. package/dist/bundled-resources/skills/deduplicate-by-evidence/SKILL.md +7 -5
  14. package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +63 -0
  15. package/dist/core/agent-session.d.ts.map +1 -1
  16. package/dist/core/agent-session.js +8 -0
  17. package/dist/core/agent-session.js.map +1 -1
  18. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  19. package/dist/core/autonomy/lane-tool-surface.js +4 -2
  20. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  21. package/dist/core/background-lane-controller.d.ts +3 -0
  22. package/dist/core/background-lane-controller.d.ts.map +1 -1
  23. package/dist/core/background-lane-controller.js +6 -0
  24. package/dist/core/background-lane-controller.js.map +1 -1
  25. package/dist/core/compaction-controller.d.ts +2 -0
  26. package/dist/core/compaction-controller.d.ts.map +1 -1
  27. package/dist/core/compaction-controller.js +35 -13
  28. package/dist/core/compaction-controller.js.map +1 -1
  29. package/dist/core/default-tool-surface.d.ts.map +1 -1
  30. package/dist/core/default-tool-surface.js +1 -0
  31. package/dist/core/default-tool-surface.js.map +1 -1
  32. package/dist/core/delegation/worker-delegation-controller.d.ts +7 -0
  33. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  34. package/dist/core/delegation/worker-delegation-controller.js +28 -0
  35. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  36. package/dist/core/delegation/worker-profile-resolver.d.ts +2 -0
  37. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
  38. package/dist/core/delegation/worker-profile-resolver.js +46 -11
  39. package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
  40. package/dist/core/doctor.d.ts +1 -1
  41. package/dist/core/doctor.d.ts.map +1 -1
  42. package/dist/core/doctor.js +5 -4
  43. package/dist/core/doctor.js.map +1 -1
  44. package/dist/core/failure-corpus.d.ts +26 -1
  45. package/dist/core/failure-corpus.d.ts.map +1 -1
  46. package/dist/core/failure-corpus.js +17 -0
  47. package/dist/core/failure-corpus.js.map +1 -1
  48. package/dist/core/model-capability.d.ts.map +1 -1
  49. package/dist/core/model-capability.js +1 -0
  50. package/dist/core/model-capability.js.map +1 -1
  51. package/dist/core/model-tool-protocol.d.ts +3 -2
  52. package/dist/core/model-tool-protocol.d.ts.map +1 -1
  53. package/dist/core/model-tool-protocol.js +5 -1
  54. package/dist/core/model-tool-protocol.js.map +1 -1
  55. package/dist/core/models/runtime-process.d.ts +7 -1
  56. package/dist/core/models/runtime-process.d.ts.map +1 -1
  57. package/dist/core/models/runtime-process.js +4 -2
  58. package/dist/core/models/runtime-process.js.map +1 -1
  59. package/dist/core/orchestration/lane-tool-manifests.d.ts +1 -1
  60. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
  61. package/dist/core/orchestration/lane-tool-manifests.js +6 -1
  62. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
  63. package/dist/core/orchestration/session-task-profile-store.d.ts +31 -0
  64. package/dist/core/orchestration/session-task-profile-store.d.ts.map +1 -0
  65. package/dist/core/orchestration/session-task-profile-store.js +138 -0
  66. package/dist/core/orchestration/session-task-profile-store.js.map +1 -0
  67. package/dist/core/orchestration/task-profile-writer.d.ts +58 -0
  68. package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -0
  69. package/dist/core/orchestration/task-profile-writer.js +165 -0
  70. package/dist/core/orchestration/task-profile-writer.js.map +1 -0
  71. package/dist/core/process-matrix/runtime.js +43 -11
  72. package/dist/core/process-matrix/runtime.js.map +1 -1
  73. package/dist/core/resource-loader.d.ts +2 -0
  74. package/dist/core/resource-loader.d.ts.map +1 -1
  75. package/dist/core/resource-loader.js +18 -6
  76. package/dist/core/resource-loader.js.map +1 -1
  77. package/dist/core/runtime-builder.d.ts +3 -1
  78. package/dist/core/runtime-builder.d.ts.map +1 -1
  79. package/dist/core/runtime-builder.js +14 -0
  80. package/dist/core/runtime-builder.js.map +1 -1
  81. package/dist/core/security/untrusted-boundary.d.ts.map +1 -1
  82. package/dist/core/security/untrusted-boundary.js +4 -6
  83. package/dist/core/security/untrusted-boundary.js.map +1 -1
  84. package/dist/core/session-role.d.ts.map +1 -1
  85. package/dist/core/session-role.js +1 -0
  86. package/dist/core/session-role.js.map +1 -1
  87. package/dist/core/system-prompt.d.ts.map +1 -1
  88. package/dist/core/system-prompt.js +21 -23
  89. package/dist/core/system-prompt.js.map +1 -1
  90. package/dist/core/tool-capability-policy.js +1 -1
  91. package/dist/core/tool-capability-policy.js.map +1 -1
  92. package/dist/core/tool-recovery-log-records.d.ts +33 -1
  93. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  94. package/dist/core/tool-recovery-log-records.js +59 -12
  95. package/dist/core/tool-recovery-log-records.js.map +1 -1
  96. package/dist/core/tool-recovery-logger.d.ts +12 -1
  97. package/dist/core/tool-recovery-logger.d.ts.map +1 -1
  98. package/dist/core/tool-recovery-logger.js +24 -1
  99. package/dist/core/tool-recovery-logger.js.map +1 -1
  100. package/dist/core/tool-repair-health.d.ts.map +1 -1
  101. package/dist/core/tool-repair-health.js +6 -0
  102. package/dist/core/tool-repair-health.js.map +1 -1
  103. package/dist/core/tools/bash.d.ts +3 -8
  104. package/dist/core/tools/bash.d.ts.map +1 -1
  105. package/dist/core/tools/bash.js +4 -28
  106. package/dist/core/tools/bash.js.map +1 -1
  107. package/dist/core/tools/delegate.js +4 -4
  108. package/dist/core/tools/delegate.js.map +1 -1
  109. package/dist/core/tools/edit-diff.d.ts +32 -5
  110. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  111. package/dist/core/tools/edit-diff.js +137 -69
  112. package/dist/core/tools/edit-diff.js.map +1 -1
  113. package/dist/core/tools/edit.d.ts +22 -7
  114. package/dist/core/tools/edit.d.ts.map +1 -1
  115. package/dist/core/tools/edit.js +128 -55
  116. package/dist/core/tools/edit.js.map +1 -1
  117. package/dist/core/tools/file-mutation-intent.d.ts +70 -0
  118. package/dist/core/tools/file-mutation-intent.d.ts.map +1 -0
  119. package/dist/core/tools/file-mutation-intent.js +325 -0
  120. package/dist/core/tools/file-mutation-intent.js.map +1 -0
  121. package/dist/core/tools/find.d.ts +2 -1
  122. package/dist/core/tools/find.d.ts.map +1 -1
  123. package/dist/core/tools/find.js +2 -6
  124. package/dist/core/tools/find.js.map +1 -1
  125. package/dist/core/tools/goal.d.ts.map +1 -1
  126. package/dist/core/tools/goal.js +41 -18
  127. package/dist/core/tools/goal.js.map +1 -1
  128. package/dist/core/tools/grep.d.ts +2 -1
  129. package/dist/core/tools/grep.d.ts.map +1 -1
  130. package/dist/core/tools/grep.js +2 -6
  131. package/dist/core/tools/grep.js.map +1 -1
  132. package/dist/core/tools/index.d.ts +3 -1
  133. package/dist/core/tools/index.d.ts.map +1 -1
  134. package/dist/core/tools/index.js +31 -8
  135. package/dist/core/tools/index.js.map +1 -1
  136. package/dist/core/tools/managed-search-tool.d.ts +8 -0
  137. package/dist/core/tools/managed-search-tool.d.ts.map +1 -0
  138. package/dist/core/tools/managed-search-tool.js +10 -0
  139. package/dist/core/tools/managed-search-tool.js.map +1 -0
  140. package/dist/core/tools/profile-writer.d.ts +33 -0
  141. package/dist/core/tools/profile-writer.d.ts.map +1 -0
  142. package/dist/core/tools/profile-writer.js +67 -0
  143. package/dist/core/tools/profile-writer.js.map +1 -0
  144. package/dist/core/tools/shell-command-parser.d.ts +4 -3
  145. package/dist/core/tools/shell-command-parser.d.ts.map +1 -1
  146. package/dist/core/tools/shell-command-parser.js +32 -7
  147. package/dist/core/tools/shell-command-parser.js.map +1 -1
  148. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  149. package/dist/core/tools/shell-contract-router.js +23 -1
  150. package/dist/core/tools/shell-contract-router.js.map +1 -1
  151. package/dist/core/tools/task-steps.d.ts.map +1 -1
  152. package/dist/core/tools/task-steps.js +6 -11
  153. package/dist/core/tools/task-steps.js.map +1 -1
  154. package/dist/core/tools/tmux-dispatch.d.ts +2 -0
  155. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  156. package/dist/core/tools/tmux-dispatch.js +16 -2
  157. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  158. package/dist/core/tools/windows-shell-engine.js +1 -1
  159. package/dist/core/tools/windows-shell-engine.js.map +1 -1
  160. package/dist/core/tools/write.d.ts +24 -7
  161. package/dist/core/tools/write.d.ts.map +1 -1
  162. package/dist/core/tools/write.js +182 -107
  163. package/dist/core/tools/write.js.map +1 -1
  164. package/dist/index.d.ts +1 -1
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +1 -1
  167. package/dist/index.js.map +1 -1
  168. package/dist/jscpd-cli.d.ts +3 -0
  169. package/dist/jscpd-cli.d.ts.map +1 -0
  170. package/dist/jscpd-cli.js +22 -0
  171. package/dist/jscpd-cli.js.map +1 -0
  172. package/dist/modes/interactive/components/profile-resource-editor.js +2 -2
  173. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  174. package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  175. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  176. package/dist/modes/interactive/components/tool-execution.js +85 -3
  177. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  178. package/dist/modes/interactive/interactive-mode.js +1 -1
  179. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  180. package/dist/utils/bundled-jscpd.d.ts +20 -0
  181. package/dist/utils/bundled-jscpd.d.ts.map +1 -0
  182. package/dist/utils/bundled-jscpd.js +154 -0
  183. package/dist/utils/bundled-jscpd.js.map +1 -0
  184. package/dist/utils/paths.js +1 -1
  185. package/dist/utils/paths.js.map +1 -1
  186. package/dist/utils/shell.d.ts.map +1 -1
  187. package/dist/utils/shell.js +11 -0
  188. package/dist/utils/shell.js.map +1 -1
  189. package/dist/utils/tools-manager.d.ts +19 -2
  190. package/dist/utils/tools-manager.d.ts.map +1 -1
  191. package/dist/utils/tools-manager.js +92 -40
  192. package/dist/utils/tools-manager.js.map +1 -1
  193. package/docs/index.md +3 -0
  194. package/docs/managed-data-tools.md +15 -0
  195. package/docs/models.md +1 -1
  196. package/docs/quickstart.md +2 -2
  197. package/docs/settings.md +1 -1
  198. package/docs/tool-boundary-performance-roadmap-2026-08-02.md +166 -0
  199. package/docs/tool-repair.md +4 -4
  200. package/docs/windows.md +7 -5
  201. package/docs/worker-profiles.md +16 -0
  202. package/examples/extensions/built-in-tool-renderer.ts +12 -5
  203. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  204. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  205. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  206. package/examples/extensions/minimal-mode.ts +8 -7
  207. package/examples/extensions/prompt-customizer.ts +4 -2
  208. package/examples/extensions/sandbox/package-lock.json +2 -2
  209. package/examples/extensions/sandbox/package.json +1 -1
  210. package/examples/extensions/ssh.ts +113 -24
  211. package/examples/extensions/with-deps/package-lock.json +2 -2
  212. package/examples/extensions/with-deps/package.json +1 -1
  213. package/npm-shrinkwrap.json +112 -12
  214. package/package.json +7 -5
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-process.js","sourceRoot":"","sources":["../../../src/core/models/runtime-process.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Readable, Transform, Writable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { spawnProcess, spawnProcessSync, waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { createRollingOutputBuffer } from \"../exec.ts\";\n\nexport interface RuntimeCommandResult {\n\tok: boolean;\n\tstdout: string;\n\tstderr: string;\n\tcode?: number | null;\n\terror?: string;\n}\n\nexport interface RuntimeCommandOptions {\n\tenv?: NodeJS.ProcessEnv;\n\tonOutput?: (chunk: string) => void;\n}\n\nexport type RuntimeCommandRunner = (\n\tcommand: string,\n\targs: string[],\n\toptions?: RuntimeCommandOptions,\n) => Promise<RuntimeCommandResult>;\n\nexport interface RuntimeCommandRunnerLimits {\n\ttimeoutMs: number;\n\tkillGraceMs: number;\n\tmaxOutputUnits?: number;\n}\n\nconst DEFAULT_RUNTIME_OUTPUT_UNITS = 1024 * 1024;\n\n/**\n * Build a runtime-management command runner with one bounded process lifecycle.\n * Output is retained as chunk tails and flattened once, after the child reaches a terminal state.\n */\nexport function createRuntimeCommandRunner(limits: RuntimeCommandRunnerLimits): RuntimeCommandRunner {\n\tconst requestedOutputUnits = limits.maxOutputUnits ?? DEFAULT_RUNTIME_OUTPUT_UNITS;\n\tconst maxOutputUnits =\n\t\tNumber.isFinite(requestedOutputUnits) && requestedOutputUnits > 0\n\t\t\t? Math.floor(requestedOutputUnits)\n\t\t\t: DEFAULT_RUNTIME_OUTPUT_UNITS;\n\treturn async (command, args, options = {}) => {\n\t\ttry {\n\t\t\tconst proc = spawnProcess(command, args, {\n\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\tenv: options.env ? { ...process.env, ...options.env } : process.env,\n\t\t\t});\n\t\t\tconst stdout = createRollingOutputBuffer(maxOutputUnits);\n\t\t\tconst stderr = createRollingOutputBuffer(maxOutputUnits);\n\t\t\tproc.stdout.setEncoding(\"utf8\");\n\t\t\tproc.stderr.setEncoding(\"utf8\");\n\t\t\tproc.stdout.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout.push(chunk);\n\t\t\t\toptions.onOutput?.(chunk);\n\t\t\t});\n\t\t\tproc.stderr.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr.push(chunk);\n\t\t\t\toptions.onOutput?.(chunk);\n\t\t\t});\n\t\t\tconst terminal = await waitForChildProcessWithTermination(proc, {\n\t\t\t\ttimeoutMs: limits.timeoutMs,\n\t\t\t\tkillGraceMs: limits.killGraceMs,\n\t\t\t});\n\t\t\tconst stdoutText = stdout.text();\n\t\t\tconst stderrText = stderr.text();\n\t\t\treturn {\n\t\t\t\tok: terminal.code === 0,\n\t\t\t\tstdout: stdoutText,\n\t\t\t\tstderr: stderrText,\n\t\t\t\tcode: terminal.code,\n\t\t\t\t...(terminal.code === 0\n\t\t\t\t\t? {}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\tterminal.reason === \"timeout\"\n\t\t\t\t\t\t\t\t\t? `${command} timed out after ${limits.timeoutMs}ms`\n\t\t\t\t\t\t\t\t\t: stderrText.trim() || stdoutText.trim() || `exit code ${terminal.code ?? \"unknown\"}`,\n\t\t\t\t\t\t}),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: \"\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t};\n}\n\nexport function runtimeCommandAvailable(command: string): boolean {\n\treturn spawnProcessSync(command, [\"--version\"], { encoding: \"utf8\", timeout: 5_000 }).error === undefined;\n}\n\nexport function runtimeSleep(ms: number): Promise<void> {\n\treturn sleep(ms);\n}\n\nexport type ManagedRuntimeChild = Pick<ChildProcess, \"pid\" | \"kill\" | \"unref\" | \"on\">;\nexport interface ManagedRuntimeSpawnOptions {\n\tdetached?: boolean;\n\tstdio?: \"ignore\";\n\tenv: NodeJS.ProcessEnv;\n}\nexport type ManagedRuntimeSpawn = (\n\tcommand: string,\n\targs: string[],\n\toptions: ManagedRuntimeSpawnOptions,\n) => ManagedRuntimeChild;\n\nexport function spawnManagedRuntime(\n\tcommand: string,\n\targs: string[],\n\toptions: ManagedRuntimeSpawnOptions,\n): ManagedRuntimeChild {\n\treturn spawn(command, args, { ...options, stdio: \"ignore\" });\n}\n\nexport interface RuntimeLifecycleDependencyOverrides {\n\tfetchFn?: typeof fetch;\n\tspawnFn?: ManagedRuntimeSpawn;\n\texistsFn?: (path: string) => boolean;\n\tsleepFn?: (ms: number) => Promise<void>;\n}\n\nexport type RuntimeLifecycleDependencies = readonly [\n\tfetchFn: typeof fetch,\n\tspawnFn: ManagedRuntimeSpawn,\n\texistsFn: (path: string) => boolean,\n\tsleepFn: (ms: number) => Promise<void>,\n];\n\n/** Resolve the common runtime lifecycle boundary once, during construction. */\nexport function resolveRuntimeLifecycleDependencies(\n\toverrides?: RuntimeLifecycleDependencyOverrides,\n): RuntimeLifecycleDependencies {\n\treturn [\n\t\toverrides?.fetchFn ?? fetch,\n\t\toverrides?.spawnFn ?? spawnManagedRuntime,\n\t\toverrides?.existsFn ?? existsSync,\n\t\toverrides?.sleepFn ?? runtimeSleep,\n\t];\n}\n\nexport type RuntimeDownloadResult =\n\t| { ok: true; response: Response; body: ReadableStream<Uint8Array> }\n\t| { ok: false; error: string };\n\ntype RuntimeFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\n/** Validate a runtime download without consuming, decoding, or copying its response body. */\nexport async function fetchRuntimeDownload(\n\tfetchFn: RuntimeFetch,\n\turl: string,\n\tinit?: RequestInit,\n): Promise<RuntimeDownloadResult> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchFn(url, init);\n\t} catch (error) {\n\t\treturn { ok: false, error: `download-fail: ${error instanceof Error ? error.message : String(error)}` };\n\t}\n\tif (!response.ok || !response.body) return { ok: false, error: `download-fail: HTTP ${response.status}` };\n\treturn { ok: true, response, body: response.body };\n}\n\n/** Download and extract a runtime archive without materializing or copying its body. */\nexport async function installRuntimeArchive<TInput extends NodeJS.ReadableStream, TKind extends string>(\n\tfetchFn: RuntimeFetch,\n\tdownloadUrl: string,\n\tdestDir: string,\n\tasset: { name: string; kind: TKind },\n\textractArchive: (input: TInput, destDir: string, kind: TKind) => Promise<{ ok: boolean; error?: string }>,\n\tonProgress?: (status: string) => void,\n): Promise<{ ok: boolean; error?: string }> {\n\tonProgress?.(`Downloading ${asset.name}…`);\n\tconst download = await fetchRuntimeDownload(fetchFn, downloadUrl);\n\tif (!download.ok) return download;\n\tmkdirSync(destDir, { recursive: true });\n\tonProgress?.(`Extracting ${asset.name}…`);\n\treturn extractArchive(download.body as unknown as TInput, destDir, asset.kind);\n}\n\nexport function tryFileSizeBytes(path: string): number | undefined {\n\ttry {\n\t\treturn statSync(path).size;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function removePartialDownload(path: string): void {\n\ttry {\n\t\trmSync(path, { force: true });\n\t} catch {\n\t\t// best-effort cleanup\n\t}\n}\n\n/** Wait for a failed pipeline's file descriptor to close before deleting its partial output. */\nexport function waitForWritableClosed(stream: Writable & { closed?: boolean }): Promise<void> {\n\tif (stream.closed) return Promise.resolve();\n\treturn new Promise((resolve) => {\n\t\tstream.once(\"close\", resolve);\n\t\tstream.destroy();\n\t});\n}\n\n/** Stream a runtime payload to disk, closing and deleting partial output on any failure. */\nexport async function writeRuntimeDownload(\n\tinput: Readable,\n\tdestPath: string,\n\ttransform?: Transform,\n): Promise<{ ok: true } | { ok: false; error: string }> {\n\tconst writeStream = createWriteStream(destPath);\n\ttry {\n\t\tif (transform) await pipeline(input, transform, writeStream);\n\t\telse await pipeline(input, writeStream);\n\t\treturn { ok: true };\n\t} catch (error) {\n\t\tawait waitForWritableClosed(writeStream);\n\t\tremovePartialDownload(destPath);\n\t\treturn { ok: false, error: `download-fail: ${error instanceof Error ? error.message : String(error)}` };\n\t}\n}\n\nexport function requireRuntimeStdin(proc: ChildProcess, label: string): Writable {\n\tif (!proc.stdin) throw new Error(`${label}: no stdin pipe`);\n\treturn proc.stdin;\n}\n\nexport interface ExtractZipArchiveOptions {\n\tinput: Readable;\n\tdestDir: string;\n\ttempPrefix: string;\n\tplatform: () => string;\n\thasCommand: (command: string) => boolean;\n\ttimeoutMs: number;\n\tkillGraceMs: number;\n}\n\n/** Shared seekable-file extraction path for managed runtime zip archives. */\nexport async function extractZipArchive(options: ExtractZipArchiveOptions): Promise<{ ok: boolean; error?: string }> {\n\tconst zipPath = join(options.destDir, \"..\", `${options.tempPrefix}-${process.pid}-${Date.now()}.zip`);\n\ttry {\n\t\tawait pipeline(options.input, createWriteStream(zipPath));\n\t\tconst extractCommand = options.platform() === \"win32\" && options.hasCommand(\"tar\") ? \"tar\" : \"unzip\";\n\t\tconst args =\n\t\t\textractCommand === \"tar\" ? [\"-xf\", zipPath, \"-C\", options.destDir] : [\"-q\", zipPath, \"-d\", options.destDir];\n\t\tconst proc = spawnProcess(extractCommand, args, {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tconst terminal = await waitForChildProcessWithTermination(proc, {\n\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\tkillGraceMs: options.killGraceMs,\n\t\t});\n\t\tif (terminal.reason === \"timeout\" || terminal.code !== 0) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror:\n\t\t\t\t\tterminal.reason === \"timeout\"\n\t\t\t\t\t\t? `extract-fail: ${extractCommand} timed out after ${options.timeoutMs}ms`\n\t\t\t\t\t\t: `extract-fail: ${extractCommand} exited with code ${terminal.code ?? \"unknown\"}`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true };\n\t} finally {\n\t\tremovePartialDownload(zipPath);\n\t}\n}\n"]}
1
+ {"version":3,"file":"runtime-process.js","sourceRoot":"","sources":["../../../src/core/models/runtime-process.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, spawn } from \"node:child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Readable, Transform, Writable } from \"node:stream\";\nimport { pipeline } from \"node:stream/promises\";\nimport { spawnProcess, spawnProcessSync, waitForChildProcessWithTermination } from \"../../utils/child-process.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { createRollingOutputBuffer } from \"../exec.ts\";\n\nexport interface RuntimeCommandResult {\n\tok: boolean;\n\tstdout: string;\n\tstderr: string;\n\tcode?: number | null;\n\terror?: string;\n}\n\nexport interface RuntimeCommandOptions {\n\tenv?: NodeJS.ProcessEnv;\n\tonOutput?: (chunk: string) => void;\n}\n\nexport type RuntimeCommandRunner = (\n\tcommand: string,\n\targs: string[],\n\toptions?: RuntimeCommandOptions,\n) => Promise<RuntimeCommandResult>;\n\nexport interface RuntimeCommandRunnerLimits {\n\ttimeoutMs: number;\n\tkillGraceMs: number;\n\tmaxOutputUnits?: number;\n}\n\nconst DEFAULT_RUNTIME_OUTPUT_UNITS = 1024 * 1024;\n\n/**\n * Build a runtime-management command runner with one bounded process lifecycle.\n * Output is retained as chunk tails and flattened once, after the child reaches a terminal state.\n */\nexport function createRuntimeCommandRunner(limits: RuntimeCommandRunnerLimits): RuntimeCommandRunner {\n\tconst requestedOutputUnits = limits.maxOutputUnits ?? DEFAULT_RUNTIME_OUTPUT_UNITS;\n\tconst maxOutputUnits =\n\t\tNumber.isFinite(requestedOutputUnits) && requestedOutputUnits > 0\n\t\t\t? Math.floor(requestedOutputUnits)\n\t\t\t: DEFAULT_RUNTIME_OUTPUT_UNITS;\n\treturn async (command, args, options = {}) => {\n\t\ttry {\n\t\t\tconst proc = spawnProcess(command, args, {\n\t\t\t\tdetached: process.platform !== \"win32\",\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\tenv: options.env ? { ...process.env, ...options.env } : process.env,\n\t\t\t});\n\t\t\tconst stdout = createRollingOutputBuffer(maxOutputUnits);\n\t\t\tconst stderr = createRollingOutputBuffer(maxOutputUnits);\n\t\t\tproc.stdout.setEncoding(\"utf8\");\n\t\t\tproc.stderr.setEncoding(\"utf8\");\n\t\t\tproc.stdout.on(\"data\", (chunk: string) => {\n\t\t\t\tstdout.push(chunk);\n\t\t\t\toptions.onOutput?.(chunk);\n\t\t\t});\n\t\t\tproc.stderr.on(\"data\", (chunk: string) => {\n\t\t\t\tstderr.push(chunk);\n\t\t\t\toptions.onOutput?.(chunk);\n\t\t\t});\n\t\t\tconst terminal = await waitForChildProcessWithTermination(proc, {\n\t\t\t\ttimeoutMs: limits.timeoutMs,\n\t\t\t\tkillGraceMs: limits.killGraceMs,\n\t\t\t});\n\t\t\tconst stdoutText = stdout.text();\n\t\t\tconst stderrText = stderr.text();\n\t\t\treturn {\n\t\t\t\tok: terminal.code === 0,\n\t\t\t\tstdout: stdoutText,\n\t\t\t\tstderr: stderrText,\n\t\t\t\tcode: terminal.code,\n\t\t\t\t...(terminal.code === 0\n\t\t\t\t\t? {}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\tterminal.reason === \"timeout\"\n\t\t\t\t\t\t\t\t\t? `${command} timed out after ${limits.timeoutMs}ms`\n\t\t\t\t\t\t\t\t\t: stderrText.trim() || stdoutText.trim() || `exit code ${terminal.code ?? \"unknown\"}`,\n\t\t\t\t\t\t}),\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tstdout: \"\",\n\t\t\t\tstderr: \"\",\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t};\n\t\t}\n\t};\n}\n\ntype RuntimeCommandProbe = (\n\tcommand: string,\n\targs: string[],\n\toptions: { encoding: \"utf8\"; timeout: number },\n) => { error?: unknown };\n\nexport function runtimeCommandAvailable(command: string, probe: RuntimeCommandProbe = spawnProcessSync): boolean {\n\t// Node returns `undefined` on success; cross-spawn normalizes that field to `null` on Windows.\n\t// Both are the absence of an error. A strict undefined check made every Windows probe fail.\n\treturn probe(command, [\"--version\"], { encoding: \"utf8\", timeout: 5_000 }).error == null;\n}\n\nexport function runtimeSleep(ms: number): Promise<void> {\n\treturn sleep(ms);\n}\n\nexport type ManagedRuntimeChild = Pick<ChildProcess, \"pid\" | \"kill\" | \"unref\" | \"on\">;\nexport interface ManagedRuntimeSpawnOptions {\n\tdetached?: boolean;\n\tstdio?: \"ignore\";\n\tenv: NodeJS.ProcessEnv;\n}\nexport type ManagedRuntimeSpawn = (\n\tcommand: string,\n\targs: string[],\n\toptions: ManagedRuntimeSpawnOptions,\n) => ManagedRuntimeChild;\n\nexport function spawnManagedRuntime(\n\tcommand: string,\n\targs: string[],\n\toptions: ManagedRuntimeSpawnOptions,\n): ManagedRuntimeChild {\n\treturn spawn(command, args, { ...options, stdio: \"ignore\" });\n}\n\nexport interface RuntimeLifecycleDependencyOverrides {\n\tfetchFn?: typeof fetch;\n\tspawnFn?: ManagedRuntimeSpawn;\n\texistsFn?: (path: string) => boolean;\n\tsleepFn?: (ms: number) => Promise<void>;\n}\n\nexport type RuntimeLifecycleDependencies = readonly [\n\tfetchFn: typeof fetch,\n\tspawnFn: ManagedRuntimeSpawn,\n\texistsFn: (path: string) => boolean,\n\tsleepFn: (ms: number) => Promise<void>,\n];\n\n/** Resolve the common runtime lifecycle boundary once, during construction. */\nexport function resolveRuntimeLifecycleDependencies(\n\toverrides?: RuntimeLifecycleDependencyOverrides,\n): RuntimeLifecycleDependencies {\n\treturn [\n\t\toverrides?.fetchFn ?? fetch,\n\t\toverrides?.spawnFn ?? spawnManagedRuntime,\n\t\toverrides?.existsFn ?? existsSync,\n\t\toverrides?.sleepFn ?? runtimeSleep,\n\t];\n}\n\nexport type RuntimeDownloadResult =\n\t| { ok: true; response: Response; body: ReadableStream<Uint8Array> }\n\t| { ok: false; error: string };\n\ntype RuntimeFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\n/** Validate a runtime download without consuming, decoding, or copying its response body. */\nexport async function fetchRuntimeDownload(\n\tfetchFn: RuntimeFetch,\n\turl: string,\n\tinit?: RequestInit,\n): Promise<RuntimeDownloadResult> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetchFn(url, init);\n\t} catch (error) {\n\t\treturn { ok: false, error: `download-fail: ${error instanceof Error ? error.message : String(error)}` };\n\t}\n\tif (!response.ok || !response.body) return { ok: false, error: `download-fail: HTTP ${response.status}` };\n\treturn { ok: true, response, body: response.body };\n}\n\n/** Download and extract a runtime archive without materializing or copying its body. */\nexport async function installRuntimeArchive<TInput extends NodeJS.ReadableStream, TKind extends string>(\n\tfetchFn: RuntimeFetch,\n\tdownloadUrl: string,\n\tdestDir: string,\n\tasset: { name: string; kind: TKind },\n\textractArchive: (input: TInput, destDir: string, kind: TKind) => Promise<{ ok: boolean; error?: string }>,\n\tonProgress?: (status: string) => void,\n): Promise<{ ok: boolean; error?: string }> {\n\tonProgress?.(`Downloading ${asset.name}…`);\n\tconst download = await fetchRuntimeDownload(fetchFn, downloadUrl);\n\tif (!download.ok) return download;\n\tmkdirSync(destDir, { recursive: true });\n\tonProgress?.(`Extracting ${asset.name}…`);\n\treturn extractArchive(download.body as unknown as TInput, destDir, asset.kind);\n}\n\nexport function tryFileSizeBytes(path: string): number | undefined {\n\ttry {\n\t\treturn statSync(path).size;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function removePartialDownload(path: string): void {\n\ttry {\n\t\trmSync(path, { force: true });\n\t} catch {\n\t\t// best-effort cleanup\n\t}\n}\n\n/** Wait for a failed pipeline's file descriptor to close before deleting its partial output. */\nexport function waitForWritableClosed(stream: Writable & { closed?: boolean }): Promise<void> {\n\tif (stream.closed) return Promise.resolve();\n\treturn new Promise((resolve) => {\n\t\tstream.once(\"close\", resolve);\n\t\tstream.destroy();\n\t});\n}\n\n/** Stream a runtime payload to disk, closing and deleting partial output on any failure. */\nexport async function writeRuntimeDownload(\n\tinput: Readable,\n\tdestPath: string,\n\ttransform?: Transform,\n): Promise<{ ok: true } | { ok: false; error: string }> {\n\tconst writeStream = createWriteStream(destPath);\n\ttry {\n\t\tif (transform) await pipeline(input, transform, writeStream);\n\t\telse await pipeline(input, writeStream);\n\t\treturn { ok: true };\n\t} catch (error) {\n\t\tawait waitForWritableClosed(writeStream);\n\t\tremovePartialDownload(destPath);\n\t\treturn { ok: false, error: `download-fail: ${error instanceof Error ? error.message : String(error)}` };\n\t}\n}\n\nexport function requireRuntimeStdin(proc: ChildProcess, label: string): Writable {\n\tif (!proc.stdin) throw new Error(`${label}: no stdin pipe`);\n\treturn proc.stdin;\n}\n\nexport interface ExtractZipArchiveOptions {\n\tinput: Readable;\n\tdestDir: string;\n\ttempPrefix: string;\n\tplatform: () => string;\n\thasCommand: (command: string) => boolean;\n\ttimeoutMs: number;\n\tkillGraceMs: number;\n}\n\n/** Shared seekable-file extraction path for managed runtime zip archives. */\nexport async function extractZipArchive(options: ExtractZipArchiveOptions): Promise<{ ok: boolean; error?: string }> {\n\tconst zipPath = join(options.destDir, \"..\", `${options.tempPrefix}-${process.pid}-${Date.now()}.zip`);\n\ttry {\n\t\tawait pipeline(options.input, createWriteStream(zipPath));\n\t\tconst extractCommand = options.platform() === \"win32\" && options.hasCommand(\"tar\") ? \"tar\" : \"unzip\";\n\t\tconst args =\n\t\t\textractCommand === \"tar\" ? [\"-xf\", zipPath, \"-C\", options.destDir] : [\"-q\", zipPath, \"-d\", options.destDir];\n\t\tconst proc = spawnProcess(extractCommand, args, {\n\t\t\tdetached: process.platform !== \"win32\",\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tconst terminal = await waitForChildProcessWithTermination(proc, {\n\t\t\ttimeoutMs: options.timeoutMs,\n\t\t\tkillGraceMs: options.killGraceMs,\n\t\t});\n\t\tif (terminal.reason === \"timeout\" || terminal.code !== 0) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror:\n\t\t\t\t\tterminal.reason === \"timeout\"\n\t\t\t\t\t\t? `extract-fail: ${extractCommand} timed out after ${options.timeoutMs}ms`\n\t\t\t\t\t\t: `extract-fail: ${extractCommand} exited with code ${terminal.code ?? \"unknown\"}`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true };\n\t} finally {\n\t\tremovePartialDownload(zipPath);\n\t}\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { OrchestrationProfile, ToolCapabilityManifest } from "./contracts.ts";
2
2
  export declare const CLASSIFIED_LANE_TOOL_NAMES: readonly ["read", "grep", "find", "ls", "write", "edit", "memory", "run_process"];
3
- export declare const ORCHESTRATION_PROFILE_TOOL_NAMES: readonly ["read", "grep", "find", "ls", "write", "edit", "memory", "run_process", "delegate", "delegate_status"];
3
+ export declare const ORCHESTRATION_PROFILE_TOOL_NAMES: readonly ["read", "grep", "find", "ls", "write", "edit", "memory", "run_process", "delegate", "delegate_status", "profile_writer"];
4
4
  /**
5
5
  * Manifest-only lane catalogue. It contains no tool factories, so policy compilation can omit
6
6
  * denied tools before their executable implementations are constructed.
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tool-manifests.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/lane-tool-manifests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAEnF,eAAO,MAAM,0BAA0B,YACtC,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,OAAO,EACP,MAAM,EACN,QAAQ,EACR,aAAa,CACJ,CAAC;AACX,eAAO,MAAM,gCAAgC,kHAA0E,CAAC;AAExH;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,EAAE,SAAS,MAAM,EAAE,GACjC,sBAAsB,EAAE,CAkB1B"}
1
+ {"version":3,"file":"lane-tool-manifests.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/lane-tool-manifests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAEnF,eAAO,MAAM,0BAA0B,YACtC,MAAM,EACN,MAAM,EACN,MAAM,EACN,IAAI,EACJ,OAAO,EACP,MAAM,EACN,QAAQ,EACR,aAAa,CACJ,CAAC;AACX,eAAO,MAAM,gCAAgC,oIAKnC,CAAC;AAEX;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,EAAE,SAAS,MAAM,EAAE,GACjC,sBAAsB,EAAE,CAkB1B"}
@@ -9,7 +9,12 @@ export const CLASSIFIED_LANE_TOOL_NAMES = [
9
9
  "memory",
10
10
  "run_process",
11
11
  ];
12
- export const ORCHESTRATION_PROFILE_TOOL_NAMES = [...CLASSIFIED_LANE_TOOL_NAMES, "delegate", "delegate_status"];
12
+ export const ORCHESTRATION_PROFILE_TOOL_NAMES = [
13
+ ...CLASSIFIED_LANE_TOOL_NAMES,
14
+ "delegate",
15
+ "delegate_status",
16
+ "profile_writer",
17
+ ];
13
18
  /**
14
19
  * Manifest-only lane catalogue. It contains no tool factories, so policy compilation can omit
15
20
  * denied tools before their executable implementations are constructed.
@@ -1 +1 @@
1
- {"version":3,"file":"lane-tool-manifests.js","sourceRoot":"","sources":["../../../src/core/orchestration/lane-tool-manifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAGrG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,OAAO;IACP,MAAM;IACN,QAAQ;IACR,aAAa;CACJ,CAAC;AACX,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,GAAG,0BAA0B,EAAE,UAAU,EAAE,iBAAiB,CAAU,CAAC;AAExH;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACrC,OAA6B,EAC7B,gBAAmC;IAEnC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1C,MAAM,SAAS,GAA6B,EAAE,CAAC;IAE/C,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACrC,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM;YAAE,SAAS;QACrC,SAAS,CAAC,IAAI,CAAC;YACd,QAAQ;YACR,eAAe,EAAE,YAAY,QAAQ,KAAK;YAC1C,YAAY,EAAE,CAAC,UAAU,CAAC;YAC1B,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACrB,YAAY,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;SAClC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["import { getToolCapabilityPolicy, resolveProfileToolCapability } from \"../tool-capability-policy.ts\";\nimport type { OrchestrationProfile, ToolCapabilityManifest } from \"./contracts.ts\";\n\nexport const CLASSIFIED_LANE_TOOL_NAMES = [\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"write\",\n\t\"edit\",\n\t\"memory\",\n\t\"run_process\",\n] as const;\nexport const ORCHESTRATION_PROFILE_TOOL_NAMES = [...CLASSIFIED_LANE_TOOL_NAMES, \"delegate\", \"delegate_status\"] as const;\n\n/**\n * Manifest-only lane catalogue. It contains no tool factories, so policy compilation can omit\n * denied tools before their executable implementations are constructed.\n */\nexport function buildLaneToolManifests(\n\tprofile: OrchestrationProfile,\n\tenabledToolNames: readonly string[],\n): ToolCapabilityManifest[] {\n\tconst enabled = new Set(enabledToolNames);\n\tconst manifests: ToolCapabilityManifest[] = [];\n\n\tfor (const toolName of profile.toolNames) {\n\t\tif (!enabled.has(toolName)) continue;\n\t\tconst policy = getToolCapabilityPolicy(toolName);\n\t\tconst capability = resolveProfileToolCapability(profile, toolName);\n\t\tif (!capability || !policy) continue;\n\t\tmanifests.push({\n\t\t\ttoolName,\n\t\t\tmoduleSpecifier: `../tools/${toolName}.ts`,\n\t\t\tcapabilities: [capability],\n\t\t\troles: [profile.role],\n\t\t\tenforcements: [policy.enforcement],\n\t\t});\n\t}\n\treturn manifests;\n}\n"]}
1
+ {"version":3,"file":"lane-tool-manifests.js","sourceRoot":"","sources":["../../../src/core/orchestration/lane-tool-manifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAGrG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACzC,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,OAAO;IACP,MAAM;IACN,QAAQ;IACR,aAAa;CACJ,CAAC;AACX,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC/C,GAAG,0BAA0B;IAC7B,UAAU;IACV,iBAAiB;IACjB,gBAAgB;CACP,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACrC,OAA6B,EAC7B,gBAAmC;IAEnC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1C,MAAM,SAAS,GAA6B,EAAE,CAAC;IAE/C,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACrC,MAAM,MAAM,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM;YAAE,SAAS;QACrC,SAAS,CAAC,IAAI,CAAC;YACd,QAAQ;YACR,eAAe,EAAE,YAAY,QAAQ,KAAK;YAC1C,YAAY,EAAE,CAAC,UAAU,CAAC;YAC1B,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACrB,YAAY,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC;SAClC,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC","sourcesContent":["import { getToolCapabilityPolicy, resolveProfileToolCapability } from \"../tool-capability-policy.ts\";\nimport type { OrchestrationProfile, ToolCapabilityManifest } from \"./contracts.ts\";\n\nexport const CLASSIFIED_LANE_TOOL_NAMES = [\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"write\",\n\t\"edit\",\n\t\"memory\",\n\t\"run_process\",\n] as const;\nexport const ORCHESTRATION_PROFILE_TOOL_NAMES = [\n\t...CLASSIFIED_LANE_TOOL_NAMES,\n\t\"delegate\",\n\t\"delegate_status\",\n\t\"profile_writer\",\n] as const;\n\n/**\n * Manifest-only lane catalogue. It contains no tool factories, so policy compilation can omit\n * denied tools before their executable implementations are constructed.\n */\nexport function buildLaneToolManifests(\n\tprofile: OrchestrationProfile,\n\tenabledToolNames: readonly string[],\n): ToolCapabilityManifest[] {\n\tconst enabled = new Set(enabledToolNames);\n\tconst manifests: ToolCapabilityManifest[] = [];\n\n\tfor (const toolName of profile.toolNames) {\n\t\tif (!enabled.has(toolName)) continue;\n\t\tconst policy = getToolCapabilityPolicy(toolName);\n\t\tconst capability = resolveProfileToolCapability(profile, toolName);\n\t\tif (!capability || !policy) continue;\n\t\tmanifests.push({\n\t\t\ttoolName,\n\t\t\tmoduleSpecifier: `../tools/${toolName}.ts`,\n\t\t\tcapabilities: [capability],\n\t\t\troles: [profile.role],\n\t\t\tenforcements: [policy.enforcement],\n\t\t});\n\t}\n\treturn manifests;\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { SessionManager } from "@caupulican/pi-agent-core/node";
2
+ import type { OrchestrationProfile } from "./contracts.ts";
3
+ export declare const SESSION_TASK_PROFILE_CUSTOM_TYPE = "session_task_profile";
4
+ export declare const MAX_SESSION_TASK_PROFILES = 32;
5
+ export interface SessionTaskProfileRecord {
6
+ baseProfileId: string;
7
+ authorProfileId?: string;
8
+ profile: OrchestrationProfile;
9
+ }
10
+ export interface SessionTaskProfileLoadResult {
11
+ records: SessionTaskProfileRecord[];
12
+ registry: ReadonlyMap<string, SessionTaskProfileRecord>;
13
+ diagnostics: string[];
14
+ }
15
+ /**
16
+ * Append-only task-profile storage on the active session branch.
17
+ *
18
+ * The common append path walks only entries added since the cached leaf. Branching away from the
19
+ * cached leaf deliberately rebuilds from parent links so abandoned task profiles cannot leak into
20
+ * the active branch.
21
+ */
22
+ export declare class SessionTaskProfileStore {
23
+ private readonly sessionManager;
24
+ private cachedLeafId;
25
+ private cachedResult;
26
+ constructor(sessionManager: SessionManager);
27
+ load(): SessionTaskProfileLoadResult;
28
+ append(input: SessionTaskProfileRecord): SessionTaskProfileRecord;
29
+ private cloneResult;
30
+ }
31
+ //# sourceMappingURL=session-task-profile-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-task-profile-store.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/session-task-profile-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAG3D,eAAO,MAAM,gCAAgC,yBAAyB,CAAC;AACvE,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAG5C,MAAM,WAAW,wBAAwB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,4BAA4B;IAC5C,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,WAAW,EAAE,MAAM,EAAE,CAAC;CACtB;AAoCD;;;;;;GAMG;AACH,qBAAa,uBAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,YAAY,CAIlB;IAEF,YAAY,cAAc,EAAE,cAAc,EAEzC;IAED,IAAI,IAAI,4BAA4B,CAqDnC;IAED,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,wBAAwB,CAiChE;IAED,OAAO,CAAC,WAAW;CAQnB"}
@@ -0,0 +1,138 @@
1
+ import { parseOrchestrationProfile } from "./profile-registry.js";
2
+ export const SESSION_TASK_PROFILE_CUSTOM_TYPE = "session_task_profile";
3
+ export const MAX_SESSION_TASK_PROFILES = 32;
4
+ const BRANCH_STORAGE_REQUIRED = "session task profiles require branch-aware session storage";
5
+ function parseRecord(value) {
6
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
7
+ throw new Error("session task profile record must be an object");
8
+ }
9
+ const candidate = value;
10
+ const keys = Object.keys(candidate);
11
+ if (candidate.version !== 1 ||
12
+ keys.some((key) => !["version", "baseProfileId", "authorProfileId", "profile"].includes(key)) ||
13
+ typeof candidate.baseProfileId !== "string" ||
14
+ candidate.baseProfileId.length === 0 ||
15
+ (candidate.authorProfileId !== undefined &&
16
+ (typeof candidate.authorProfileId !== "string" || candidate.authorProfileId.length === 0))) {
17
+ throw new Error("session task profile record is invalid");
18
+ }
19
+ return {
20
+ baseProfileId: candidate.baseProfileId,
21
+ ...(candidate.authorProfileId ? { authorProfileId: candidate.authorProfileId } : {}),
22
+ profile: parseOrchestrationProfile(candidate.profile),
23
+ };
24
+ }
25
+ function cloneRecord(record) {
26
+ return structuredClone(record);
27
+ }
28
+ /**
29
+ * Append-only task-profile storage on the active session branch.
30
+ *
31
+ * The common append path walks only entries added since the cached leaf. Branching away from the
32
+ * cached leaf deliberately rebuilds from parent links so abandoned task profiles cannot leak into
33
+ * the active branch.
34
+ */
35
+ export class SessionTaskProfileStore {
36
+ constructor(sessionManager) {
37
+ this.cachedResult = {
38
+ records: [],
39
+ registry: new Map(),
40
+ diagnostics: [],
41
+ };
42
+ this.sessionManager = sessionManager;
43
+ }
44
+ load() {
45
+ if (typeof this.sessionManager.getLeafId !== "function" || typeof this.sessionManager.getEntry !== "function") {
46
+ this.cachedLeafId = undefined;
47
+ this.cachedResult = {
48
+ records: [],
49
+ registry: new Map(),
50
+ diagnostics: [BRANCH_STORAGE_REQUIRED],
51
+ };
52
+ return this.cloneResult(this.cachedResult);
53
+ }
54
+ const leafId = this.sessionManager.getLeafId();
55
+ if (this.cachedLeafId === leafId)
56
+ return this.cloneResult(this.cachedResult);
57
+ const appended = [];
58
+ let cursor = leafId;
59
+ while (cursor !== null && cursor !== this.cachedLeafId) {
60
+ const entry = this.sessionManager.getEntry(cursor);
61
+ if (!entry) {
62
+ cursor = null;
63
+ break;
64
+ }
65
+ appended.push(entry);
66
+ cursor = entry.parentId;
67
+ }
68
+ const extendsCache = this.cachedLeafId !== undefined && cursor === this.cachedLeafId;
69
+ const records = extendsCache ? this.cachedResult.records.map(cloneRecord) : [];
70
+ const diagnostics = extendsCache ? [...this.cachedResult.diagnostics] : [];
71
+ const registry = new Map(records.map((record) => [record.profile.profileId, record]));
72
+ for (let index = appended.length - 1; index >= 0; index--) {
73
+ const entry = appended[index];
74
+ if (entry.type !== "custom" || entry.customType !== SESSION_TASK_PROFILE_CUSTOM_TYPE)
75
+ continue;
76
+ try {
77
+ const record = parseRecord(entry.data);
78
+ if (records.length >= MAX_SESSION_TASK_PROFILES) {
79
+ diagnostics.push(`ignored ${record.profile.profileId}: session task profile limit exceeded`);
80
+ continue;
81
+ }
82
+ if (registry.has(record.profile.profileId)) {
83
+ diagnostics.push(`ignored duplicate session task profile ${record.profile.profileId}`);
84
+ continue;
85
+ }
86
+ records.push(record);
87
+ registry.set(record.profile.profileId, record);
88
+ }
89
+ catch (error) {
90
+ diagnostics.push(error instanceof Error ? error.message : String(error));
91
+ }
92
+ }
93
+ this.cachedLeafId = leafId;
94
+ this.cachedResult = { records, registry, diagnostics };
95
+ return this.cloneResult(this.cachedResult);
96
+ }
97
+ append(input) {
98
+ if (typeof this.sessionManager.getLeafId !== "function" ||
99
+ typeof this.sessionManager.getEntry !== "function" ||
100
+ typeof this.sessionManager.appendCustomEntry !== "function") {
101
+ throw new Error(BRANCH_STORAGE_REQUIRED);
102
+ }
103
+ const loaded = this.load();
104
+ if (loaded.records.length >= MAX_SESSION_TASK_PROFILES) {
105
+ throw new Error(`session task profile limit (${MAX_SESSION_TASK_PROFILES}) reached`);
106
+ }
107
+ if (loaded.registry.has(input.profile.profileId)) {
108
+ throw new Error(`session task profile '${input.profile.profileId}' already exists`);
109
+ }
110
+ const record = cloneRecord(input);
111
+ parseOrchestrationProfile(record.profile);
112
+ const persisted = {
113
+ version: 1,
114
+ baseProfileId: record.baseProfileId,
115
+ ...(record.authorProfileId ? { authorProfileId: record.authorProfileId } : {}),
116
+ profile: record.profile,
117
+ };
118
+ this.sessionManager.appendCustomEntry(SESSION_TASK_PROFILE_CUSTOM_TYPE, persisted);
119
+ const registry = new Map(loaded.registry);
120
+ registry.set(record.profile.profileId, record);
121
+ this.cachedLeafId = this.sessionManager.getLeafId();
122
+ this.cachedResult = {
123
+ records: [...loaded.records, record],
124
+ registry,
125
+ diagnostics: loaded.diagnostics,
126
+ };
127
+ return cloneRecord(record);
128
+ }
129
+ cloneResult(result) {
130
+ const records = result.records.map(cloneRecord);
131
+ return {
132
+ records,
133
+ registry: new Map(records.map((record) => [record.profile.profileId, record])),
134
+ diagnostics: [...result.diagnostics],
135
+ };
136
+ }
137
+ }
138
+ //# sourceMappingURL=session-task-profile-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-task-profile-store.js","sourceRoot":"","sources":["../../../src/core/orchestration/session-task-profile-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionEntry, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport type { OrchestrationProfile } from \"./contracts.ts\";\nimport { parseOrchestrationProfile } from \"./profile-registry.ts\";\n\nexport const SESSION_TASK_PROFILE_CUSTOM_TYPE = \"session_task_profile\";\nexport const MAX_SESSION_TASK_PROFILES = 32;\nconst BRANCH_STORAGE_REQUIRED = \"session task profiles require branch-aware session storage\";\n\nexport interface SessionTaskProfileRecord {\n\tbaseProfileId: string;\n\tauthorProfileId?: string;\n\tprofile: OrchestrationProfile;\n}\n\nexport interface SessionTaskProfileLoadResult {\n\trecords: SessionTaskProfileRecord[];\n\tregistry: ReadonlyMap<string, SessionTaskProfileRecord>;\n\tdiagnostics: string[];\n}\n\ninterface PersistedSessionTaskProfileRecord {\n\tversion: 1;\n\tbaseProfileId: string;\n\tauthorProfileId?: string;\n\tprofile: OrchestrationProfile;\n}\n\nfunction parseRecord(value: unknown): SessionTaskProfileRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\tthrow new Error(\"session task profile record must be an object\");\n\t}\n\tconst candidate = value as Partial<PersistedSessionTaskProfileRecord>;\n\tconst keys = Object.keys(candidate);\n\tif (\n\t\tcandidate.version !== 1 ||\n\t\tkeys.some((key) => ![\"version\", \"baseProfileId\", \"authorProfileId\", \"profile\"].includes(key)) ||\n\t\ttypeof candidate.baseProfileId !== \"string\" ||\n\t\tcandidate.baseProfileId.length === 0 ||\n\t\t(candidate.authorProfileId !== undefined &&\n\t\t\t(typeof candidate.authorProfileId !== \"string\" || candidate.authorProfileId.length === 0))\n\t) {\n\t\tthrow new Error(\"session task profile record is invalid\");\n\t}\n\treturn {\n\t\tbaseProfileId: candidate.baseProfileId,\n\t\t...(candidate.authorProfileId ? { authorProfileId: candidate.authorProfileId } : {}),\n\t\tprofile: parseOrchestrationProfile(candidate.profile),\n\t};\n}\n\nfunction cloneRecord(record: SessionTaskProfileRecord): SessionTaskProfileRecord {\n\treturn structuredClone(record);\n}\n\n/**\n * Append-only task-profile storage on the active session branch.\n *\n * The common append path walks only entries added since the cached leaf. Branching away from the\n * cached leaf deliberately rebuilds from parent links so abandoned task profiles cannot leak into\n * the active branch.\n */\nexport class SessionTaskProfileStore {\n\tprivate readonly sessionManager: SessionManager;\n\tprivate cachedLeafId: string | null | undefined;\n\tprivate cachedResult: SessionTaskProfileLoadResult = {\n\t\trecords: [],\n\t\tregistry: new Map(),\n\t\tdiagnostics: [],\n\t};\n\n\tconstructor(sessionManager: SessionManager) {\n\t\tthis.sessionManager = sessionManager;\n\t}\n\n\tload(): SessionTaskProfileLoadResult {\n\t\tif (typeof this.sessionManager.getLeafId !== \"function\" || typeof this.sessionManager.getEntry !== \"function\") {\n\t\t\tthis.cachedLeafId = undefined;\n\t\t\tthis.cachedResult = {\n\t\t\t\trecords: [],\n\t\t\t\tregistry: new Map(),\n\t\t\t\tdiagnostics: [BRANCH_STORAGE_REQUIRED],\n\t\t\t};\n\t\t\treturn this.cloneResult(this.cachedResult);\n\t\t}\n\t\tconst leafId = this.sessionManager.getLeafId();\n\t\tif (this.cachedLeafId === leafId) return this.cloneResult(this.cachedResult);\n\n\t\tconst appended: SessionEntry[] = [];\n\t\tlet cursor = leafId;\n\t\twhile (cursor !== null && cursor !== this.cachedLeafId) {\n\t\t\tconst entry = this.sessionManager.getEntry(cursor);\n\t\t\tif (!entry) {\n\t\t\t\tcursor = null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tappended.push(entry);\n\t\t\tcursor = entry.parentId;\n\t\t}\n\n\t\tconst extendsCache = this.cachedLeafId !== undefined && cursor === this.cachedLeafId;\n\t\tconst records = extendsCache ? this.cachedResult.records.map(cloneRecord) : [];\n\t\tconst diagnostics = extendsCache ? [...this.cachedResult.diagnostics] : [];\n\t\tconst registry = new Map(records.map((record) => [record.profile.profileId, record]));\n\n\t\tfor (let index = appended.length - 1; index >= 0; index--) {\n\t\t\tconst entry = appended[index];\n\t\t\tif (entry.type !== \"custom\" || entry.customType !== SESSION_TASK_PROFILE_CUSTOM_TYPE) continue;\n\t\t\ttry {\n\t\t\t\tconst record = parseRecord(entry.data);\n\t\t\t\tif (records.length >= MAX_SESSION_TASK_PROFILES) {\n\t\t\t\t\tdiagnostics.push(`ignored ${record.profile.profileId}: session task profile limit exceeded`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (registry.has(record.profile.profileId)) {\n\t\t\t\t\tdiagnostics.push(`ignored duplicate session task profile ${record.profile.profileId}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\trecords.push(record);\n\t\t\t\tregistry.set(record.profile.profileId, record);\n\t\t\t} catch (error) {\n\t\t\t\tdiagnostics.push(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t}\n\n\t\tthis.cachedLeafId = leafId;\n\t\tthis.cachedResult = { records, registry, diagnostics };\n\t\treturn this.cloneResult(this.cachedResult);\n\t}\n\n\tappend(input: SessionTaskProfileRecord): SessionTaskProfileRecord {\n\t\tif (\n\t\t\ttypeof this.sessionManager.getLeafId !== \"function\" ||\n\t\t\ttypeof this.sessionManager.getEntry !== \"function\" ||\n\t\t\ttypeof this.sessionManager.appendCustomEntry !== \"function\"\n\t\t) {\n\t\t\tthrow new Error(BRANCH_STORAGE_REQUIRED);\n\t\t}\n\t\tconst loaded = this.load();\n\t\tif (loaded.records.length >= MAX_SESSION_TASK_PROFILES) {\n\t\t\tthrow new Error(`session task profile limit (${MAX_SESSION_TASK_PROFILES}) reached`);\n\t\t}\n\t\tif (loaded.registry.has(input.profile.profileId)) {\n\t\t\tthrow new Error(`session task profile '${input.profile.profileId}' already exists`);\n\t\t}\n\t\tconst record = cloneRecord(input);\n\t\tparseOrchestrationProfile(record.profile);\n\t\tconst persisted: PersistedSessionTaskProfileRecord = {\n\t\t\tversion: 1,\n\t\t\tbaseProfileId: record.baseProfileId,\n\t\t\t...(record.authorProfileId ? { authorProfileId: record.authorProfileId } : {}),\n\t\t\tprofile: record.profile,\n\t\t};\n\t\tthis.sessionManager.appendCustomEntry(SESSION_TASK_PROFILE_CUSTOM_TYPE, persisted);\n\t\tconst registry = new Map(loaded.registry);\n\t\tregistry.set(record.profile.profileId, record);\n\t\tthis.cachedLeafId = this.sessionManager.getLeafId();\n\t\tthis.cachedResult = {\n\t\t\trecords: [...loaded.records, record],\n\t\t\tregistry,\n\t\t\tdiagnostics: loaded.diagnostics,\n\t\t};\n\t\treturn cloneRecord(record);\n\t}\n\n\tprivate cloneResult(result: SessionTaskProfileLoadResult): SessionTaskProfileLoadResult {\n\t\tconst records = result.records.map(cloneRecord);\n\t\treturn {\n\t\t\trecords,\n\t\t\tregistry: new Map(records.map((record) => [record.profile.profileId, record])),\n\t\t\tdiagnostics: [...result.diagnostics],\n\t\t};\n\t}\n}\n"]}
@@ -0,0 +1,58 @@
1
+ import type { ModelRegistry } from "../model-registry.ts";
2
+ import type { SettingsManager } from "../settings-manager.ts";
3
+ import type { OrchestrationProfile, OrchestrationThinkingLevel, RiskBudget } from "./contracts.ts";
4
+ import type { SessionTaskProfileStore } from "./session-task-profile-store.ts";
5
+ export interface TaskProfileModelSelection {
6
+ provider: string;
7
+ modelId: string;
8
+ thinkingLevel: OrchestrationThinkingLevel;
9
+ }
10
+ export interface TaskProfileCreateInput {
11
+ task: string;
12
+ baseProfileId?: string;
13
+ model?: TaskProfileModelSelection;
14
+ toolNames?: readonly string[];
15
+ resourceProfileNames?: readonly string[];
16
+ budget?: RiskBudget;
17
+ }
18
+ export interface TaskProfileInspection {
19
+ baseProfiles: Array<{
20
+ profileId: string;
21
+ role: string;
22
+ description: string;
23
+ }>;
24
+ models: Array<{
25
+ provider: string;
26
+ modelId: string;
27
+ thinkingLevels: readonly OrchestrationThinkingLevel[];
28
+ }>;
29
+ }
30
+ export interface TaskProfileCreateResult {
31
+ created: boolean;
32
+ reason?: string;
33
+ profileId?: string;
34
+ baseProfileId?: string;
35
+ changedFields?: string[];
36
+ }
37
+ export interface TaskProfileWriterPort {
38
+ inspectTaskProfileOptions(): TaskProfileInspection;
39
+ createTaskProfile(input: TaskProfileCreateInput): TaskProfileCreateResult;
40
+ }
41
+ export interface TaskProfileWriterOptions {
42
+ agentDir: string;
43
+ cwd: string;
44
+ store: SessionTaskProfileStore;
45
+ getSettingsManager(): SettingsManager;
46
+ getModelRegistry(): ModelRegistry;
47
+ isModelExhausted(provider: string, modelId: string): boolean;
48
+ getActiveOrchestrationProfile(): OrchestrationProfile | undefined;
49
+ }
50
+ export declare class TaskProfileWriter implements TaskProfileWriterPort {
51
+ private readonly options;
52
+ constructor(options: TaskProfileWriterOptions);
53
+ inspectTaskProfileOptions(): TaskProfileInspection;
54
+ createTaskProfile(input: TaskProfileCreateInput): TaskProfileCreateResult;
55
+ private authorizedBaseProfiles;
56
+ private loadOwnerProfiles;
57
+ }
58
+ //# sourceMappingURL=task-profile-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-profile-writer.d.ts","sourceRoot":"","sources":["../../../src/core/orchestration/task-profile-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAGX,oBAAoB,EACpB,0BAA0B,EAC1B,UAAU,EACV,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,WAAW,yBAAyB;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,0BAA0B,CAAC;CAC1C;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,oBAAoB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,MAAM,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACrC,YAAY,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9E,MAAM,EAAE,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,SAAS,0BAA0B,EAAE,CAAC;KACtD,CAAC,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACrC,yBAAyB,IAAI,qBAAqB,CAAC;IACnD,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CAAC;CAC1E;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,uBAAuB,CAAC;IAC/B,kBAAkB,IAAI,eAAe,CAAC;IACtC,gBAAgB,IAAI,aAAa,CAAC;IAClC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7D,6BAA6B,IAAI,oBAAoB,GAAG,SAAS,CAAC;CAClE;AAyDD,qBAAa,iBAAkB,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAEnD,YAAY,OAAO,EAAE,wBAAwB,EAE5C;IAED,yBAAyB,IAAI,qBAAqB,CAkBjD;IAED,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CAqExE;IAED,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,iBAAiB;CAQzB"}
@@ -0,0 +1,165 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { getSupportedThinkingLevels } from "@caupulican/pi-ai";
3
+ import { MAX_ORCHESTRATION_DESCRIPTION_LENGTH } from "./contracts.js";
4
+ import { resolvePinnedOrchestrationModel } from "./model-binding.js";
5
+ import { validateOrchestrationProfile } from "./profile-registry.js";
6
+ import { OrchestrationProfileStore } from "./profile-store.js";
7
+ const MAX_INSPECTED_MODELS = 64;
8
+ const MAX_TASK_DESCRIPTION_LENGTH = 3_500;
9
+ const MAX_BUDGET_KEYS = ["maxTokens", "maxWallClockMs", "maxCostUsd", "maxAttempts", "maxToolCalls"];
10
+ function sameStrings(left, right) {
11
+ return left.length === right.length && left.every((value, index) => value === right[index]);
12
+ }
13
+ function isExactSubset(candidate, ceiling) {
14
+ const allowed = new Set(ceiling);
15
+ const unique = new Set(candidate);
16
+ return unique.size === candidate.length && candidate.every((value) => allowed.has(value));
17
+ }
18
+ function narrowBudget(base, patch) {
19
+ if (!patch)
20
+ return structuredClone(base);
21
+ const narrowed = { ...base };
22
+ for (const key of MAX_BUDGET_KEYS) {
23
+ const requested = patch[key];
24
+ if (requested === undefined)
25
+ continue;
26
+ const ceiling = base[key];
27
+ if (ceiling !== undefined && requested > ceiling)
28
+ return undefined;
29
+ narrowed[key] = requested;
30
+ }
31
+ if (patch.requireApprovalAboveCostUsd !== undefined) {
32
+ const ceiling = base.requireApprovalAboveCostUsd;
33
+ if (ceiling !== undefined && patch.requireApprovalAboveCostUsd > ceiling)
34
+ return undefined;
35
+ narrowed.requireApprovalAboveCostUsd = patch.requireApprovalAboveCostUsd;
36
+ }
37
+ return narrowed;
38
+ }
39
+ function sameBudget(left, right) {
40
+ return (MAX_BUDGET_KEYS.every((key) => left[key] === right[key]) &&
41
+ left.requireApprovalAboveCostUsd === right.requireApprovalAboveCostUsd);
42
+ }
43
+ function sameModelPolicy(left, right) {
44
+ return (left.mode === right.mode &&
45
+ left.candidates.length === right.candidates.length &&
46
+ left.candidates.every((candidate, index) => {
47
+ const other = right.candidates[index];
48
+ return (other !== undefined &&
49
+ candidate.provider === other.provider &&
50
+ candidate.modelId === other.modelId &&
51
+ candidate.thinkingLevel === other.thinkingLevel);
52
+ }));
53
+ }
54
+ export class TaskProfileWriter {
55
+ constructor(options) {
56
+ this.options = options;
57
+ }
58
+ inspectTaskProfileOptions() {
59
+ const baseProfiles = this.authorizedBaseProfiles().map((profile) => ({
60
+ profileId: profile.profileId,
61
+ role: profile.role,
62
+ description: profile.description,
63
+ }));
64
+ const models = this.options
65
+ .getModelRegistry()
66
+ .getAvailable()
67
+ .filter((model) => !this.options.isModelExhausted(model.provider, model.id))
68
+ .sort((left, right) => `${left.provider}/${left.id}`.localeCompare(`${right.provider}/${right.id}`))
69
+ .slice(0, MAX_INSPECTED_MODELS)
70
+ .map((model) => ({
71
+ provider: model.provider,
72
+ modelId: model.id,
73
+ thinkingLevels: getSupportedThinkingLevels(model),
74
+ }));
75
+ return { baseProfiles, models };
76
+ }
77
+ createTaskProfile(input) {
78
+ try {
79
+ const task = input.task.trim();
80
+ if (!task || task.length > MAX_TASK_DESCRIPTION_LENGTH) {
81
+ return { created: false, reason: "task_profile_description_invalid" };
82
+ }
83
+ const bases = this.authorizedBaseProfiles();
84
+ const baseProfileId = input.baseProfileId?.trim() || (bases.length === 1 ? bases[0].profileId : undefined);
85
+ if (!baseProfileId)
86
+ return { created: false, reason: "task_profile_base_required" };
87
+ const ownerProfiles = this.loadOwnerProfiles();
88
+ const base = ownerProfiles.get(baseProfileId);
89
+ if (!base || base.role === "orchestrator") {
90
+ return { created: false, reason: "task_profile_base_not_found" };
91
+ }
92
+ if (!bases.some((candidate) => candidate.profileId === baseProfileId)) {
93
+ return { created: false, reason: "task_profile_base_not_authorized" };
94
+ }
95
+ const toolNames = input.toolNames ? [...input.toolNames] : [...base.toolNames];
96
+ if (!isExactSubset(toolNames, base.toolNames)) {
97
+ return { created: false, reason: "task_profile_tool_authority_expansion" };
98
+ }
99
+ const resourceProfileNames = input.resourceProfileNames
100
+ ? [...input.resourceProfileNames]
101
+ : [...base.resourceProfileNames];
102
+ if (!isExactSubset(resourceProfileNames, base.resourceProfileNames)) {
103
+ return { created: false, reason: "task_profile_resource_authority_expansion" };
104
+ }
105
+ const budget = narrowBudget(base.budget, input.budget);
106
+ if (!budget)
107
+ return { created: false, reason: "task_profile_budget_expansion" };
108
+ let modelPolicy = structuredClone(base.modelPolicy);
109
+ if (input.model) {
110
+ const binding = { ...input.model };
111
+ const resolved = resolvePinnedOrchestrationModel(binding, this.options.getModelRegistry(), (model) => this.options.isModelExhausted(model.provider, model.id));
112
+ if (!resolved)
113
+ return { created: false, reason: "task_profile_model_unavailable" };
114
+ modelPolicy = { mode: "fixed", candidates: [binding] };
115
+ }
116
+ const now = new Date().toISOString();
117
+ const profile = structuredClone(base);
118
+ delete profile.sourcePath;
119
+ profile.profileId = `task-${randomUUID()}`;
120
+ profile.description = `Task-scoped worker: ${task}`.slice(0, MAX_ORCHESTRATION_DESCRIPTION_LENGTH);
121
+ profile.modelPolicy = modelPolicy;
122
+ profile.toolNames = toolNames;
123
+ profile.resourceProfileNames = resourceProfileNames;
124
+ profile.budget = budget;
125
+ profile.createdAt = now;
126
+ profile.updatedAt = now;
127
+ validateOrchestrationProfile(profile);
128
+ const activeProfile = this.options.getActiveOrchestrationProfile();
129
+ this.options.store.append({
130
+ baseProfileId,
131
+ ...(activeProfile ? { authorProfileId: activeProfile.profileId } : {}),
132
+ profile,
133
+ });
134
+ const changedFields = ["description"];
135
+ if (input.model && !sameModelPolicy(modelPolicy, base.modelPolicy))
136
+ changedFields.push("model");
137
+ if (!sameStrings(toolNames, base.toolNames))
138
+ changedFields.push("tools");
139
+ if (!sameStrings(resourceProfileNames, base.resourceProfileNames))
140
+ changedFields.push("resources");
141
+ if (!sameBudget(budget, base.budget))
142
+ changedFields.push("budget");
143
+ return { created: true, profileId: profile.profileId, baseProfileId, changedFields };
144
+ }
145
+ catch (error) {
146
+ return { created: false, reason: error instanceof Error ? error.message : String(error) };
147
+ }
148
+ }
149
+ authorizedBaseProfiles() {
150
+ const active = this.options.getActiveOrchestrationProfile();
151
+ if (active && active.role !== "orchestrator")
152
+ return [];
153
+ const allowed = active ? new Set(active.dispatchProfileIds) : undefined;
154
+ return [...this.loadOwnerProfiles().values()].filter((profile) => profile.role !== "orchestrator" && (!allowed || allowed.has(profile.profileId)));
155
+ }
156
+ loadOwnerProfiles() {
157
+ const profiles = new OrchestrationProfileStore({
158
+ agentDir: this.options.agentDir,
159
+ cwd: this.options.cwd,
160
+ projectTrusted: this.options.getSettingsManager().isProjectTrusted(),
161
+ }).load().profiles;
162
+ return new Map(profiles.map((profile) => [profile.profileId, profile]));
163
+ }
164
+ }
165
+ //# sourceMappingURL=task-profile-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-profile-writer.js","sourceRoot":"","sources":["../../../src/core/orchestration/task-profile-writer.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { getSupportedThinkingLevels } from \"@caupulican/pi-ai\";\nimport type { ModelRegistry } from \"../model-registry.ts\";\nimport type { SettingsManager } from \"../settings-manager.ts\";\nimport type {\n\tOrchestrationModelBinding,\n\tOrchestrationModelPolicy,\n\tOrchestrationProfile,\n\tOrchestrationThinkingLevel,\n\tRiskBudget,\n} from \"./contracts.ts\";\nimport { MAX_ORCHESTRATION_DESCRIPTION_LENGTH } from \"./contracts.ts\";\nimport { resolvePinnedOrchestrationModel } from \"./model-binding.ts\";\nimport { validateOrchestrationProfile } from \"./profile-registry.ts\";\nimport { OrchestrationProfileStore } from \"./profile-store.ts\";\nimport type { SessionTaskProfileStore } from \"./session-task-profile-store.ts\";\n\nexport interface TaskProfileModelSelection {\n\tprovider: string;\n\tmodelId: string;\n\tthinkingLevel: OrchestrationThinkingLevel;\n}\n\nexport interface TaskProfileCreateInput {\n\ttask: string;\n\tbaseProfileId?: string;\n\tmodel?: TaskProfileModelSelection;\n\ttoolNames?: readonly string[];\n\tresourceProfileNames?: readonly string[];\n\tbudget?: RiskBudget;\n}\n\nexport interface TaskProfileInspection {\n\tbaseProfiles: Array<{ profileId: string; role: string; description: string }>;\n\tmodels: Array<{\n\t\tprovider: string;\n\t\tmodelId: string;\n\t\tthinkingLevels: readonly OrchestrationThinkingLevel[];\n\t}>;\n}\n\nexport interface TaskProfileCreateResult {\n\tcreated: boolean;\n\treason?: string;\n\tprofileId?: string;\n\tbaseProfileId?: string;\n\tchangedFields?: string[];\n}\n\nexport interface TaskProfileWriterPort {\n\tinspectTaskProfileOptions(): TaskProfileInspection;\n\tcreateTaskProfile(input: TaskProfileCreateInput): TaskProfileCreateResult;\n}\n\nexport interface TaskProfileWriterOptions {\n\tagentDir: string;\n\tcwd: string;\n\tstore: SessionTaskProfileStore;\n\tgetSettingsManager(): SettingsManager;\n\tgetModelRegistry(): ModelRegistry;\n\tisModelExhausted(provider: string, modelId: string): boolean;\n\tgetActiveOrchestrationProfile(): OrchestrationProfile | undefined;\n}\n\nconst MAX_INSPECTED_MODELS = 64;\nconst MAX_TASK_DESCRIPTION_LENGTH = 3_500;\nconst MAX_BUDGET_KEYS = [\"maxTokens\", \"maxWallClockMs\", \"maxCostUsd\", \"maxAttempts\", \"maxToolCalls\"] as const;\n\nfunction sameStrings(left: readonly string[], right: readonly string[]): boolean {\n\treturn left.length === right.length && left.every((value, index) => value === right[index]);\n}\n\nfunction isExactSubset(candidate: readonly string[], ceiling: readonly string[]): boolean {\n\tconst allowed = new Set(ceiling);\n\tconst unique = new Set(candidate);\n\treturn unique.size === candidate.length && candidate.every((value) => allowed.has(value));\n}\n\nfunction narrowBudget(base: RiskBudget, patch: RiskBudget | undefined): RiskBudget | undefined {\n\tif (!patch) return structuredClone(base);\n\tconst narrowed: RiskBudget = { ...base };\n\tfor (const key of MAX_BUDGET_KEYS) {\n\t\tconst requested = patch[key];\n\t\tif (requested === undefined) continue;\n\t\tconst ceiling = base[key];\n\t\tif (ceiling !== undefined && requested > ceiling) return undefined;\n\t\tnarrowed[key] = requested;\n\t}\n\tif (patch.requireApprovalAboveCostUsd !== undefined) {\n\t\tconst ceiling = base.requireApprovalAboveCostUsd;\n\t\tif (ceiling !== undefined && patch.requireApprovalAboveCostUsd > ceiling) return undefined;\n\t\tnarrowed.requireApprovalAboveCostUsd = patch.requireApprovalAboveCostUsd;\n\t}\n\treturn narrowed;\n}\n\nfunction sameBudget(left: RiskBudget, right: RiskBudget): boolean {\n\treturn (\n\t\tMAX_BUDGET_KEYS.every((key) => left[key] === right[key]) &&\n\t\tleft.requireApprovalAboveCostUsd === right.requireApprovalAboveCostUsd\n\t);\n}\n\nfunction sameModelPolicy(left: OrchestrationModelPolicy, right: OrchestrationModelPolicy): boolean {\n\treturn (\n\t\tleft.mode === right.mode &&\n\t\tleft.candidates.length === right.candidates.length &&\n\t\tleft.candidates.every((candidate, index) => {\n\t\t\tconst other = right.candidates[index];\n\t\t\treturn (\n\t\t\t\tother !== undefined &&\n\t\t\t\tcandidate.provider === other.provider &&\n\t\t\t\tcandidate.modelId === other.modelId &&\n\t\t\t\tcandidate.thinkingLevel === other.thinkingLevel\n\t\t\t);\n\t\t})\n\t);\n}\n\nexport class TaskProfileWriter implements TaskProfileWriterPort {\n\tprivate readonly options: TaskProfileWriterOptions;\n\n\tconstructor(options: TaskProfileWriterOptions) {\n\t\tthis.options = options;\n\t}\n\n\tinspectTaskProfileOptions(): TaskProfileInspection {\n\t\tconst baseProfiles = this.authorizedBaseProfiles().map((profile) => ({\n\t\t\tprofileId: profile.profileId,\n\t\t\trole: profile.role,\n\t\t\tdescription: profile.description,\n\t\t}));\n\t\tconst models = this.options\n\t\t\t.getModelRegistry()\n\t\t\t.getAvailable()\n\t\t\t.filter((model) => !this.options.isModelExhausted(model.provider, model.id))\n\t\t\t.sort((left, right) => `${left.provider}/${left.id}`.localeCompare(`${right.provider}/${right.id}`))\n\t\t\t.slice(0, MAX_INSPECTED_MODELS)\n\t\t\t.map((model) => ({\n\t\t\t\tprovider: model.provider,\n\t\t\t\tmodelId: model.id,\n\t\t\t\tthinkingLevels: getSupportedThinkingLevels(model),\n\t\t\t}));\n\t\treturn { baseProfiles, models };\n\t}\n\n\tcreateTaskProfile(input: TaskProfileCreateInput): TaskProfileCreateResult {\n\t\ttry {\n\t\t\tconst task = input.task.trim();\n\t\t\tif (!task || task.length > MAX_TASK_DESCRIPTION_LENGTH) {\n\t\t\t\treturn { created: false, reason: \"task_profile_description_invalid\" };\n\t\t\t}\n\t\t\tconst bases = this.authorizedBaseProfiles();\n\t\t\tconst baseProfileId = input.baseProfileId?.trim() || (bases.length === 1 ? bases[0].profileId : undefined);\n\t\t\tif (!baseProfileId) return { created: false, reason: \"task_profile_base_required\" };\n\t\t\tconst ownerProfiles = this.loadOwnerProfiles();\n\t\t\tconst base = ownerProfiles.get(baseProfileId);\n\t\t\tif (!base || base.role === \"orchestrator\") {\n\t\t\t\treturn { created: false, reason: \"task_profile_base_not_found\" };\n\t\t\t}\n\t\t\tif (!bases.some((candidate) => candidate.profileId === baseProfileId)) {\n\t\t\t\treturn { created: false, reason: \"task_profile_base_not_authorized\" };\n\t\t\t}\n\n\t\t\tconst toolNames = input.toolNames ? [...input.toolNames] : [...base.toolNames];\n\t\t\tif (!isExactSubset(toolNames, base.toolNames)) {\n\t\t\t\treturn { created: false, reason: \"task_profile_tool_authority_expansion\" };\n\t\t\t}\n\t\t\tconst resourceProfileNames = input.resourceProfileNames\n\t\t\t\t? [...input.resourceProfileNames]\n\t\t\t\t: [...base.resourceProfileNames];\n\t\t\tif (!isExactSubset(resourceProfileNames, base.resourceProfileNames)) {\n\t\t\t\treturn { created: false, reason: \"task_profile_resource_authority_expansion\" };\n\t\t\t}\n\t\t\tconst budget = narrowBudget(base.budget, input.budget);\n\t\t\tif (!budget) return { created: false, reason: \"task_profile_budget_expansion\" };\n\n\t\t\tlet modelPolicy = structuredClone(base.modelPolicy);\n\t\t\tif (input.model) {\n\t\t\t\tconst binding: OrchestrationModelBinding = { ...input.model };\n\t\t\t\tconst resolved = resolvePinnedOrchestrationModel(binding, this.options.getModelRegistry(), (model) =>\n\t\t\t\t\tthis.options.isModelExhausted(model.provider, model.id),\n\t\t\t\t);\n\t\t\t\tif (!resolved) return { created: false, reason: \"task_profile_model_unavailable\" };\n\t\t\t\tmodelPolicy = { mode: \"fixed\", candidates: [binding] };\n\t\t\t}\n\n\t\t\tconst now = new Date().toISOString();\n\t\t\tconst profile = structuredClone(base);\n\t\t\tdelete profile.sourcePath;\n\t\t\tprofile.profileId = `task-${randomUUID()}`;\n\t\t\tprofile.description = `Task-scoped worker: ${task}`.slice(0, MAX_ORCHESTRATION_DESCRIPTION_LENGTH);\n\t\t\tprofile.modelPolicy = modelPolicy;\n\t\t\tprofile.toolNames = toolNames;\n\t\t\tprofile.resourceProfileNames = resourceProfileNames;\n\t\t\tprofile.budget = budget;\n\t\t\tprofile.createdAt = now;\n\t\t\tprofile.updatedAt = now;\n\t\t\tvalidateOrchestrationProfile(profile);\n\n\t\t\tconst activeProfile = this.options.getActiveOrchestrationProfile();\n\t\t\tthis.options.store.append({\n\t\t\t\tbaseProfileId,\n\t\t\t\t...(activeProfile ? { authorProfileId: activeProfile.profileId } : {}),\n\t\t\t\tprofile,\n\t\t\t});\n\t\t\tconst changedFields = [\"description\"];\n\t\t\tif (input.model && !sameModelPolicy(modelPolicy, base.modelPolicy)) changedFields.push(\"model\");\n\t\t\tif (!sameStrings(toolNames, base.toolNames)) changedFields.push(\"tools\");\n\t\t\tif (!sameStrings(resourceProfileNames, base.resourceProfileNames)) changedFields.push(\"resources\");\n\t\t\tif (!sameBudget(budget, base.budget)) changedFields.push(\"budget\");\n\t\t\treturn { created: true, profileId: profile.profileId, baseProfileId, changedFields };\n\t\t} catch (error) {\n\t\t\treturn { created: false, reason: error instanceof Error ? error.message : String(error) };\n\t\t}\n\t}\n\n\tprivate authorizedBaseProfiles(): OrchestrationProfile[] {\n\t\tconst active = this.options.getActiveOrchestrationProfile();\n\t\tif (active && active.role !== \"orchestrator\") return [];\n\t\tconst allowed = active ? new Set(active.dispatchProfileIds) : undefined;\n\t\treturn [...this.loadOwnerProfiles().values()].filter(\n\t\t\t(profile) => profile.role !== \"orchestrator\" && (!allowed || allowed.has(profile.profileId)),\n\t\t);\n\t}\n\n\tprivate loadOwnerProfiles(): ReadonlyMap<string, OrchestrationProfile> {\n\t\tconst profiles = new OrchestrationProfileStore({\n\t\t\tagentDir: this.options.agentDir,\n\t\t\tcwd: this.options.cwd,\n\t\t\tprojectTrusted: this.options.getSettingsManager().isProjectTrusted(),\n\t\t}).load().profiles;\n\t\treturn new Map(profiles.map((profile) => [profile.profileId, profile]));\n\t}\n}\n"]}