@caupulican/pi-adaptative 0.94.1 → 0.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +32 -13
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +7 -4
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +201 -293
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +272 -392
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.d.ts +52 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.d.ts.map +1 -0
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.js +118 -0
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.js.map +1 -0
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/launch-profile.ts +169 -0
  13. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/builder-validator.json +1 -1
  14. package/dist/bundled-resources/extensions/tmux-agent-manager/templates/provider-prompt-smoke.json +1 -1
  15. package/dist/bundled-resources/extensions/tps/index.d.ts +3 -0
  16. package/dist/bundled-resources/extensions/tps/index.d.ts.map +1 -0
  17. package/dist/bundled-resources/extensions/tps/index.js +44 -0
  18. package/dist/bundled-resources/extensions/tps/index.js.map +1 -0
  19. package/dist/bundled-resources/extensions/tps/index.ts +48 -0
  20. package/dist/bundled-resources/skills/pi-harness-learning/SKILL.md +13 -7
  21. package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +11 -11
  22. package/dist/core/agent-session-services.d.ts.map +1 -1
  23. package/dist/core/agent-session-services.js +12 -3
  24. package/dist/core/agent-session-services.js.map +1 -1
  25. package/dist/core/agent-session.d.ts +11 -41
  26. package/dist/core/agent-session.d.ts.map +1 -1
  27. package/dist/core/agent-session.js +93 -160
  28. package/dist/core/agent-session.js.map +1 -1
  29. package/dist/core/autonomy/envelope-enforcement.d.ts +6 -1
  30. package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
  31. package/dist/core/autonomy/envelope-enforcement.js +26 -25
  32. package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
  33. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -1
  34. package/dist/core/autonomy/lane-private-paths.js +2 -1
  35. package/dist/core/autonomy/lane-private-paths.js.map +1 -1
  36. package/dist/core/autonomy/lane-tool-surface.d.ts +8 -8
  37. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  38. package/dist/core/autonomy/lane-tool-surface.js +45 -30
  39. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  40. package/dist/core/autonomy/worker-session-private-scope.d.ts +12 -0
  41. package/dist/core/autonomy/worker-session-private-scope.d.ts.map +1 -0
  42. package/dist/core/autonomy/worker-session-private-scope.js +42 -0
  43. package/dist/core/autonomy/worker-session-private-scope.js.map +1 -0
  44. package/dist/core/autonomy/worker-tool-adapter-registry.d.ts +65 -0
  45. package/dist/core/autonomy/worker-tool-adapter-registry.d.ts.map +1 -0
  46. package/dist/core/autonomy/worker-tool-adapter-registry.js +145 -0
  47. package/dist/core/autonomy/worker-tool-adapter-registry.js.map +1 -0
  48. package/dist/core/background-lane-controller.d.ts +1 -1
  49. package/dist/core/background-lane-controller.d.ts.map +1 -1
  50. package/dist/core/background-lane-controller.js +1 -1
  51. package/dist/core/background-lane-controller.js.map +1 -1
  52. package/dist/core/background-tool-task-controller.d.ts +8 -2
  53. package/dist/core/background-tool-task-controller.d.ts.map +1 -1
  54. package/dist/core/background-tool-task-controller.js +10 -2
  55. package/dist/core/background-tool-task-controller.js.map +1 -1
  56. package/dist/core/compaction-controller.d.ts +3 -0
  57. package/dist/core/compaction-controller.d.ts.map +1 -1
  58. package/dist/core/compaction-controller.js +12 -1
  59. package/dist/core/compaction-controller.js.map +1 -1
  60. package/dist/core/cost-guard-controller.d.ts +37 -0
  61. package/dist/core/cost-guard-controller.d.ts.map +1 -0
  62. package/dist/core/cost-guard-controller.js +71 -0
  63. package/dist/core/cost-guard-controller.js.map +1 -0
  64. package/dist/core/cost-guard.d.ts +9 -4
  65. package/dist/core/cost-guard.d.ts.map +1 -1
  66. package/dist/core/cost-guard.js +7 -3
  67. package/dist/core/cost-guard.js.map +1 -1
  68. package/dist/core/delegation/worker-attempt-executor.d.ts +1 -1
  69. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  70. package/dist/core/delegation/worker-attempt-executor.js +0 -1
  71. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  72. package/dist/core/delegation/worker-authority-resolver.d.ts +16 -3
  73. package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
  74. package/dist/core/delegation/worker-authority-resolver.js +114 -55
  75. package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
  76. package/dist/core/delegation/worker-claim.d.ts +1 -2
  77. package/dist/core/delegation/worker-claim.d.ts.map +1 -1
  78. package/dist/core/delegation/worker-claim.js.map +1 -1
  79. package/dist/core/delegation/worker-delegation-controller.d.ts +19 -6
  80. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  81. package/dist/core/delegation/worker-delegation-controller.js +125 -40
  82. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  83. package/dist/core/delegation/worker-delegation-request.d.ts +3 -3
  84. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
  85. package/dist/core/delegation/worker-delegation-request.js +13 -19
  86. package/dist/core/delegation/worker-delegation-request.js.map +1 -1
  87. package/dist/core/delegation/worker-execution-policy.d.ts +3 -2
  88. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
  89. package/dist/core/delegation/worker-execution-policy.js +54 -39
  90. package/dist/core/delegation/worker-execution-policy.js.map +1 -1
  91. package/dist/core/delegation/worker-fleet-limits.d.ts +3 -3
  92. package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
  93. package/dist/core/delegation/worker-fleet-limits.js +7 -7
  94. package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
  95. package/dist/core/delegation/worker-machine-scope.d.ts +12 -0
  96. package/dist/core/delegation/worker-machine-scope.d.ts.map +1 -0
  97. package/dist/core/delegation/worker-machine-scope.js +38 -0
  98. package/dist/core/delegation/worker-machine-scope.js.map +1 -0
  99. package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
  100. package/dist/core/delegation/worker-recovery-coordinator.js +6 -1
  101. package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
  102. package/dist/core/delegation/worker-runner.d.ts +5 -7
  103. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  104. package/dist/core/delegation/worker-runner.js +1 -4
  105. package/dist/core/delegation/worker-runner.js.map +1 -1
  106. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +3 -2
  107. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
  108. package/dist/core/delegation/worker-write-reservation-coordinator.js +50 -25
  109. package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
  110. package/dist/core/durable-custom-message-turn-controller.d.ts +6 -0
  111. package/dist/core/durable-custom-message-turn-controller.d.ts.map +1 -1
  112. package/dist/core/durable-custom-message-turn-controller.js +38 -15
  113. package/dist/core/durable-custom-message-turn-controller.js.map +1 -1
  114. package/dist/core/extension-binding-controller.d.ts +5 -1
  115. package/dist/core/extension-binding-controller.d.ts.map +1 -1
  116. package/dist/core/extension-binding-controller.js +15 -0
  117. package/dist/core/extension-binding-controller.js.map +1 -1
  118. package/dist/core/extension-import-authority.d.ts +3 -1
  119. package/dist/core/extension-import-authority.d.ts.map +1 -1
  120. package/dist/core/extension-import-authority.js +15 -0
  121. package/dist/core/extension-import-authority.js.map +1 -1
  122. package/dist/core/extensions/factory-runtime.d.ts.map +1 -1
  123. package/dist/core/extensions/factory-runtime.js +5 -0
  124. package/dist/core/extensions/factory-runtime.js.map +1 -1
  125. package/dist/core/extensions/runner.d.ts.map +1 -1
  126. package/dist/core/extensions/runner.js +1 -0
  127. package/dist/core/extensions/runner.js.map +1 -1
  128. package/dist/core/extensions/types.d.ts +8 -4
  129. package/dist/core/extensions/types.d.ts.map +1 -1
  130. package/dist/core/extensions/types.js.map +1 -1
  131. package/dist/core/foreground-terminal-handoff-controller.d.ts +14 -0
  132. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
  133. package/dist/core/foreground-terminal-handoff-controller.js +188 -72
  134. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
  135. package/dist/core/goals/goal-session-controller.d.ts +2 -0
  136. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  137. package/dist/core/goals/goal-session-controller.js +8 -0
  138. package/dist/core/goals/goal-session-controller.js.map +1 -1
  139. package/dist/core/goals/goal-tool-core.d.ts +5 -4
  140. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  141. package/dist/core/goals/goal-tool-core.js +23 -19
  142. package/dist/core/goals/goal-tool-core.js.map +1 -1
  143. package/dist/core/keybindings.d.ts +2 -2
  144. package/dist/core/keybindings.d.ts.map +1 -1
  145. package/dist/core/keybindings.js +2 -2
  146. package/dist/core/keybindings.js.map +1 -1
  147. package/dist/core/learning/auto-learn-settings.d.ts +84 -0
  148. package/dist/core/learning/auto-learn-settings.d.ts.map +1 -0
  149. package/dist/core/learning/auto-learn-settings.js +66 -0
  150. package/dist/core/learning/auto-learn-settings.js.map +1 -0
  151. package/dist/core/learning/reflection-engine.d.ts +4 -0
  152. package/dist/core/learning/reflection-engine.d.ts.map +1 -1
  153. package/dist/core/learning/reflection-engine.js +48 -10
  154. package/dist/core/learning/reflection-engine.js.map +1 -1
  155. package/dist/core/local-prefix-warm-controller.d.ts +24 -0
  156. package/dist/core/local-prefix-warm-controller.d.ts.map +1 -0
  157. package/dist/core/local-prefix-warm-controller.js +79 -0
  158. package/dist/core/local-prefix-warm-controller.js.map +1 -0
  159. package/dist/core/memory/providers/file-store.d.ts +2 -0
  160. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  161. package/dist/core/memory/providers/file-store.js +71 -15
  162. package/dist/core/memory/providers/file-store.js.map +1 -1
  163. package/dist/core/memory/worker-memory-tools.d.ts +5 -0
  164. package/dist/core/memory/worker-memory-tools.d.ts.map +1 -0
  165. package/dist/core/memory/worker-memory-tools.js +5 -0
  166. package/dist/core/memory/worker-memory-tools.js.map +1 -0
  167. package/dist/core/model-capability.d.ts +7 -0
  168. package/dist/core/model-capability.d.ts.map +1 -1
  169. package/dist/core/model-capability.js +12 -0
  170. package/dist/core/model-capability.js.map +1 -1
  171. package/dist/core/model-registry.d.ts.map +1 -1
  172. package/dist/core/model-registry.js +2 -10
  173. package/dist/core/model-registry.js.map +1 -1
  174. package/dist/core/model-router-controller.d.ts +3 -2
  175. package/dist/core/model-router-controller.d.ts.map +1 -1
  176. package/dist/core/model-router-controller.js +3 -2
  177. package/dist/core/model-router-controller.js.map +1 -1
  178. package/dist/core/orchestration/contracts.d.ts +16 -12
  179. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  180. package/dist/core/orchestration/contracts.js +2 -2
  181. package/dist/core/orchestration/contracts.js.map +1 -1
  182. package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
  183. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
  184. package/dist/core/orchestration/lane-tool-manifests.js +6 -1
  185. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
  186. package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
  187. package/dist/core/orchestration/profile-registry.js +14 -0
  188. package/dist/core/orchestration/profile-registry.js.map +1 -1
  189. package/dist/core/orchestration/task-profile-writer.d.ts +7 -4
  190. package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -1
  191. package/dist/core/orchestration/task-profile-writer.js +71 -59
  192. package/dist/core/orchestration/task-profile-writer.js.map +1 -1
  193. package/dist/core/orchestration/thinking-level-schema.d.ts +7 -0
  194. package/dist/core/orchestration/thinking-level-schema.d.ts.map +1 -0
  195. package/dist/core/orchestration/thinking-level-schema.js +19 -0
  196. package/dist/core/orchestration/thinking-level-schema.js.map +1 -0
  197. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
  198. package/dist/core/orchestration/worker-execution-contract.js +12 -5
  199. package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
  200. package/dist/core/profile-filter-controller.d.ts.map +1 -1
  201. package/dist/core/profile-filter-controller.js +5 -2
  202. package/dist/core/profile-filter-controller.js.map +1 -1
  203. package/dist/core/provider-prompt-contracts.d.ts +6 -5
  204. package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
  205. package/dist/core/provider-prompt-contracts.js +9 -11
  206. package/dist/core/provider-prompt-contracts.js.map +1 -1
  207. package/dist/core/provider-request-context-controller.d.ts +2 -0
  208. package/dist/core/provider-request-context-controller.d.ts.map +1 -1
  209. package/dist/core/provider-request-context-controller.js +10 -3
  210. package/dist/core/provider-request-context-controller.js.map +1 -1
  211. package/dist/core/reflection-controller.d.ts +56 -27
  212. package/dist/core/reflection-controller.d.ts.map +1 -1
  213. package/dist/core/reflection-controller.js +206 -117
  214. package/dist/core/reflection-controller.js.map +1 -1
  215. package/dist/core/resource-loader.d.ts.map +1 -1
  216. package/dist/core/resource-loader.js +6 -2
  217. package/dist/core/resource-loader.js.map +1 -1
  218. package/dist/core/risk-classifier.d.ts.map +1 -1
  219. package/dist/core/risk-classifier.js +22 -2
  220. package/dist/core/risk-classifier.js.map +1 -1
  221. package/dist/core/runtime-builder.d.ts +1 -0
  222. package/dist/core/runtime-builder.d.ts.map +1 -1
  223. package/dist/core/runtime-builder.js +25 -14
  224. package/dist/core/runtime-builder.js.map +1 -1
  225. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
  226. package/dist/core/secrets/credential-exposure-guard.js +55 -10
  227. package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
  228. package/dist/core/session-role.d.ts +6 -8
  229. package/dist/core/session-role.d.ts.map +1 -1
  230. package/dist/core/session-role.js +8 -18
  231. package/dist/core/session-role.js.map +1 -1
  232. package/dist/core/settings-manager.d.ts +20 -16
  233. package/dist/core/settings-manager.d.ts.map +1 -1
  234. package/dist/core/settings-manager.js +75 -50
  235. package/dist/core/settings-manager.js.map +1 -1
  236. package/dist/core/skill-vault.d.ts +15 -0
  237. package/dist/core/skill-vault.d.ts.map +1 -1
  238. package/dist/core/skill-vault.js +79 -45
  239. package/dist/core/skill-vault.js.map +1 -1
  240. package/dist/core/skills.d.ts +3 -0
  241. package/dist/core/skills.d.ts.map +1 -1
  242. package/dist/core/skills.js +6 -6
  243. package/dist/core/skills.js.map +1 -1
  244. package/dist/core/system-prompt-builder.d.ts +3 -0
  245. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  246. package/dist/core/system-prompt-builder.js +73 -13
  247. package/dist/core/system-prompt-builder.js.map +1 -1
  248. package/dist/core/system-prompt.d.ts.map +1 -1
  249. package/dist/core/system-prompt.js +6 -2
  250. package/dist/core/system-prompt.js.map +1 -1
  251. package/dist/core/tool-capability-policy.d.ts +3 -0
  252. package/dist/core/tool-capability-policy.d.ts.map +1 -1
  253. package/dist/core/tool-capability-policy.js +13 -2
  254. package/dist/core/tool-capability-policy.js.map +1 -1
  255. package/dist/core/toolkit/script-runner.d.ts +2 -1
  256. package/dist/core/toolkit/script-runner.d.ts.map +1 -1
  257. package/dist/core/toolkit/script-runner.js +10 -2
  258. package/dist/core/toolkit/script-runner.js.map +1 -1
  259. package/dist/core/tools/delegate-status.d.ts +1 -1
  260. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  261. package/dist/core/tools/delegate-status.js +1 -1
  262. package/dist/core/tools/delegate-status.js.map +1 -1
  263. package/dist/core/tools/delegate.d.ts +4 -15
  264. package/dist/core/tools/delegate.d.ts.map +1 -1
  265. package/dist/core/tools/delegate.js +111 -73
  266. package/dist/core/tools/delegate.js.map +1 -1
  267. package/dist/core/tools/goal.d.ts +3 -4
  268. package/dist/core/tools/goal.d.ts.map +1 -1
  269. package/dist/core/tools/goal.js +30 -23
  270. package/dist/core/tools/goal.js.map +1 -1
  271. package/dist/core/tools/orchestration-panel.d.ts +7 -0
  272. package/dist/core/tools/orchestration-panel.d.ts.map +1 -1
  273. package/dist/core/tools/orchestration-panel.js +58 -9
  274. package/dist/core/tools/orchestration-panel.js.map +1 -1
  275. package/dist/core/tools/profile-writer.d.ts +2 -8
  276. package/dist/core/tools/profile-writer.d.ts.map +1 -1
  277. package/dist/core/tools/profile-writer.js +6 -18
  278. package/dist/core/tools/profile-writer.js.map +1 -1
  279. package/dist/core/tools/run-toolkit-script.d.ts +1 -1
  280. package/dist/core/tools/run-toolkit-script.d.ts.map +1 -1
  281. package/dist/core/tools/run-toolkit-script.js +2 -2
  282. package/dist/core/tools/run-toolkit-script.js.map +1 -1
  283. package/dist/core/tools/skill-audit.d.ts +28 -1
  284. package/dist/core/tools/skill-audit.d.ts.map +1 -1
  285. package/dist/core/tools/skill-audit.js +56 -12
  286. package/dist/core/tools/skill-audit.js.map +1 -1
  287. package/dist/core/tools/skill.d.ts +12 -1
  288. package/dist/core/tools/skill.d.ts.map +1 -1
  289. package/dist/core/tools/skill.js +52 -0
  290. package/dist/core/tools/skill.js.map +1 -1
  291. package/dist/core/tools/skillify.d.ts.map +1 -1
  292. package/dist/core/tools/skillify.js +16 -7
  293. package/dist/core/tools/skillify.js.map +1 -1
  294. package/dist/core/tools/task-steps.d.ts.map +1 -1
  295. package/dist/core/tools/task-steps.js +2 -1
  296. package/dist/core/tools/task-steps.js.map +1 -1
  297. package/dist/core/tools/tmux-dispatch.d.ts +4 -16
  298. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  299. package/dist/core/tools/tmux-dispatch.js +5 -20
  300. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  301. package/dist/core/worktree-sync/codes.d.ts +1 -2
  302. package/dist/core/worktree-sync/codes.d.ts.map +1 -1
  303. package/dist/core/worktree-sync/codes.js +1 -2
  304. package/dist/core/worktree-sync/codes.js.map +1 -1
  305. package/dist/core/worktree-sync/lane-gate.d.ts +4 -8
  306. package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -1
  307. package/dist/core/worktree-sync/lane-gate.js +5 -51
  308. package/dist/core/worktree-sync/lane-gate.js.map +1 -1
  309. package/dist/index.d.ts +5 -0
  310. package/dist/index.d.ts.map +1 -1
  311. package/dist/index.js +7 -0
  312. package/dist/index.js.map +1 -1
  313. package/dist/modes/interactive/auto-learn-controller.d.ts +6 -7
  314. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  315. package/dist/modes/interactive/auto-learn-controller.js +30 -207
  316. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  317. package/dist/modes/interactive/autonomy-commands.js +2 -2
  318. package/dist/modes/interactive/autonomy-commands.js.map +1 -1
  319. package/dist/modes/interactive/components/agents-overlay.d.ts +16 -4
  320. package/dist/modes/interactive/components/agents-overlay.d.ts.map +1 -1
  321. package/dist/modes/interactive/components/agents-overlay.js +108 -29
  322. package/dist/modes/interactive/components/agents-overlay.js.map +1 -1
  323. package/dist/modes/interactive/components/custom-message.js +17 -0
  324. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  325. package/dist/modes/interactive/components/fitness-role-selector.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/fitness-role-selector.js +2 -2
  327. package/dist/modes/interactive/components/fitness-role-selector.js.map +1 -1
  328. package/dist/modes/interactive/components/footer.js +1 -1
  329. package/dist/modes/interactive/components/footer.js.map +1 -1
  330. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  331. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  332. package/dist/modes/interactive/components/settings-selector.js +150 -73
  333. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  334. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  335. package/dist/modes/interactive/interactive-mode.js +5 -4
  336. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  337. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  338. package/dist/modes/interactive/report-commands.js +8 -4
  339. package/dist/modes/interactive/report-commands.js.map +1 -1
  340. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  341. package/dist/modes/interactive/settings-selector-flow.js +10 -0
  342. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  343. package/docs/extensions.md +10 -0
  344. package/docs/harness-architecture.md +28 -32
  345. package/docs/index.md +2 -1
  346. package/docs/keybindings.md +2 -0
  347. package/docs/process-matrix.md +8 -6
  348. package/docs/resources.md +1 -1
  349. package/docs/settings.md +61 -51
  350. package/docs/task-steps.md +2 -0
  351. package/docs/tmux-agent-manager.md +48 -41
  352. package/docs/usage.md +1 -1
  353. package/docs/work-lifecycle.md +137 -0
  354. package/docs/worker-profiles.md +8 -6
  355. package/docs/worktree-sync.md +26 -20
  356. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  357. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  358. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  359. package/examples/extensions/sandbox/package-lock.json +2 -2
  360. package/examples/extensions/sandbox/package.json +1 -1
  361. package/examples/extensions/with-deps/package-lock.json +2 -2
  362. package/examples/extensions/with-deps/package.json +1 -1
  363. package/npm-shrinkwrap.json +12 -12
  364. package/package.json +4 -4
  365. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +0 -133
  366. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +0 -1
  367. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +0 -199
  368. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +0 -1
  369. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +0 -312
@@ -1 +0,0 @@
1
- {"version":3,"file":"dispatch-grant.js","sourceRoot":"","sources":["../../../../src/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts"],"names":[],"mappings":"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","sourcesContent":["import * as crypto from \"node:crypto\";\nimport type { Usage } from \"@caupulican/pi-ai\";\n\n/**\n * The STANDING GRANT for approval-gated tmux dispatch (owner authorizes once via `grant_dispatch`;\n * the extension then dispatches unattended WITHIN the grant's bounds). Pure data + pure decode/decision\n * logic only — no session/tmux/filesystem access, so every function here is directly unit-testable.\n * The extension (index.ts) owns reading/writing session custom entries and calls into this module for\n * decoding and authorization decisions.\n *\n * HONEST TRUST BOUNDARY: this grant bounds WHO may be launched, HOW OFTEN, and WITH WHAT launch-time\n * envelope (pushed into the child's own CLI flags) — it never claims to gate the child's in-process\n * tool loop, which is a separate OS process outside this runtime's `beforeToolCall` machinery.\n */\n\nexport type Provider = \"pi\" | \"codex\" | \"agy\" | \"claude\" | \"opencode\" | \"custom\";\n\nexport const GRANT_CUSTOM_TYPE = \"tmux-dispatch-grant\";\nexport const GRANT_USAGE_CUSTOM_TYPE = \"tmux-dispatch-grant-usage\";\n\nexport interface TmuxDispatchGrantEnvelope {\n\tallowedTools?: string[];\n\tresourceProfile?: string;\n\twritePaths?: string[];\n}\n\nexport interface TmuxDispatchGrantBudget {\n\tmaxLaunches: number;\n\tmaxWallClockMs?: number;\n\tmaxUsdAdvisory?: number;\n}\n\nexport interface TmuxDispatchGrant {\n\tgrantId: string;\n\tcreatedAt: string;\n\tagent: Provider;\n\tscope: { goalId?: string };\n\tenvelope: TmuxDispatchGrantEnvelope;\n\tbudget: TmuxDispatchGrantBudget;\n\texpiresAt?: string;\n}\n\n/** Appended by `revoke_grant`. Shares `GRANT_CUSTOM_TYPE` so the SAME latest-on-branch read that\n * resolves an active grant also sees a revocation and stops treating any older grant beneath it as\n * active — a tombstone is a hard stop, never skipped over to resurrect an earlier grant. */\nexport interface TmuxDispatchGrantTombstone {\n\ttombstone: true;\n\tgrantId: string;\n\trevokedAt: string;\n}\n\nexport interface TmuxDispatchGrantUsage {\n\tgrantId: string;\n\tjobId: string;\n\tat: string;\n}\n\nconst PROVIDERS: readonly Provider[] = [\"pi\", \"codex\", \"agy\", \"claude\", \"opencode\", \"custom\"];\n\nfunction isProvider(value: unknown): value is Provider {\n\treturn typeof value === \"string\" && (PROVIDERS as readonly string[]).includes(value);\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function isTmuxDispatchGrantTombstone(value: unknown): value is TmuxDispatchGrantTombstone {\n\tif (!isPlainRecord(value)) return false;\n\treturn value.tombstone === true && typeof value.grantId === \"string\" && typeof value.revokedAt === \"string\";\n}\n\nexport function isTmuxDispatchGrant(value: unknown): value is TmuxDispatchGrant {\n\tif (!isPlainRecord(value) || value.tombstone === true) return false;\n\tif (typeof value.grantId !== \"string\" || typeof value.createdAt !== \"string\" || !isProvider(value.agent))\n\t\treturn false;\n\tif (!isPlainRecord(value.scope) || !isPlainRecord(value.envelope) || !isPlainRecord(value.budget)) return false;\n\treturn typeof value.budget.maxLaunches === \"number\" && Number.isFinite(value.budget.maxLaunches);\n}\n\nexport function isTmuxDispatchGrantUsage(value: unknown): value is TmuxDispatchGrantUsage {\n\tif (!isPlainRecord(value)) return false;\n\treturn typeof value.grantId === \"string\" && typeof value.jobId === \"string\" && typeof value.at === \"string\";\n}\n\nexport function makeGrantId(): string {\n\treturn `grant-${Date.now().toString(36)}-${crypto.randomBytes(4).toString(\"hex\")}`;\n}\n\nexport interface GrantCoverageRequest {\n\tagent: Provider;\n\tgoalId?: string;\n\tnowIso?: string;\n}\n\n/** Whether `grant` authorizes a launch for `request`: same agent, goal-scope match (an UNSCOPED grant\n * covers any goal including none; a goal-SCOPED grant covers ONLY that exact goalId), and the grant is\n * not past `expiresAt`. Budget (maxLaunches) is checked separately via {@link isGrantBudgetExhausted}\n * because counting usages requires the caller's session-entry access. */\nexport function grantCovers(grant: TmuxDispatchGrant, request: GrantCoverageRequest): boolean {\n\tif (grant.agent !== request.agent) return false;\n\tif (grant.scope.goalId && grant.scope.goalId !== request.goalId) return false;\n\tif (grant.expiresAt) {\n\t\tconst now = Date.parse(request.nowIso ?? new Date().toISOString());\n\t\tconst expiry = Date.parse(grant.expiresAt);\n\t\tif (Number.isFinite(expiry) && Number.isFinite(now) && now >= expiry) return false;\n\t}\n\treturn true;\n}\n\n/** Count spend entries for `grantId` among already-decoded custom-entry payloads (the caller walks the\n * session branch and passes the raw `data` values — this stays pure/session-agnostic). */\nexport function countGrantUsages(grantId: string, usageEntries: readonly unknown[]): number {\n\tlet count = 0;\n\tfor (const entry of usageEntries) if (isTmuxDispatchGrantUsage(entry) && entry.grantId === grantId) count++;\n\treturn count;\n}\n\nexport function isGrantBudgetExhausted(grant: TmuxDispatchGrant, usedCount: number): boolean {\n\treturn usedCount >= grant.budget.maxLaunches;\n}\n\nexport function buildGrantUsageEntry(\n\tgrantId: string,\n\tjobId: string,\n\tnowIso = new Date().toISOString(),\n): TmuxDispatchGrantUsage {\n\treturn { grantId, jobId, at: nowIso };\n}\n\nexport function buildTombstone(grantId: string, nowIso = new Date().toISOString()): TmuxDispatchGrantTombstone {\n\treturn { tombstone: true, grantId, revokedAt: nowIso };\n}\n\nexport interface GrantDispatchParams {\n\tagent: Provider;\n\tgoalId?: string;\n\tallowedTools?: string[];\n\tresourceProfile?: string;\n\twritePaths?: string[];\n\tmaxLaunches: number;\n\texpiresInMinutes?: number;\n\tmaxUsdAdvisory?: number;\n}\n\n/** Build a new grant record from `grant_dispatch` params. Pure — the caller (index.ts) owns the\n * approval gate (ui.confirm / opt-in flag) and the `pi.appendEntry` persistence; this only shapes the\n * data, so it stays independently testable and never itself decides whether creation is authorized. */\nexport function buildGrant(params: GrantDispatchParams, nowIso = new Date().toISOString()): TmuxDispatchGrant {\n\tif (!Number.isFinite(params.maxLaunches) || params.maxLaunches < 1)\n\t\tthrow new Error(\"grant_dispatch requires maxLaunches >= 1\");\n\tconst expiresAt =\n\t\tparams.expiresInMinutes !== undefined\n\t\t\t? new Date(Date.parse(nowIso) + Math.max(1, params.expiresInMinutes) * 60_000).toISOString()\n\t\t\t: undefined;\n\treturn {\n\t\tgrantId: makeGrantId(),\n\t\tcreatedAt: nowIso,\n\t\tagent: params.agent,\n\t\tscope: { goalId: params.goalId },\n\t\tenvelope: {\n\t\t\tallowedTools: params.allowedTools,\n\t\t\tresourceProfile: params.resourceProfile,\n\t\t\twritePaths: params.writePaths,\n\t\t},\n\t\tbudget: {\n\t\t\tmaxLaunches: Math.trunc(params.maxLaunches),\n\t\t\tmaxUsdAdvisory: params.maxUsdAdvisory,\n\t\t},\n\t\texpiresAt,\n\t};\n}\n\nexport function describeGrant(grant: TmuxDispatchGrant): string {\n\treturn [\n\t\t`Grant id: ${grant.grantId}`,\n\t\t`Agent: ${grant.agent}`,\n\t\tgrant.scope.goalId ? `Goal scope: ${grant.scope.goalId}` : \"Goal scope: none (covers any goal)\",\n\t\t`Max launches: ${grant.budget.maxLaunches}`,\n\t\tgrant.expiresAt ? `Expires: ${grant.expiresAt}` : \"Expires: never (until revoke_grant)\",\n\t\tgrant.envelope.allowedTools?.length\n\t\t\t? `Allowed tools: ${grant.envelope.allowedTools.join(\", \")}`\n\t\t\t: `Allowed tools: read-biased safe default (${DEFAULT_READ_BIASED_TOOLS.join(\", \")})`,\n\t\tgrant.envelope.resourceProfile\n\t\t\t? `Resource profile: ${grant.envelope.resourceProfile}`\n\t\t\t: \"Resource profile: none (child launches with --no-extensions --no-skills)\",\n\t\tgrant.envelope.writePaths?.length\n\t\t\t? `Write paths: ${grant.envelope.writePaths.join(\", \")}`\n\t\t\t: \"Write paths: none declared\",\n\t\tgrant.budget.maxUsdAdvisory !== undefined\n\t\t\t? `Advisory USD cap: ${grant.budget.maxUsdAdvisory} (not enforced across the process boundary — advisory only)`\n\t\t\t: undefined,\n\t]\n\t\t.filter((line): line is string => Boolean(line))\n\t\t.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Launch-profile flags: the REAL lever — pushed into the child `pi` CLI's own config.\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_READ_BIASED_TOOLS: readonly string[] = [\"read\", \"grep\", \"find\", \"ls\"];\n\nexport interface LaunchProfileSource {\n\t/** Human-readable identity for the scoped system prompt (e.g. \"grant <id>\" or a one-shot label). */\n\tidentity: string;\n\tallowedTools?: string[];\n\tresourceProfile?: string;\n\twritePaths?: string[];\n\t/**\n\t * Worktree-sync lane key this launch is bound to (per-agent -- see `applyLaunchProfile`'s caller,\n\t * which builds a per-agent `LaunchProfileSource` only when that agent carries `worktreeLane`).\n\t * When present, `buildLaunchProfileFlags` appends `--worktree-lane <key>` (the same CLI flag\n\t * `src/cli/args.ts` already exposes, sugar over the `PI_WORKTREE_LANE` env contract) and\n\t * `buildScopedSystemPrompt` appends one lane-doctrine sentence.\n\t */\n\tworktreeLane?: string;\n\t/**\n\t * Process-matrix parent identity for this launch (see `core/process-matrix/runtime.ts`): the\n\t * dispatching process's own pid/sessionId. When present, `buildLaunchProfileFlags` appends\n\t * `--parent-pid`/`--parent-session` (sugar over `PI_PARENT_PID`/`PI_PARENT_SESSION`) so the\n\t * child self-registers as a worker of this session and winds down gracefully if it disappears.\n\t */\n\tparentPid?: number;\n\tparentSession?: string;\n\t/** Stable goal/task identity used to fence process-matrix recovery. */\n\ttaskRef?: string;\n}\n\n/** A grant-covered launch derives its profile from the grant's envelope. */\nexport function launchProfileSourceFromGrant(grant: TmuxDispatchGrant): LaunchProfileSource {\n\treturn {\n\t\tidentity: `grant ${grant.grantId}`,\n\t\tallowedTools: grant.envelope.allowedTools,\n\t\tresourceProfile: grant.envelope.resourceProfile,\n\t\twritePaths: grant.envelope.writePaths,\n\t};\n}\n\n/** A one-shot interactively-approved launch (no standing grant) still gets the conservative default\n * profile — approving a single launch is not the same as defining an unrestricted envelope. */\nexport const ONE_SHOT_LAUNCH_PROFILE_SOURCE: LaunchProfileSource = {\n\tidentity: \"a one-shot owner-approved tmux dispatch (no standing grant)\",\n};\n\nexport interface LaunchProfileFlag {\n\tflag: string;\n\tvalue?: string;\n}\n\n/** Build the CLI flags to append to a child `pi` invocation so the grant's envelope lives in the\n * child's OWN launch config (verified flag names: --tools, --resource-profile, --no-extensions,\n * --no-skills, --append-system-prompt). Never includes --no-approve: the child must keep gating its\n * own hard stops. */\nexport function buildLaunchProfileFlags(source: LaunchProfileSource): LaunchProfileFlag[] {\n\tconst tools = source.allowedTools?.length ? source.allowedTools : DEFAULT_READ_BIASED_TOOLS;\n\tconst flags: LaunchProfileFlag[] = [{ flag: \"--tools\", value: tools.join(\",\") }];\n\tif (source.resourceProfile) flags.push({ flag: \"--resource-profile\", value: source.resourceProfile });\n\telse flags.push({ flag: \"--no-extensions\" }, { flag: \"--no-skills\" });\n\tif (source.worktreeLane) flags.push({ flag: \"--worktree-lane\", value: source.worktreeLane });\n\tif (source.parentPid !== undefined) flags.push({ flag: \"--parent-pid\", value: String(source.parentPid) });\n\tif (source.parentSession) flags.push({ flag: \"--parent-session\", value: source.parentSession });\n\tif (source.taskRef) flags.push({ flag: \"--task-ref\", value: source.taskRef });\n\tflags.push({ flag: \"--append-system-prompt\", value: buildScopedSystemPrompt(source) });\n\tflags.push({ flag: \"--session-mode\", value: \"worker\" });\n\treturn flags;\n}\n\nexport function buildScopedSystemPrompt(source: LaunchProfileSource): string {\n\tconst paths = source.writePaths?.length ? source.writePaths.join(\", \") : \"no additional paths granted\";\n\tconst sentences = [\n\t\t`You are a tmux worker dispatched under ${source.identity}.`,\n\t\t`Stay within these write paths: ${paths}.`,\n\t\t\"Hard stops — publishing/npm, git push, tagging a release, changing credentials/auth, or destructive deletion — require returning BLOCKED for owner approval. Never self-approve a hard stop.\",\n\t];\n\tif (source.worktreeLane) {\n\t\tsentences.push(\n\t\t\t`You are bound to worktree-sync lane '${source.worktreeLane}': work only inside this lane's own worktree, integrate exclusively via worktree_sync land, and never touch main directly.`,\n\t\t);\n\t}\n\treturn sentences.join(\" \");\n}\n\n// ---------------------------------------------------------------------------\n// Advisory worker usage claim: budget stays advisory across the process boundary.\n// ---------------------------------------------------------------------------\n\n/** Permissively decode a worker-reported usage CLAIM (a cooperative worker may write this to a\n * well-known sibling file before printing its completion marker). Read-defensive: missing/malformed\n * numeric fields default to 0 rather than throwing — this is untrusted, OPTIONAL, advisory input, never\n * an authoritative billing record. Returns undefined only when `raw` isn't even an object, so the\n * caller can distinguish \"no claim offered\" (skip reporting) from \"a claim was offered\" (report it,\n * however partial). */\nexport function decodeTmuxWorkerUsageClaim(raw: unknown): Usage | undefined {\n\tif (!isPlainRecord(raw)) return undefined;\n\tconst num = (value: unknown): number => (typeof value === \"number\" && Number.isFinite(value) ? value : 0);\n\tconst cost = isPlainRecord(raw.cost) ? raw.cost : {};\n\treturn {\n\t\tinput: num(raw.input),\n\t\toutput: num(raw.output),\n\t\tcacheRead: num(raw.cacheRead),\n\t\tcacheWrite: num(raw.cacheWrite),\n\t\ttotalTokens: num(raw.totalTokens),\n\t\tcost: {\n\t\t\tinput: num(cost.input),\n\t\t\toutput: num(cost.output),\n\t\t\tcacheRead: num(cost.cacheRead),\n\t\t\tcacheWrite: num(cost.cacheWrite),\n\t\t\ttotal: num(cost.total),\n\t\t},\n\t};\n}\n"]}
@@ -1,312 +0,0 @@
1
- import * as crypto from "node:crypto";
2
- import type { Usage } from "@caupulican/pi-ai";
3
-
4
- /**
5
- * The STANDING GRANT for approval-gated tmux dispatch (owner authorizes once via `grant_dispatch`;
6
- * the extension then dispatches unattended WITHIN the grant's bounds). Pure data + pure decode/decision
7
- * logic only — no session/tmux/filesystem access, so every function here is directly unit-testable.
8
- * The extension (index.ts) owns reading/writing session custom entries and calls into this module for
9
- * decoding and authorization decisions.
10
- *
11
- * HONEST TRUST BOUNDARY: this grant bounds WHO may be launched, HOW OFTEN, and WITH WHAT launch-time
12
- * envelope (pushed into the child's own CLI flags) — it never claims to gate the child's in-process
13
- * tool loop, which is a separate OS process outside this runtime's `beforeToolCall` machinery.
14
- */
15
-
16
- export type Provider = "pi" | "codex" | "agy" | "claude" | "opencode" | "custom";
17
-
18
- export const GRANT_CUSTOM_TYPE = "tmux-dispatch-grant";
19
- export const GRANT_USAGE_CUSTOM_TYPE = "tmux-dispatch-grant-usage";
20
-
21
- export interface TmuxDispatchGrantEnvelope {
22
- allowedTools?: string[];
23
- resourceProfile?: string;
24
- writePaths?: string[];
25
- }
26
-
27
- export interface TmuxDispatchGrantBudget {
28
- maxLaunches: number;
29
- maxWallClockMs?: number;
30
- maxUsdAdvisory?: number;
31
- }
32
-
33
- export interface TmuxDispatchGrant {
34
- grantId: string;
35
- createdAt: string;
36
- agent: Provider;
37
- scope: { goalId?: string };
38
- envelope: TmuxDispatchGrantEnvelope;
39
- budget: TmuxDispatchGrantBudget;
40
- expiresAt?: string;
41
- }
42
-
43
- /** Appended by `revoke_grant`. Shares `GRANT_CUSTOM_TYPE` so the SAME latest-on-branch read that
44
- * resolves an active grant also sees a revocation and stops treating any older grant beneath it as
45
- * active — a tombstone is a hard stop, never skipped over to resurrect an earlier grant. */
46
- export interface TmuxDispatchGrantTombstone {
47
- tombstone: true;
48
- grantId: string;
49
- revokedAt: string;
50
- }
51
-
52
- export interface TmuxDispatchGrantUsage {
53
- grantId: string;
54
- jobId: string;
55
- at: string;
56
- }
57
-
58
- const PROVIDERS: readonly Provider[] = ["pi", "codex", "agy", "claude", "opencode", "custom"];
59
-
60
- function isProvider(value: unknown): value is Provider {
61
- return typeof value === "string" && (PROVIDERS as readonly string[]).includes(value);
62
- }
63
-
64
- function isPlainRecord(value: unknown): value is Record<string, unknown> {
65
- return typeof value === "object" && value !== null && !Array.isArray(value);
66
- }
67
-
68
- export function isTmuxDispatchGrantTombstone(value: unknown): value is TmuxDispatchGrantTombstone {
69
- if (!isPlainRecord(value)) return false;
70
- return value.tombstone === true && typeof value.grantId === "string" && typeof value.revokedAt === "string";
71
- }
72
-
73
- export function isTmuxDispatchGrant(value: unknown): value is TmuxDispatchGrant {
74
- if (!isPlainRecord(value) || value.tombstone === true) return false;
75
- if (typeof value.grantId !== "string" || typeof value.createdAt !== "string" || !isProvider(value.agent))
76
- return false;
77
- if (!isPlainRecord(value.scope) || !isPlainRecord(value.envelope) || !isPlainRecord(value.budget)) return false;
78
- return typeof value.budget.maxLaunches === "number" && Number.isFinite(value.budget.maxLaunches);
79
- }
80
-
81
- export function isTmuxDispatchGrantUsage(value: unknown): value is TmuxDispatchGrantUsage {
82
- if (!isPlainRecord(value)) return false;
83
- return typeof value.grantId === "string" && typeof value.jobId === "string" && typeof value.at === "string";
84
- }
85
-
86
- export function makeGrantId(): string {
87
- return `grant-${Date.now().toString(36)}-${crypto.randomBytes(4).toString("hex")}`;
88
- }
89
-
90
- export interface GrantCoverageRequest {
91
- agent: Provider;
92
- goalId?: string;
93
- nowIso?: string;
94
- }
95
-
96
- /** Whether `grant` authorizes a launch for `request`: same agent, goal-scope match (an UNSCOPED grant
97
- * covers any goal including none; a goal-SCOPED grant covers ONLY that exact goalId), and the grant is
98
- * not past `expiresAt`. Budget (maxLaunches) is checked separately via {@link isGrantBudgetExhausted}
99
- * because counting usages requires the caller's session-entry access. */
100
- export function grantCovers(grant: TmuxDispatchGrant, request: GrantCoverageRequest): boolean {
101
- if (grant.agent !== request.agent) return false;
102
- if (grant.scope.goalId && grant.scope.goalId !== request.goalId) return false;
103
- if (grant.expiresAt) {
104
- const now = Date.parse(request.nowIso ?? new Date().toISOString());
105
- const expiry = Date.parse(grant.expiresAt);
106
- if (Number.isFinite(expiry) && Number.isFinite(now) && now >= expiry) return false;
107
- }
108
- return true;
109
- }
110
-
111
- /** Count spend entries for `grantId` among already-decoded custom-entry payloads (the caller walks the
112
- * session branch and passes the raw `data` values — this stays pure/session-agnostic). */
113
- export function countGrantUsages(grantId: string, usageEntries: readonly unknown[]): number {
114
- let count = 0;
115
- for (const entry of usageEntries) if (isTmuxDispatchGrantUsage(entry) && entry.grantId === grantId) count++;
116
- return count;
117
- }
118
-
119
- export function isGrantBudgetExhausted(grant: TmuxDispatchGrant, usedCount: number): boolean {
120
- return usedCount >= grant.budget.maxLaunches;
121
- }
122
-
123
- export function buildGrantUsageEntry(
124
- grantId: string,
125
- jobId: string,
126
- nowIso = new Date().toISOString(),
127
- ): TmuxDispatchGrantUsage {
128
- return { grantId, jobId, at: nowIso };
129
- }
130
-
131
- export function buildTombstone(grantId: string, nowIso = new Date().toISOString()): TmuxDispatchGrantTombstone {
132
- return { tombstone: true, grantId, revokedAt: nowIso };
133
- }
134
-
135
- export interface GrantDispatchParams {
136
- agent: Provider;
137
- goalId?: string;
138
- allowedTools?: string[];
139
- resourceProfile?: string;
140
- writePaths?: string[];
141
- maxLaunches: number;
142
- expiresInMinutes?: number;
143
- maxUsdAdvisory?: number;
144
- }
145
-
146
- /** Build a new grant record from `grant_dispatch` params. Pure — the caller (index.ts) owns the
147
- * approval gate (ui.confirm / opt-in flag) and the `pi.appendEntry` persistence; this only shapes the
148
- * data, so it stays independently testable and never itself decides whether creation is authorized. */
149
- export function buildGrant(params: GrantDispatchParams, nowIso = new Date().toISOString()): TmuxDispatchGrant {
150
- if (!Number.isFinite(params.maxLaunches) || params.maxLaunches < 1)
151
- throw new Error("grant_dispatch requires maxLaunches >= 1");
152
- const expiresAt =
153
- params.expiresInMinutes !== undefined
154
- ? new Date(Date.parse(nowIso) + Math.max(1, params.expiresInMinutes) * 60_000).toISOString()
155
- : undefined;
156
- return {
157
- grantId: makeGrantId(),
158
- createdAt: nowIso,
159
- agent: params.agent,
160
- scope: { goalId: params.goalId },
161
- envelope: {
162
- allowedTools: params.allowedTools,
163
- resourceProfile: params.resourceProfile,
164
- writePaths: params.writePaths,
165
- },
166
- budget: {
167
- maxLaunches: Math.trunc(params.maxLaunches),
168
- maxUsdAdvisory: params.maxUsdAdvisory,
169
- },
170
- expiresAt,
171
- };
172
- }
173
-
174
- export function describeGrant(grant: TmuxDispatchGrant): string {
175
- return [
176
- `Grant id: ${grant.grantId}`,
177
- `Agent: ${grant.agent}`,
178
- grant.scope.goalId ? `Goal scope: ${grant.scope.goalId}` : "Goal scope: none (covers any goal)",
179
- `Max launches: ${grant.budget.maxLaunches}`,
180
- grant.expiresAt ? `Expires: ${grant.expiresAt}` : "Expires: never (until revoke_grant)",
181
- grant.envelope.allowedTools?.length
182
- ? `Allowed tools: ${grant.envelope.allowedTools.join(", ")}`
183
- : `Allowed tools: read-biased safe default (${DEFAULT_READ_BIASED_TOOLS.join(", ")})`,
184
- grant.envelope.resourceProfile
185
- ? `Resource profile: ${grant.envelope.resourceProfile}`
186
- : "Resource profile: none (child launches with --no-extensions --no-skills)",
187
- grant.envelope.writePaths?.length
188
- ? `Write paths: ${grant.envelope.writePaths.join(", ")}`
189
- : "Write paths: none declared",
190
- grant.budget.maxUsdAdvisory !== undefined
191
- ? `Advisory USD cap: ${grant.budget.maxUsdAdvisory} (not enforced across the process boundary — advisory only)`
192
- : undefined,
193
- ]
194
- .filter((line): line is string => Boolean(line))
195
- .join("\n");
196
- }
197
-
198
- // ---------------------------------------------------------------------------
199
- // Launch-profile flags: the REAL lever — pushed into the child `pi` CLI's own config.
200
- // ---------------------------------------------------------------------------
201
-
202
- export const DEFAULT_READ_BIASED_TOOLS: readonly string[] = ["read", "grep", "find", "ls"];
203
-
204
- export interface LaunchProfileSource {
205
- /** Human-readable identity for the scoped system prompt (e.g. "grant <id>" or a one-shot label). */
206
- identity: string;
207
- allowedTools?: string[];
208
- resourceProfile?: string;
209
- writePaths?: string[];
210
- /**
211
- * Worktree-sync lane key this launch is bound to (per-agent -- see `applyLaunchProfile`'s caller,
212
- * which builds a per-agent `LaunchProfileSource` only when that agent carries `worktreeLane`).
213
- * When present, `buildLaunchProfileFlags` appends `--worktree-lane <key>` (the same CLI flag
214
- * `src/cli/args.ts` already exposes, sugar over the `PI_WORKTREE_LANE` env contract) and
215
- * `buildScopedSystemPrompt` appends one lane-doctrine sentence.
216
- */
217
- worktreeLane?: string;
218
- /**
219
- * Process-matrix parent identity for this launch (see `core/process-matrix/runtime.ts`): the
220
- * dispatching process's own pid/sessionId. When present, `buildLaunchProfileFlags` appends
221
- * `--parent-pid`/`--parent-session` (sugar over `PI_PARENT_PID`/`PI_PARENT_SESSION`) so the
222
- * child self-registers as a worker of this session and winds down gracefully if it disappears.
223
- */
224
- parentPid?: number;
225
- parentSession?: string;
226
- /** Stable goal/task identity used to fence process-matrix recovery. */
227
- taskRef?: string;
228
- }
229
-
230
- /** A grant-covered launch derives its profile from the grant's envelope. */
231
- export function launchProfileSourceFromGrant(grant: TmuxDispatchGrant): LaunchProfileSource {
232
- return {
233
- identity: `grant ${grant.grantId}`,
234
- allowedTools: grant.envelope.allowedTools,
235
- resourceProfile: grant.envelope.resourceProfile,
236
- writePaths: grant.envelope.writePaths,
237
- };
238
- }
239
-
240
- /** A one-shot interactively-approved launch (no standing grant) still gets the conservative default
241
- * profile — approving a single launch is not the same as defining an unrestricted envelope. */
242
- export const ONE_SHOT_LAUNCH_PROFILE_SOURCE: LaunchProfileSource = {
243
- identity: "a one-shot owner-approved tmux dispatch (no standing grant)",
244
- };
245
-
246
- export interface LaunchProfileFlag {
247
- flag: string;
248
- value?: string;
249
- }
250
-
251
- /** Build the CLI flags to append to a child `pi` invocation so the grant's envelope lives in the
252
- * child's OWN launch config (verified flag names: --tools, --resource-profile, --no-extensions,
253
- * --no-skills, --append-system-prompt). Never includes --no-approve: the child must keep gating its
254
- * own hard stops. */
255
- export function buildLaunchProfileFlags(source: LaunchProfileSource): LaunchProfileFlag[] {
256
- const tools = source.allowedTools?.length ? source.allowedTools : DEFAULT_READ_BIASED_TOOLS;
257
- const flags: LaunchProfileFlag[] = [{ flag: "--tools", value: tools.join(",") }];
258
- if (source.resourceProfile) flags.push({ flag: "--resource-profile", value: source.resourceProfile });
259
- else flags.push({ flag: "--no-extensions" }, { flag: "--no-skills" });
260
- if (source.worktreeLane) flags.push({ flag: "--worktree-lane", value: source.worktreeLane });
261
- if (source.parentPid !== undefined) flags.push({ flag: "--parent-pid", value: String(source.parentPid) });
262
- if (source.parentSession) flags.push({ flag: "--parent-session", value: source.parentSession });
263
- if (source.taskRef) flags.push({ flag: "--task-ref", value: source.taskRef });
264
- flags.push({ flag: "--append-system-prompt", value: buildScopedSystemPrompt(source) });
265
- flags.push({ flag: "--session-mode", value: "worker" });
266
- return flags;
267
- }
268
-
269
- export function buildScopedSystemPrompt(source: LaunchProfileSource): string {
270
- const paths = source.writePaths?.length ? source.writePaths.join(", ") : "no additional paths granted";
271
- const sentences = [
272
- `You are a tmux worker dispatched under ${source.identity}.`,
273
- `Stay within these write paths: ${paths}.`,
274
- "Hard stops — publishing/npm, git push, tagging a release, changing credentials/auth, or destructive deletion — require returning BLOCKED for owner approval. Never self-approve a hard stop.",
275
- ];
276
- if (source.worktreeLane) {
277
- sentences.push(
278
- `You are bound to worktree-sync lane '${source.worktreeLane}': work only inside this lane's own worktree, integrate exclusively via worktree_sync land, and never touch main directly.`,
279
- );
280
- }
281
- return sentences.join(" ");
282
- }
283
-
284
- // ---------------------------------------------------------------------------
285
- // Advisory worker usage claim: budget stays advisory across the process boundary.
286
- // ---------------------------------------------------------------------------
287
-
288
- /** Permissively decode a worker-reported usage CLAIM (a cooperative worker may write this to a
289
- * well-known sibling file before printing its completion marker). Read-defensive: missing/malformed
290
- * numeric fields default to 0 rather than throwing — this is untrusted, OPTIONAL, advisory input, never
291
- * an authoritative billing record. Returns undefined only when `raw` isn't even an object, so the
292
- * caller can distinguish "no claim offered" (skip reporting) from "a claim was offered" (report it,
293
- * however partial). */
294
- export function decodeTmuxWorkerUsageClaim(raw: unknown): Usage | undefined {
295
- if (!isPlainRecord(raw)) return undefined;
296
- const num = (value: unknown): number => (typeof value === "number" && Number.isFinite(value) ? value : 0);
297
- const cost = isPlainRecord(raw.cost) ? raw.cost : {};
298
- return {
299
- input: num(raw.input),
300
- output: num(raw.output),
301
- cacheRead: num(raw.cacheRead),
302
- cacheWrite: num(raw.cacheWrite),
303
- totalTokens: num(raw.totalTokens),
304
- cost: {
305
- input: num(cost.input),
306
- output: num(cost.output),
307
- cacheRead: num(cost.cacheRead),
308
- cacheWrite: num(cost.cacheWrite),
309
- total: num(cost.total),
310
- },
311
- };
312
- }