@caupulican/pi-adaptative 0.90.2 → 0.90.4

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 (162) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/core/agent-session-contracts.d.ts +2 -0
  3. package/dist/core/agent-session-contracts.d.ts.map +1 -1
  4. package/dist/core/agent-session-contracts.js.map +1 -1
  5. package/dist/core/autonomy/bounded-completion.d.ts +10 -1
  6. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  7. package/dist/core/autonomy/bounded-completion.js +24 -2
  8. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  9. package/dist/core/autonomy/lane-tracker.d.ts +1 -1
  10. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  11. package/dist/core/autonomy/lane-tracker.js +9 -1
  12. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  13. package/dist/core/background-lane-controller.d.ts +1 -3
  14. package/dist/core/background-lane-controller.d.ts.map +1 -1
  15. package/dist/core/background-lane-controller.js.map +1 -1
  16. package/dist/core/compaction-controller.d.ts.map +1 -1
  17. package/dist/core/compaction-controller.js +0 -1
  18. package/dist/core/compaction-controller.js.map +1 -1
  19. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
  20. package/dist/core/delegation/managed-lane-controller.js +5 -1
  21. package/dist/core/delegation/managed-lane-controller.js.map +1 -1
  22. package/dist/core/delegation/worker-agent-control-coordinator.d.ts +8 -1
  23. package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -1
  24. package/dist/core/delegation/worker-agent-control-coordinator.js +94 -36
  25. package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -1
  26. package/dist/core/delegation/worker-agent-control.d.ts +1 -0
  27. package/dist/core/delegation/worker-agent-control.d.ts.map +1 -1
  28. package/dist/core/delegation/worker-agent-control.js.map +1 -1
  29. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  30. package/dist/core/delegation/worker-attempt-executor.js +7 -2
  31. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  32. package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
  33. package/dist/core/delegation/worker-authority-resolver.js +26 -3
  34. package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
  35. package/dist/core/delegation/worker-delegation-controller.d.ts +7 -4
  36. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  37. package/dist/core/delegation/worker-delegation-controller.js +110 -27
  38. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  39. package/dist/core/delegation/worker-fleet-limits.d.ts +9 -2
  40. package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
  41. package/dist/core/delegation/worker-fleet-limits.js +39 -3
  42. package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
  43. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -1
  44. package/dist/core/delegation/worker-lane-projection.js +4 -0
  45. package/dist/core/delegation/worker-lane-projection.js.map +1 -1
  46. package/dist/core/delegation/worker-lease-heartbeat.d.ts +16 -0
  47. package/dist/core/delegation/worker-lease-heartbeat.d.ts.map +1 -0
  48. package/dist/core/delegation/worker-lease-heartbeat.js +37 -0
  49. package/dist/core/delegation/worker-lease-heartbeat.js.map +1 -0
  50. package/dist/core/delegation/worker-lifecycle.d.ts +1 -0
  51. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
  52. package/dist/core/delegation/worker-lifecycle.js +6 -0
  53. package/dist/core/delegation/worker-lifecycle.js.map +1 -1
  54. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -1
  55. package/dist/core/delegation/worker-notification-coordinator.js +2 -1
  56. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -1
  57. package/dist/core/delegation/worker-runner.js +2 -2
  58. package/dist/core/delegation/worker-runner.js.map +1 -1
  59. package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts +1 -0
  60. package/dist/core/delegation/worker-terminal-handoff-coordinator.d.ts.map +1 -1
  61. package/dist/core/delegation/worker-terminal-handoff-coordinator.js +1 -0
  62. package/dist/core/delegation/worker-terminal-handoff-coordinator.js.map +1 -1
  63. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts +4 -2
  64. package/dist/core/delegation/worker-tree-budget-coordinator.d.ts.map +1 -1
  65. package/dist/core/delegation/worker-tree-budget-coordinator.js +10 -2
  66. package/dist/core/delegation/worker-tree-budget-coordinator.js.map +1 -1
  67. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +14 -0
  68. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
  69. package/dist/core/delegation/worker-write-reservation-coordinator.js +121 -33
  70. package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
  71. package/dist/core/foreground-terminal-handoff-controller.d.ts +5 -0
  72. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
  73. package/dist/core/foreground-terminal-handoff-controller.js +28 -12
  74. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
  75. package/dist/core/orchestration/capability-gateway.d.ts +2 -1
  76. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
  77. package/dist/core/orchestration/capability-gateway.js +9 -2
  78. package/dist/core/orchestration/capability-gateway.js.map +1 -1
  79. package/dist/core/orchestration/contracts.d.ts +16 -1
  80. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  81. package/dist/core/orchestration/contracts.js +5 -0
  82. package/dist/core/orchestration/contracts.js.map +1 -1
  83. package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
  84. package/dist/core/orchestration/profile-registry.js +38 -1
  85. package/dist/core/orchestration/profile-registry.js.map +1 -1
  86. package/dist/core/orchestration/risk-budget.d.ts +10 -0
  87. package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
  88. package/dist/core/orchestration/risk-budget.js +14 -0
  89. package/dist/core/orchestration/risk-budget.js.map +1 -1
  90. package/dist/core/orchestration/task-runtime-reducer.d.ts +1 -0
  91. package/dist/core/orchestration/task-runtime-reducer.d.ts.map +1 -1
  92. package/dist/core/orchestration/task-runtime-reducer.js +34 -0
  93. package/dist/core/orchestration/task-runtime-reducer.js.map +1 -1
  94. package/dist/core/orchestration/task-runtime.d.ts +1 -0
  95. package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
  96. package/dist/core/orchestration/task-runtime.js +24 -1
  97. package/dist/core/orchestration/task-runtime.js.map +1 -1
  98. package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
  99. package/dist/core/provider-prompt-contracts.js +2 -1
  100. package/dist/core/provider-prompt-contracts.js.map +1 -1
  101. package/dist/core/reflection-controller.d.ts.map +1 -1
  102. package/dist/core/reflection-controller.js +8 -1
  103. package/dist/core/reflection-controller.js.map +1 -1
  104. package/dist/core/settings-manager.d.ts +2 -2
  105. package/dist/core/settings-manager.d.ts.map +1 -1
  106. package/dist/core/settings-manager.js +2 -2
  107. package/dist/core/settings-manager.js.map +1 -1
  108. package/dist/core/tools/bash.d.ts +3 -0
  109. package/dist/core/tools/bash.d.ts.map +1 -1
  110. package/dist/core/tools/bash.js +13 -2
  111. package/dist/core/tools/bash.js.map +1 -1
  112. package/dist/core/tools/delegate-status.d.ts +1 -0
  113. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  114. package/dist/core/tools/delegate-status.js +19 -1
  115. package/dist/core/tools/delegate-status.js.map +1 -1
  116. package/dist/core/tools/delegate.d.ts +9 -1
  117. package/dist/core/tools/delegate.d.ts.map +1 -1
  118. package/dist/core/tools/delegate.js +198 -64
  119. package/dist/core/tools/delegate.js.map +1 -1
  120. package/dist/core/tools/edit.d.ts.map +1 -1
  121. package/dist/core/tools/edit.js +14 -1
  122. package/dist/core/tools/edit.js.map +1 -1
  123. package/dist/core/tools/file-failure-recovery.d.ts +3 -0
  124. package/dist/core/tools/file-failure-recovery.d.ts.map +1 -1
  125. package/dist/core/tools/file-failure-recovery.js +11 -0
  126. package/dist/core/tools/file-failure-recovery.js.map +1 -1
  127. package/dist/core/tools/orchestration-panel.d.ts +1 -1
  128. package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
  129. package/dist/core/tools/orchestration-panel.js +1 -0
  130. package/dist/core/tools/orchestration-panel.js.map +1 -1
  131. package/dist/core/tools/profile-writer.d.ts.map +1 -1
  132. package/dist/core/tools/profile-writer.js +2 -8
  133. package/dist/core/tools/profile-writer.js.map +1 -1
  134. package/dist/core/tools/search-command-guard.d.ts.map +1 -1
  135. package/dist/core/tools/search-command-guard.js +10 -3
  136. package/dist/core/tools/search-command-guard.js.map +1 -1
  137. package/dist/core/tools/write.d.ts.map +1 -1
  138. package/dist/core/tools/write.js +10 -1
  139. package/dist/core/tools/write.js.map +1 -1
  140. package/dist/modes/interactive/components/activity-lane.d.ts +1 -1
  141. package/dist/modes/interactive/components/activity-lane.d.ts.map +1 -1
  142. package/dist/modes/interactive/components/activity-lane.js +11 -2
  143. package/dist/modes/interactive/components/activity-lane.js.map +1 -1
  144. package/dist/modes/interactive/components/settings-selector.js +1 -1
  145. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  146. package/dist/utils/shell.d.ts +2 -0
  147. package/dist/utils/shell.d.ts.map +1 -1
  148. package/dist/utils/shell.js +3 -1
  149. package/dist/utils/shell.js.map +1 -1
  150. package/docs/harness-architecture.md +6 -3
  151. package/docs/settings.md +8 -6
  152. package/docs/tool-repair.md +1 -1
  153. package/docs/worker-profiles.md +2 -2
  154. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  155. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  156. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  157. package/examples/extensions/sandbox/package-lock.json +2 -2
  158. package/examples/extensions/sandbox/package.json +1 -1
  159. package/examples/extensions/with-deps/package-lock.json +2 -2
  160. package/examples/extensions/with-deps/package.json +1 -1
  161. package/npm-shrinkwrap.json +12 -12
  162. package/package.json +4 -4
@@ -4,6 +4,8 @@ export interface ShellConfig {
4
4
  args: string[];
5
5
  }
6
6
  export declare const POWERSHELL_UTF8_PREFIX = "try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\n";
7
+ /** Native PowerShell cold starts can cross five seconds under loaded Windows/WSL hosts. */
8
+ export declare const POWERSHELL_STARTUP_PROBE_TIMEOUT_MS = 15000;
7
9
  export declare function getPlatformShellToolName(platform?: NodeJS.Platform): PlatformShellToolName;
8
10
  export declare function prefixPowerShellCommand(command: string): string;
9
11
  /** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,eAAO,MAAM,sBAAsB,8EAA8E,CAAC;AAIlH,wBAAgB,wBAAwB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,qBAAqB,CAE5G;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAqFD,sHAAsH;AACtH,wBAAgB,cAAc,CAC7B,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,GAAE,qBAAkD,GAC3D,WAAW,CAeb;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,UAAU,CAoB/C;AAQD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAyBjD"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,eAAO,MAAM,sBAAsB,8EAA8E,CAAC;AAClH,2FAA2F;AAC3F,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAI1D,wBAAgB,wBAAwB,CAAC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAAG,qBAAqB,CAE5G;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAqFD,sHAAsH;AACtH,wBAAgB,cAAc,CAC7B,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,GAAE,qBAAkD,GAC3D,WAAW,CAeb;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,UAAU,CAoB/C;AAQD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzD;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAKlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAyBjD"}
@@ -5,6 +5,8 @@ import { getBinDir } from "../config.js";
5
5
  import { ensureManagedJscpd } from "./bundled-jscpd.js";
6
6
  import { normalizePath } from "./paths.js";
7
7
  export const POWERSHELL_UTF8_PREFIX = "try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\n";
8
+ /** Native PowerShell cold starts can cross five seconds under loaded Windows/WSL hosts. */
9
+ export const POWERSHELL_STARTUP_PROBE_TIMEOUT_MS = 15_000;
8
10
  const POWERSHELL_ARGS = ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command"];
9
11
  export function getPlatformShellToolName(platform = process.platform) {
10
12
  return platform === "win32" ? "powershell" : "bash";
@@ -35,7 +37,7 @@ function isPowerShellExecutableAvailable(executable) {
35
37
  try {
36
38
  return (spawnSync(executable, [...POWERSHELL_ARGS, "Write-Output ok"], {
37
39
  encoding: "utf-8",
38
- timeout: 5_000,
40
+ timeout: POWERSHELL_STARTUP_PROBE_TIMEOUT_MS,
39
41
  windowsHide: true,
40
42
  }).status === 0);
41
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\nimport { ensureManagedJscpd } from \"./bundled-jscpd.ts\";\nimport { normalizePath } from \"./paths.ts\";\n\nexport type PlatformShellToolName = \"bash\" | \"powershell\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n}\n\nexport const POWERSHELL_UTF8_PREFIX = \"try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\\n\";\n\nconst POWERSHELL_ARGS = [\"-NoLogo\", \"-NoProfile\", \"-NonInteractive\", \"-Command\"];\n\nexport function getPlatformShellToolName(platform: NodeJS.Platform = process.platform): PlatformShellToolName {\n\treturn platform === \"win32\" ? \"powershell\" : \"bash\";\n}\n\nexport function prefixPowerShellCommand(command: string): string {\n\treturn command.trimStart().startsWith(POWERSHELL_UTF8_PREFIX) ? command : `${POWERSHELL_UTF8_PREFIX}${command}`;\n}\n\nfunction findExecutableOnPath(executable: string): string | null {\n\tconst locator = process.platform === \"win32\" ? \"where\" : \"which\";\n\ttry {\n\t\tconst result = spawnSync(locator, [executable], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 5_000,\n\t\t\twindowsHide: true,\n\t\t});\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch && (process.platform !== \"win32\" || existsSync(firstMatch))) return firstMatch;\n\t\t}\n\t} catch {\n\t\t// Resolution falls through to known paths or the platform fallback.\n\t}\n\treturn null;\n}\n\nfunction isPowerShellExecutableAvailable(executable: string): boolean {\n\ttry {\n\t\treturn (\n\t\t\tspawnSync(executable, [...POWERSHELL_ARGS, \"Write-Output ok\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: 5_000,\n\t\t\t\twindowsHide: true,\n\t\t\t}).status === 0\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getPowerShellConfig(): ShellConfig {\n\tconst pwshOnPath = findExecutableOnPath(process.platform === \"win32\" ? \"pwsh.exe\" : \"pwsh\");\n\tif (pwshOnPath && isPowerShellExecutableAvailable(pwshOnPath)) {\n\t\treturn { shell: pwshOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\n\tconst knownPaths: string[] = [];\n\tconst programFiles = process.env.ProgramFiles;\n\tif (programFiles) knownPaths.push(`${programFiles}\\\\PowerShell\\\\7\\\\pwsh.exe`);\n\tconst systemRoot = process.env.SystemRoot;\n\tif (systemRoot) knownPaths.push(`${systemRoot}\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`);\n\tfor (const path of knownPaths) {\n\t\tif (existsSync(path) && isPowerShellExecutableAvailable(path)) {\n\t\t\treturn { shell: path, args: [...POWERSHELL_ARGS] };\n\t\t}\n\t}\n\n\tconst windowsPowerShellOnPath = findExecutableOnPath(\"powershell.exe\");\n\tif (windowsPowerShellOnPath && isPowerShellExecutableAvailable(windowsPowerShellOnPath)) {\n\t\treturn { shell: windowsPowerShellOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\tthrow new Error(\n\t\t\"No PowerShell executable found. Install PowerShell 7 (pwsh), restore Windows PowerShell, or set shellPath in settings.json.\",\n\t);\n}\n\nfunction getBashConfig(): ShellConfig {\n\tif (process.platform === \"win32\") {\n\t\tconst knownPaths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) knownPaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) knownPaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const path of knownPaths) {\n\t\t\tif (existsSync(path)) return { shell: path, args: [\"-c\"] };\n\t\t}\n\t\tconst bashOnPath = findExecutableOnPath(\"bash.exe\");\n\t\tif (bashOnPath) return { shell: bashOnPath, args: [\"-c\"] };\n\t\tthrow new Error(\"No Bash executable found. Install Git Bash or set shellPath in settings.json.\");\n\t}\n\tif (existsSync(\"/bin/bash\")) return { shell: \"/bin/bash\", args: [\"-c\"] };\n\tconst bashOnPath = findExecutableOnPath(\"bash\");\n\treturn bashOnPath ? { shell: bashOnPath, args: [\"-c\"] } : { shell: \"sh\", args: [\"-c\"] };\n}\n\n// Platform shell resolution spawns probe processes (`where`/`which`, plus a full PowerShell\n// boot on Windows) and is a process-lifetime invariant, so successful resolutions are cached.\n// Failures are not cached: the user can install a shell and retry without restarting.\nconst resolvedPlatformShellConfigs = new Map<PlatformShellToolName, ShellConfig>();\nlet managedJscpdProvisionAttempted = false;\n\n/** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */\nexport function getShellConfig(\n\tcustomShellPath?: string,\n\tshellName: PlatformShellToolName = getPlatformShellToolName(),\n): ShellConfig {\n\tif (customShellPath) {\n\t\tconst resolvedShellPath = normalizePath(customShellPath);\n\t\tif (!existsSync(resolvedShellPath)) throw new Error(`Custom shell path not found: ${resolvedShellPath}`);\n\t\treturn {\n\t\t\tshell: resolvedShellPath,\n\t\t\targs: shellName === \"powershell\" ? [...POWERSHELL_ARGS] : [\"-c\"],\n\t\t};\n\t}\n\tlet resolved = resolvedPlatformShellConfigs.get(shellName);\n\tif (!resolved) {\n\t\tresolved = shellName === \"powershell\" ? getPowerShellConfig() : getBashConfig();\n\t\tresolvedPlatformShellConfigs.set(shellName, resolved);\n\t}\n\treturn { shell: resolved.shell, args: [...resolved.args] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tif (!managedJscpdProvisionAttempted) {\n\t\tmanagedJscpdProvisionAttempted = true;\n\t\ttry {\n\t\t\tensureManagedJscpd();\n\t\t} catch {\n\t\t\t// The jscpd wrapper and doctor surface the exact packaging failure. Shell startup stays usable.\n\t\t}\n\t}\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform).\n *\n * Windows uses `spawnSync` (not `spawn`) deliberately: callers rely on this function returning\n * only once the tree is actually gone (e.g. before removing a directory that was the killed\n * process's cwd — a directory Windows keeps locked until every handle into it, including a\n * live process's cwd handle, is released). A fire-and-forget async `taskkill` would return before\n * termination completed, leaving a race where the directory is still locked.\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree; spawnSync blocks until taskkill itself\n\t\t// (and therefore the termination it requested) has finished.\n\t\ttry {\n\t\t\tspawnSync(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\nimport { ensureManagedJscpd } from \"./bundled-jscpd.ts\";\nimport { normalizePath } from \"./paths.ts\";\n\nexport type PlatformShellToolName = \"bash\" | \"powershell\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n}\n\nexport const POWERSHELL_UTF8_PREFIX = \"try { [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 } catch {}\\n\";\n/** Native PowerShell cold starts can cross five seconds under loaded Windows/WSL hosts. */\nexport const POWERSHELL_STARTUP_PROBE_TIMEOUT_MS = 15_000;\n\nconst POWERSHELL_ARGS = [\"-NoLogo\", \"-NoProfile\", \"-NonInteractive\", \"-Command\"];\n\nexport function getPlatformShellToolName(platform: NodeJS.Platform = process.platform): PlatformShellToolName {\n\treturn platform === \"win32\" ? \"powershell\" : \"bash\";\n}\n\nexport function prefixPowerShellCommand(command: string): string {\n\treturn command.trimStart().startsWith(POWERSHELL_UTF8_PREFIX) ? command : `${POWERSHELL_UTF8_PREFIX}${command}`;\n}\n\nfunction findExecutableOnPath(executable: string): string | null {\n\tconst locator = process.platform === \"win32\" ? \"where\" : \"which\";\n\ttry {\n\t\tconst result = spawnSync(locator, [executable], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 5_000,\n\t\t\twindowsHide: true,\n\t\t});\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch && (process.platform !== \"win32\" || existsSync(firstMatch))) return firstMatch;\n\t\t}\n\t} catch {\n\t\t// Resolution falls through to known paths or the platform fallback.\n\t}\n\treturn null;\n}\n\nfunction isPowerShellExecutableAvailable(executable: string): boolean {\n\ttry {\n\t\treturn (\n\t\t\tspawnSync(executable, [...POWERSHELL_ARGS, \"Write-Output ok\"], {\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t\ttimeout: POWERSHELL_STARTUP_PROBE_TIMEOUT_MS,\n\t\t\t\twindowsHide: true,\n\t\t\t}).status === 0\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction getPowerShellConfig(): ShellConfig {\n\tconst pwshOnPath = findExecutableOnPath(process.platform === \"win32\" ? \"pwsh.exe\" : \"pwsh\");\n\tif (pwshOnPath && isPowerShellExecutableAvailable(pwshOnPath)) {\n\t\treturn { shell: pwshOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\n\tconst knownPaths: string[] = [];\n\tconst programFiles = process.env.ProgramFiles;\n\tif (programFiles) knownPaths.push(`${programFiles}\\\\PowerShell\\\\7\\\\pwsh.exe`);\n\tconst systemRoot = process.env.SystemRoot;\n\tif (systemRoot) knownPaths.push(`${systemRoot}\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe`);\n\tfor (const path of knownPaths) {\n\t\tif (existsSync(path) && isPowerShellExecutableAvailable(path)) {\n\t\t\treturn { shell: path, args: [...POWERSHELL_ARGS] };\n\t\t}\n\t}\n\n\tconst windowsPowerShellOnPath = findExecutableOnPath(\"powershell.exe\");\n\tif (windowsPowerShellOnPath && isPowerShellExecutableAvailable(windowsPowerShellOnPath)) {\n\t\treturn { shell: windowsPowerShellOnPath, args: [...POWERSHELL_ARGS] };\n\t}\n\tthrow new Error(\n\t\t\"No PowerShell executable found. Install PowerShell 7 (pwsh), restore Windows PowerShell, or set shellPath in settings.json.\",\n\t);\n}\n\nfunction getBashConfig(): ShellConfig {\n\tif (process.platform === \"win32\") {\n\t\tconst knownPaths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) knownPaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) knownPaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\tfor (const path of knownPaths) {\n\t\t\tif (existsSync(path)) return { shell: path, args: [\"-c\"] };\n\t\t}\n\t\tconst bashOnPath = findExecutableOnPath(\"bash.exe\");\n\t\tif (bashOnPath) return { shell: bashOnPath, args: [\"-c\"] };\n\t\tthrow new Error(\"No Bash executable found. Install Git Bash or set shellPath in settings.json.\");\n\t}\n\tif (existsSync(\"/bin/bash\")) return { shell: \"/bin/bash\", args: [\"-c\"] };\n\tconst bashOnPath = findExecutableOnPath(\"bash\");\n\treturn bashOnPath ? { shell: bashOnPath, args: [\"-c\"] } : { shell: \"sh\", args: [\"-c\"] };\n}\n\n// Platform shell resolution spawns probe processes (`where`/`which`, plus a full PowerShell\n// boot on Windows) and is a process-lifetime invariant, so successful resolutions are cached.\n// Failures are not cached: the user can install a shell and retry without restarting.\nconst resolvedPlatformShellConfigs = new Map<PlatformShellToolName, ShellConfig>();\nlet managedJscpdProvisionAttempted = false;\n\n/** Resolve the requested shell. Runtime callers omit shellName to select PowerShell on Windows and Bash elsewhere. */\nexport function getShellConfig(\n\tcustomShellPath?: string,\n\tshellName: PlatformShellToolName = getPlatformShellToolName(),\n): ShellConfig {\n\tif (customShellPath) {\n\t\tconst resolvedShellPath = normalizePath(customShellPath);\n\t\tif (!existsSync(resolvedShellPath)) throw new Error(`Custom shell path not found: ${resolvedShellPath}`);\n\t\treturn {\n\t\t\tshell: resolvedShellPath,\n\t\t\targs: shellName === \"powershell\" ? [...POWERSHELL_ARGS] : [\"-c\"],\n\t\t};\n\t}\n\tlet resolved = resolvedPlatformShellConfigs.get(shellName);\n\tif (!resolved) {\n\t\tresolved = shellName === \"powershell\" ? getPowerShellConfig() : getBashConfig();\n\t\tresolvedPlatformShellConfigs.set(shellName, resolved);\n\t}\n\treturn { shell: resolved.shell, args: [...resolved.args] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tif (!managedJscpdProvisionAttempted) {\n\t\tmanagedJscpdProvisionAttempted = true;\n\t\ttry {\n\t\t\tensureManagedJscpd();\n\t\t} catch {\n\t\t\t// The jscpd wrapper and doctor surface the exact packaging failure. Shell startup stays usable.\n\t\t}\n\t}\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform).\n *\n * Windows uses `spawnSync` (not `spawn`) deliberately: callers rely on this function returning\n * only once the tree is actually gone (e.g. before removing a directory that was the killed\n * process's cwd — a directory Windows keeps locked until every handle into it, including a\n * live process's cwd handle, is released). A fire-and-forget async `taskkill` would return before\n * termination completed, leaving a race where the directory is still locked.\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree; spawnSync blocks until taskkill itself\n\t\t// (and therefore the termination it requested) has finished.\n\t\ttry {\n\t\t\tspawnSync(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\twindowsHide: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -128,9 +128,12 @@ process-tree termination contract. The platform shell is real host process autho
128
128
  isolation or a path-scoped substitute for `write`/`edit`.
129
129
 
130
130
  Birth context is selected once, before a new logical agent is admitted, with `forkTurns: "none"`,
131
- `"all"`, or a positive turn count such as `"3"`. Omission means `all` only when parent and child use
132
- the exact same provider and model; crossing either boundary defaults to `none`, and an explicit
133
- non-`none` cross-boundary request is rejected. The content-addressed snapshot contains bounded whole
131
+ `"all"`, or a positive turn count such as `"3"`. Omitted top-level starts mean `all` only when the
132
+ foreground and worker use the exact same provider and model. Omitted nested starts mean `none`, so a
133
+ self-contained child task cannot inherit and mistake parent-level orchestration intent for child
134
+ ownership; explicit nested inheritance remains available inside the exact provider/model boundary.
135
+ Crossing either provider or model defaults to `none`, and an explicit non-`none` cross-boundary
136
+ request is rejected. The content-addressed snapshot contains bounded whole
134
137
  user turns and complete text-only assistant answers. It excludes system/developer/custom messages,
135
138
  reasoning and commentary, tool calls/results, mailbox controls, non-text attachments, and incomplete
136
139
  assistant output. A compacted prefix can enter only as its bounded checkpoint attached to the next
package/docs/settings.md CHANGED
@@ -152,7 +152,7 @@ Pi's native delegation runtime is a durable recursive agent tree. A profile is n
152
152
 
153
153
  An agent may set `authority` on `delegate` to choose its child's role label, authenticated model, supported reasoning level, semantic capabilities, tools, read/write paths, and budget. Omitted fields inherit from the parent or selected preset. The host validates the request, resolves the concrete model and tools, intersects execution authority with the immutable parent grant and live global switches, then persists the exact result before the child starts. A descendant can specialize or narrow authority but cannot add an execution capability, tool, path, or budget that the parent did not hold. Profile selection also cannot add context: every child resource pointer must fully match an ancestral pointer (ID alone is insufficient), soul text must match exactly, and a verifier stays within its previously admitted ancestral verifier or worker boundary. Roles are descriptive routing and audit labels; the built-in compiler does not impose hidden role ceilings, though an embedding may supply an explicit host ceiling.
154
154
 
155
- For a new logical agent, `forkTurns` chooses immutable sanitized birth context: `"none"`, `"all"`, or a positive user-turn count encoded as a string, such as `"3"`. When omitted, an exact same-provider/model child defaults to `"all"`; a child that changes provider or model defaults to `"none"`, and explicitly requesting inherited turns across that boundary is rejected. The bounded snapshot keeps whole text-only user/complete-assistant turns and a valid compaction checkpoint when needed. It excludes system/developer/custom context, reasoning/commentary, tool protocol and results, mailbox controls, attachments, and incomplete assistant output. A reused `agentId` continues its existing transcript and cannot replace its birth context.
155
+ For a new logical agent, `forkTurns` chooses immutable sanitized birth context: `"none"`, `"all"`, or a positive user-turn count encoded as a string, such as `"3"`. When omitted, an exact same-provider/model top-level worker defaults to `"all"`, while a nested worker defaults to `"none"` so the parent's global orchestration request cannot replace the child's self-contained task. A worker that changes provider or model also defaults to `"none"`, and explicitly requesting inherited turns across that boundary is rejected. Explicit nested `"all"` or count inheritance remains available inside the exact provider/model boundary. The bounded snapshot keeps whole text-only user/complete-assistant turns and a valid compaction checkpoint when needed. It excludes system/developer/custom context, reasoning/commentary, tool protocol and results, mailbox controls, attachments, and incomplete assistant output. A reused `agentId` continues its existing transcript and cannot replace its birth context.
156
156
 
157
157
  ```json
158
158
  {
@@ -180,7 +180,7 @@ For a new logical agent, `forkTurns` chooses immutable sanitized birth context:
180
180
  }
181
181
  ```
182
182
 
183
- Fleet creation is bounded before Pi creates a durable task, conversation, agent, or queue entry: depth is at most 8, one parent may own at most 64 direct children, one session may retain at most 256 logical agents, and the scheduler may retain at most 256 queued dispatches. Admission dynamically preserves queue and durable-projection headroom for every implementation whose mandatory verifier has not yet materialized, plus a newly admitted contract's verifier. A verifier dispatch that encounters saturation remains represented by its durable subject and replays on a queue-capacity event. The shared durable projection independently caps agents, tasks, and attempts at 256 each. `workerDelegation.maxConcurrent` remains the global running-agent limit; excess admitted work enters the bounded durable queue. The kernel also rejects an exact recursive cycle when a child repeats the same normalized instructions and effective profile already present in its ancestor chain. Root budgets are cumulative across every descendant and attempt: token, cost, tool-call, active-wall-clock, and attempt usage are reconstructed from durable checkpoints and checked before more work is admitted.
183
+ Fleet creation is bounded before Pi creates a durable task, conversation, agent, or queue entry: depth is at most 8, one parent may own at most 64 direct children, one session may retain at most 256 logical agents, and the scheduler may retain at most 256 queued dispatches. The profile-free baseline is deliberately lean: the session may retain one nested identity at depth one, and that child is a leaf; additional root workers remain available and can reuse the retained specialists. An owner-authored profile may set `delegationLimits.maxDepth`, `delegationLimits.maxChildrenPerAgent`, and `delegationLimits.maxNestedAgentsPerSession` up to the host ceilings; omitted authored limits retain the host ceilings. Descendant profile selection intersects these limits with the ancestor's immutable contract and cannot widen them. Admission dynamically preserves queue and durable-projection headroom for every implementation whose mandatory verifier has not yet materialized, plus a newly admitted contract's verifier. A verifier dispatch that encounters saturation remains represented by its durable subject and replays on a queue-capacity event. The shared durable projection independently caps agents, tasks, and attempts at 256 each. `workerDelegation.maxConcurrent` remains the global running-agent limit; excess admitted work enters the bounded durable queue. The kernel also rejects an exact recursive cycle when a child repeats the same normalized instructions and effective profile already present in its ancestor chain. Root budgets are cumulative across every descendant and attempt: token, cost, tool-call, active-wall-clock, and attempt usage are reconstructed from durable checkpoints and checked before more work is admitted. The default delegation baseline adds no cost or active-time ceiling; positive global settings, profile budgets, and inherited foreground ceilings remain authoritative when explicitly configured.
184
184
 
185
185
  `delegate` exposes the shared durable task/tree state through distinct authority boundaries:
186
186
 
@@ -194,9 +194,9 @@ Fleet creation is bounded before Pi creates a durable task, conversation, agent,
194
194
 
195
195
  Transient attempt retries are evidence-gated. A classified provider or transport failure suspends the exact attempt with its retry count and ISO `notBefore` deadline, then resumes from the persisted transcript under a fresh fence when that deadline is eligible. Restart recovery uses the durable deadline rather than resetting an in-memory backoff; `maxAttempts: 1` disables the ladder, and missing/unknown failure classification never retries.
196
196
 
197
- `delegate` returns a stable agent/lane identity immediately. Completion persists a bounded terminal handoff before waking the parent; late output stays in the worker transcript instead of racing into the active foreground transcript. A full parent mailbox retains the attempt-keyed handoff until an explicit terminal, mailbox-capacity, state-change, or recovery event drains it—there is no retry polling loop. Exact replays are inert, conflicts fail closed, and delivery errors remain retained. Use `delegate { action: "status", laneId }` for bounded lane-result retrieval.
197
+ `delegate` returns a stable agent/lane identity immediately. A fresh `start` does not accept `laneId`; omit it, retain the returned `agentId`, and pass that `agentId` to a later `start` to reuse the persistent worker. Completion persists a bounded terminal handoff before waking the parent; late output stays in the worker transcript instead of racing into the active foreground transcript. Review-pending results remain `partial` and project blockers remain `blocked` in lane status and terminal handoffs instead of either being collapsed into harness failures. A scheduled transient retry is reported as nonterminal with its durable state retained. A full parent mailbox retains the attempt-keyed handoff until an explicit terminal, mailbox-capacity, state-change, or recovery event drains it—there is no retry polling loop. Exact replays are inert, conflicts fail closed, and delivery errors remain retained. Use `delegate { action: "status", laneId }` for bounded lane-result retrieval.
198
198
 
199
- Global profiles live at `~/.pi/agent/profiles/orchestration/<id>.json`; project profiles live at `.pi/profiles/orchestration/<id>.json`. They are optional presets for model, reasoning, tools, resources, budget, verification, and prompt defaults. Select one with `profileId` on a call or configure `workerDelegation.orchestrationProfile`. `dispatchProfileIds` is preset-routing metadata, not an admission allowlist. Profile `maxConcurrent` is retained in the authored schema but does not override the global scheduler. `delegate` actions `profile_inspect` and `profile_create` manage optional immutable session-scoped narrowings; direct authority selection does not require one.
199
+ Global profiles live at `~/.pi/agent/profiles/orchestration/<id>.json`; project profiles live at `.pi/profiles/orchestration/<id>.json`. They are optional presets for model, reasoning, tools, resources, budget, verification, prompt defaults, and recursive `delegationLimits`. Select one with `profileId` on a call or configure `workerDelegation.orchestrationProfile`. `dispatchProfileIds` is preset-routing metadata, not an admission allowlist. Profile `maxConcurrent` is retained in the authored schema but does not override the global scheduler. `delegate` actions `profile_inspect` and `profile_create` manage optional immutable session-scoped narrowings; direct authority selection does not require one.
200
200
 
201
201
  A preset with `requireIndependentVerification: true` still names an owner-authored `verificationProfileId`. The runtime creates a separate durable verifier task and accepts the implementation only after a typed verifier decision. A profile using `run_process` must declare `executionPolicy`; that tool launches only listed executables as direct argv. The platform shell is different: it is a real persistent per-agent shell and is not OS/container isolation. Shell commands can exercise the host process, filesystem, network, and credentials available to Pi; direct `write`/`edit` path scopes do not sandbox shell side effects.
202
202
 
@@ -206,8 +206,8 @@ Direct `write`/`edit` calls use review-after-apply semantics. The compiled grant
206
206
  |---------|------|---------|-------------|
207
207
  | `workerDelegation.enabled` | boolean | `true` | Enable autonomous recursive agent trees; explicit `false` is a hard off-switch |
208
208
  | `workerDelegation.orchestrationProfile` | string | - | Optional default execution preset; agents may replace its defaults within inherited authority |
209
- | `workerDelegation.maxUsd` | number | `0.5` | Cumulative USD ceiling for one root tree; `0` disables this settings-level ceiling |
210
- | `workerDelegation.maxWallClockMs` | number | `120000` | Cumulative active wall-clock ceiling for one root tree; `0` disables this settings-level ceiling |
209
+ | `workerDelegation.maxUsd` | number | `0` | Optional cumulative USD ceiling for one root tree; `0` leaves this settings-level ceiling unbounded |
210
+ | `workerDelegation.maxWallClockMs` | number | `0` | Optional cumulative active wall-clock ceiling for one root tree; `0` leaves this settings-level ceiling unbounded |
211
211
  | `workerDelegation.maxConcurrent` | number | `20` | Global running-agent concurrency inside the fixed fleet and queue bounds |
212
212
  | `workerDelegation.writeEnabled` | boolean | `true` | Expose direct `write`/`edit`; explicit `false` revokes them for newly admitted work and narrows resumed grants |
213
213
  | `workerDelegation.writePaths` | string[] | `["."]` | Global envelope for direct child writes; an explicit empty array revokes direct `write`/`edit` |
@@ -276,6 +276,8 @@ When enabled, Auto Learn keeps a small shared state file for visibility/cooldown
276
276
 
277
277
  ### Compaction
278
278
 
279
+ The checkpoint owns user intent mechanically: `## Active Task` copies the latest user request verbatim, and a split-turn prefix copies its original request without a second model rewrite. Tool output remains evidence and cannot become a new active task. Validated one-turn operation rejections expire instead of becoming durable completed actions or open problems.
280
+
279
281
  | Setting | Type | Default | Description |
280
282
  |---------|------|---------|-------------|
281
283
  | `compaction.enabled` | boolean | `true` | Enable auto-compaction |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Pi validates every model-emitted tool call against its TypeBox schema before execution. Valid calls run unchanged. Invalid calls either pass through a named deterministic repair and then execute with the repaired arguments, or they bounce with schema feedback when no safe repair applies.
4
4
 
5
- Execution failures are not argument repairs. Pi removes their potentially large failed protocol turns from provider context and normally retains one bounded failure record: constant-size operation fingerprint, bounded operation preview, occurrence count, failure code, a cause-bearing diagnostic when available, and `next_action`. Every retained record carries `"MUST":true`; the provider receives one canonical `mandatory_tool_failure_recovery_protocol` template explaining that `repair` or `next_action` is an execution constraint, unchanged retries are gated, and unrelated argument changes are not recovery. A matching successful retry clears the record. Change-approach classes such as non-UTF-8 text edits are different: Pi discards the complete attempted operation, exposes one bounded reason/directive for the next assistant response, then expires it. Pi uses `repair` only for argument/protocol rejections with a concrete call correction; policy, preflight, abort, and execution failures use `next_action`. It never invents a deterministic repair from an unknown nonzero exit.
5
+ Execution failures are not argument repairs. Pi removes their potentially large failed protocol turns from provider context and normally retains one bounded failure record: constant-size operation fingerprint, bounded operation preview, occurrence count, failure code, a cause-bearing diagnostic when available, and `next_action`. Every retained record carries `"MUST":true`; the provider receives one canonical `mandatory_tool_failure_recovery_protocol` template explaining that `repair` or `next_action` is an execution constraint, unchanged retries are gated, and unrelated argument changes are not recovery. A matching successful retry clears the record. Change-approach classes such as non-UTF-8 text edits are different: Pi discards the complete attempted operation, exposes one bounded reason/directive for the next assistant response, then expires it. A tool-owned guard can use the same one-turn path for an operation rejected before external execution; the runtime remains available, and compaction does not retain that rejected call as completed work or an open problem. Pi uses `repair` only for argument/protocol rejections with a concrete call correction; policy, preflight, abort, and execution failures use `next_action`. It never invents a deterministic repair from an unknown nonzero exit.
6
6
 
7
7
  Canonical execution-failure template:
8
8
 
@@ -15,8 +15,8 @@ Use `delegate { action: "profile_inspect" }` when the reusable bases or model co
15
15
 
16
16
  Worker agents do not receive the root-only profile/status actions. They receive `delegate` only when their admitted tool set and capability ceiling both retain delegation; a caller can create a non-delegating leaf by narrowing either field. Delegating workers may recursively create descendants within the fixed depth, direct-child, session-agent, and queue bounds. They can discover safe session-peer metadata, exchange non-waking threaded messages and bounded broadcasts, and use event-driven `wait`/`wait_many`, but bounded transcript reads and waking controls remain limited to the caller's own control subtree. Transcript cursors address raw session entries, so a continuation page may be empty after non-message entries; an individually oversized message is omitted with a count instead of being truncated. A descendant may vary model or role through another preset, but it cannot acquire new resources: pointers must fully match the ancestor's admitted pointer metadata, soul text must match exactly, and verifier resources and authority stay within the ancestral verifier or worker boundary.
17
17
 
18
- New agents may receive immutable sanitized birth context with `forkTurns: "none"`, `"all"`, or a positive user-turn count such as `"3"`. Omission inherits all bounded complete turns only for the exact same provider and model. Crossing either provider or model defaults to no inherited turns, and an explicit non-`none` cross-boundary fork is rejected. Tool calls/results, reasoning/commentary, system/developer/custom messages, mailbox controls, non-text content, and incomplete assistant output never enter the snapshot. Dispatching another task with an existing `agentId` reuses that agent's durable transcript and cannot replace its birth context.
18
+ New agents may receive immutable sanitized birth context with `forkTurns: "none"`, `"all"`, or a positive user-turn count such as `"3"`. Omitted top-level starts inherit all bounded complete turns only for the exact same provider and model. Omitted nested starts receive no parent transcript, keeping their self-contained task separate from the parent's global orchestration instructions; explicit nested inheritance remains available inside the exact provider/model boundary. Crossing either provider or model defaults to no inherited turns, and an explicit non-`none` cross-boundary fork is rejected. Tool calls/results, reasoning/commentary, system/developer/custom messages, mailbox controls, non-text content, and incomplete assistant output never enter the snapshot. Dispatching another task with an existing `agentId` reuses that agent's durable transcript and cannot replace its birth context.
19
19
 
20
20
  `delegate tasks` is the bounded view of the same durable task/DAG runtime used for dispatch and recovery. A new task may name existing same-objective task IDs with `dependsOn`; it remains pending until those dependencies complete, while invalid or cyclic edges fail closed. Evidence-classified transient failures retain their attempt/retry count and exact `notBefore` deadline across restart. Agent, task, and attempt projections are independently capped at 256 entries.
21
21
 
22
- Pi admits fleet and queue capacity before registering a new logical child; every accepted queued child then has a stable agent ID. Queue and projection admission preserve one continuation slot for every pending mandatory verifier, and a verifier blocked by saturation is retried from durable subject state when capacity changes. A parent that waits yields its scheduler slot until an event-driven state change, and every terminal child writes one bounded, idempotent handoff to its owning parent's mailbox. A full mailbox retains that handoff by terminal attempt ID until an explicit capacity/state/recovery signal drains it; no timer polls for delivery. Active parents receive the handoff without transcript races; idle registered parents resume once. Child output remains in the child transcript. `interrupt`, `resume`, `cancel`, and `follow_up` are subtree-scoped; a paused objective keeps a suspended worker nonterminal until resume. `retire` closes only an idle leaf with no unresolved mailbox/reply work and preserves its binding and transcript. A resumed worker retains the exact admitted preset or adaptive grant, model, resources, lineage, and transcript.
22
+ Pi admits fleet and queue capacity before registering a new logical child; every accepted queued child then has a stable agent ID. Queue and projection admission preserve one continuation slot for every pending mandatory verifier, and a verifier blocked by saturation is retried from durable subject state when capacity changes. A parent that waits yields its scheduler slot until an event-driven state change. A worker cannot wait for itself or for a queued target blocked by its own write reservation; that wait fails immediately and tells the worker to finish its task so the owning parent can continue coordination. Every terminal child writes one bounded, idempotent handoff to its owning parent's mailbox. Review-pending results retain terminal status `partial`, and project-level blockers retain `blocked`; neither is projected as a harness failure. Evidence-classified retries stay nonterminal and report that their durable state is preserved. A full mailbox retains that handoff by terminal attempt ID until an explicit capacity/state/recovery signal drains it; no timer polls for delivery. Active parents receive the handoff without transcript races; idle registered parents resume once. Child output remains in the child transcript. `interrupt`, `resume`, `cancel`, and `follow_up` are subtree-scoped; a paused objective keeps a suspended worker nonterminal until resume. `retire` closes only an idle leaf with no unresolved mailbox/reply work and preserves its binding and transcript. A resumed worker retains the exact admitted preset or adaptive grant, model, resources, lineage, and transcript.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider",
3
- "version": "0.90.2",
3
+ "version": "0.90.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-custom-provider",
9
- "version": "0.90.2",
9
+ "version": "0.90.4",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.52.0"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.90.2",
4
+ "version": "0.90.4",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.90.2",
4
+ "version": "0.90.4",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
- "version": "0.90.2",
3
+ "version": "0.90.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-sandbox",
9
- "version": "0.90.2",
9
+ "version": "0.90.4",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sandbox-runtime": "^0.0.26"
12
12
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-sandbox",
3
3
  "private": true,
4
- "version": "0.90.2",
4
+ "version": "0.90.4",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.90.2",
3
+ "version": "0.90.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.90.2",
9
+ "version": "0.90.4",
10
10
  "dependencies": {
11
11
  "ms": "^2.1.3"
12
12
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.90.2",
4
+ "version": "0.90.4",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "clean": "echo 'nothing to clean'",
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@caupulican/pi-adaptative",
3
- "version": "0.90.2",
3
+ "version": "0.90.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@caupulican/pi-adaptative",
9
- "version": "0.90.2",
9
+ "version": "0.90.4",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@caupulican/pi-agent-core": "^0.90.2",
13
- "@caupulican/pi-ai": "^0.90.2",
14
- "@caupulican/pi-tui": "^0.90.2",
12
+ "@caupulican/pi-agent-core": "^0.90.4",
13
+ "@caupulican/pi-ai": "^0.90.4",
14
+ "@caupulican/pi-tui": "^0.90.4",
15
15
  "@silvia-odwyer/photon-node": "0.3.4",
16
16
  "chalk": "5.6.2",
17
17
  "cross-spawn": "7.0.6",
@@ -547,11 +547,11 @@
547
547
  }
548
548
  },
549
549
  "node_modules/@caupulican/pi-agent-core": {
550
- "version": "0.90.2",
551
- "resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.90.2.tgz",
550
+ "version": "0.90.4",
551
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.90.4.tgz",
552
552
  "license": "MIT",
553
553
  "dependencies": {
554
- "@caupulican/pi-ai": "^0.90.2",
554
+ "@caupulican/pi-ai": "^0.90.4",
555
555
  "ignore": "7.0.5",
556
556
  "typebox": "1.1.38",
557
557
  "yaml": "2.9.0"
@@ -561,8 +561,8 @@
561
561
  }
562
562
  },
563
563
  "node_modules/@caupulican/pi-ai": {
564
- "version": "0.90.2",
565
- "resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.90.2.tgz",
564
+ "version": "0.90.4",
565
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.90.4.tgz",
566
566
  "license": "MIT",
567
567
  "dependencies": {
568
568
  "@anthropic-ai/sdk": "0.91.1",
@@ -616,8 +616,8 @@
616
616
  }
617
617
  },
618
618
  "node_modules/@caupulican/pi-tui": {
619
- "version": "0.90.2",
620
- "resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.90.2.tgz",
619
+ "version": "0.90.4",
620
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.90.4.tgz",
621
621
  "license": "MIT",
622
622
  "dependencies": {
623
623
  "get-east-asian-width": "1.6.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caupulican/pi-adaptative",
3
- "version": "0.90.2",
3
+ "version": "0.90.4",
4
4
  "description": "Adaptive fork of Pi coding agent for self-evolving agent harness experiments",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -84,9 +84,9 @@
84
84
  "postinstall": "node scripts/postinstall-python-runtime.mjs"
85
85
  },
86
86
  "dependencies": {
87
- "@caupulican/pi-agent-core": "^0.90.2",
88
- "@caupulican/pi-ai": "^0.90.2",
89
- "@caupulican/pi-tui": "^0.90.2",
87
+ "@caupulican/pi-agent-core": "^0.90.4",
88
+ "@caupulican/pi-ai": "^0.90.4",
89
+ "@caupulican/pi-tui": "^0.90.4",
90
90
  "@silvia-odwyer/photon-node": "0.3.4",
91
91
  "chalk": "5.6.2",
92
92
  "cross-spawn": "7.0.6",