@caupulican/pi-adaptative 0.94.1 → 0.95.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 (324) hide show
  1. package/CHANGELOG.md +39 -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 +173 -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 +247 -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/skills/pi-harness-learning/SKILL.md +13 -7
  16. package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +11 -11
  17. package/dist/core/agent-session.d.ts +11 -41
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +93 -160
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/autonomy/envelope-enforcement.d.ts +6 -1
  22. package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
  23. package/dist/core/autonomy/envelope-enforcement.js +26 -25
  24. package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
  25. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -1
  26. package/dist/core/autonomy/lane-private-paths.js +2 -1
  27. package/dist/core/autonomy/lane-private-paths.js.map +1 -1
  28. package/dist/core/autonomy/lane-tool-surface.d.ts +8 -8
  29. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  30. package/dist/core/autonomy/lane-tool-surface.js +45 -30
  31. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  32. package/dist/core/autonomy/worker-session-private-scope.d.ts +12 -0
  33. package/dist/core/autonomy/worker-session-private-scope.d.ts.map +1 -0
  34. package/dist/core/autonomy/worker-session-private-scope.js +42 -0
  35. package/dist/core/autonomy/worker-session-private-scope.js.map +1 -0
  36. package/dist/core/autonomy/worker-tool-adapter-registry.d.ts +65 -0
  37. package/dist/core/autonomy/worker-tool-adapter-registry.d.ts.map +1 -0
  38. package/dist/core/autonomy/worker-tool-adapter-registry.js +145 -0
  39. package/dist/core/autonomy/worker-tool-adapter-registry.js.map +1 -0
  40. package/dist/core/background-lane-controller.d.ts +1 -1
  41. package/dist/core/background-lane-controller.d.ts.map +1 -1
  42. package/dist/core/background-lane-controller.js +1 -1
  43. package/dist/core/background-lane-controller.js.map +1 -1
  44. package/dist/core/background-tool-task-controller.d.ts +8 -2
  45. package/dist/core/background-tool-task-controller.d.ts.map +1 -1
  46. package/dist/core/background-tool-task-controller.js +10 -2
  47. package/dist/core/background-tool-task-controller.js.map +1 -1
  48. package/dist/core/cost-guard-controller.d.ts +37 -0
  49. package/dist/core/cost-guard-controller.d.ts.map +1 -0
  50. package/dist/core/cost-guard-controller.js +71 -0
  51. package/dist/core/cost-guard-controller.js.map +1 -0
  52. package/dist/core/cost-guard.d.ts +9 -4
  53. package/dist/core/cost-guard.d.ts.map +1 -1
  54. package/dist/core/cost-guard.js +7 -3
  55. package/dist/core/cost-guard.js.map +1 -1
  56. package/dist/core/delegation/worker-attempt-executor.d.ts +1 -1
  57. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -1
  58. package/dist/core/delegation/worker-attempt-executor.js +0 -1
  59. package/dist/core/delegation/worker-attempt-executor.js.map +1 -1
  60. package/dist/core/delegation/worker-authority-resolver.d.ts +16 -3
  61. package/dist/core/delegation/worker-authority-resolver.d.ts.map +1 -1
  62. package/dist/core/delegation/worker-authority-resolver.js +114 -55
  63. package/dist/core/delegation/worker-authority-resolver.js.map +1 -1
  64. package/dist/core/delegation/worker-claim.d.ts +1 -2
  65. package/dist/core/delegation/worker-claim.d.ts.map +1 -1
  66. package/dist/core/delegation/worker-claim.js.map +1 -1
  67. package/dist/core/delegation/worker-delegation-controller.d.ts +19 -6
  68. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  69. package/dist/core/delegation/worker-delegation-controller.js +125 -40
  70. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  71. package/dist/core/delegation/worker-delegation-request.d.ts +3 -3
  72. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
  73. package/dist/core/delegation/worker-delegation-request.js +13 -19
  74. package/dist/core/delegation/worker-delegation-request.js.map +1 -1
  75. package/dist/core/delegation/worker-execution-policy.d.ts +3 -2
  76. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
  77. package/dist/core/delegation/worker-execution-policy.js +54 -39
  78. package/dist/core/delegation/worker-execution-policy.js.map +1 -1
  79. package/dist/core/delegation/worker-fleet-limits.d.ts +3 -3
  80. package/dist/core/delegation/worker-fleet-limits.d.ts.map +1 -1
  81. package/dist/core/delegation/worker-fleet-limits.js +7 -7
  82. package/dist/core/delegation/worker-fleet-limits.js.map +1 -1
  83. package/dist/core/delegation/worker-machine-scope.d.ts +12 -0
  84. package/dist/core/delegation/worker-machine-scope.d.ts.map +1 -0
  85. package/dist/core/delegation/worker-machine-scope.js +38 -0
  86. package/dist/core/delegation/worker-machine-scope.js.map +1 -0
  87. package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -1
  88. package/dist/core/delegation/worker-recovery-coordinator.js +6 -1
  89. package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -1
  90. package/dist/core/delegation/worker-runner.d.ts +5 -7
  91. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  92. package/dist/core/delegation/worker-runner.js +1 -4
  93. package/dist/core/delegation/worker-runner.js.map +1 -1
  94. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +3 -2
  95. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -1
  96. package/dist/core/delegation/worker-write-reservation-coordinator.js +50 -25
  97. package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -1
  98. package/dist/core/durable-custom-message-turn-controller.d.ts +6 -0
  99. package/dist/core/durable-custom-message-turn-controller.d.ts.map +1 -1
  100. package/dist/core/durable-custom-message-turn-controller.js +38 -15
  101. package/dist/core/durable-custom-message-turn-controller.js.map +1 -1
  102. package/dist/core/extension-binding-controller.d.ts +5 -1
  103. package/dist/core/extension-binding-controller.d.ts.map +1 -1
  104. package/dist/core/extension-binding-controller.js +15 -0
  105. package/dist/core/extension-binding-controller.js.map +1 -1
  106. package/dist/core/extensions/factory-runtime.d.ts.map +1 -1
  107. package/dist/core/extensions/factory-runtime.js +5 -0
  108. package/dist/core/extensions/factory-runtime.js.map +1 -1
  109. package/dist/core/extensions/runner.d.ts.map +1 -1
  110. package/dist/core/extensions/runner.js +1 -0
  111. package/dist/core/extensions/runner.js.map +1 -1
  112. package/dist/core/extensions/types.d.ts +8 -4
  113. package/dist/core/extensions/types.d.ts.map +1 -1
  114. package/dist/core/extensions/types.js.map +1 -1
  115. package/dist/core/foreground-terminal-handoff-controller.d.ts +14 -0
  116. package/dist/core/foreground-terminal-handoff-controller.d.ts.map +1 -1
  117. package/dist/core/foreground-terminal-handoff-controller.js +188 -72
  118. package/dist/core/foreground-terminal-handoff-controller.js.map +1 -1
  119. package/dist/core/goals/goal-session-controller.d.ts +2 -0
  120. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  121. package/dist/core/goals/goal-session-controller.js +8 -0
  122. package/dist/core/goals/goal-session-controller.js.map +1 -1
  123. package/dist/core/goals/goal-tool-core.d.ts +5 -4
  124. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  125. package/dist/core/goals/goal-tool-core.js +23 -19
  126. package/dist/core/goals/goal-tool-core.js.map +1 -1
  127. package/dist/core/learning/auto-learn-settings.d.ts +84 -0
  128. package/dist/core/learning/auto-learn-settings.d.ts.map +1 -0
  129. package/dist/core/learning/auto-learn-settings.js +66 -0
  130. package/dist/core/learning/auto-learn-settings.js.map +1 -0
  131. package/dist/core/learning/reflection-engine.d.ts +4 -0
  132. package/dist/core/learning/reflection-engine.d.ts.map +1 -1
  133. package/dist/core/learning/reflection-engine.js +48 -10
  134. package/dist/core/learning/reflection-engine.js.map +1 -1
  135. package/dist/core/local-prefix-warm-controller.d.ts +24 -0
  136. package/dist/core/local-prefix-warm-controller.d.ts.map +1 -0
  137. package/dist/core/local-prefix-warm-controller.js +79 -0
  138. package/dist/core/local-prefix-warm-controller.js.map +1 -0
  139. package/dist/core/memory/providers/file-store.d.ts +2 -0
  140. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  141. package/dist/core/memory/providers/file-store.js +71 -15
  142. package/dist/core/memory/providers/file-store.js.map +1 -1
  143. package/dist/core/memory/worker-memory-tools.d.ts +5 -0
  144. package/dist/core/memory/worker-memory-tools.d.ts.map +1 -0
  145. package/dist/core/memory/worker-memory-tools.js +5 -0
  146. package/dist/core/memory/worker-memory-tools.js.map +1 -0
  147. package/dist/core/model-capability.d.ts +7 -0
  148. package/dist/core/model-capability.d.ts.map +1 -1
  149. package/dist/core/model-capability.js +12 -0
  150. package/dist/core/model-capability.js.map +1 -1
  151. package/dist/core/model-registry.d.ts.map +1 -1
  152. package/dist/core/model-registry.js +2 -10
  153. package/dist/core/model-registry.js.map +1 -1
  154. package/dist/core/model-router-controller.d.ts +3 -2
  155. package/dist/core/model-router-controller.d.ts.map +1 -1
  156. package/dist/core/model-router-controller.js +3 -2
  157. package/dist/core/model-router-controller.js.map +1 -1
  158. package/dist/core/orchestration/contracts.d.ts +16 -12
  159. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  160. package/dist/core/orchestration/contracts.js +2 -2
  161. package/dist/core/orchestration/contracts.js.map +1 -1
  162. package/dist/core/orchestration/lane-tool-manifests.d.ts +2 -2
  163. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -1
  164. package/dist/core/orchestration/lane-tool-manifests.js +6 -1
  165. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -1
  166. package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
  167. package/dist/core/orchestration/profile-registry.js +14 -0
  168. package/dist/core/orchestration/profile-registry.js.map +1 -1
  169. package/dist/core/orchestration/task-profile-writer.d.ts +7 -4
  170. package/dist/core/orchestration/task-profile-writer.d.ts.map +1 -1
  171. package/dist/core/orchestration/task-profile-writer.js +71 -59
  172. package/dist/core/orchestration/task-profile-writer.js.map +1 -1
  173. package/dist/core/orchestration/thinking-level-schema.d.ts +7 -0
  174. package/dist/core/orchestration/thinking-level-schema.d.ts.map +1 -0
  175. package/dist/core/orchestration/thinking-level-schema.js +19 -0
  176. package/dist/core/orchestration/thinking-level-schema.js.map +1 -0
  177. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
  178. package/dist/core/orchestration/worker-execution-contract.js +12 -5
  179. package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
  180. package/dist/core/provider-prompt-contracts.d.ts +1 -4
  181. package/dist/core/provider-prompt-contracts.d.ts.map +1 -1
  182. package/dist/core/provider-prompt-contracts.js +4 -10
  183. package/dist/core/provider-prompt-contracts.js.map +1 -1
  184. package/dist/core/provider-request-context-controller.d.ts +2 -0
  185. package/dist/core/provider-request-context-controller.d.ts.map +1 -1
  186. package/dist/core/provider-request-context-controller.js +10 -3
  187. package/dist/core/provider-request-context-controller.js.map +1 -1
  188. package/dist/core/reflection-controller.d.ts +56 -27
  189. package/dist/core/reflection-controller.d.ts.map +1 -1
  190. package/dist/core/reflection-controller.js +206 -117
  191. package/dist/core/reflection-controller.js.map +1 -1
  192. package/dist/core/runtime-builder.d.ts +1 -0
  193. package/dist/core/runtime-builder.d.ts.map +1 -1
  194. package/dist/core/runtime-builder.js +25 -14
  195. package/dist/core/runtime-builder.js.map +1 -1
  196. package/dist/core/secrets/credential-exposure-guard.d.ts.map +1 -1
  197. package/dist/core/secrets/credential-exposure-guard.js +55 -10
  198. package/dist/core/secrets/credential-exposure-guard.js.map +1 -1
  199. package/dist/core/session-role.d.ts +6 -8
  200. package/dist/core/session-role.d.ts.map +1 -1
  201. package/dist/core/session-role.js +8 -18
  202. package/dist/core/session-role.js.map +1 -1
  203. package/dist/core/settings-manager.d.ts +13 -16
  204. package/dist/core/settings-manager.d.ts.map +1 -1
  205. package/dist/core/settings-manager.js +53 -50
  206. package/dist/core/settings-manager.js.map +1 -1
  207. package/dist/core/skill-vault.d.ts +15 -0
  208. package/dist/core/skill-vault.d.ts.map +1 -1
  209. package/dist/core/skill-vault.js +79 -45
  210. package/dist/core/skill-vault.js.map +1 -1
  211. package/dist/core/skills.d.ts +3 -0
  212. package/dist/core/skills.d.ts.map +1 -1
  213. package/dist/core/skills.js +6 -6
  214. package/dist/core/skills.js.map +1 -1
  215. package/dist/core/system-prompt-builder.d.ts +2 -0
  216. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  217. package/dist/core/system-prompt-builder.js +52 -12
  218. package/dist/core/system-prompt-builder.js.map +1 -1
  219. package/dist/core/system-prompt.js +1 -1
  220. package/dist/core/system-prompt.js.map +1 -1
  221. package/dist/core/tool-capability-policy.d.ts +3 -0
  222. package/dist/core/tool-capability-policy.d.ts.map +1 -1
  223. package/dist/core/tool-capability-policy.js +13 -2
  224. package/dist/core/tool-capability-policy.js.map +1 -1
  225. package/dist/core/toolkit/script-runner.d.ts +2 -1
  226. package/dist/core/toolkit/script-runner.d.ts.map +1 -1
  227. package/dist/core/toolkit/script-runner.js +10 -2
  228. package/dist/core/toolkit/script-runner.js.map +1 -1
  229. package/dist/core/tools/delegate-status.d.ts +1 -1
  230. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  231. package/dist/core/tools/delegate-status.js +1 -1
  232. package/dist/core/tools/delegate-status.js.map +1 -1
  233. package/dist/core/tools/delegate.d.ts +4 -15
  234. package/dist/core/tools/delegate.d.ts.map +1 -1
  235. package/dist/core/tools/delegate.js +111 -73
  236. package/dist/core/tools/delegate.js.map +1 -1
  237. package/dist/core/tools/goal.d.ts +3 -4
  238. package/dist/core/tools/goal.d.ts.map +1 -1
  239. package/dist/core/tools/goal.js +24 -7
  240. package/dist/core/tools/goal.js.map +1 -1
  241. package/dist/core/tools/profile-writer.d.ts +2 -8
  242. package/dist/core/tools/profile-writer.d.ts.map +1 -1
  243. package/dist/core/tools/profile-writer.js +6 -18
  244. package/dist/core/tools/profile-writer.js.map +1 -1
  245. package/dist/core/tools/run-toolkit-script.d.ts +1 -1
  246. package/dist/core/tools/run-toolkit-script.d.ts.map +1 -1
  247. package/dist/core/tools/run-toolkit-script.js +2 -2
  248. package/dist/core/tools/run-toolkit-script.js.map +1 -1
  249. package/dist/core/tools/skill-audit.d.ts +28 -1
  250. package/dist/core/tools/skill-audit.d.ts.map +1 -1
  251. package/dist/core/tools/skill-audit.js +56 -12
  252. package/dist/core/tools/skill-audit.js.map +1 -1
  253. package/dist/core/tools/skill.d.ts +12 -1
  254. package/dist/core/tools/skill.d.ts.map +1 -1
  255. package/dist/core/tools/skill.js +52 -0
  256. package/dist/core/tools/skill.js.map +1 -1
  257. package/dist/core/tools/skillify.d.ts.map +1 -1
  258. package/dist/core/tools/skillify.js +16 -7
  259. package/dist/core/tools/skillify.js.map +1 -1
  260. package/dist/core/tools/task-steps.js +1 -1
  261. package/dist/core/tools/task-steps.js.map +1 -1
  262. package/dist/core/tools/tmux-dispatch.d.ts +4 -16
  263. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -1
  264. package/dist/core/tools/tmux-dispatch.js +5 -20
  265. package/dist/core/tools/tmux-dispatch.js.map +1 -1
  266. package/dist/core/worktree-sync/codes.d.ts +1 -2
  267. package/dist/core/worktree-sync/codes.d.ts.map +1 -1
  268. package/dist/core/worktree-sync/codes.js +1 -2
  269. package/dist/core/worktree-sync/codes.js.map +1 -1
  270. package/dist/core/worktree-sync/lane-gate.d.ts +4 -8
  271. package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -1
  272. package/dist/core/worktree-sync/lane-gate.js +5 -51
  273. package/dist/core/worktree-sync/lane-gate.js.map +1 -1
  274. package/dist/index.d.ts +5 -0
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +7 -0
  277. package/dist/index.js.map +1 -1
  278. package/dist/modes/interactive/auto-learn-controller.d.ts +6 -7
  279. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  280. package/dist/modes/interactive/auto-learn-controller.js +30 -207
  281. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  282. package/dist/modes/interactive/autonomy-commands.js +2 -2
  283. package/dist/modes/interactive/autonomy-commands.js.map +1 -1
  284. package/dist/modes/interactive/components/custom-message.js +17 -0
  285. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  286. package/dist/modes/interactive/components/fitness-role-selector.d.ts.map +1 -1
  287. package/dist/modes/interactive/components/fitness-role-selector.js +2 -2
  288. package/dist/modes/interactive/components/fitness-role-selector.js.map +1 -1
  289. package/dist/modes/interactive/components/footer.js +1 -1
  290. package/dist/modes/interactive/components/footer.js.map +1 -1
  291. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  292. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  293. package/dist/modes/interactive/components/settings-selector.js +150 -73
  294. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  295. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  296. package/dist/modes/interactive/report-commands.js +8 -4
  297. package/dist/modes/interactive/report-commands.js.map +1 -1
  298. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -1
  299. package/dist/modes/interactive/settings-selector-flow.js +10 -0
  300. package/dist/modes/interactive/settings-selector-flow.js.map +1 -1
  301. package/docs/extensions.md +8 -0
  302. package/docs/harness-architecture.md +28 -32
  303. package/docs/index.md +1 -1
  304. package/docs/process-matrix.md +8 -6
  305. package/docs/resources.md +1 -1
  306. package/docs/settings.md +61 -51
  307. package/docs/tmux-agent-manager.md +47 -40
  308. package/docs/usage.md +1 -1
  309. package/docs/worker-profiles.md +8 -6
  310. package/docs/worktree-sync.md +26 -20
  311. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  312. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  313. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  314. package/examples/extensions/sandbox/package-lock.json +2 -2
  315. package/examples/extensions/sandbox/package.json +1 -1
  316. package/examples/extensions/with-deps/package-lock.json +2 -2
  317. package/examples/extensions/with-deps/package.json +1 -1
  318. package/npm-shrinkwrap.json +12 -12
  319. package/package.json +4 -4
  320. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +0 -133
  321. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +0 -1
  322. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +0 -199
  323. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +0 -1
  324. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +0 -312
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "pi-extension-with-deps",
3
- "version": "0.94.1",
3
+ "version": "0.95.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "pi-extension-with-deps",
9
- "version": "0.94.1",
9
+ "version": "0.95.0",
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.94.1",
4
+ "version": "0.95.0",
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.94.1",
3
+ "version": "0.95.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@caupulican/pi-adaptative",
9
- "version": "0.94.1",
9
+ "version": "0.95.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@caupulican/pi-agent-core": "^0.94.1",
13
- "@caupulican/pi-ai": "^0.94.1",
14
- "@caupulican/pi-tui": "^0.94.1",
12
+ "@caupulican/pi-agent-core": "^0.95.0",
13
+ "@caupulican/pi-ai": "^0.95.0",
14
+ "@caupulican/pi-tui": "^0.95.0",
15
15
  "@silvia-odwyer/photon-node": "0.3.4",
16
16
  "chalk": "5.6.2",
17
17
  "cross-spawn": "7.0.6",
@@ -506,11 +506,11 @@
506
506
  }
507
507
  },
508
508
  "node_modules/@caupulican/pi-agent-core": {
509
- "version": "0.94.1",
510
- "resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.94.1.tgz",
509
+ "version": "0.95.0",
510
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-agent-core/-/pi-agent-core-0.95.0.tgz",
511
511
  "license": "MIT",
512
512
  "dependencies": {
513
- "@caupulican/pi-ai": "^0.94.1",
513
+ "@caupulican/pi-ai": "^0.95.0",
514
514
  "ignore": "7.0.5",
515
515
  "typebox": "1.1.38",
516
516
  "yaml": "2.9.0"
@@ -520,8 +520,8 @@
520
520
  }
521
521
  },
522
522
  "node_modules/@caupulican/pi-ai": {
523
- "version": "0.94.1",
524
- "resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.94.1.tgz",
523
+ "version": "0.95.0",
524
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-ai/-/pi-ai-0.95.0.tgz",
525
525
  "license": "MIT",
526
526
  "dependencies": {
527
527
  "@anthropic-ai/sdk": "0.117.1",
@@ -546,8 +546,8 @@
546
546
  }
547
547
  },
548
548
  "node_modules/@caupulican/pi-tui": {
549
- "version": "0.94.1",
550
- "resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.94.1.tgz",
549
+ "version": "0.95.0",
550
+ "resolved": "https://registry.npmjs.org/@caupulican/pi-tui/-/pi-tui-0.95.0.tgz",
551
551
  "license": "MIT",
552
552
  "dependencies": {
553
553
  "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.94.1",
3
+ "version": "0.95.0",
4
4
  "description": "Adaptive fork of Pi coding agent for self-evolving agent harness experiments",
5
5
  "type": "module",
6
6
  "piConfig": {
@@ -89,9 +89,9 @@
89
89
  "postinstall": "node scripts/postinstall-python-runtime.mjs"
90
90
  },
91
91
  "dependencies": {
92
- "@caupulican/pi-agent-core": "^0.94.1",
93
- "@caupulican/pi-ai": "^0.94.1",
94
- "@caupulican/pi-tui": "^0.94.1",
92
+ "@caupulican/pi-agent-core": "^0.95.0",
93
+ "@caupulican/pi-ai": "^0.95.0",
94
+ "@caupulican/pi-tui": "^0.95.0",
95
95
  "@silvia-odwyer/photon-node": "0.3.4",
96
96
  "chalk": "5.6.2",
97
97
  "cross-spawn": "7.0.6",
@@ -1,133 +0,0 @@
1
- import type { Usage } from "@caupulican/pi-ai";
2
- /**
3
- * The STANDING GRANT for approval-gated tmux dispatch (owner authorizes once via `grant_dispatch`;
4
- * the extension then dispatches unattended WITHIN the grant's bounds). Pure data + pure decode/decision
5
- * logic only — no session/tmux/filesystem access, so every function here is directly unit-testable.
6
- * The extension (index.ts) owns reading/writing session custom entries and calls into this module for
7
- * decoding and authorization decisions.
8
- *
9
- * HONEST TRUST BOUNDARY: this grant bounds WHO may be launched, HOW OFTEN, and WITH WHAT launch-time
10
- * envelope (pushed into the child's own CLI flags) — it never claims to gate the child's in-process
11
- * tool loop, which is a separate OS process outside this runtime's `beforeToolCall` machinery.
12
- */
13
- export type Provider = "pi" | "codex" | "agy" | "claude" | "opencode" | "custom";
14
- export declare const GRANT_CUSTOM_TYPE = "tmux-dispatch-grant";
15
- export declare const GRANT_USAGE_CUSTOM_TYPE = "tmux-dispatch-grant-usage";
16
- export interface TmuxDispatchGrantEnvelope {
17
- allowedTools?: string[];
18
- resourceProfile?: string;
19
- writePaths?: string[];
20
- }
21
- export interface TmuxDispatchGrantBudget {
22
- maxLaunches: number;
23
- maxWallClockMs?: number;
24
- maxUsdAdvisory?: number;
25
- }
26
- export interface TmuxDispatchGrant {
27
- grantId: string;
28
- createdAt: string;
29
- agent: Provider;
30
- scope: {
31
- goalId?: string;
32
- };
33
- envelope: TmuxDispatchGrantEnvelope;
34
- budget: TmuxDispatchGrantBudget;
35
- expiresAt?: string;
36
- }
37
- /** Appended by `revoke_grant`. Shares `GRANT_CUSTOM_TYPE` so the SAME latest-on-branch read that
38
- * resolves an active grant also sees a revocation and stops treating any older grant beneath it as
39
- * active — a tombstone is a hard stop, never skipped over to resurrect an earlier grant. */
40
- export interface TmuxDispatchGrantTombstone {
41
- tombstone: true;
42
- grantId: string;
43
- revokedAt: string;
44
- }
45
- export interface TmuxDispatchGrantUsage {
46
- grantId: string;
47
- jobId: string;
48
- at: string;
49
- }
50
- export declare function isTmuxDispatchGrantTombstone(value: unknown): value is TmuxDispatchGrantTombstone;
51
- export declare function isTmuxDispatchGrant(value: unknown): value is TmuxDispatchGrant;
52
- export declare function isTmuxDispatchGrantUsage(value: unknown): value is TmuxDispatchGrantUsage;
53
- export declare function makeGrantId(): string;
54
- export interface GrantCoverageRequest {
55
- agent: Provider;
56
- goalId?: string;
57
- nowIso?: string;
58
- }
59
- /** Whether `grant` authorizes a launch for `request`: same agent, goal-scope match (an UNSCOPED grant
60
- * covers any goal including none; a goal-SCOPED grant covers ONLY that exact goalId), and the grant is
61
- * not past `expiresAt`. Budget (maxLaunches) is checked separately via {@link isGrantBudgetExhausted}
62
- * because counting usages requires the caller's session-entry access. */
63
- export declare function grantCovers(grant: TmuxDispatchGrant, request: GrantCoverageRequest): boolean;
64
- /** Count spend entries for `grantId` among already-decoded custom-entry payloads (the caller walks the
65
- * session branch and passes the raw `data` values — this stays pure/session-agnostic). */
66
- export declare function countGrantUsages(grantId: string, usageEntries: readonly unknown[]): number;
67
- export declare function isGrantBudgetExhausted(grant: TmuxDispatchGrant, usedCount: number): boolean;
68
- export declare function buildGrantUsageEntry(grantId: string, jobId: string, nowIso?: string): TmuxDispatchGrantUsage;
69
- export declare function buildTombstone(grantId: string, nowIso?: string): TmuxDispatchGrantTombstone;
70
- export interface GrantDispatchParams {
71
- agent: Provider;
72
- goalId?: string;
73
- allowedTools?: string[];
74
- resourceProfile?: string;
75
- writePaths?: string[];
76
- maxLaunches: number;
77
- expiresInMinutes?: number;
78
- maxUsdAdvisory?: number;
79
- }
80
- /** Build a new grant record from `grant_dispatch` params. Pure — the caller (index.ts) owns the
81
- * approval gate (ui.confirm / opt-in flag) and the `pi.appendEntry` persistence; this only shapes the
82
- * data, so it stays independently testable and never itself decides whether creation is authorized. */
83
- export declare function buildGrant(params: GrantDispatchParams, nowIso?: string): TmuxDispatchGrant;
84
- export declare function describeGrant(grant: TmuxDispatchGrant): string;
85
- export declare const DEFAULT_READ_BIASED_TOOLS: readonly string[];
86
- export interface LaunchProfileSource {
87
- /** Human-readable identity for the scoped system prompt (e.g. "grant <id>" or a one-shot label). */
88
- identity: string;
89
- allowedTools?: string[];
90
- resourceProfile?: string;
91
- writePaths?: string[];
92
- /**
93
- * Worktree-sync lane key this launch is bound to (per-agent -- see `applyLaunchProfile`'s caller,
94
- * which builds a per-agent `LaunchProfileSource` only when that agent carries `worktreeLane`).
95
- * When present, `buildLaunchProfileFlags` appends `--worktree-lane <key>` (the same CLI flag
96
- * `src/cli/args.ts` already exposes, sugar over the `PI_WORKTREE_LANE` env contract) and
97
- * `buildScopedSystemPrompt` appends one lane-doctrine sentence.
98
- */
99
- worktreeLane?: string;
100
- /**
101
- * Process-matrix parent identity for this launch (see `core/process-matrix/runtime.ts`): the
102
- * dispatching process's own pid/sessionId. When present, `buildLaunchProfileFlags` appends
103
- * `--parent-pid`/`--parent-session` (sugar over `PI_PARENT_PID`/`PI_PARENT_SESSION`) so the
104
- * child self-registers as a worker of this session and winds down gracefully if it disappears.
105
- */
106
- parentPid?: number;
107
- parentSession?: string;
108
- /** Stable goal/task identity used to fence process-matrix recovery. */
109
- taskRef?: string;
110
- }
111
- /** A grant-covered launch derives its profile from the grant's envelope. */
112
- export declare function launchProfileSourceFromGrant(grant: TmuxDispatchGrant): LaunchProfileSource;
113
- /** A one-shot interactively-approved launch (no standing grant) still gets the conservative default
114
- * profile — approving a single launch is not the same as defining an unrestricted envelope. */
115
- export declare const ONE_SHOT_LAUNCH_PROFILE_SOURCE: LaunchProfileSource;
116
- export interface LaunchProfileFlag {
117
- flag: string;
118
- value?: string;
119
- }
120
- /** Build the CLI flags to append to a child `pi` invocation so the grant's envelope lives in the
121
- * child's OWN launch config (verified flag names: --tools, --resource-profile, --no-extensions,
122
- * --no-skills, --append-system-prompt). Never includes --no-approve: the child must keep gating its
123
- * own hard stops. */
124
- export declare function buildLaunchProfileFlags(source: LaunchProfileSource): LaunchProfileFlag[];
125
- export declare function buildScopedSystemPrompt(source: LaunchProfileSource): string;
126
- /** Permissively decode a worker-reported usage CLAIM (a cooperative worker may write this to a
127
- * well-known sibling file before printing its completion marker). Read-defensive: missing/malformed
128
- * numeric fields default to 0 rather than throwing — this is untrusted, OPTIONAL, advisory input, never
129
- * an authoritative billing record. Returns undefined only when `raw` isn't even an object, so the
130
- * caller can distinguish "no claim offered" (skip reporting) from "a claim was offered" (report it,
131
- * however partial). */
132
- export declare function decodeTmuxWorkerUsageClaim(raw: unknown): Usage | undefined;
133
- //# sourceMappingURL=dispatch-grant.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dispatch-grant.d.ts","sourceRoot":"","sources":["../../../../src/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEjF,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,MAAM,WAAW,yBAAyB;IACzC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,QAAQ,EAAE,yBAAyB,CAAC;IACpC,MAAM,EAAE,uBAAuB,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;4FAE4F;AAC5F,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACX;AAYD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,0BAA0B,CAGhG;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAM9E;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,sBAAsB,CAGxF;AAED,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;yEAGyE;AACzE,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAS5F;AAED;0FAC0F;AAC1F,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAI1F;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3F;AAED,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,SAA2B,GAC/B,sBAAsB,CAExB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAA2B,GAAG,0BAA0B,CAE7G;AAED,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;uGAEuG;AACvG,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,SAA2B,GAAG,iBAAiB,CAuB5G;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAsB9D;AAMD,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAAmC,CAAC;AAE3F,MAAM,WAAW,mBAAmB;IACnC,oGAAoG;IACpG,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,iBAAiB,GAAG,mBAAmB,CAO1F;AAED;+FAC+F;AAC/F,eAAO,MAAM,8BAA8B,EAAE,mBAE5C,CAAC;AAEF,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;qBAGqB;AACrB,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,iBAAiB,EAAE,CAYxF;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAa3E;AAMD;;;;;uBAKuB;AACvB,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAkB1E"}
@@ -1,199 +0,0 @@
1
- import * as crypto from "node:crypto";
2
- export const GRANT_CUSTOM_TYPE = "tmux-dispatch-grant";
3
- export const GRANT_USAGE_CUSTOM_TYPE = "tmux-dispatch-grant-usage";
4
- const PROVIDERS = ["pi", "codex", "agy", "claude", "opencode", "custom"];
5
- function isProvider(value) {
6
- return typeof value === "string" && PROVIDERS.includes(value);
7
- }
8
- function isPlainRecord(value) {
9
- return typeof value === "object" && value !== null && !Array.isArray(value);
10
- }
11
- export function isTmuxDispatchGrantTombstone(value) {
12
- if (!isPlainRecord(value))
13
- return false;
14
- return value.tombstone === true && typeof value.grantId === "string" && typeof value.revokedAt === "string";
15
- }
16
- export function isTmuxDispatchGrant(value) {
17
- if (!isPlainRecord(value) || value.tombstone === true)
18
- return false;
19
- if (typeof value.grantId !== "string" || typeof value.createdAt !== "string" || !isProvider(value.agent))
20
- return false;
21
- if (!isPlainRecord(value.scope) || !isPlainRecord(value.envelope) || !isPlainRecord(value.budget))
22
- return false;
23
- return typeof value.budget.maxLaunches === "number" && Number.isFinite(value.budget.maxLaunches);
24
- }
25
- export function isTmuxDispatchGrantUsage(value) {
26
- if (!isPlainRecord(value))
27
- return false;
28
- return typeof value.grantId === "string" && typeof value.jobId === "string" && typeof value.at === "string";
29
- }
30
- export function makeGrantId() {
31
- return `grant-${Date.now().toString(36)}-${crypto.randomBytes(4).toString("hex")}`;
32
- }
33
- /** Whether `grant` authorizes a launch for `request`: same agent, goal-scope match (an UNSCOPED grant
34
- * covers any goal including none; a goal-SCOPED grant covers ONLY that exact goalId), and the grant is
35
- * not past `expiresAt`. Budget (maxLaunches) is checked separately via {@link isGrantBudgetExhausted}
36
- * because counting usages requires the caller's session-entry access. */
37
- export function grantCovers(grant, request) {
38
- if (grant.agent !== request.agent)
39
- return false;
40
- if (grant.scope.goalId && grant.scope.goalId !== request.goalId)
41
- return false;
42
- if (grant.expiresAt) {
43
- const now = Date.parse(request.nowIso ?? new Date().toISOString());
44
- const expiry = Date.parse(grant.expiresAt);
45
- if (Number.isFinite(expiry) && Number.isFinite(now) && now >= expiry)
46
- return false;
47
- }
48
- return true;
49
- }
50
- /** Count spend entries for `grantId` among already-decoded custom-entry payloads (the caller walks the
51
- * session branch and passes the raw `data` values — this stays pure/session-agnostic). */
52
- export function countGrantUsages(grantId, usageEntries) {
53
- let count = 0;
54
- for (const entry of usageEntries)
55
- if (isTmuxDispatchGrantUsage(entry) && entry.grantId === grantId)
56
- count++;
57
- return count;
58
- }
59
- export function isGrantBudgetExhausted(grant, usedCount) {
60
- return usedCount >= grant.budget.maxLaunches;
61
- }
62
- export function buildGrantUsageEntry(grantId, jobId, nowIso = new Date().toISOString()) {
63
- return { grantId, jobId, at: nowIso };
64
- }
65
- export function buildTombstone(grantId, nowIso = new Date().toISOString()) {
66
- return { tombstone: true, grantId, revokedAt: nowIso };
67
- }
68
- /** Build a new grant record from `grant_dispatch` params. Pure — the caller (index.ts) owns the
69
- * approval gate (ui.confirm / opt-in flag) and the `pi.appendEntry` persistence; this only shapes the
70
- * data, so it stays independently testable and never itself decides whether creation is authorized. */
71
- export function buildGrant(params, nowIso = new Date().toISOString()) {
72
- if (!Number.isFinite(params.maxLaunches) || params.maxLaunches < 1)
73
- throw new Error("grant_dispatch requires maxLaunches >= 1");
74
- const expiresAt = params.expiresInMinutes !== undefined
75
- ? new Date(Date.parse(nowIso) + Math.max(1, params.expiresInMinutes) * 60_000).toISOString()
76
- : undefined;
77
- return {
78
- grantId: makeGrantId(),
79
- createdAt: nowIso,
80
- agent: params.agent,
81
- scope: { goalId: params.goalId },
82
- envelope: {
83
- allowedTools: params.allowedTools,
84
- resourceProfile: params.resourceProfile,
85
- writePaths: params.writePaths,
86
- },
87
- budget: {
88
- maxLaunches: Math.trunc(params.maxLaunches),
89
- maxUsdAdvisory: params.maxUsdAdvisory,
90
- },
91
- expiresAt,
92
- };
93
- }
94
- export function describeGrant(grant) {
95
- return [
96
- `Grant id: ${grant.grantId}`,
97
- `Agent: ${grant.agent}`,
98
- grant.scope.goalId ? `Goal scope: ${grant.scope.goalId}` : "Goal scope: none (covers any goal)",
99
- `Max launches: ${grant.budget.maxLaunches}`,
100
- grant.expiresAt ? `Expires: ${grant.expiresAt}` : "Expires: never (until revoke_grant)",
101
- grant.envelope.allowedTools?.length
102
- ? `Allowed tools: ${grant.envelope.allowedTools.join(", ")}`
103
- : `Allowed tools: read-biased safe default (${DEFAULT_READ_BIASED_TOOLS.join(", ")})`,
104
- grant.envelope.resourceProfile
105
- ? `Resource profile: ${grant.envelope.resourceProfile}`
106
- : "Resource profile: none (child launches with --no-extensions --no-skills)",
107
- grant.envelope.writePaths?.length
108
- ? `Write paths: ${grant.envelope.writePaths.join(", ")}`
109
- : "Write paths: none declared",
110
- grant.budget.maxUsdAdvisory !== undefined
111
- ? `Advisory USD cap: ${grant.budget.maxUsdAdvisory} (not enforced across the process boundary — advisory only)`
112
- : undefined,
113
- ]
114
- .filter((line) => Boolean(line))
115
- .join("\n");
116
- }
117
- // ---------------------------------------------------------------------------
118
- // Launch-profile flags: the REAL lever — pushed into the child `pi` CLI's own config.
119
- // ---------------------------------------------------------------------------
120
- export const DEFAULT_READ_BIASED_TOOLS = ["read", "grep", "find", "ls"];
121
- /** A grant-covered launch derives its profile from the grant's envelope. */
122
- export function launchProfileSourceFromGrant(grant) {
123
- return {
124
- identity: `grant ${grant.grantId}`,
125
- allowedTools: grant.envelope.allowedTools,
126
- resourceProfile: grant.envelope.resourceProfile,
127
- writePaths: grant.envelope.writePaths,
128
- };
129
- }
130
- /** A one-shot interactively-approved launch (no standing grant) still gets the conservative default
131
- * profile — approving a single launch is not the same as defining an unrestricted envelope. */
132
- export const ONE_SHOT_LAUNCH_PROFILE_SOURCE = {
133
- identity: "a one-shot owner-approved tmux dispatch (no standing grant)",
134
- };
135
- /** Build the CLI flags to append to a child `pi` invocation so the grant's envelope lives in the
136
- * child's OWN launch config (verified flag names: --tools, --resource-profile, --no-extensions,
137
- * --no-skills, --append-system-prompt). Never includes --no-approve: the child must keep gating its
138
- * own hard stops. */
139
- export function buildLaunchProfileFlags(source) {
140
- const tools = source.allowedTools?.length ? source.allowedTools : DEFAULT_READ_BIASED_TOOLS;
141
- const flags = [{ flag: "--tools", value: tools.join(",") }];
142
- if (source.resourceProfile)
143
- flags.push({ flag: "--resource-profile", value: source.resourceProfile });
144
- else
145
- flags.push({ flag: "--no-extensions" }, { flag: "--no-skills" });
146
- if (source.worktreeLane)
147
- flags.push({ flag: "--worktree-lane", value: source.worktreeLane });
148
- if (source.parentPid !== undefined)
149
- flags.push({ flag: "--parent-pid", value: String(source.parentPid) });
150
- if (source.parentSession)
151
- flags.push({ flag: "--parent-session", value: source.parentSession });
152
- if (source.taskRef)
153
- flags.push({ flag: "--task-ref", value: source.taskRef });
154
- flags.push({ flag: "--append-system-prompt", value: buildScopedSystemPrompt(source) });
155
- flags.push({ flag: "--session-mode", value: "worker" });
156
- return flags;
157
- }
158
- export function buildScopedSystemPrompt(source) {
159
- const paths = source.writePaths?.length ? source.writePaths.join(", ") : "no additional paths granted";
160
- const sentences = [
161
- `You are a tmux worker dispatched under ${source.identity}.`,
162
- `Stay within these write paths: ${paths}.`,
163
- "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.",
164
- ];
165
- if (source.worktreeLane) {
166
- sentences.push(`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.`);
167
- }
168
- return sentences.join(" ");
169
- }
170
- // ---------------------------------------------------------------------------
171
- // Advisory worker usage claim: budget stays advisory across the process boundary.
172
- // ---------------------------------------------------------------------------
173
- /** Permissively decode a worker-reported usage CLAIM (a cooperative worker may write this to a
174
- * well-known sibling file before printing its completion marker). Read-defensive: missing/malformed
175
- * numeric fields default to 0 rather than throwing — this is untrusted, OPTIONAL, advisory input, never
176
- * an authoritative billing record. Returns undefined only when `raw` isn't even an object, so the
177
- * caller can distinguish "no claim offered" (skip reporting) from "a claim was offered" (report it,
178
- * however partial). */
179
- export function decodeTmuxWorkerUsageClaim(raw) {
180
- if (!isPlainRecord(raw))
181
- return undefined;
182
- const num = (value) => (typeof value === "number" && Number.isFinite(value) ? value : 0);
183
- const cost = isPlainRecord(raw.cost) ? raw.cost : {};
184
- return {
185
- input: num(raw.input),
186
- output: num(raw.output),
187
- cacheRead: num(raw.cacheRead),
188
- cacheWrite: num(raw.cacheWrite),
189
- totalTokens: num(raw.totalTokens),
190
- cost: {
191
- input: num(cost.input),
192
- output: num(cost.output),
193
- cacheRead: num(cost.cacheRead),
194
- cacheWrite: num(cost.cacheWrite),
195
- total: num(cost.total),
196
- },
197
- };
198
- }
199
- //# sourceMappingURL=dispatch-grant.js.map
@@ -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"]}