@caupulican/pi-adaptative 0.81.38 → 0.81.40

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 (881) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/README.md +2 -0
  3. package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +18 -1
  4. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +133 -0
  5. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -0
  6. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +198 -0
  7. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -0
  8. package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +311 -0
  9. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +31 -2
  10. package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
  11. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +823 -79
  12. package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
  13. package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +1043 -86
  14. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/__init__.py +43 -0
  15. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/fs.py +270 -0
  16. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/search.py +252 -0
  17. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/strings.py +399 -0
  18. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +575 -0
  19. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +52 -0
  20. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +49 -0
  21. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +734 -0
  22. package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +238 -0
  23. package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +132 -0
  24. package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +116 -0
  25. package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +287 -0
  26. package/dist/bundled-resources/runtimes/pi-shell-engine/proc.py +137 -0
  27. package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +100 -0
  28. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +579 -0
  29. package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +19 -9
  30. package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +22 -5
  31. package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +7 -7
  32. package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +28 -7
  33. package/dist/cli/args.d.ts +5 -0
  34. package/dist/cli/args.d.ts.map +1 -1
  35. package/dist/cli/args.js +24 -0
  36. package/dist/cli/args.js.map +1 -1
  37. package/dist/core/agent-directory-layout.d.ts +15 -0
  38. package/dist/core/agent-directory-layout.d.ts.map +1 -0
  39. package/dist/core/agent-directory-layout.js +72 -0
  40. package/dist/core/agent-directory-layout.js.map +1 -0
  41. package/dist/core/agent-paths.d.ts +66 -0
  42. package/dist/core/agent-paths.d.ts.map +1 -0
  43. package/dist/core/agent-paths.js +170 -0
  44. package/dist/core/agent-paths.js.map +1 -0
  45. package/dist/core/agent-session-runtime.d.ts +52 -8
  46. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  47. package/dist/core/agent-session-runtime.js +397 -79
  48. package/dist/core/agent-session-runtime.js.map +1 -1
  49. package/dist/core/agent-session-services.d.ts +1 -0
  50. package/dist/core/agent-session-services.d.ts.map +1 -1
  51. package/dist/core/agent-session-services.js +4 -3
  52. package/dist/core/agent-session-services.js.map +1 -1
  53. package/dist/core/agent-session.d.ts +255 -103
  54. package/dist/core/agent-session.d.ts.map +1 -1
  55. package/dist/core/agent-session.js +754 -1173
  56. package/dist/core/agent-session.js.map +1 -1
  57. package/dist/core/autonomy/approval-gate.d.ts +3 -2
  58. package/dist/core/autonomy/approval-gate.d.ts.map +1 -1
  59. package/dist/core/autonomy/approval-gate.js +6 -28
  60. package/dist/core/autonomy/approval-gate.js.map +1 -1
  61. package/dist/core/autonomy/bounded-completion.d.ts +1 -1
  62. package/dist/core/autonomy/bounded-completion.d.ts.map +1 -1
  63. package/dist/core/autonomy/bounded-completion.js +1 -1
  64. package/dist/core/autonomy/bounded-completion.js.map +1 -1
  65. package/dist/core/autonomy/contracts.d.ts +26 -9
  66. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  67. package/dist/core/autonomy/contracts.js.map +1 -1
  68. package/dist/core/autonomy/foreground-envelope.d.ts +8 -2
  69. package/dist/core/autonomy/foreground-envelope.d.ts.map +1 -1
  70. package/dist/core/autonomy/foreground-envelope.js +8 -25
  71. package/dist/core/autonomy/foreground-envelope.js.map +1 -1
  72. package/dist/core/autonomy/gates.d.ts.map +1 -1
  73. package/dist/core/autonomy/gates.js +8 -10
  74. package/dist/core/autonomy/gates.js.map +1 -1
  75. package/dist/core/autonomy/lane-private-paths.d.ts +2 -0
  76. package/dist/core/autonomy/lane-private-paths.d.ts.map +1 -0
  77. package/dist/core/autonomy/lane-private-paths.js +16 -0
  78. package/dist/core/autonomy/lane-private-paths.js.map +1 -0
  79. package/dist/core/autonomy/lane-tool-surface.d.ts +10 -0
  80. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  81. package/dist/core/autonomy/lane-tool-surface.js +46 -8
  82. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  83. package/dist/core/autonomy/lane-tracker.d.ts +24 -1
  84. package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
  85. package/dist/core/autonomy/lane-tracker.js +43 -1
  86. package/dist/core/autonomy/lane-tracker.js.map +1 -1
  87. package/dist/core/autonomy/risk-assessment.d.ts +1 -2
  88. package/dist/core/autonomy/risk-assessment.d.ts.map +1 -1
  89. package/dist/core/autonomy/risk-assessment.js +1 -123
  90. package/dist/core/autonomy/risk-assessment.js.map +1 -1
  91. package/dist/core/autonomy/session-lane-record.d.ts +4 -4
  92. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  93. package/dist/core/autonomy/session-lane-record.js +16 -29
  94. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  95. package/dist/core/autonomy/telemetry-events.d.ts +1 -1
  96. package/dist/core/autonomy/telemetry-events.d.ts.map +1 -1
  97. package/dist/core/autonomy/telemetry-events.js +1 -1
  98. package/dist/core/autonomy/telemetry-events.js.map +1 -1
  99. package/dist/core/autonomy-telemetry.d.ts +7 -7
  100. package/dist/core/autonomy-telemetry.d.ts.map +1 -1
  101. package/dist/core/autonomy-telemetry.js +9 -9
  102. package/dist/core/autonomy-telemetry.js.map +1 -1
  103. package/dist/core/background-lane-controller.d.ts +90 -156
  104. package/dist/core/background-lane-controller.d.ts.map +1 -1
  105. package/dist/core/background-lane-controller.js +192 -968
  106. package/dist/core/background-lane-controller.js.map +1 -1
  107. package/dist/core/bash-execution-controller.d.ts +4 -0
  108. package/dist/core/bash-execution-controller.d.ts.map +1 -1
  109. package/dist/core/bash-execution-controller.js +7 -1
  110. package/dist/core/bash-execution-controller.js.map +1 -1
  111. package/dist/core/capability-contract.d.ts +4 -0
  112. package/dist/core/capability-contract.d.ts.map +1 -0
  113. package/dist/core/capability-contract.js +28 -0
  114. package/dist/core/capability-contract.js.map +1 -0
  115. package/dist/core/compaction-controller.d.ts +90 -0
  116. package/dist/core/compaction-controller.d.ts.map +1 -0
  117. package/dist/core/compaction-controller.js +452 -0
  118. package/dist/core/compaction-controller.js.map +1 -0
  119. package/dist/core/compaction-support.d.ts +24 -13
  120. package/dist/core/compaction-support.d.ts.map +1 -1
  121. package/dist/core/compaction-support.js +43 -7
  122. package/dist/core/compaction-support.js.map +1 -1
  123. package/dist/core/context/context-artifacts.d.ts +6 -2
  124. package/dist/core/context/context-artifacts.d.ts.map +1 -1
  125. package/dist/core/context/context-artifacts.js +34 -2
  126. package/dist/core/context/context-artifacts.js.map +1 -1
  127. package/dist/core/context/context-audit.d.ts +33 -1
  128. package/dist/core/context/context-audit.d.ts.map +1 -1
  129. package/dist/core/context/context-audit.js +31 -5
  130. package/dist/core/context/context-audit.js.map +1 -1
  131. package/dist/core/context/context-store-retention.d.ts +8 -2
  132. package/dist/core/context/context-store-retention.d.ts.map +1 -1
  133. package/dist/core/context/context-store-retention.js +158 -35
  134. package/dist/core/context/context-store-retention.js.map +1 -1
  135. package/dist/core/context/okf-memory.d.ts.map +1 -1
  136. package/dist/core/context/okf-memory.js +9 -11
  137. package/dist/core/context/okf-memory.js.map +1 -1
  138. package/dist/core/context/sqlite-runtime-index.d.ts.map +1 -1
  139. package/dist/core/context/sqlite-runtime-index.js +6 -8
  140. package/dist/core/context/sqlite-runtime-index.js.map +1 -1
  141. package/dist/core/context-gc.d.ts +3 -0
  142. package/dist/core/context-gc.d.ts.map +1 -1
  143. package/dist/core/context-gc.js +26 -6
  144. package/dist/core/context-gc.js.map +1 -1
  145. package/dist/core/context-pipeline.d.ts +26 -4
  146. package/dist/core/context-pipeline.d.ts.map +1 -1
  147. package/dist/core/context-pipeline.js +146 -18
  148. package/dist/core/context-pipeline.js.map +1 -1
  149. package/dist/core/cost-guard.d.ts +19 -3
  150. package/dist/core/cost-guard.d.ts.map +1 -1
  151. package/dist/core/cost-guard.js +18 -3
  152. package/dist/core/cost-guard.js.map +1 -1
  153. package/dist/core/default-tool-surface.d.ts.map +1 -1
  154. package/dist/core/default-tool-surface.js +1 -0
  155. package/dist/core/default-tool-surface.js.map +1 -1
  156. package/dist/core/delegation/managed-lane-controller.d.ts +34 -0
  157. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -0
  158. package/dist/core/delegation/managed-lane-controller.js +217 -0
  159. package/dist/core/delegation/managed-lane-controller.js.map +1 -0
  160. package/dist/core/delegation/session-worker-claim.d.ts +44 -0
  161. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -0
  162. package/dist/core/delegation/session-worker-claim.js +98 -0
  163. package/dist/core/delegation/session-worker-claim.js.map +1 -0
  164. package/dist/core/delegation/worker-actions.d.ts +7 -5
  165. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  166. package/dist/core/delegation/worker-actions.js +20 -4
  167. package/dist/core/delegation/worker-actions.js.map +1 -1
  168. package/dist/core/delegation/worker-claim.d.ts +56 -0
  169. package/dist/core/delegation/worker-claim.d.ts.map +1 -0
  170. package/dist/core/delegation/worker-claim.js +239 -0
  171. package/dist/core/delegation/worker-claim.js.map +1 -0
  172. package/dist/core/delegation/worker-delegation-controller.d.ts +110 -0
  173. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -0
  174. package/dist/core/delegation/worker-delegation-controller.js +861 -0
  175. package/dist/core/delegation/worker-delegation-controller.js.map +1 -0
  176. package/dist/core/delegation/worker-delegation-request.d.ts +11 -0
  177. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -0
  178. package/dist/core/delegation/worker-delegation-request.js +2 -0
  179. package/dist/core/delegation/worker-delegation-request.js.map +1 -0
  180. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +40 -0
  181. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -0
  182. package/dist/core/delegation/worker-dispatch-scheduler.js +93 -0
  183. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -0
  184. package/dist/core/delegation/worker-execution-policy.d.ts +62 -0
  185. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -0
  186. package/dist/core/delegation/worker-execution-policy.js +160 -0
  187. package/dist/core/delegation/worker-execution-policy.js.map +1 -0
  188. package/dist/core/delegation/worker-lane-projection.d.ts +14 -0
  189. package/dist/core/delegation/worker-lane-projection.d.ts.map +1 -0
  190. package/dist/core/delegation/worker-lane-projection.js +100 -0
  191. package/dist/core/delegation/worker-lane-projection.js.map +1 -0
  192. package/dist/core/delegation/worker-lifecycle.d.ts +97 -0
  193. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -0
  194. package/dist/core/delegation/worker-lifecycle.js +339 -0
  195. package/dist/core/delegation/worker-lifecycle.js.map +1 -0
  196. package/dist/core/delegation/worker-notification-coordinator.d.ts +36 -0
  197. package/dist/core/delegation/worker-notification-coordinator.d.ts.map +1 -0
  198. package/dist/core/delegation/worker-notification-coordinator.js +90 -0
  199. package/dist/core/delegation/worker-notification-coordinator.js.map +1 -0
  200. package/dist/core/delegation/worker-profile-resolver.d.ts +55 -0
  201. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -0
  202. package/dist/core/delegation/worker-profile-resolver.js +113 -0
  203. package/dist/core/delegation/worker-profile-resolver.js.map +1 -0
  204. package/dist/core/delegation/worker-runner.d.ts +25 -14
  205. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  206. package/dist/core/delegation/worker-runner.js +122 -53
  207. package/dist/core/delegation/worker-runner.js.map +1 -1
  208. package/dist/core/delegation/worker-task-label.d.ts +3 -0
  209. package/dist/core/delegation/worker-task-label.d.ts.map +1 -0
  210. package/dist/core/delegation/worker-task-label.js +11 -0
  211. package/dist/core/delegation/worker-task-label.js.map +1 -0
  212. package/dist/core/doctor.d.ts +8 -0
  213. package/dist/core/doctor.d.ts.map +1 -1
  214. package/dist/core/doctor.js +32 -1
  215. package/dist/core/doctor.js.map +1 -1
  216. package/dist/core/extensions/index.d.ts +1 -1
  217. package/dist/core/extensions/index.d.ts.map +1 -1
  218. package/dist/core/extensions/index.js.map +1 -1
  219. package/dist/core/extensions/loader.d.ts +5 -1
  220. package/dist/core/extensions/loader.d.ts.map +1 -1
  221. package/dist/core/extensions/loader.js +68 -13
  222. package/dist/core/extensions/loader.js.map +1 -1
  223. package/dist/core/extensions/runner.d.ts.map +1 -1
  224. package/dist/core/extensions/runner.js +7 -0
  225. package/dist/core/extensions/runner.js.map +1 -1
  226. package/dist/core/extensions/storage.d.ts +8 -0
  227. package/dist/core/extensions/storage.d.ts.map +1 -0
  228. package/dist/core/extensions/storage.js +28 -0
  229. package/dist/core/extensions/storage.js.map +1 -0
  230. package/dist/core/extensions/types.d.ts +101 -1
  231. package/dist/core/extensions/types.d.ts.map +1 -1
  232. package/dist/core/extensions/types.js.map +1 -1
  233. package/dist/core/failure-corpus.d.ts +1 -15
  234. package/dist/core/failure-corpus.d.ts.map +1 -1
  235. package/dist/core/failure-corpus.js +9 -37
  236. package/dist/core/failure-corpus.js.map +1 -1
  237. package/dist/core/foreground-recovery-controller.d.ts +52 -0
  238. package/dist/core/foreground-recovery-controller.d.ts.map +1 -0
  239. package/dist/core/foreground-recovery-controller.js +111 -0
  240. package/dist/core/foreground-recovery-controller.js.map +1 -0
  241. package/dist/core/gateways/channel-provider.d.ts +3 -0
  242. package/dist/core/gateways/channel-provider.d.ts.map +1 -1
  243. package/dist/core/gateways/channel-provider.js +31 -6
  244. package/dist/core/gateways/channel-provider.js.map +1 -1
  245. package/dist/core/goal-loop-controller.d.ts +17 -1
  246. package/dist/core/goal-loop-controller.d.ts.map +1 -1
  247. package/dist/core/goal-loop-controller.js +79 -11
  248. package/dist/core/goal-loop-controller.js.map +1 -1
  249. package/dist/core/goals/goal-acceptance.d.ts +11 -0
  250. package/dist/core/goals/goal-acceptance.d.ts.map +1 -0
  251. package/dist/core/goals/goal-acceptance.js +25 -0
  252. package/dist/core/goals/goal-acceptance.js.map +1 -0
  253. package/dist/core/goals/goal-auto-continue-controller.d.ts +27 -0
  254. package/dist/core/goals/goal-auto-continue-controller.d.ts.map +1 -0
  255. package/dist/core/goals/goal-auto-continue-controller.js +93 -0
  256. package/dist/core/goals/goal-auto-continue-controller.js.map +1 -0
  257. package/dist/core/goals/goal-continuation-controller.d.ts +48 -2
  258. package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
  259. package/dist/core/goals/goal-continuation-controller.js +87 -0
  260. package/dist/core/goals/goal-continuation-controller.js.map +1 -1
  261. package/dist/core/goals/goal-continuation-defaults.d.ts +39 -0
  262. package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
  263. package/dist/core/goals/goal-continuation-defaults.js +42 -0
  264. package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
  265. package/dist/core/goals/goal-continuation-prompt.d.ts +5 -1
  266. package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
  267. package/dist/core/goals/goal-continuation-prompt.js +56 -15
  268. package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
  269. package/dist/core/goals/goal-lifecycle.d.ts +20 -0
  270. package/dist/core/goals/goal-lifecycle.d.ts.map +1 -0
  271. package/dist/core/goals/goal-lifecycle.js +17 -0
  272. package/dist/core/goals/goal-lifecycle.js.map +1 -0
  273. package/dist/core/goals/goal-runtime-snapshot.d.ts +105 -4
  274. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  275. package/dist/core/goals/goal-runtime-snapshot.js +91 -6
  276. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  277. package/dist/core/goals/goal-state.d.ts +90 -1
  278. package/dist/core/goals/goal-state.d.ts.map +1 -1
  279. package/dist/core/goals/goal-state.js +78 -15
  280. package/dist/core/goals/goal-state.js.map +1 -1
  281. package/dist/core/goals/goal-tool-core.d.ts +58 -2
  282. package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
  283. package/dist/core/goals/goal-tool-core.js +82 -6
  284. package/dist/core/goals/goal-tool-core.js.map +1 -1
  285. package/dist/core/goals/session-goal-state.d.ts +13 -6
  286. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  287. package/dist/core/goals/session-goal-state.js +20 -28
  288. package/dist/core/goals/session-goal-state.js.map +1 -1
  289. package/dist/core/human-input.d.ts +100 -0
  290. package/dist/core/human-input.d.ts.map +1 -0
  291. package/dist/core/human-input.js +362 -0
  292. package/dist/core/human-input.js.map +1 -0
  293. package/dist/core/index.d.ts +9 -1
  294. package/dist/core/index.d.ts.map +1 -1
  295. package/dist/core/index.js +9 -1
  296. package/dist/core/index.js.map +1 -1
  297. package/dist/core/{telemetry.d.ts → install-telemetry.d.ts} +1 -1
  298. package/dist/core/install-telemetry.d.ts.map +1 -0
  299. package/dist/core/{telemetry.js → install-telemetry.js} +1 -1
  300. package/dist/core/install-telemetry.js.map +1 -0
  301. package/dist/core/keybindings.d.ts +27 -1
  302. package/dist/core/keybindings.d.ts.map +1 -1
  303. package/dist/core/keybindings.js +34 -8
  304. package/dist/core/keybindings.js.map +1 -1
  305. package/dist/core/learning/learning-audit.d.ts +2 -4
  306. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  307. package/dist/core/learning/learning-audit.js +9 -29
  308. package/dist/core/learning/learning-audit.js.map +1 -1
  309. package/dist/core/learning/learning-gate.d.ts.map +1 -1
  310. package/dist/core/learning/learning-gate.js +1 -6
  311. package/dist/core/learning/learning-gate.js.map +1 -1
  312. package/dist/core/learning/observation-store.d.ts +12 -3
  313. package/dist/core/learning/observation-store.d.ts.map +1 -1
  314. package/dist/core/learning/observation-store.js +30 -15
  315. package/dist/core/learning/observation-store.js.map +1 -1
  316. package/dist/core/learning/session-learning-decision.d.ts +2 -4
  317. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  318. package/dist/core/learning/session-learning-decision.js +9 -29
  319. package/dist/core/learning/session-learning-decision.js.map +1 -1
  320. package/dist/core/learning/skill-curator.d.ts +5 -1
  321. package/dist/core/learning/skill-curator.d.ts.map +1 -1
  322. package/dist/core/learning/skill-curator.js +21 -19
  323. package/dist/core/learning/skill-curator.js.map +1 -1
  324. package/dist/core/local-runtime-controller.d.ts +65 -3
  325. package/dist/core/local-runtime-controller.d.ts.map +1 -1
  326. package/dist/core/local-runtime-controller.js +186 -26
  327. package/dist/core/local-runtime-controller.js.map +1 -1
  328. package/dist/core/memory/providers/file-store.d.ts +1 -1
  329. package/dist/core/memory/providers/file-store.d.ts.map +1 -1
  330. package/dist/core/memory/providers/file-store.js +6 -6
  331. package/dist/core/memory/providers/file-store.js.map +1 -1
  332. package/dist/core/memory-controller.d.ts.map +1 -1
  333. package/dist/core/memory-controller.js +4 -4
  334. package/dist/core/memory-controller.js.map +1 -1
  335. package/dist/core/model-capability.d.ts +34 -0
  336. package/dist/core/model-capability.d.ts.map +1 -1
  337. package/dist/core/model-capability.js +43 -1
  338. package/dist/core/model-capability.js.map +1 -1
  339. package/dist/core/model-resolver.d.ts +1 -1
  340. package/dist/core/model-resolver.d.ts.map +1 -1
  341. package/dist/core/model-resolver.js +6 -9
  342. package/dist/core/model-resolver.js.map +1 -1
  343. package/dist/core/model-router/intent-classifier.d.ts +1 -4
  344. package/dist/core/model-router/intent-classifier.d.ts.map +1 -1
  345. package/dist/core/model-router/intent-classifier.js +1 -156
  346. package/dist/core/model-router/intent-classifier.js.map +1 -1
  347. package/dist/core/model-router/tool-escalation.d.ts +15 -0
  348. package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
  349. package/dist/core/model-router/tool-escalation.js +23 -1
  350. package/dist/core/model-router/tool-escalation.js.map +1 -1
  351. package/dist/core/model-router-controller.d.ts +34 -7
  352. package/dist/core/model-router-controller.d.ts.map +1 -1
  353. package/dist/core/model-router-controller.js +95 -16
  354. package/dist/core/model-router-controller.js.map +1 -1
  355. package/dist/core/model-selection-controller.d.ts +4 -4
  356. package/dist/core/model-selection-controller.d.ts.map +1 -1
  357. package/dist/core/model-selection-controller.js.map +1 -1
  358. package/dist/core/model-tool-protocol.d.ts +23 -0
  359. package/dist/core/model-tool-protocol.d.ts.map +1 -0
  360. package/dist/core/model-tool-protocol.js +43 -0
  361. package/dist/core/model-tool-protocol.js.map +1 -0
  362. package/dist/core/models/adaptation-store.d.ts +10 -5
  363. package/dist/core/models/adaptation-store.d.ts.map +1 -1
  364. package/dist/core/models/adaptation-store.js +129 -81
  365. package/dist/core/models/adaptation-store.js.map +1 -1
  366. package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
  367. package/dist/core/models/default-model-suggestions.js +17 -0
  368. package/dist/core/models/default-model-suggestions.js.map +1 -1
  369. package/dist/core/models/fitness-store.d.ts +4 -11
  370. package/dist/core/models/fitness-store.d.ts.map +1 -1
  371. package/dist/core/models/fitness-store.js +87 -51
  372. package/dist/core/models/fitness-store.js.map +1 -1
  373. package/dist/core/models/host-state-store.d.ts +34 -0
  374. package/dist/core/models/host-state-store.d.ts.map +1 -0
  375. package/dist/core/models/host-state-store.js +86 -0
  376. package/dist/core/models/host-state-store.js.map +1 -0
  377. package/dist/core/models/llamacpp-runtime.d.ts +180 -0
  378. package/dist/core/models/llamacpp-runtime.d.ts.map +1 -0
  379. package/dist/core/models/llamacpp-runtime.js +475 -0
  380. package/dist/core/models/llamacpp-runtime.js.map +1 -0
  381. package/dist/core/models/local-registration.d.ts +40 -0
  382. package/dist/core/models/local-registration.d.ts.map +1 -1
  383. package/dist/core/models/local-registration.js +94 -5
  384. package/dist/core/models/local-registration.js.map +1 -1
  385. package/dist/core/models/local-runtime.d.ts.map +1 -1
  386. package/dist/core/models/local-runtime.js +6 -5
  387. package/dist/core/models/local-runtime.js.map +1 -1
  388. package/dist/core/models/model-ref.d.ts +7 -0
  389. package/dist/core/models/model-ref.d.ts.map +1 -1
  390. package/dist/core/models/model-ref.js +26 -0
  391. package/dist/core/models/model-ref.js.map +1 -1
  392. package/dist/core/models/needle-runtime.d.ts +257 -0
  393. package/dist/core/models/needle-runtime.d.ts.map +1 -0
  394. package/dist/core/models/needle-runtime.js +519 -0
  395. package/dist/core/models/needle-runtime.js.map +1 -0
  396. package/dist/core/models/prism-llamacpp-lifecycle.d.ts +89 -0
  397. package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -0
  398. package/dist/core/models/prism-llamacpp-lifecycle.js +121 -0
  399. package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -0
  400. package/dist/core/orchestration/agent-resume.d.ts +24 -0
  401. package/dist/core/orchestration/agent-resume.d.ts.map +1 -0
  402. package/dist/core/orchestration/agent-resume.js +90 -0
  403. package/dist/core/orchestration/agent-resume.js.map +1 -0
  404. package/dist/core/orchestration/capability-gateway.d.ts +61 -0
  405. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -0
  406. package/dist/core/orchestration/capability-gateway.js +152 -0
  407. package/dist/core/orchestration/capability-gateway.js.map +1 -0
  408. package/dist/core/orchestration/contracts.d.ts +343 -0
  409. package/dist/core/orchestration/contracts.d.ts.map +1 -0
  410. package/dist/core/orchestration/contracts.js +135 -0
  411. package/dist/core/orchestration/contracts.js.map +1 -0
  412. package/dist/core/orchestration/delegation-ledger.d.ts +56 -0
  413. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -0
  414. package/dist/core/orchestration/delegation-ledger.js +197 -0
  415. package/dist/core/orchestration/delegation-ledger.js.map +1 -0
  416. package/dist/core/orchestration/event-store.d.ts +83 -0
  417. package/dist/core/orchestration/event-store.d.ts.map +1 -0
  418. package/dist/core/orchestration/event-store.js +560 -0
  419. package/dist/core/orchestration/event-store.js.map +1 -0
  420. package/dist/core/orchestration/lane-tool-manifests.d.ts +9 -0
  421. package/dist/core/orchestration/lane-tool-manifests.d.ts.map +1 -0
  422. package/dist/core/orchestration/lane-tool-manifests.js +37 -0
  423. package/dist/core/orchestration/lane-tool-manifests.js.map +1 -0
  424. package/dist/core/orchestration/model-binding.d.ts +15 -0
  425. package/dist/core/orchestration/model-binding.d.ts.map +1 -0
  426. package/dist/core/orchestration/model-binding.js +29 -0
  427. package/dist/core/orchestration/model-binding.js.map +1 -0
  428. package/dist/core/orchestration/policy-compiler.d.ts +49 -0
  429. package/dist/core/orchestration/policy-compiler.d.ts.map +1 -0
  430. package/dist/core/orchestration/policy-compiler.js +191 -0
  431. package/dist/core/orchestration/policy-compiler.js.map +1 -0
  432. package/dist/core/orchestration/policy-gate.d.ts +18 -0
  433. package/dist/core/orchestration/policy-gate.d.ts.map +1 -0
  434. package/dist/core/orchestration/policy-gate.js +24 -0
  435. package/dist/core/orchestration/policy-gate.js.map +1 -0
  436. package/dist/core/orchestration/profile-registry.d.ts +51 -0
  437. package/dist/core/orchestration/profile-registry.d.ts.map +1 -0
  438. package/dist/core/orchestration/profile-registry.js +393 -0
  439. package/dist/core/orchestration/profile-registry.js.map +1 -0
  440. package/dist/core/orchestration/profile-store.d.ts +31 -0
  441. package/dist/core/orchestration/profile-store.d.ts.map +1 -0
  442. package/dist/core/orchestration/profile-store.js +136 -0
  443. package/dist/core/orchestration/profile-store.js.map +1 -0
  444. package/dist/core/orchestration/risk-budget.d.ts +9 -0
  445. package/dist/core/orchestration/risk-budget.d.ts.map +1 -0
  446. package/dist/core/orchestration/risk-budget.js +48 -0
  447. package/dist/core/orchestration/risk-budget.js.map +1 -0
  448. package/dist/core/orchestration/task-runtime.d.ts +168 -0
  449. package/dist/core/orchestration/task-runtime.d.ts.map +1 -0
  450. package/dist/core/orchestration/task-runtime.js +1600 -0
  451. package/dist/core/orchestration/task-runtime.js.map +1 -0
  452. package/dist/core/orchestration/work-state-projection.d.ts +32 -0
  453. package/dist/core/orchestration/work-state-projection.d.ts.map +1 -0
  454. package/dist/core/orchestration/work-state-projection.js +116 -0
  455. package/dist/core/orchestration/work-state-projection.js.map +1 -0
  456. package/dist/core/orchestration/worker-execution-contract.d.ts +21 -0
  457. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -0
  458. package/dist/core/orchestration/worker-execution-contract.js +179 -0
  459. package/dist/core/orchestration/worker-execution-contract.js.map +1 -0
  460. package/dist/core/orchestration/worker-result-adapter.d.ts +21 -0
  461. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -0
  462. package/dist/core/orchestration/worker-result-adapter.js +109 -0
  463. package/dist/core/orchestration/worker-result-adapter.js.map +1 -0
  464. package/dist/core/package-manager.d.ts.map +1 -1
  465. package/dist/core/package-manager.js +11 -10
  466. package/dist/core/package-manager.js.map +1 -1
  467. package/dist/core/process-identity.d.ts +11 -0
  468. package/dist/core/process-identity.d.ts.map +1 -0
  469. package/dist/core/process-identity.js +26 -0
  470. package/dist/core/process-identity.js.map +1 -0
  471. package/dist/core/process-matrix/codes.d.ts +83 -0
  472. package/dist/core/process-matrix/codes.d.ts.map +1 -0
  473. package/dist/core/process-matrix/codes.js +15 -0
  474. package/dist/core/process-matrix/codes.js.map +1 -0
  475. package/dist/core/process-matrix/resume-launcher.d.ts +26 -0
  476. package/dist/core/process-matrix/resume-launcher.d.ts.map +1 -0
  477. package/dist/core/process-matrix/resume-launcher.js +62 -0
  478. package/dist/core/process-matrix/resume-launcher.js.map +1 -0
  479. package/dist/core/process-matrix/runtime.d.ts +78 -0
  480. package/dist/core/process-matrix/runtime.d.ts.map +1 -0
  481. package/dist/core/process-matrix/runtime.js +633 -0
  482. package/dist/core/process-matrix/runtime.js.map +1 -0
  483. package/dist/core/process-matrix/store.d.ts +25 -0
  484. package/dist/core/process-matrix/store.d.ts.map +1 -0
  485. package/dist/core/process-matrix/store.js +189 -0
  486. package/dist/core/process-matrix/store.js.map +1 -0
  487. package/dist/core/process-matrix/supervisor.d.ts +75 -0
  488. package/dist/core/process-matrix/supervisor.d.ts.map +1 -0
  489. package/dist/core/process-matrix/supervisor.js +161 -0
  490. package/dist/core/process-matrix/supervisor.js.map +1 -0
  491. package/dist/core/profile-registry.d.ts +7 -0
  492. package/dist/core/profile-registry.d.ts.map +1 -1
  493. package/dist/core/profile-registry.js +25 -7
  494. package/dist/core/profile-registry.js.map +1 -1
  495. package/dist/core/python-runtime.d.ts.map +1 -1
  496. package/dist/core/python-runtime.js +3 -3
  497. package/dist/core/python-runtime.js.map +1 -1
  498. package/dist/core/reflection-controller.d.ts +33 -9
  499. package/dist/core/reflection-controller.d.ts.map +1 -1
  500. package/dist/core/reflection-controller.js +217 -127
  501. package/dist/core/reflection-controller.js.map +1 -1
  502. package/dist/core/reload-blockers.d.ts +36 -0
  503. package/dist/core/reload-blockers.d.ts.map +1 -1
  504. package/dist/core/reload-blockers.js +50 -8
  505. package/dist/core/reload-blockers.js.map +1 -1
  506. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  507. package/dist/core/research/evidence-bundle.js +1 -6
  508. package/dist/core/research/evidence-bundle.js.map +1 -1
  509. package/dist/core/research/lane-model-resolver.d.ts +33 -0
  510. package/dist/core/research/lane-model-resolver.d.ts.map +1 -0
  511. package/dist/core/research/lane-model-resolver.js +65 -0
  512. package/dist/core/research/lane-model-resolver.js.map +1 -0
  513. package/dist/core/research/model-fitness-controller.d.ts +38 -0
  514. package/dist/core/research/model-fitness-controller.d.ts.map +1 -0
  515. package/dist/core/research/model-fitness-controller.js +106 -0
  516. package/dist/core/research/model-fitness-controller.js.map +1 -0
  517. package/dist/core/research/model-fitness.d.ts +1 -1
  518. package/dist/core/research/model-fitness.d.ts.map +1 -1
  519. package/dist/core/research/model-fitness.js +4 -4
  520. package/dist/core/research/model-fitness.js.map +1 -1
  521. package/dist/core/research/research-gate.d.ts.map +1 -1
  522. package/dist/core/research/research-gate.js +7 -7
  523. package/dist/core/research/research-gate.js.map +1 -1
  524. package/dist/core/research/research-lane-controller.d.ts +62 -0
  525. package/dist/core/research/research-lane-controller.d.ts.map +1 -0
  526. package/dist/core/research/research-lane-controller.js +292 -0
  527. package/dist/core/research/research-lane-controller.js.map +1 -0
  528. package/dist/core/research/session-evidence-bundle.d.ts +2 -4
  529. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  530. package/dist/core/research/session-evidence-bundle.js +10 -46
  531. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  532. package/dist/core/resource-loader.d.ts.map +1 -1
  533. package/dist/core/resource-loader.js +15 -9
  534. package/dist/core/resource-loader.js.map +1 -1
  535. package/dist/core/risk-classifier.d.ts +6 -0
  536. package/dist/core/risk-classifier.d.ts.map +1 -0
  537. package/dist/core/risk-classifier.js +225 -0
  538. package/dist/core/risk-classifier.js.map +1 -0
  539. package/dist/core/runtime-builder.d.ts +76 -17
  540. package/dist/core/runtime-builder.d.ts.map +1 -1
  541. package/dist/core/runtime-builder.js +367 -124
  542. package/dist/core/runtime-builder.js.map +1 -1
  543. package/dist/core/scout-controller.d.ts +6 -0
  544. package/dist/core/scout-controller.d.ts.map +1 -1
  545. package/dist/core/scout-controller.js +66 -52
  546. package/dist/core/scout-controller.js.map +1 -1
  547. package/dist/core/sdk.d.ts +6 -3
  548. package/dist/core/sdk.d.ts.map +1 -1
  549. package/dist/core/sdk.js +64 -27
  550. package/dist/core/sdk.js.map +1 -1
  551. package/dist/core/session-analytics.d.ts.map +1 -1
  552. package/dist/core/session-analytics.js +28 -1
  553. package/dist/core/session-analytics.js.map +1 -1
  554. package/dist/core/session-image-store.d.ts +33 -0
  555. package/dist/core/session-image-store.d.ts.map +1 -0
  556. package/dist/core/session-image-store.js +283 -0
  557. package/dist/core/session-image-store.js.map +1 -0
  558. package/dist/core/session-role.d.ts +33 -0
  559. package/dist/core/session-role.d.ts.map +1 -0
  560. package/dist/core/session-role.js +58 -0
  561. package/dist/core/session-role.js.map +1 -0
  562. package/dist/core/session-snapshot.d.ts +34 -0
  563. package/dist/core/session-snapshot.d.ts.map +1 -0
  564. package/dist/core/session-snapshot.js +68 -0
  565. package/dist/core/session-snapshot.js.map +1 -0
  566. package/dist/core/session-supervision-runtime.d.ts +31 -0
  567. package/dist/core/session-supervision-runtime.d.ts.map +1 -0
  568. package/dist/core/session-supervision-runtime.js +97 -0
  569. package/dist/core/session-supervision-runtime.js.map +1 -0
  570. package/dist/core/settings-manager.d.ts +51 -7
  571. package/dist/core/settings-manager.d.ts.map +1 -1
  572. package/dist/core/settings-manager.js +168 -82
  573. package/dist/core/settings-manager.js.map +1 -1
  574. package/dist/core/system-prompt-builder.d.ts +12 -0
  575. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  576. package/dist/core/system-prompt-builder.js +6 -0
  577. package/dist/core/system-prompt-builder.js.map +1 -1
  578. package/dist/core/system-prompt.d.ts +14 -1
  579. package/dist/core/system-prompt.d.ts.map +1 -1
  580. package/dist/core/system-prompt.js +20 -3
  581. package/dist/core/system-prompt.js.map +1 -1
  582. package/dist/core/tasks/session-task-state.d.ts +13 -6
  583. package/dist/core/tasks/session-task-state.d.ts.map +1 -1
  584. package/dist/core/tasks/session-task-state.js +20 -22
  585. package/dist/core/tasks/session-task-state.js.map +1 -1
  586. package/dist/core/tasks/task-contract-monitor.d.ts +45 -0
  587. package/dist/core/tasks/task-contract-monitor.d.ts.map +1 -0
  588. package/dist/core/tasks/task-contract-monitor.js +56 -0
  589. package/dist/core/tasks/task-contract-monitor.js.map +1 -0
  590. package/dist/core/tasks/task-projection.d.ts +20 -0
  591. package/dist/core/tasks/task-projection.d.ts.map +1 -0
  592. package/dist/core/tasks/task-projection.js +47 -0
  593. package/dist/core/tasks/task-projection.js.map +1 -0
  594. package/dist/core/tasks/task-state.d.ts +12 -0
  595. package/dist/core/tasks/task-state.d.ts.map +1 -1
  596. package/dist/core/tasks/task-state.js +56 -12
  597. package/dist/core/tasks/task-state.js.map +1 -1
  598. package/dist/core/tool-capability-policy.d.ts +13 -0
  599. package/dist/core/tool-capability-policy.d.ts.map +1 -0
  600. package/dist/core/tool-capability-policy.js +85 -0
  601. package/dist/core/tool-capability-policy.js.map +1 -0
  602. package/dist/core/tool-gate-controller.d.ts.map +1 -1
  603. package/dist/core/tool-gate-controller.js +5 -0
  604. package/dist/core/tool-gate-controller.js.map +1 -1
  605. package/dist/core/tool-protocol-controller.d.ts +91 -0
  606. package/dist/core/tool-protocol-controller.d.ts.map +1 -0
  607. package/dist/core/tool-protocol-controller.js +512 -0
  608. package/dist/core/tool-protocol-controller.js.map +1 -0
  609. package/dist/core/tool-recovery-log-records.d.ts +6 -0
  610. package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
  611. package/dist/core/tool-recovery-log-records.js +13 -31
  612. package/dist/core/tool-recovery-log-records.js.map +1 -1
  613. package/dist/core/tool-selection/promotion.d.ts +54 -0
  614. package/dist/core/tool-selection/promotion.d.ts.map +1 -0
  615. package/dist/core/tool-selection/promotion.js +81 -0
  616. package/dist/core/tool-selection/promotion.js.map +1 -0
  617. package/dist/core/tool-selection/tool-performance-store.d.ts +39 -6
  618. package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
  619. package/dist/core/tool-selection/tool-performance-store.js +153 -110
  620. package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
  621. package/dist/core/tool-selection/tool-selection-controller.d.ts +45 -0
  622. package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
  623. package/dist/core/tool-selection/tool-selection-controller.js +96 -0
  624. package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
  625. package/dist/core/tools/ask-question.d.ts +124 -0
  626. package/dist/core/tools/ask-question.d.ts.map +1 -0
  627. package/dist/core/tools/ask-question.js +693 -0
  628. package/dist/core/tools/ask-question.js.map +1 -0
  629. package/dist/core/tools/bash.d.ts +18 -0
  630. package/dist/core/tools/bash.d.ts.map +1 -1
  631. package/dist/core/tools/bash.js +95 -16
  632. package/dist/core/tools/bash.js.map +1 -1
  633. package/dist/core/tools/delegate-status.d.ts +44 -2
  634. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  635. package/dist/core/tools/delegate-status.js +214 -19
  636. package/dist/core/tools/delegate-status.js.map +1 -1
  637. package/dist/core/tools/delegate.d.ts +15 -13
  638. package/dist/core/tools/delegate.d.ts.map +1 -1
  639. package/dist/core/tools/delegate.js +124 -22
  640. package/dist/core/tools/delegate.js.map +1 -1
  641. package/dist/core/tools/extensionify.d.ts.map +1 -1
  642. package/dist/core/tools/extensionify.js +1 -0
  643. package/dist/core/tools/extensionify.js.map +1 -1
  644. package/dist/core/tools/goal.d.ts +94 -3
  645. package/dist/core/tools/goal.d.ts.map +1 -1
  646. package/dist/core/tools/goal.js +165 -15
  647. package/dist/core/tools/goal.js.map +1 -1
  648. package/dist/core/tools/model-fitness.d.ts +7 -0
  649. package/dist/core/tools/model-fitness.d.ts.map +1 -1
  650. package/dist/core/tools/model-fitness.js +4 -4
  651. package/dist/core/tools/model-fitness.js.map +1 -1
  652. package/dist/core/tools/orchestration-panel.d.ts +43 -0
  653. package/dist/core/tools/orchestration-panel.d.ts.map +1 -0
  654. package/dist/core/tools/orchestration-panel.js +168 -0
  655. package/dist/core/tools/orchestration-panel.js.map +1 -0
  656. package/dist/core/tools/run-process.d.ts +26 -0
  657. package/dist/core/tools/run-process.d.ts.map +1 -0
  658. package/dist/core/tools/run-process.js +138 -0
  659. package/dist/core/tools/run-process.js.map +1 -0
  660. package/dist/core/tools/shell-contract-router.d.ts +6 -1
  661. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  662. package/dist/core/tools/shell-contract-router.js +23 -2
  663. package/dist/core/tools/shell-contract-router.js.map +1 -1
  664. package/dist/core/tools/shell-session.d.ts +89 -0
  665. package/dist/core/tools/shell-session.d.ts.map +1 -0
  666. package/dist/core/tools/shell-session.js +432 -0
  667. package/dist/core/tools/shell-session.js.map +1 -0
  668. package/dist/core/tools/task-steps.d.ts +6 -0
  669. package/dist/core/tools/task-steps.d.ts.map +1 -1
  670. package/dist/core/tools/task-steps.js +165 -8
  671. package/dist/core/tools/task-steps.js.map +1 -1
  672. package/dist/core/tools/tmux-dispatch.d.ts +84 -0
  673. package/dist/core/tools/tmux-dispatch.d.ts.map +1 -0
  674. package/dist/core/tools/tmux-dispatch.js +91 -0
  675. package/dist/core/tools/tmux-dispatch.js.map +1 -0
  676. package/dist/core/tools/windows-shell-engine.d.ts +42 -0
  677. package/dist/core/tools/windows-shell-engine.d.ts.map +1 -0
  678. package/dist/core/tools/windows-shell-engine.js +151 -0
  679. package/dist/core/tools/windows-shell-engine.js.map +1 -0
  680. package/dist/core/tools/windows-shell-state.d.ts +40 -0
  681. package/dist/core/tools/windows-shell-state.d.ts.map +1 -0
  682. package/dist/core/tools/windows-shell-state.js +59 -0
  683. package/dist/core/tools/windows-shell-state.js.map +1 -0
  684. package/dist/core/tools/worktree-sync.d.ts +24 -0
  685. package/dist/core/tools/worktree-sync.d.ts.map +1 -0
  686. package/dist/core/tools/worktree-sync.js +338 -0
  687. package/dist/core/tools/worktree-sync.js.map +1 -0
  688. package/dist/core/trust-manager.d.ts +4 -1
  689. package/dist/core/trust-manager.d.ts.map +1 -1
  690. package/dist/core/trust-manager.js +20 -2
  691. package/dist/core/trust-manager.js.map +1 -1
  692. package/dist/core/util/atomic-file.d.ts +55 -0
  693. package/dist/core/util/atomic-file.d.ts.map +1 -0
  694. package/dist/core/util/atomic-file.js +255 -0
  695. package/dist/core/util/atomic-file.js.map +1 -0
  696. package/dist/core/util/bounded-jsonl.d.ts +10 -0
  697. package/dist/core/util/bounded-jsonl.d.ts.map +1 -0
  698. package/dist/core/util/bounded-jsonl.js +75 -0
  699. package/dist/core/util/bounded-jsonl.js.map +1 -0
  700. package/dist/core/util/minimatch-cache.d.ts +33 -0
  701. package/dist/core/util/minimatch-cache.d.ts.map +1 -0
  702. package/dist/core/util/minimatch-cache.js +0 -0
  703. package/dist/core/util/minimatch-cache.js.map +1 -0
  704. package/dist/core/util/value-guards.d.ts +5 -0
  705. package/dist/core/util/value-guards.d.ts.map +1 -0
  706. package/dist/core/util/value-guards.js +12 -0
  707. package/dist/core/util/value-guards.js.map +1 -0
  708. package/dist/core/worktree-sync/codes.d.ts +227 -0
  709. package/dist/core/worktree-sync/codes.d.ts.map +1 -0
  710. package/dist/core/worktree-sync/codes.js +14 -0
  711. package/dist/core/worktree-sync/codes.js.map +1 -0
  712. package/dist/core/worktree-sync/git-engine.d.ts +156 -0
  713. package/dist/core/worktree-sync/git-engine.d.ts.map +1 -0
  714. package/dist/core/worktree-sync/git-engine.js +1191 -0
  715. package/dist/core/worktree-sync/git-engine.js.map +1 -0
  716. package/dist/core/worktree-sync/lane-gate.d.ts +75 -0
  717. package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -0
  718. package/dist/core/worktree-sync/lane-gate.js +360 -0
  719. package/dist/core/worktree-sync/lane-gate.js.map +1 -0
  720. package/dist/core/worktree-sync/runtime.d.ts +47 -0
  721. package/dist/core/worktree-sync/runtime.d.ts.map +1 -0
  722. package/dist/core/worktree-sync/runtime.js +96 -0
  723. package/dist/core/worktree-sync/runtime.js.map +1 -0
  724. package/dist/core/worktree-sync/store.d.ts +69 -0
  725. package/dist/core/worktree-sync/store.d.ts.map +1 -0
  726. package/dist/core/worktree-sync/store.js +252 -0
  727. package/dist/core/worktree-sync/store.js.map +1 -0
  728. package/dist/core/worktree-sync/watcher.d.ts +29 -0
  729. package/dist/core/worktree-sync/watcher.d.ts.map +1 -0
  730. package/dist/core/worktree-sync/watcher.js +93 -0
  731. package/dist/core/worktree-sync/watcher.js.map +1 -0
  732. package/dist/index.d.ts +13 -3
  733. package/dist/index.d.ts.map +1 -1
  734. package/dist/index.js +12 -2
  735. package/dist/index.js.map +1 -1
  736. package/dist/main.d.ts.map +1 -1
  737. package/dist/main.js +179 -1
  738. package/dist/main.js.map +1 -1
  739. package/dist/migrations.d.ts +7 -0
  740. package/dist/migrations.d.ts.map +1 -1
  741. package/dist/migrations.js +197 -1
  742. package/dist/migrations.js.map +1 -1
  743. package/dist/modes/interactive/auto-learn-controller.d.ts +16 -1
  744. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
  745. package/dist/modes/interactive/auto-learn-controller.js +50 -8
  746. package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
  747. package/dist/modes/interactive/clipboard-input.d.ts +7 -1
  748. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -1
  749. package/dist/modes/interactive/clipboard-input.js +44 -6
  750. package/dist/modes/interactive/clipboard-input.js.map +1 -1
  751. package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
  752. package/dist/modes/interactive/components/profile-resource-editor.js +23 -1
  753. package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
  754. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  755. package/dist/modes/interactive/components/settings-selector.js +2 -2
  756. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  757. package/dist/modes/interactive/config-backup.d.ts.map +1 -1
  758. package/dist/modes/interactive/config-backup.js +5 -4
  759. package/dist/modes/interactive/config-backup.js.map +1 -1
  760. package/dist/modes/interactive/extension-ui-host.d.ts +14 -0
  761. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -1
  762. package/dist/modes/interactive/extension-ui-host.js +76 -15
  763. package/dist/modes/interactive/extension-ui-host.js.map +1 -1
  764. package/dist/modes/interactive/interactive-mode.d.ts +4 -0
  765. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  766. package/dist/modes/interactive/interactive-mode.js +67 -1
  767. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  768. package/dist/modes/interactive/key-handlers.d.ts.map +1 -1
  769. package/dist/modes/interactive/key-handlers.js +1 -1
  770. package/dist/modes/interactive/key-handlers.js.map +1 -1
  771. package/dist/modes/interactive/local-model-commands.d.ts +43 -0
  772. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
  773. package/dist/modes/interactive/local-model-commands.js +290 -3
  774. package/dist/modes/interactive/local-model-commands.js.map +1 -1
  775. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -1
  776. package/dist/modes/interactive/profile-menu-controller.js +7 -7
  777. package/dist/modes/interactive/profile-menu-controller.js.map +1 -1
  778. package/dist/modes/interactive/report-commands.d.ts.map +1 -1
  779. package/dist/modes/interactive/report-commands.js +21 -0
  780. package/dist/modes/interactive/report-commands.js.map +1 -1
  781. package/dist/modes/interactive/session-flow-commands.d.ts +17 -2
  782. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
  783. package/dist/modes/interactive/session-flow-commands.js +74 -21
  784. package/dist/modes/interactive/session-flow-commands.js.map +1 -1
  785. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -1
  786. package/dist/modes/interactive/session-io-commands.js +16 -6
  787. package/dist/modes/interactive/session-io-commands.js.map +1 -1
  788. package/dist/modes/interactive/session-replacement-errors.d.ts +7 -0
  789. package/dist/modes/interactive/session-replacement-errors.d.ts.map +1 -0
  790. package/dist/modes/interactive/session-replacement-errors.js +15 -0
  791. package/dist/modes/interactive/session-replacement-errors.js.map +1 -0
  792. package/dist/modes/interactive/startup-checks.d.ts.map +1 -1
  793. package/dist/modes/interactive/startup-checks.js +1 -1
  794. package/dist/modes/interactive/startup-checks.js.map +1 -1
  795. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  796. package/dist/modes/rpc/rpc-mode.js +82 -23
  797. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  798. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  799. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  800. package/dist/modes/rpc/rpc-types.js +138 -1
  801. package/dist/modes/rpc/rpc-types.js.map +1 -1
  802. package/dist/utils/clipboard-image.d.ts.map +1 -1
  803. package/dist/utils/clipboard-image.js +2 -13
  804. package/dist/utils/clipboard-image.js.map +1 -1
  805. package/dist/utils/clipboard-native.d.ts +1 -0
  806. package/dist/utils/clipboard-native.d.ts.map +1 -1
  807. package/dist/utils/clipboard-native.js.map +1 -1
  808. package/dist/utils/clipboard.d.ts +1 -0
  809. package/dist/utils/clipboard.d.ts.map +1 -1
  810. package/dist/utils/clipboard.js +52 -1
  811. package/dist/utils/clipboard.js.map +1 -1
  812. package/dist/utils/fs-watch.d.ts +11 -0
  813. package/dist/utils/fs-watch.d.ts.map +1 -1
  814. package/dist/utils/fs-watch.js +20 -2
  815. package/dist/utils/fs-watch.js.map +1 -1
  816. package/dist/utils/highlight-js-languages.d.ts +4 -0
  817. package/dist/utils/highlight-js-languages.d.ts.map +1 -0
  818. package/dist/utils/highlight-js-languages.js +573 -0
  819. package/dist/utils/highlight-js-languages.js.map +1 -0
  820. package/dist/utils/platform.d.ts +3 -0
  821. package/dist/utils/platform.d.ts.map +1 -0
  822. package/dist/utils/platform.js +8 -0
  823. package/dist/utils/platform.js.map +1 -0
  824. package/dist/utils/shell.d.ts +7 -1
  825. package/dist/utils/shell.d.ts.map +1 -1
  826. package/dist/utils/shell.js +21 -6
  827. package/dist/utils/shell.js.map +1 -1
  828. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  829. package/dist/utils/syntax-highlight.js +53 -5
  830. package/dist/utils/syntax-highlight.js.map +1 -1
  831. package/dist/utils/tools-manager.d.ts.map +1 -1
  832. package/dist/utils/tools-manager.js +112 -1
  833. package/dist/utils/tools-manager.js.map +1 -1
  834. package/dist/utils/work-directory.d.ts +11 -0
  835. package/dist/utils/work-directory.d.ts.map +1 -1
  836. package/dist/utils/work-directory.js +30 -9
  837. package/dist/utils/work-directory.js.map +1 -1
  838. package/docs/UI_POLISH_ORCHESTRATION.md +44 -0
  839. package/docs/UI_QUALITY_ORCHESTRATION.md +30 -0
  840. package/docs/docs.json +4 -0
  841. package/docs/extensions.md +62 -2
  842. package/docs/harness-architecture.md +156 -0
  843. package/docs/keybindings.md +11 -1
  844. package/docs/process-matrix.md +153 -0
  845. package/docs/rpc.md +45 -2
  846. package/docs/sessions.md +15 -0
  847. package/docs/settings.md +128 -11
  848. package/docs/task-steps.md +8 -0
  849. package/docs/telemetry.md +19 -0
  850. package/docs/tmux-agent-manager.md +92 -2
  851. package/docs/ui-reference/README.md +9 -0
  852. package/docs/ui-reference/orchestration-after.txt +7 -0
  853. package/docs/ui-reference/orchestration-before.txt +7 -0
  854. package/docs/ui-reference/orchestration-reference.txt +6 -0
  855. package/docs/usage.md +14 -2
  856. package/docs/windows.md +52 -3
  857. package/docs/work-directory.md +42 -2
  858. package/docs/worktree-sync.md +250 -0
  859. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  860. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  861. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  862. package/examples/extensions/question.ts +34 -245
  863. package/examples/extensions/questionnaire.ts +41 -407
  864. package/examples/extensions/sandbox/package-lock.json +2 -2
  865. package/examples/extensions/sandbox/package.json +1 -1
  866. package/examples/extensions/with-deps/package-lock.json +2 -2
  867. package/examples/extensions/with-deps/package.json +1 -1
  868. package/npm-shrinkwrap.json +12 -12
  869. package/package.json +10 -4
  870. package/dist/core/delegation/session-worker-result.d.ts +0 -16
  871. package/dist/core/delegation/session-worker-result.d.ts.map +0 -1
  872. package/dist/core/delegation/session-worker-result.js +0 -53
  873. package/dist/core/delegation/session-worker-result.js.map +0 -1
  874. package/dist/core/delegation/worker-result.d.ts +0 -15
  875. package/dist/core/delegation/worker-result.d.ts.map +0 -1
  876. package/dist/core/delegation/worker-result.js +0 -161
  877. package/dist/core/delegation/worker-result.js.map +0 -1
  878. package/dist/core/telemetry.d.ts.map +0 -1
  879. package/dist/core/telemetry.js.map +0 -1
  880. package/docs/integration-sweep-builder-blueprint-2026-07-09.md +0 -365
  881. package/docs/integration-sweep-resume-2026-07-09.md +0 -407
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Worktree-sync on-disk store: coordination state shared by EVERY process working on one repo.
3
+ *
4
+ * Lives under `<git-common-dir>/pi-worktree-sync/` -- all worktrees of a repository share the git
5
+ * common dir, so the store is repo-scoped and cross-process by construction, survives `/reload`
6
+ * and crashes, is invisible to `git status`, and needs no gitignore entry.
7
+ *
8
+ * The store is an INDEX, not the truth: freshness/dirtiness/progress are always re-derived from
9
+ * git by the engine (`git-engine.ts`). A deleted or corrupt store is rebuildable via reconcile --
10
+ * every reader here treats missing/corrupt files as "absent", never as an error.
11
+ *
12
+ * Writes are tmp+rename atomic (`util/atomic-file.ts`); the audit log uses the shared bounded JSONL
13
+ * sink, which serializes concurrent writers and atomically rotates to its newest low-water tail.
14
+ * The integration lock is a mkdir-atomic directory with an owner manifest: mkdir either succeeds
15
+ * (lock acquired) or fails EEXIST (held), with takeover ONLY for a provably-dead same-host owner.
16
+ */
17
+ import type { IntegrationLockAcquisition, IntegrationLockOwner, LandingTransaction, LaneRegistration, WorktreeSyncEpoch } from "./codes.ts";
18
+ export interface SyncStorePaths {
19
+ root: string;
20
+ epochFile: string;
21
+ landingTransactionFile: string;
22
+ lanesDir: string;
23
+ lockDir: string;
24
+ lockOwnerFile: string;
25
+ lockGuardFile: string;
26
+ lifecycleLockFile: string;
27
+ eventsFile: string;
28
+ }
29
+ /** Grace window after which an ownerless lock dir (crash between mkdir and owner write) counts as
30
+ * dead and may be taken over. Fresh ownerless dirs are conservatively treated as held. */
31
+ export declare const OWNERLESS_LOCK_STALE_MS = 30000;
32
+ export declare function syncStorePaths(gitCommonDir: string): SyncStorePaths;
33
+ /**
34
+ * Stable per-repo slug for the lane-worktree checkout root: sanitized repo basename plus 8 hex of
35
+ * sha256 over the REALPATH of the git common dir -- same-named repos in different places cannot
36
+ * collide, and every worktree of one repo resolves the same slug.
37
+ */
38
+ export declare function repoSlug(repoTopLevel: string, gitCommonDir: string): string;
39
+ export declare function readEpoch(paths: SyncStorePaths): Promise<WorktreeSyncEpoch | undefined>;
40
+ export declare function writeEpoch(paths: SyncStorePaths, epoch: WorktreeSyncEpoch): Promise<void>;
41
+ export declare function readLandingTransaction(paths: SyncStorePaths): Promise<LandingTransaction | undefined>;
42
+ export declare function writeLandingTransaction(paths: SyncStorePaths, transaction: LandingTransaction): Promise<void>;
43
+ export declare function clearLandingTransaction(paths: SyncStorePaths): Promise<void>;
44
+ export declare function readLane(paths: SyncStorePaths, laneKey: string): Promise<LaneRegistration | undefined>;
45
+ export declare function writeLane(paths: SyncStorePaths, lane: LaneRegistration): Promise<void>;
46
+ export declare function listLanes(paths: SyncStorePaths): Promise<LaneRegistration[]>;
47
+ /** Append one audit event as a single JSON line. `at` is stamped here so every event carries it. */
48
+ export declare function appendAuditEvent(paths: SyncStorePaths, event: {
49
+ event: string;
50
+ } & Record<string, unknown>, at: string): Promise<void>;
51
+ export interface IntegrationLockDeps {
52
+ /** Injectable liveness probe (deterministic tests). Default: same-host `process.kill(pid, 0)`. */
53
+ isPidAlive?: (owner: IntegrationLockOwner) => boolean;
54
+ now?: () => string;
55
+ nowMs?: () => number;
56
+ }
57
+ /** Same-host pid liveness. A foreign-host owner is ALWAYS treated as alive -- never taken over. */
58
+ export declare function defaultIsPidAlive(owner: IntegrationLockOwner): boolean;
59
+ /**
60
+ * Acquire the single integration lock (G1: landing is serialized). Non-blocking: a held lock
61
+ * returns `{acquired:false, holder, holderAlive}` immediately -- callers surface `lock_busy` and
62
+ * retry on their own cadence rather than spinning here. Takeover happens ONLY when the recorded
63
+ * owner is provably dead on this host (or the lock dir is ownerless and older than
64
+ * {@link OWNERLESS_LOCK_STALE_MS}); every takeover is audited.
65
+ */
66
+ export declare function acquireIntegrationLock(paths: SyncStorePaths, owner: Omit<IntegrationLockOwner, "acquiredAt" | "token">, deps?: IntegrationLockDeps): Promise<IntegrationLockAcquisition>;
67
+ export declare function releaseIntegrationLock(paths: SyncStorePaths, token: string, deps?: IntegrationLockDeps): Promise<boolean>;
68
+ export declare function readLockHolder(paths: SyncStorePaths): Promise<IntegrationLockOwner | undefined>;
69
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/worktree-sync/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Worktree-sync on-disk store: coordination state shared by EVERY process working on one repo.\n *\n * Lives under `<git-common-dir>/pi-worktree-sync/` -- all worktrees of a repository share the git\n * common dir, so the store is repo-scoped and cross-process by construction, survives `/reload`\n * and crashes, is invisible to `git status`, and needs no gitignore entry.\n *\n * The store is an INDEX, not the truth: freshness/dirtiness/progress are always re-derived from\n * git by the engine (`git-engine.ts`). A deleted or corrupt store is rebuildable via reconcile --\n * every reader here treats missing/corrupt files as \"absent\", never as an error.\n *\n * Writes are tmp+rename atomic (`util/atomic-file.ts`); the audit log uses the shared bounded JSONL\n * sink, which serializes concurrent writers and atomically rotates to its newest low-water tail.\n * The integration lock is a mkdir-atomic directory with an owner manifest: mkdir either succeeds\n * (lock acquired) or fails EEXIST (held), with takeover ONLY for a provably-dead same-host owner.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { promises as fsPromises, realpathSync } from \"node:fs\";\nimport { hostname as osHostname } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\nimport { withFileLock, writeFileAtomic } from \"../util/atomic-file.ts\";\nimport { appendBoundedJsonLine, type BoundedJsonlLimits } from \"../util/bounded-jsonl.ts\";\nimport type {\n\tIntegrationLockAcquisition,\n\tIntegrationLockOwner,\n\tLandingTransaction,\n\tLaneRegistration,\n\tWorktreeSyncEpoch,\n} from \"./codes.ts\";\n\nexport interface SyncStorePaths {\n\troot: string;\n\tepochFile: string;\n\tlandingTransactionFile: string;\n\tlanesDir: string;\n\tlockDir: string;\n\tlockOwnerFile: string;\n\tlockGuardFile: string;\n\tlifecycleLockFile: string;\n\teventsFile: string;\n}\n\n/** Grace window after which an ownerless lock dir (crash between mkdir and owner write) counts as\n * dead and may be taken over. Fresh ownerless dirs are conservatively treated as held. */\nexport const OWNERLESS_LOCK_STALE_MS = 30_000;\n\nconst STORE_DIR_NAME = \"pi-worktree-sync\";\nconst WORKTREE_AUDIT_EVENT_LIMITS: BoundedJsonlLimits = {\n\tmaxBytes: 4 * 1024 * 1024,\n\ttargetBytes: Math.floor(4 * 1024 * 1024 * 0.75),\n\tmaxRecords: 10_000,\n};\n\nexport function syncStorePaths(gitCommonDir: string): SyncStorePaths {\n\tconst root = join(gitCommonDir, STORE_DIR_NAME);\n\treturn {\n\t\troot,\n\t\tepochFile: join(root, \"epoch.json\"),\n\t\tlandingTransactionFile: join(root, \"landing-transaction.json\"),\n\t\tlanesDir: join(root, \"lanes\"),\n\t\tlockDir: join(root, \"locks\", \"integration\"),\n\t\tlockOwnerFile: join(root, \"locks\", \"integration\", \"owner.json\"),\n\t\tlockGuardFile: join(root, \"locks\", \"integration-metadata\"),\n\t\tlifecycleLockFile: join(root, \"locks\", \"lifecycle\"),\n\t\teventsFile: join(root, \"events.jsonl\"),\n\t};\n}\n\n/**\n * Stable per-repo slug for the lane-worktree checkout root: sanitized repo basename plus 8 hex of\n * sha256 over the REALPATH of the git common dir -- same-named repos in different places cannot\n * collide, and every worktree of one repo resolves the same slug.\n */\nexport function repoSlug(repoTopLevel: string, gitCommonDir: string): string {\n\tlet canonical = gitCommonDir;\n\ttry {\n\t\tcanonical = realpathSync(gitCommonDir);\n\t} catch {\n\t\t// Unresolvable (already-deleted repo during teardown): hash the raw path deterministically.\n\t}\n\tconst hash = createHash(\"sha256\").update(canonical).digest(\"hex\").slice(0, 8);\n\tconst base = basename(repoTopLevel)\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]+/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\")\n\t\t.slice(0, 48);\n\treturn `${base || \"repo\"}-${hash}`;\n}\n\nasync function readJsonFile<T>(filePath: string): Promise<T | undefined> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\treturn JSON.parse(raw) as T;\n\t} catch {\n\t\t// Corrupt store files are treated as absent -- git remains the truth and reconcile rebuilds.\n\t\treturn undefined;\n\t}\n}\n\nexport async function readEpoch(paths: SyncStorePaths): Promise<WorktreeSyncEpoch | undefined> {\n\treturn readJsonFile<WorktreeSyncEpoch>(paths.epochFile);\n}\n\nexport async function writeEpoch(paths: SyncStorePaths, epoch: WorktreeSyncEpoch): Promise<void> {\n\tawait writeFileAtomic(paths.epochFile, `${JSON.stringify(epoch, null, \"\\t\")}\\n`);\n}\n\nexport async function readLandingTransaction(paths: SyncStorePaths): Promise<LandingTransaction | undefined> {\n\tconst value = await readJsonFile<unknown>(paths.landingTransactionFile);\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.laneKey !== \"string\" ||\n\t\ttypeof record.priorMainSha !== \"string\" ||\n\t\ttypeof record.testedTipSha !== \"string\" ||\n\t\t!Array.isArray(record.changedPaths) ||\n\t\t!record.changedPaths.every((path) => typeof path === \"string\") ||\n\t\ttypeof record.changedPathsTruncated !== \"boolean\" ||\n\t\ttypeof record.lockToken !== \"string\" ||\n\t\t(record.gate !== \"passed\" && record.gate !== \"off\") ||\n\t\t(record.stage !== \"ready_to_merge\" &&\n\t\t\trecord.stage !== \"main_moved\" &&\n\t\t\trecord.stage !== \"epoch_written\" &&\n\t\t\trecord.stage !== \"audit_logged\")\n\t) {\n\t\treturn undefined;\n\t}\n\treturn record as unknown as LandingTransaction;\n}\n\nexport async function writeLandingTransaction(paths: SyncStorePaths, transaction: LandingTransaction): Promise<void> {\n\tawait writeFileAtomic(paths.landingTransactionFile, `${JSON.stringify(transaction, null, \"\\t\")}\\n`);\n}\n\nexport async function clearLandingTransaction(paths: SyncStorePaths): Promise<void> {\n\ttry {\n\t\tawait fsPromises.unlink(paths.landingTransactionFile);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n}\n\nfunction laneFile(paths: SyncStorePaths, laneKey: string): string {\n\treturn join(paths.lanesDir, `${laneKey}.json`);\n}\n\nexport async function readLane(paths: SyncStorePaths, laneKey: string): Promise<LaneRegistration | undefined> {\n\treturn readJsonFile<LaneRegistration>(laneFile(paths, laneKey));\n}\n\nexport async function writeLane(paths: SyncStorePaths, lane: LaneRegistration): Promise<void> {\n\tawait writeFileAtomic(laneFile(paths, lane.laneKey), `${JSON.stringify(lane, null, \"\\t\")}\\n`);\n}\n\nexport async function listLanes(paths: SyncStorePaths): Promise<LaneRegistration[]> {\n\tlet entries: string[];\n\ttry {\n\t\tentries = await fsPromises.readdir(paths.lanesDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst lanes: LaneRegistration[] = [];\n\tfor (const entry of entries.sort()) {\n\t\tif (!entry.endsWith(\".json\")) continue;\n\t\tconst lane = await readJsonFile<LaneRegistration>(join(paths.lanesDir, entry));\n\t\tif (lane?.laneKey) lanes.push(lane);\n\t}\n\treturn lanes;\n}\n\n/** Append one audit event as a single JSON line. `at` is stamped here so every event carries it. */\nexport async function appendAuditEvent(\n\tpaths: SyncStorePaths,\n\tevent: { event: string } & Record<string, unknown>,\n\tat: string,\n): Promise<void> {\n\tawait appendBoundedJsonLine(paths.eventsFile, { at, ...event }, WORKTREE_AUDIT_EVENT_LIMITS);\n}\n\nexport interface IntegrationLockDeps {\n\t/** Injectable liveness probe (deterministic tests). Default: same-host `process.kill(pid, 0)`. */\n\tisPidAlive?: (owner: IntegrationLockOwner) => boolean;\n\tnow?: () => string;\n\tnowMs?: () => number;\n}\n\n/** Same-host pid liveness. A foreign-host owner is ALWAYS treated as alive -- never taken over. */\nexport function defaultIsPidAlive(owner: IntegrationLockOwner): boolean {\n\tif (owner.hostname !== osHostname()) return true;\n\ttry {\n\t\tprocess.kill(owner.pid, 0);\n\t\treturn true;\n\t} catch (err) {\n\t\t// EPERM means the pid exists but belongs to another user -- alive. Only ESRCH is dead.\n\t\treturn (err as NodeJS.ErrnoException).code === \"EPERM\";\n\t}\n}\n\nasync function readLockOwner(paths: SyncStorePaths): Promise<IntegrationLockOwner | undefined> {\n\treturn readJsonFile<IntegrationLockOwner>(paths.lockOwnerFile);\n}\n\nasync function tryMkdirLock(paths: SyncStorePaths): Promise<boolean> {\n\ttry {\n\t\tawait fsPromises.mkdir(paths.lockDir, { recursive: false });\n\t\treturn true;\n\t} catch (err) {\n\t\tif ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\t// Parent `locks/` missing on first use: create it, then retry the ATOMIC non-recursive mkdir.\n\t\t\tawait fsPromises.mkdir(dirname(paths.lockDir), { recursive: true });\n\t\t\ttry {\n\t\t\t\tawait fsPromises.mkdir(paths.lockDir, { recursive: false });\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Acquire the single integration lock (G1: landing is serialized). Non-blocking: a held lock\n * returns `{acquired:false, holder, holderAlive}` immediately -- callers surface `lock_busy` and\n * retry on their own cadence rather than spinning here. Takeover happens ONLY when the recorded\n * owner is provably dead on this host (or the lock dir is ownerless and older than\n * {@link OWNERLESS_LOCK_STALE_MS}); every takeover is audited.\n */\nexport async function acquireIntegrationLock(\n\tpaths: SyncStorePaths,\n\towner: Omit<IntegrationLockOwner, \"acquiredAt\" | \"token\">,\n\tdeps: IntegrationLockDeps = {},\n): Promise<IntegrationLockAcquisition> {\n\treturn withFileLock(paths.lockGuardFile, async () => {\n\t\tconst now = deps.now ?? (() => new Date().toISOString());\n\t\tconst nowMs = deps.nowMs ?? (() => Date.now());\n\t\tconst isPidAlive = deps.isPidAlive ?? defaultIsPidAlive;\n\t\tfor (let attempt = 0; attempt < 2; attempt++) {\n\t\t\tif (await tryMkdirLock(paths)) {\n\t\t\t\tconst token = randomUUID();\n\t\t\t\tconst manifest: IntegrationLockOwner = { ...owner, token, acquiredAt: now() };\n\t\t\t\tawait fsPromises.writeFile(paths.lockOwnerFile, `${JSON.stringify(manifest)}\\n`, \"utf-8\");\n\t\t\t\tawait appendAuditEvent(\n\t\t\t\t\tpaths,\n\t\t\t\t\t{ event: \"lock_acquired\", ...(attempt > 0 ? { takeover: true } : {}) },\n\t\t\t\t\tnow(),\n\t\t\t\t);\n\t\t\t\treturn { acquired: true, takeover: attempt > 0, token };\n\t\t\t}\n\n\t\t\tconst holder = await readLockOwner(paths);\n\t\t\tif (holder) {\n\t\t\t\tif (isPidAlive(holder)) return { acquired: false, holder, holderAlive: true };\n\t\t\t} else {\n\t\t\t\t// Ownerless dir: a crash between mkdir and the owner write. Only stale ones are dead.\n\t\t\t\tlet dirMtimeMs: number | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tdirMtimeMs = (await fsPromises.stat(paths.lockDir)).mtimeMs;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (nowMs() - dirMtimeMs < OWNERLESS_LOCK_STALE_MS) return { acquired: false, holderAlive: true };\n\t\t\t}\n\n\t\t\t// Metadata serialization makes the stale observation and directory removal one guarded\n\t\t\t// operation; a successor cannot be removed by a stale observer.\n\t\t\tawait fsPromises.rm(paths.lockDir, { recursive: true, force: true });\n\t\t\tawait appendAuditEvent(\n\t\t\t\tpaths,\n\t\t\t\t{\n\t\t\t\t\tevent: \"lock_takeover\",\n\t\t\t\t\t...(holder ? { deadOwnerPid: holder.pid, deadOwnerLaneKey: holder.laneKey } : {}),\n\t\t\t\t},\n\t\t\t\tnow(),\n\t\t\t);\n\t\t}\n\t\tconst holder = await readLockOwner(paths);\n\t\treturn { acquired: false, holder, holderAlive: holder ? isPidAlive(holder) : true };\n\t});\n}\n\nexport async function releaseIntegrationLock(\n\tpaths: SyncStorePaths,\n\ttoken: string,\n\tdeps: IntegrationLockDeps = {},\n): Promise<boolean> {\n\treturn withFileLock(paths.lockGuardFile, async () => {\n\t\tconst now = deps.now ?? (() => new Date().toISOString());\n\t\tconst holder = await readLockOwner(paths);\n\t\tif (!holder || holder.token !== token) return false;\n\t\tawait fsPromises.rm(paths.lockDir, { recursive: true, force: true });\n\t\tawait appendAuditEvent(paths, { event: \"lock_released\" }, now());\n\t\treturn true;\n\t});\n}\n\nexport async function readLockHolder(paths: SyncStorePaths): Promise<IntegrationLockOwner | undefined> {\n\treturn readLockOwner(paths);\n}\n"]}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Worktree-sync on-disk store: coordination state shared by EVERY process working on one repo.
3
+ *
4
+ * Lives under `<git-common-dir>/pi-worktree-sync/` -- all worktrees of a repository share the git
5
+ * common dir, so the store is repo-scoped and cross-process by construction, survives `/reload`
6
+ * and crashes, is invisible to `git status`, and needs no gitignore entry.
7
+ *
8
+ * The store is an INDEX, not the truth: freshness/dirtiness/progress are always re-derived from
9
+ * git by the engine (`git-engine.ts`). A deleted or corrupt store is rebuildable via reconcile --
10
+ * every reader here treats missing/corrupt files as "absent", never as an error.
11
+ *
12
+ * Writes are tmp+rename atomic (`util/atomic-file.ts`); the audit log uses the shared bounded JSONL
13
+ * sink, which serializes concurrent writers and atomically rotates to its newest low-water tail.
14
+ * The integration lock is a mkdir-atomic directory with an owner manifest: mkdir either succeeds
15
+ * (lock acquired) or fails EEXIST (held), with takeover ONLY for a provably-dead same-host owner.
16
+ */
17
+ import { createHash, randomUUID } from "node:crypto";
18
+ import { promises as fsPromises, realpathSync } from "node:fs";
19
+ import { hostname as osHostname } from "node:os";
20
+ import { basename, dirname, join } from "node:path";
21
+ import { withFileLock, writeFileAtomic } from "../util/atomic-file.js";
22
+ import { appendBoundedJsonLine } from "../util/bounded-jsonl.js";
23
+ /** Grace window after which an ownerless lock dir (crash between mkdir and owner write) counts as
24
+ * dead and may be taken over. Fresh ownerless dirs are conservatively treated as held. */
25
+ export const OWNERLESS_LOCK_STALE_MS = 30_000;
26
+ const STORE_DIR_NAME = "pi-worktree-sync";
27
+ const WORKTREE_AUDIT_EVENT_LIMITS = {
28
+ maxBytes: 4 * 1024 * 1024,
29
+ targetBytes: Math.floor(4 * 1024 * 1024 * 0.75),
30
+ maxRecords: 10_000,
31
+ };
32
+ export function syncStorePaths(gitCommonDir) {
33
+ const root = join(gitCommonDir, STORE_DIR_NAME);
34
+ return {
35
+ root,
36
+ epochFile: join(root, "epoch.json"),
37
+ landingTransactionFile: join(root, "landing-transaction.json"),
38
+ lanesDir: join(root, "lanes"),
39
+ lockDir: join(root, "locks", "integration"),
40
+ lockOwnerFile: join(root, "locks", "integration", "owner.json"),
41
+ lockGuardFile: join(root, "locks", "integration-metadata"),
42
+ lifecycleLockFile: join(root, "locks", "lifecycle"),
43
+ eventsFile: join(root, "events.jsonl"),
44
+ };
45
+ }
46
+ /**
47
+ * Stable per-repo slug for the lane-worktree checkout root: sanitized repo basename plus 8 hex of
48
+ * sha256 over the REALPATH of the git common dir -- same-named repos in different places cannot
49
+ * collide, and every worktree of one repo resolves the same slug.
50
+ */
51
+ export function repoSlug(repoTopLevel, gitCommonDir) {
52
+ let canonical = gitCommonDir;
53
+ try {
54
+ canonical = realpathSync(gitCommonDir);
55
+ }
56
+ catch {
57
+ // Unresolvable (already-deleted repo during teardown): hash the raw path deterministically.
58
+ }
59
+ const hash = createHash("sha256").update(canonical).digest("hex").slice(0, 8);
60
+ const base = basename(repoTopLevel)
61
+ .toLowerCase()
62
+ .replace(/[^a-z0-9-]+/g, "-")
63
+ .replace(/^-+|-+$/g, "")
64
+ .slice(0, 48);
65
+ return `${base || "repo"}-${hash}`;
66
+ }
67
+ async function readJsonFile(filePath) {
68
+ let raw;
69
+ try {
70
+ raw = await fsPromises.readFile(filePath, "utf-8");
71
+ }
72
+ catch {
73
+ return undefined;
74
+ }
75
+ try {
76
+ return JSON.parse(raw);
77
+ }
78
+ catch {
79
+ // Corrupt store files are treated as absent -- git remains the truth and reconcile rebuilds.
80
+ return undefined;
81
+ }
82
+ }
83
+ export async function readEpoch(paths) {
84
+ return readJsonFile(paths.epochFile);
85
+ }
86
+ export async function writeEpoch(paths, epoch) {
87
+ await writeFileAtomic(paths.epochFile, `${JSON.stringify(epoch, null, "\t")}\n`);
88
+ }
89
+ export async function readLandingTransaction(paths) {
90
+ const value = await readJsonFile(paths.landingTransactionFile);
91
+ if (typeof value !== "object" || value === null || Array.isArray(value))
92
+ return undefined;
93
+ const record = value;
94
+ if (typeof record.laneKey !== "string" ||
95
+ typeof record.priorMainSha !== "string" ||
96
+ typeof record.testedTipSha !== "string" ||
97
+ !Array.isArray(record.changedPaths) ||
98
+ !record.changedPaths.every((path) => typeof path === "string") ||
99
+ typeof record.changedPathsTruncated !== "boolean" ||
100
+ typeof record.lockToken !== "string" ||
101
+ (record.gate !== "passed" && record.gate !== "off") ||
102
+ (record.stage !== "ready_to_merge" &&
103
+ record.stage !== "main_moved" &&
104
+ record.stage !== "epoch_written" &&
105
+ record.stage !== "audit_logged")) {
106
+ return undefined;
107
+ }
108
+ return record;
109
+ }
110
+ export async function writeLandingTransaction(paths, transaction) {
111
+ await writeFileAtomic(paths.landingTransactionFile, `${JSON.stringify(transaction, null, "\t")}\n`);
112
+ }
113
+ export async function clearLandingTransaction(paths) {
114
+ try {
115
+ await fsPromises.unlink(paths.landingTransactionFile);
116
+ }
117
+ catch (error) {
118
+ if (error.code !== "ENOENT")
119
+ throw error;
120
+ }
121
+ }
122
+ function laneFile(paths, laneKey) {
123
+ return join(paths.lanesDir, `${laneKey}.json`);
124
+ }
125
+ export async function readLane(paths, laneKey) {
126
+ return readJsonFile(laneFile(paths, laneKey));
127
+ }
128
+ export async function writeLane(paths, lane) {
129
+ await writeFileAtomic(laneFile(paths, lane.laneKey), `${JSON.stringify(lane, null, "\t")}\n`);
130
+ }
131
+ export async function listLanes(paths) {
132
+ let entries;
133
+ try {
134
+ entries = await fsPromises.readdir(paths.lanesDir);
135
+ }
136
+ catch {
137
+ return [];
138
+ }
139
+ const lanes = [];
140
+ for (const entry of entries.sort()) {
141
+ if (!entry.endsWith(".json"))
142
+ continue;
143
+ const lane = await readJsonFile(join(paths.lanesDir, entry));
144
+ if (lane?.laneKey)
145
+ lanes.push(lane);
146
+ }
147
+ return lanes;
148
+ }
149
+ /** Append one audit event as a single JSON line. `at` is stamped here so every event carries it. */
150
+ export async function appendAuditEvent(paths, event, at) {
151
+ await appendBoundedJsonLine(paths.eventsFile, { at, ...event }, WORKTREE_AUDIT_EVENT_LIMITS);
152
+ }
153
+ /** Same-host pid liveness. A foreign-host owner is ALWAYS treated as alive -- never taken over. */
154
+ export function defaultIsPidAlive(owner) {
155
+ if (owner.hostname !== osHostname())
156
+ return true;
157
+ try {
158
+ process.kill(owner.pid, 0);
159
+ return true;
160
+ }
161
+ catch (err) {
162
+ // EPERM means the pid exists but belongs to another user -- alive. Only ESRCH is dead.
163
+ return err.code === "EPERM";
164
+ }
165
+ }
166
+ async function readLockOwner(paths) {
167
+ return readJsonFile(paths.lockOwnerFile);
168
+ }
169
+ async function tryMkdirLock(paths) {
170
+ try {
171
+ await fsPromises.mkdir(paths.lockDir, { recursive: false });
172
+ return true;
173
+ }
174
+ catch (err) {
175
+ if (err.code === "ENOENT") {
176
+ // Parent `locks/` missing on first use: create it, then retry the ATOMIC non-recursive mkdir.
177
+ await fsPromises.mkdir(dirname(paths.lockDir), { recursive: true });
178
+ try {
179
+ await fsPromises.mkdir(paths.lockDir, { recursive: false });
180
+ return true;
181
+ }
182
+ catch {
183
+ return false;
184
+ }
185
+ }
186
+ return false;
187
+ }
188
+ }
189
+ /**
190
+ * Acquire the single integration lock (G1: landing is serialized). Non-blocking: a held lock
191
+ * returns `{acquired:false, holder, holderAlive}` immediately -- callers surface `lock_busy` and
192
+ * retry on their own cadence rather than spinning here. Takeover happens ONLY when the recorded
193
+ * owner is provably dead on this host (or the lock dir is ownerless and older than
194
+ * {@link OWNERLESS_LOCK_STALE_MS}); every takeover is audited.
195
+ */
196
+ export async function acquireIntegrationLock(paths, owner, deps = {}) {
197
+ return withFileLock(paths.lockGuardFile, async () => {
198
+ const now = deps.now ?? (() => new Date().toISOString());
199
+ const nowMs = deps.nowMs ?? (() => Date.now());
200
+ const isPidAlive = deps.isPidAlive ?? defaultIsPidAlive;
201
+ for (let attempt = 0; attempt < 2; attempt++) {
202
+ if (await tryMkdirLock(paths)) {
203
+ const token = randomUUID();
204
+ const manifest = { ...owner, token, acquiredAt: now() };
205
+ await fsPromises.writeFile(paths.lockOwnerFile, `${JSON.stringify(manifest)}\n`, "utf-8");
206
+ await appendAuditEvent(paths, { event: "lock_acquired", ...(attempt > 0 ? { takeover: true } : {}) }, now());
207
+ return { acquired: true, takeover: attempt > 0, token };
208
+ }
209
+ const holder = await readLockOwner(paths);
210
+ if (holder) {
211
+ if (isPidAlive(holder))
212
+ return { acquired: false, holder, holderAlive: true };
213
+ }
214
+ else {
215
+ // Ownerless dir: a crash between mkdir and the owner write. Only stale ones are dead.
216
+ let dirMtimeMs;
217
+ try {
218
+ dirMtimeMs = (await fsPromises.stat(paths.lockDir)).mtimeMs;
219
+ }
220
+ catch {
221
+ continue;
222
+ }
223
+ if (nowMs() - dirMtimeMs < OWNERLESS_LOCK_STALE_MS)
224
+ return { acquired: false, holderAlive: true };
225
+ }
226
+ // Metadata serialization makes the stale observation and directory removal one guarded
227
+ // operation; a successor cannot be removed by a stale observer.
228
+ await fsPromises.rm(paths.lockDir, { recursive: true, force: true });
229
+ await appendAuditEvent(paths, {
230
+ event: "lock_takeover",
231
+ ...(holder ? { deadOwnerPid: holder.pid, deadOwnerLaneKey: holder.laneKey } : {}),
232
+ }, now());
233
+ }
234
+ const holder = await readLockOwner(paths);
235
+ return { acquired: false, holder, holderAlive: holder ? isPidAlive(holder) : true };
236
+ });
237
+ }
238
+ export async function releaseIntegrationLock(paths, token, deps = {}) {
239
+ return withFileLock(paths.lockGuardFile, async () => {
240
+ const now = deps.now ?? (() => new Date().toISOString());
241
+ const holder = await readLockOwner(paths);
242
+ if (!holder || holder.token !== token)
243
+ return false;
244
+ await fsPromises.rm(paths.lockDir, { recursive: true, force: true });
245
+ await appendAuditEvent(paths, { event: "lock_released" }, now());
246
+ return true;
247
+ });
248
+ }
249
+ export async function readLockHolder(paths) {
250
+ return readLockOwner(paths);
251
+ }
252
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/worktree-sync/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Worktree-sync on-disk store: coordination state shared by EVERY process working on one repo.\n *\n * Lives under `<git-common-dir>/pi-worktree-sync/` -- all worktrees of a repository share the git\n * common dir, so the store is repo-scoped and cross-process by construction, survives `/reload`\n * and crashes, is invisible to `git status`, and needs no gitignore entry.\n *\n * The store is an INDEX, not the truth: freshness/dirtiness/progress are always re-derived from\n * git by the engine (`git-engine.ts`). A deleted or corrupt store is rebuildable via reconcile --\n * every reader here treats missing/corrupt files as \"absent\", never as an error.\n *\n * Writes are tmp+rename atomic (`util/atomic-file.ts`); the audit log uses the shared bounded JSONL\n * sink, which serializes concurrent writers and atomically rotates to its newest low-water tail.\n * The integration lock is a mkdir-atomic directory with an owner manifest: mkdir either succeeds\n * (lock acquired) or fails EEXIST (held), with takeover ONLY for a provably-dead same-host owner.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { promises as fsPromises, realpathSync } from \"node:fs\";\nimport { hostname as osHostname } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\nimport { withFileLock, writeFileAtomic } from \"../util/atomic-file.ts\";\nimport { appendBoundedJsonLine, type BoundedJsonlLimits } from \"../util/bounded-jsonl.ts\";\nimport type {\n\tIntegrationLockAcquisition,\n\tIntegrationLockOwner,\n\tLandingTransaction,\n\tLaneRegistration,\n\tWorktreeSyncEpoch,\n} from \"./codes.ts\";\n\nexport interface SyncStorePaths {\n\troot: string;\n\tepochFile: string;\n\tlandingTransactionFile: string;\n\tlanesDir: string;\n\tlockDir: string;\n\tlockOwnerFile: string;\n\tlockGuardFile: string;\n\tlifecycleLockFile: string;\n\teventsFile: string;\n}\n\n/** Grace window after which an ownerless lock dir (crash between mkdir and owner write) counts as\n * dead and may be taken over. Fresh ownerless dirs are conservatively treated as held. */\nexport const OWNERLESS_LOCK_STALE_MS = 30_000;\n\nconst STORE_DIR_NAME = \"pi-worktree-sync\";\nconst WORKTREE_AUDIT_EVENT_LIMITS: BoundedJsonlLimits = {\n\tmaxBytes: 4 * 1024 * 1024,\n\ttargetBytes: Math.floor(4 * 1024 * 1024 * 0.75),\n\tmaxRecords: 10_000,\n};\n\nexport function syncStorePaths(gitCommonDir: string): SyncStorePaths {\n\tconst root = join(gitCommonDir, STORE_DIR_NAME);\n\treturn {\n\t\troot,\n\t\tepochFile: join(root, \"epoch.json\"),\n\t\tlandingTransactionFile: join(root, \"landing-transaction.json\"),\n\t\tlanesDir: join(root, \"lanes\"),\n\t\tlockDir: join(root, \"locks\", \"integration\"),\n\t\tlockOwnerFile: join(root, \"locks\", \"integration\", \"owner.json\"),\n\t\tlockGuardFile: join(root, \"locks\", \"integration-metadata\"),\n\t\tlifecycleLockFile: join(root, \"locks\", \"lifecycle\"),\n\t\teventsFile: join(root, \"events.jsonl\"),\n\t};\n}\n\n/**\n * Stable per-repo slug for the lane-worktree checkout root: sanitized repo basename plus 8 hex of\n * sha256 over the REALPATH of the git common dir -- same-named repos in different places cannot\n * collide, and every worktree of one repo resolves the same slug.\n */\nexport function repoSlug(repoTopLevel: string, gitCommonDir: string): string {\n\tlet canonical = gitCommonDir;\n\ttry {\n\t\tcanonical = realpathSync(gitCommonDir);\n\t} catch {\n\t\t// Unresolvable (already-deleted repo during teardown): hash the raw path deterministically.\n\t}\n\tconst hash = createHash(\"sha256\").update(canonical).digest(\"hex\").slice(0, 8);\n\tconst base = basename(repoTopLevel)\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]+/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\")\n\t\t.slice(0, 48);\n\treturn `${base || \"repo\"}-${hash}`;\n}\n\nasync function readJsonFile<T>(filePath: string): Promise<T | undefined> {\n\tlet raw: string;\n\ttry {\n\t\traw = await fsPromises.readFile(filePath, \"utf-8\");\n\t} catch {\n\t\treturn undefined;\n\t}\n\ttry {\n\t\treturn JSON.parse(raw) as T;\n\t} catch {\n\t\t// Corrupt store files are treated as absent -- git remains the truth and reconcile rebuilds.\n\t\treturn undefined;\n\t}\n}\n\nexport async function readEpoch(paths: SyncStorePaths): Promise<WorktreeSyncEpoch | undefined> {\n\treturn readJsonFile<WorktreeSyncEpoch>(paths.epochFile);\n}\n\nexport async function writeEpoch(paths: SyncStorePaths, epoch: WorktreeSyncEpoch): Promise<void> {\n\tawait writeFileAtomic(paths.epochFile, `${JSON.stringify(epoch, null, \"\\t\")}\\n`);\n}\n\nexport async function readLandingTransaction(paths: SyncStorePaths): Promise<LandingTransaction | undefined> {\n\tconst value = await readJsonFile<unknown>(paths.landingTransactionFile);\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.laneKey !== \"string\" ||\n\t\ttypeof record.priorMainSha !== \"string\" ||\n\t\ttypeof record.testedTipSha !== \"string\" ||\n\t\t!Array.isArray(record.changedPaths) ||\n\t\t!record.changedPaths.every((path) => typeof path === \"string\") ||\n\t\ttypeof record.changedPathsTruncated !== \"boolean\" ||\n\t\ttypeof record.lockToken !== \"string\" ||\n\t\t(record.gate !== \"passed\" && record.gate !== \"off\") ||\n\t\t(record.stage !== \"ready_to_merge\" &&\n\t\t\trecord.stage !== \"main_moved\" &&\n\t\t\trecord.stage !== \"epoch_written\" &&\n\t\t\trecord.stage !== \"audit_logged\")\n\t) {\n\t\treturn undefined;\n\t}\n\treturn record as unknown as LandingTransaction;\n}\n\nexport async function writeLandingTransaction(paths: SyncStorePaths, transaction: LandingTransaction): Promise<void> {\n\tawait writeFileAtomic(paths.landingTransactionFile, `${JSON.stringify(transaction, null, \"\\t\")}\\n`);\n}\n\nexport async function clearLandingTransaction(paths: SyncStorePaths): Promise<void> {\n\ttry {\n\t\tawait fsPromises.unlink(paths.landingTransactionFile);\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t}\n}\n\nfunction laneFile(paths: SyncStorePaths, laneKey: string): string {\n\treturn join(paths.lanesDir, `${laneKey}.json`);\n}\n\nexport async function readLane(paths: SyncStorePaths, laneKey: string): Promise<LaneRegistration | undefined> {\n\treturn readJsonFile<LaneRegistration>(laneFile(paths, laneKey));\n}\n\nexport async function writeLane(paths: SyncStorePaths, lane: LaneRegistration): Promise<void> {\n\tawait writeFileAtomic(laneFile(paths, lane.laneKey), `${JSON.stringify(lane, null, \"\\t\")}\\n`);\n}\n\nexport async function listLanes(paths: SyncStorePaths): Promise<LaneRegistration[]> {\n\tlet entries: string[];\n\ttry {\n\t\tentries = await fsPromises.readdir(paths.lanesDir);\n\t} catch {\n\t\treturn [];\n\t}\n\tconst lanes: LaneRegistration[] = [];\n\tfor (const entry of entries.sort()) {\n\t\tif (!entry.endsWith(\".json\")) continue;\n\t\tconst lane = await readJsonFile<LaneRegistration>(join(paths.lanesDir, entry));\n\t\tif (lane?.laneKey) lanes.push(lane);\n\t}\n\treturn lanes;\n}\n\n/** Append one audit event as a single JSON line. `at` is stamped here so every event carries it. */\nexport async function appendAuditEvent(\n\tpaths: SyncStorePaths,\n\tevent: { event: string } & Record<string, unknown>,\n\tat: string,\n): Promise<void> {\n\tawait appendBoundedJsonLine(paths.eventsFile, { at, ...event }, WORKTREE_AUDIT_EVENT_LIMITS);\n}\n\nexport interface IntegrationLockDeps {\n\t/** Injectable liveness probe (deterministic tests). Default: same-host `process.kill(pid, 0)`. */\n\tisPidAlive?: (owner: IntegrationLockOwner) => boolean;\n\tnow?: () => string;\n\tnowMs?: () => number;\n}\n\n/** Same-host pid liveness. A foreign-host owner is ALWAYS treated as alive -- never taken over. */\nexport function defaultIsPidAlive(owner: IntegrationLockOwner): boolean {\n\tif (owner.hostname !== osHostname()) return true;\n\ttry {\n\t\tprocess.kill(owner.pid, 0);\n\t\treturn true;\n\t} catch (err) {\n\t\t// EPERM means the pid exists but belongs to another user -- alive. Only ESRCH is dead.\n\t\treturn (err as NodeJS.ErrnoException).code === \"EPERM\";\n\t}\n}\n\nasync function readLockOwner(paths: SyncStorePaths): Promise<IntegrationLockOwner | undefined> {\n\treturn readJsonFile<IntegrationLockOwner>(paths.lockOwnerFile);\n}\n\nasync function tryMkdirLock(paths: SyncStorePaths): Promise<boolean> {\n\ttry {\n\t\tawait fsPromises.mkdir(paths.lockDir, { recursive: false });\n\t\treturn true;\n\t} catch (err) {\n\t\tif ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n\t\t\t// Parent `locks/` missing on first use: create it, then retry the ATOMIC non-recursive mkdir.\n\t\t\tawait fsPromises.mkdir(dirname(paths.lockDir), { recursive: true });\n\t\t\ttry {\n\t\t\t\tawait fsPromises.mkdir(paths.lockDir, { recursive: false });\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n\n/**\n * Acquire the single integration lock (G1: landing is serialized). Non-blocking: a held lock\n * returns `{acquired:false, holder, holderAlive}` immediately -- callers surface `lock_busy` and\n * retry on their own cadence rather than spinning here. Takeover happens ONLY when the recorded\n * owner is provably dead on this host (or the lock dir is ownerless and older than\n * {@link OWNERLESS_LOCK_STALE_MS}); every takeover is audited.\n */\nexport async function acquireIntegrationLock(\n\tpaths: SyncStorePaths,\n\towner: Omit<IntegrationLockOwner, \"acquiredAt\" | \"token\">,\n\tdeps: IntegrationLockDeps = {},\n): Promise<IntegrationLockAcquisition> {\n\treturn withFileLock(paths.lockGuardFile, async () => {\n\t\tconst now = deps.now ?? (() => new Date().toISOString());\n\t\tconst nowMs = deps.nowMs ?? (() => Date.now());\n\t\tconst isPidAlive = deps.isPidAlive ?? defaultIsPidAlive;\n\t\tfor (let attempt = 0; attempt < 2; attempt++) {\n\t\t\tif (await tryMkdirLock(paths)) {\n\t\t\t\tconst token = randomUUID();\n\t\t\t\tconst manifest: IntegrationLockOwner = { ...owner, token, acquiredAt: now() };\n\t\t\t\tawait fsPromises.writeFile(paths.lockOwnerFile, `${JSON.stringify(manifest)}\\n`, \"utf-8\");\n\t\t\t\tawait appendAuditEvent(\n\t\t\t\t\tpaths,\n\t\t\t\t\t{ event: \"lock_acquired\", ...(attempt > 0 ? { takeover: true } : {}) },\n\t\t\t\t\tnow(),\n\t\t\t\t);\n\t\t\t\treturn { acquired: true, takeover: attempt > 0, token };\n\t\t\t}\n\n\t\t\tconst holder = await readLockOwner(paths);\n\t\t\tif (holder) {\n\t\t\t\tif (isPidAlive(holder)) return { acquired: false, holder, holderAlive: true };\n\t\t\t} else {\n\t\t\t\t// Ownerless dir: a crash between mkdir and the owner write. Only stale ones are dead.\n\t\t\t\tlet dirMtimeMs: number | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tdirMtimeMs = (await fsPromises.stat(paths.lockDir)).mtimeMs;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (nowMs() - dirMtimeMs < OWNERLESS_LOCK_STALE_MS) return { acquired: false, holderAlive: true };\n\t\t\t}\n\n\t\t\t// Metadata serialization makes the stale observation and directory removal one guarded\n\t\t\t// operation; a successor cannot be removed by a stale observer.\n\t\t\tawait fsPromises.rm(paths.lockDir, { recursive: true, force: true });\n\t\t\tawait appendAuditEvent(\n\t\t\t\tpaths,\n\t\t\t\t{\n\t\t\t\t\tevent: \"lock_takeover\",\n\t\t\t\t\t...(holder ? { deadOwnerPid: holder.pid, deadOwnerLaneKey: holder.laneKey } : {}),\n\t\t\t\t},\n\t\t\t\tnow(),\n\t\t\t);\n\t\t}\n\t\tconst holder = await readLockOwner(paths);\n\t\treturn { acquired: false, holder, holderAlive: holder ? isPidAlive(holder) : true };\n\t});\n}\n\nexport async function releaseIntegrationLock(\n\tpaths: SyncStorePaths,\n\ttoken: string,\n\tdeps: IntegrationLockDeps = {},\n): Promise<boolean> {\n\treturn withFileLock(paths.lockGuardFile, async () => {\n\t\tconst now = deps.now ?? (() => new Date().toISOString());\n\t\tconst holder = await readLockOwner(paths);\n\t\tif (!holder || holder.token !== token) return false;\n\t\tawait fsPromises.rm(paths.lockDir, { recursive: true, force: true });\n\t\tawait appendAuditEvent(paths, { event: \"lock_released\" }, now());\n\t\treturn true;\n\t});\n}\n\nexport async function readLockHolder(paths: SyncStorePaths): Promise<IntegrationLockOwner | undefined> {\n\treturn readLockOwner(paths);\n}\n"]}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Epoch watcher for lane-bound sessions: the prompt-awareness half of "perfect sync". Watches
3
+ * the shared `epoch.json` (fs.watch on its directory -- the file is replaced by rename) and, on
4
+ * an epoch advance by ANOTHER lane, injects one deterministic staleness notice through the host's
5
+ * message seam. Enforcement never rides on this watcher -- the lane gate (G8) and the land CAS
6
+ * (G3) fail closed even if it dies; this only makes lanes learn promptly instead of at their
7
+ * next tool call.
8
+ */
9
+ import type { WorktreeSyncEpoch } from "./codes.ts";
10
+ export interface EpochWatcherConfig {
11
+ epochFile: string;
12
+ /** The lane this session is bound to: lands BY this lane never notify it. */
13
+ laneKey: string;
14
+ notify: (text: string) => void;
15
+ /** Debounce for rename/change event bursts. */
16
+ debounceMs?: number;
17
+ }
18
+ export interface EpochWatcherHandle {
19
+ stop(): void;
20
+ }
21
+ /** Deterministic notice text -- assembled from epoch facts, never model-generated. */
22
+ export declare function formatEpochNotice(epoch: WorktreeSyncEpoch, laneKey: string): string;
23
+ /**
24
+ * Start watching. The initial epoch is read once as the baseline; only ADVANCES past it notify
25
+ * (a fresh session never gets a notice for history). fs.watch is backed by a low-frequency
26
+ * poll re-read on each event burst only -- no timers run while the store is quiet.
27
+ */
28
+ export declare function startEpochWatcher(config: EpochWatcherConfig): EpochWatcherHandle;
29
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../src/core/worktree-sync/watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,IAAI,IAAI,CAAC;CACb;AAUD,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAYnF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAsDhF","sourcesContent":["/**\n * Epoch watcher for lane-bound sessions: the prompt-awareness half of \"perfect sync\". Watches\n * the shared `epoch.json` (fs.watch on its directory -- the file is replaced by rename) and, on\n * an epoch advance by ANOTHER lane, injects one deterministic staleness notice through the host's\n * message seam. Enforcement never rides on this watcher -- the lane gate (G8) and the land CAS\n * (G3) fail closed even if it dies; this only makes lanes learn promptly instead of at their\n * next tool call.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname } from \"node:path\";\nimport { watchWithErrorHandler } from \"../../utils/fs-watch.ts\";\nimport type { WorktreeSyncEpoch } from \"./codes.ts\";\n\nexport interface EpochWatcherConfig {\n\tepochFile: string;\n\t/** The lane this session is bound to: lands BY this lane never notify it. */\n\tlaneKey: string;\n\tnotify: (text: string) => void;\n\t/** Debounce for rename/change event bursts. */\n\tdebounceMs?: number;\n}\n\nexport interface EpochWatcherHandle {\n\tstop(): void;\n}\n\nasync function readEpochFile(epochFile: string): Promise<WorktreeSyncEpoch | undefined> {\n\ttry {\n\t\treturn JSON.parse(await readFile(epochFile, \"utf-8\")) as WorktreeSyncEpoch;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Deterministic notice text -- assembled from epoch facts, never model-generated. */\nexport function formatEpochNotice(epoch: WorktreeSyncEpoch, laneKey: string): string {\n\tconst changed =\n\t\tepoch.changedPaths.length > 0\n\t\t\t? `${epoch.changedPaths.slice(0, 10).join(\", \")}${epoch.changedPaths.length > 10 || epoch.changedPathsTruncated ? \", ...\" : \"\"}`\n\t\t\t: \"(no files listed)\";\n\treturn [\n\t\t`worktree-sync: main advanced to epoch ${epoch.epoch}`,\n\t\t`${epoch.landedLaneKey ? ` (landed by lane '${epoch.landedLaneKey}')` : \"\"}.`,\n\t\t` Changed: ${changed}.`,\n\t\t` Your lane '${laneKey}' must rebase main before further mutations/landing:`,\n\t\t` call worktree_sync {\"action\":\"sync\"} now, resolve any conflicts locally, then continue working.`,\n\t].join(\"\");\n}\n\n/**\n * Start watching. The initial epoch is read once as the baseline; only ADVANCES past it notify\n * (a fresh session never gets a notice for history). fs.watch is backed by a low-frequency\n * poll re-read on each event burst only -- no timers run while the store is quiet.\n */\nexport function startEpochWatcher(config: EpochWatcherConfig): EpochWatcherHandle {\n\tconst debounceMs = config.debounceMs ?? 250;\n\tlet lastSeenEpoch: number | undefined;\n\tlet debounceTimer: NodeJS.Timeout | undefined;\n\tlet stopped = false;\n\n\tconst evaluate = async (): Promise<void> => {\n\t\tif (stopped) return;\n\t\tconst epoch = await readEpochFile(config.epochFile);\n\t\tif (!epoch) return;\n\t\tif (lastSeenEpoch === undefined) {\n\t\t\tlastSeenEpoch = epoch.epoch;\n\t\t\treturn;\n\t\t}\n\t\tif (epoch.epoch <= lastSeenEpoch) return;\n\t\tlastSeenEpoch = epoch.epoch;\n\t\tif (epoch.landedLaneKey === config.laneKey) return;\n\t\tconfig.notify(formatEpochNotice(epoch, config.laneKey));\n\t};\n\n\t// Baseline read; any event after this compares against it.\n\tvoid evaluate();\n\n\tconst fileName = basename(config.epochFile);\n\t// watchWithErrorHandler canonicalizes the watched dir (realpathSync.native) before calling\n\t// fs.watch -- on Windows, a non-canonical (e.g. 8.3 short-form) path here hard-aborts the\n\t// process via libuv's fs-event assertion. It also attaches an 'error' listener so an async\n\t// watcher failure (EMFILE, dir removed, etc.) can never surface as an unhandled exception.\n\tconst watcher = watchWithErrorHandler(\n\t\tdirname(config.epochFile),\n\t\t(_eventType, changedName) => {\n\t\t\tif (stopped) return;\n\t\t\tif (changedName !== null && changedName !== fileName && changedName !== `${fileName}.tmp`) return;\n\t\t\tif (debounceTimer) clearTimeout(debounceTimer);\n\t\t\tdebounceTimer = setTimeout(() => {\n\t\t\t\tvoid evaluate();\n\t\t\t}, debounceMs);\n\t\t\tdebounceTimer.unref?.();\n\t\t},\n\t\t() => {\n\t\t\t// The store dir may not exist yet, or the watcher died after creation (EMFILE, dir\n\t\t\t// removed, etc). The lane gate (G8) and land CAS (G3) still fail closed at the next\n\t\t\t// tool call regardless -- this watcher is a promptness optimization only, so on error\n\t\t\t// we simply stop watching rather than retry; correctness never depended on it.\n\t\t},\n\t);\n\n\treturn {\n\t\tstop() {\n\t\t\tstopped = true;\n\t\t\tif (debounceTimer) clearTimeout(debounceTimer);\n\t\t\twatcher?.close();\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Epoch watcher for lane-bound sessions: the prompt-awareness half of "perfect sync". Watches
3
+ * the shared `epoch.json` (fs.watch on its directory -- the file is replaced by rename) and, on
4
+ * an epoch advance by ANOTHER lane, injects one deterministic staleness notice through the host's
5
+ * message seam. Enforcement never rides on this watcher -- the lane gate (G8) and the land CAS
6
+ * (G3) fail closed even if it dies; this only makes lanes learn promptly instead of at their
7
+ * next tool call.
8
+ */
9
+ import { readFile } from "node:fs/promises";
10
+ import { basename, dirname } from "node:path";
11
+ import { watchWithErrorHandler } from "../../utils/fs-watch.js";
12
+ async function readEpochFile(epochFile) {
13
+ try {
14
+ return JSON.parse(await readFile(epochFile, "utf-8"));
15
+ }
16
+ catch {
17
+ return undefined;
18
+ }
19
+ }
20
+ /** Deterministic notice text -- assembled from epoch facts, never model-generated. */
21
+ export function formatEpochNotice(epoch, laneKey) {
22
+ const changed = epoch.changedPaths.length > 0
23
+ ? `${epoch.changedPaths.slice(0, 10).join(", ")}${epoch.changedPaths.length > 10 || epoch.changedPathsTruncated ? ", ..." : ""}`
24
+ : "(no files listed)";
25
+ return [
26
+ `worktree-sync: main advanced to epoch ${epoch.epoch}`,
27
+ `${epoch.landedLaneKey ? ` (landed by lane '${epoch.landedLaneKey}')` : ""}.`,
28
+ ` Changed: ${changed}.`,
29
+ ` Your lane '${laneKey}' must rebase main before further mutations/landing:`,
30
+ ` call worktree_sync {"action":"sync"} now, resolve any conflicts locally, then continue working.`,
31
+ ].join("");
32
+ }
33
+ /**
34
+ * Start watching. The initial epoch is read once as the baseline; only ADVANCES past it notify
35
+ * (a fresh session never gets a notice for history). fs.watch is backed by a low-frequency
36
+ * poll re-read on each event burst only -- no timers run while the store is quiet.
37
+ */
38
+ export function startEpochWatcher(config) {
39
+ const debounceMs = config.debounceMs ?? 250;
40
+ let lastSeenEpoch;
41
+ let debounceTimer;
42
+ let stopped = false;
43
+ const evaluate = async () => {
44
+ if (stopped)
45
+ return;
46
+ const epoch = await readEpochFile(config.epochFile);
47
+ if (!epoch)
48
+ return;
49
+ if (lastSeenEpoch === undefined) {
50
+ lastSeenEpoch = epoch.epoch;
51
+ return;
52
+ }
53
+ if (epoch.epoch <= lastSeenEpoch)
54
+ return;
55
+ lastSeenEpoch = epoch.epoch;
56
+ if (epoch.landedLaneKey === config.laneKey)
57
+ return;
58
+ config.notify(formatEpochNotice(epoch, config.laneKey));
59
+ };
60
+ // Baseline read; any event after this compares against it.
61
+ void evaluate();
62
+ const fileName = basename(config.epochFile);
63
+ // watchWithErrorHandler canonicalizes the watched dir (realpathSync.native) before calling
64
+ // fs.watch -- on Windows, a non-canonical (e.g. 8.3 short-form) path here hard-aborts the
65
+ // process via libuv's fs-event assertion. It also attaches an 'error' listener so an async
66
+ // watcher failure (EMFILE, dir removed, etc.) can never surface as an unhandled exception.
67
+ const watcher = watchWithErrorHandler(dirname(config.epochFile), (_eventType, changedName) => {
68
+ if (stopped)
69
+ return;
70
+ if (changedName !== null && changedName !== fileName && changedName !== `${fileName}.tmp`)
71
+ return;
72
+ if (debounceTimer)
73
+ clearTimeout(debounceTimer);
74
+ debounceTimer = setTimeout(() => {
75
+ void evaluate();
76
+ }, debounceMs);
77
+ debounceTimer.unref?.();
78
+ }, () => {
79
+ // The store dir may not exist yet, or the watcher died after creation (EMFILE, dir
80
+ // removed, etc). The lane gate (G8) and land CAS (G3) still fail closed at the next
81
+ // tool call regardless -- this watcher is a promptness optimization only, so on error
82
+ // we simply stop watching rather than retry; correctness never depended on it.
83
+ });
84
+ return {
85
+ stop() {
86
+ stopped = true;
87
+ if (debounceTimer)
88
+ clearTimeout(debounceTimer);
89
+ watcher?.close();
90
+ },
91
+ };
92
+ }
93
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/core/worktree-sync/watcher.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Epoch watcher for lane-bound sessions: the prompt-awareness half of \"perfect sync\". Watches\n * the shared `epoch.json` (fs.watch on its directory -- the file is replaced by rename) and, on\n * an epoch advance by ANOTHER lane, injects one deterministic staleness notice through the host's\n * message seam. Enforcement never rides on this watcher -- the lane gate (G8) and the land CAS\n * (G3) fail closed even if it dies; this only makes lanes learn promptly instead of at their\n * next tool call.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname } from \"node:path\";\nimport { watchWithErrorHandler } from \"../../utils/fs-watch.ts\";\nimport type { WorktreeSyncEpoch } from \"./codes.ts\";\n\nexport interface EpochWatcherConfig {\n\tepochFile: string;\n\t/** The lane this session is bound to: lands BY this lane never notify it. */\n\tlaneKey: string;\n\tnotify: (text: string) => void;\n\t/** Debounce for rename/change event bursts. */\n\tdebounceMs?: number;\n}\n\nexport interface EpochWatcherHandle {\n\tstop(): void;\n}\n\nasync function readEpochFile(epochFile: string): Promise<WorktreeSyncEpoch | undefined> {\n\ttry {\n\t\treturn JSON.parse(await readFile(epochFile, \"utf-8\")) as WorktreeSyncEpoch;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** Deterministic notice text -- assembled from epoch facts, never model-generated. */\nexport function formatEpochNotice(epoch: WorktreeSyncEpoch, laneKey: string): string {\n\tconst changed =\n\t\tepoch.changedPaths.length > 0\n\t\t\t? `${epoch.changedPaths.slice(0, 10).join(\", \")}${epoch.changedPaths.length > 10 || epoch.changedPathsTruncated ? \", ...\" : \"\"}`\n\t\t\t: \"(no files listed)\";\n\treturn [\n\t\t`worktree-sync: main advanced to epoch ${epoch.epoch}`,\n\t\t`${epoch.landedLaneKey ? ` (landed by lane '${epoch.landedLaneKey}')` : \"\"}.`,\n\t\t` Changed: ${changed}.`,\n\t\t` Your lane '${laneKey}' must rebase main before further mutations/landing:`,\n\t\t` call worktree_sync {\"action\":\"sync\"} now, resolve any conflicts locally, then continue working.`,\n\t].join(\"\");\n}\n\n/**\n * Start watching. The initial epoch is read once as the baseline; only ADVANCES past it notify\n * (a fresh session never gets a notice for history). fs.watch is backed by a low-frequency\n * poll re-read on each event burst only -- no timers run while the store is quiet.\n */\nexport function startEpochWatcher(config: EpochWatcherConfig): EpochWatcherHandle {\n\tconst debounceMs = config.debounceMs ?? 250;\n\tlet lastSeenEpoch: number | undefined;\n\tlet debounceTimer: NodeJS.Timeout | undefined;\n\tlet stopped = false;\n\n\tconst evaluate = async (): Promise<void> => {\n\t\tif (stopped) return;\n\t\tconst epoch = await readEpochFile(config.epochFile);\n\t\tif (!epoch) return;\n\t\tif (lastSeenEpoch === undefined) {\n\t\t\tlastSeenEpoch = epoch.epoch;\n\t\t\treturn;\n\t\t}\n\t\tif (epoch.epoch <= lastSeenEpoch) return;\n\t\tlastSeenEpoch = epoch.epoch;\n\t\tif (epoch.landedLaneKey === config.laneKey) return;\n\t\tconfig.notify(formatEpochNotice(epoch, config.laneKey));\n\t};\n\n\t// Baseline read; any event after this compares against it.\n\tvoid evaluate();\n\n\tconst fileName = basename(config.epochFile);\n\t// watchWithErrorHandler canonicalizes the watched dir (realpathSync.native) before calling\n\t// fs.watch -- on Windows, a non-canonical (e.g. 8.3 short-form) path here hard-aborts the\n\t// process via libuv's fs-event assertion. It also attaches an 'error' listener so an async\n\t// watcher failure (EMFILE, dir removed, etc.) can never surface as an unhandled exception.\n\tconst watcher = watchWithErrorHandler(\n\t\tdirname(config.epochFile),\n\t\t(_eventType, changedName) => {\n\t\t\tif (stopped) return;\n\t\t\tif (changedName !== null && changedName !== fileName && changedName !== `${fileName}.tmp`) return;\n\t\t\tif (debounceTimer) clearTimeout(debounceTimer);\n\t\t\tdebounceTimer = setTimeout(() => {\n\t\t\t\tvoid evaluate();\n\t\t\t}, debounceMs);\n\t\t\tdebounceTimer.unref?.();\n\t\t},\n\t\t() => {\n\t\t\t// The store dir may not exist yet, or the watcher died after creation (EMFILE, dir\n\t\t\t// removed, etc). The lane gate (G8) and land CAS (G3) still fail closed at the next\n\t\t\t// tool call regardless -- this watcher is a promptness optimization only, so on error\n\t\t\t// we simply stop watching rather than retry; correctness never depended on it.\n\t\t},\n\t);\n\n\treturn {\n\t\tstop() {\n\t\t\tstopped = true;\n\t\t\tif (debounceTimer) clearTimeout(debounceTimer);\n\t\t\twatcher?.close();\n\t\t},\n\t};\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -5,21 +5,31 @@ export { getAgentDir, VERSION } from "./config.ts";
5
5
  export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type AgentSessionEventListener, type ModelCycleResult, type ParsedSkillBlock, type PromptOptions, parseSkillBlock, type SessionStats, } from "./core/agent-session.ts";
6
6
  export { type ApiKeyCredential, type AuthCredential, type AuthStatus, AuthStorage, type AuthStorageBackend, FileAuthStorageBackend, InMemoryAuthStorageBackend, type OAuthCredential, } from "./core/auth-storage.ts";
7
7
  export { createEventBus, type EventBus, type EventBusController } from "./core/event-bus.ts";
8
- export type { AgentEndEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppKeybinding, AutocompleteProviderFactory, BashToolCallEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderRequestEvent, BeforeProviderRequestEventResult, BuildSystemPromptOptions, CompactOptions, ContextEvent, ContextUsage, CustomToolCallEvent, EditToolCallEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, GrepToolCallEvent, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, MessageRenderer, MessageRenderOptions, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, RegisteredCommand, RegisteredTool, ResolvedCommand, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent, SlashCommandInfo, SlashCommandSource, SourceInfo, TerminalInputHandler, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionMode, ToolInfo, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WorkingIndicatorOptions, WriteToolCallEvent, } from "./core/extensions/index.ts";
8
+ export type { AgentEndEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppKeybinding, AutocompleteProviderFactory, BashToolCallEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderRequestEvent, BeforeProviderRequestEventResult, BuildSystemPromptOptions, CompactOptions, ContextEvent, ContextUsage, CustomToolCallEvent, EditToolCallEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionStorage, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, ExtensionWorkRunOptions, FindToolCallEvent, GrepToolCallEvent, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, MessageRenderer, MessageRenderOptions, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, RegisteredCommand, RegisteredTool, ResolvedCommand, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent, SlashCommandInfo, SlashCommandSource, SourceInfo, TerminalInputHandler, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionMode, ToolInfo, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WorkingIndicatorOptions, WriteToolCallEvent, } from "./core/extensions/index.ts";
9
9
  export { createExtensionRuntime, defineTool, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, wrapRegisteredTool, wrapRegisteredTools, } from "./core/extensions/index.ts";
10
10
  export type { ReadonlyFooterDataProvider } from "./core/footer-data-provider.ts";
11
11
  export { appendRunRecord, type ConfidenceMode, type ConfidenceResult, cleanupImprovementSandbox, compareMetric, computeMadConfidence, createImprovementDecisionTool, createImprovementLoopTool, createImprovementSandbox, decideImprovement, exportImprovementSandboxPatch, type GitStatusEntry, type ImprovementDecision, type ImprovementDecisionInput, type ImprovementDecisionReason, type ImprovementDecisionResult, type ImprovementLoopConfig, type ImprovementLoopExec, type ImprovementLoopInitInput, type ImprovementLoopPaths, type ImprovementLoopRecordInput, type ImprovementLoopState, type ImprovementLoopStatusInput, type ImprovementLoopToolAction, type ImprovementLoopToolDetails, type ImprovementMeasurementCommandResult, type ImprovementMeasurementResult, type ImprovementRunRecord, type ImprovementSandboxCleanupInput, type ImprovementSandboxCreateInput, type ImprovementSandboxExportInput, type ImprovementSandboxRecord, improvementLoopPaths, initImprovementLoop, type LowConfidenceAction, type MetricComparison, type MetricDirection, median, medianAbsoluteDeviation, metricMapFromOutput, type OwnedDiscardPlan, type OwnedDiscardPlanInput, parseGitPorcelainStatus, parseMetricLines, planOwnedDiscard, readImprovementLoopState, readRunRecords, recordImprovementRun, runImprovementMeasurement, selectPrimaryMetric, serializeRunRecord, } from "./core/improvement-loop.ts";
12
12
  export { ModelRegistry } from "./core/model-registry.ts";
13
+ export * from "./core/orchestration/capability-gateway.ts";
14
+ export * from "./core/orchestration/contracts.ts";
15
+ export * from "./core/orchestration/event-store.ts";
16
+ export * from "./core/orchestration/model-binding.ts";
17
+ export * from "./core/orchestration/policy-compiler.ts";
18
+ export * from "./core/orchestration/profile-registry.ts";
19
+ export * from "./core/orchestration/profile-store.ts";
20
+ export * from "./core/orchestration/task-runtime.ts";
13
21
  export type { PackageManager, PathMetadata, ProgressCallback, ProgressEvent, ResolvedPaths, ResolvedResource, } from "./core/package-manager.ts";
14
22
  export { DefaultPackageManager } from "./core/package-manager.ts";
23
+ export { PI_ORCHESTRATION_AGENT_ID_ENV } from "./core/process-identity.ts";
15
24
  export { ACTIVE_TURN_TTL_MS, AUTO_RELOAD_COORDINATOR_TTL_MS, describeReloadSession, getPendingReloadBlockers, getReloadCoordinationDir, isReloadSessionProcessAlive, type PendingReloadBlockers, type ReloadBlockerOptions, type ReloadSessionRecord, } from "./core/reload-blockers.ts";
16
25
  export type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from "./core/resource-loader.ts";
17
26
  export { DefaultResourceLoader, loadProjectContextFiles } from "./core/resource-loader.ts";
18
27
  export { mergeResourceProfileMap, mergeResourceProfileSettings, parseResourceProfileBlocks, parseResourceProfileInput, parseResourceProfileJson, stripResourceProfileBlocks, } from "./core/resource-profile-blocks.ts";
19
- export { AgentSessionRuntime, type AgentSessionRuntimeDiagnostic, type AgentSessionServices, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionOptions, type CreateAgentSessionResult, type CreateAgentSessionRuntimeFactory, type CreateAgentSessionRuntimeResult, type CreateAgentSessionServicesOptions, createAgentSession, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, type PromptTemplate, } from "./core/sdk.ts";
28
+ export { AgentSessionRuntime, type AgentSessionRuntimeDiagnostic, type AgentSessionRuntimeResource, type AgentSessionServices, type AgentSessionSwitchOptions, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionOptions, type CreateAgentSessionResult, type CreateAgentSessionRuntimeFactory, type CreateAgentSessionRuntimeResult, type CreateAgentSessionServicesOptions, createAgentSession, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, type PromptTemplate, SessionReplacementCallbackError, SessionReplacementRuntimeError, } from "./core/sdk.ts";
20
29
  export { type CompactionSettings, type DirectoryResourceProfileInfo, getDirectoryResourceProfileInfo, type ImageSettings, matchesResourceProfilePattern, type PackageSource, type ResourceProfileFilterSettings, type ResourceProfileKind, type ResourceProfileSettings, type RetrySettings, SettingsManager, type SettingsManagerCreateOptions, } from "./core/settings-manager.ts";
21
30
  export { formatSkillsForPrompt, type LoadSkillsFromDirOptions, type LoadSkillsResult, loadSkills, loadSkillsFromDir, type Skill, type SkillFrontmatter, } from "./core/skills.ts";
22
31
  export { createSyntheticSourceInfo } from "./core/source-info.ts";
32
+ export { type AskQuestion, type AskQuestionAnswer, AskQuestionDialog, type AskQuestionStopReason, type AskQuestionToolDetails, type AskQuestionToolInput, type AskQuestionToolOptions, createAskQuestionToolDefinition, } from "./core/tools/ask-question.ts";
23
33
  export { type BashOperations, type BashSpawnContext, type BashSpawnHook, type BashToolDetails, type BashToolInput, type BashToolOptions, createBashToolDefinition, createEditToolDefinition, createFindToolDefinition, createGrepToolDefinition, createLocalBashOperations, createLsToolDefinition, createReadToolDefinition, createWriteToolDefinition, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type EditOperations, type EditToolDetails, type EditToolInput, type EditToolOptions, type FindOperations, type FindToolDetails, type FindToolInput, type FindToolOptions, formatSize, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, type ReadOperations, type ReadToolDetails, type ReadToolInput, type ReadToolOptions, type ToolsOptions, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, type WriteOperations, type WriteToolInput, type WriteToolOptions, withFileMutationQueue, } from "./core/tools/index.ts";
24
34
  export { jaccard, runSkillAudit, type SkillAuditReport, type SkillSummary, tokenize, } from "./core/tools/skill-audit.ts";
25
35
  export { hasProjectTrustInputs, type ProjectTrustDecision, ProjectTrustStore } from "./core/trust-manager.ts";
@@ -32,5 +42,5 @@ export { parseFrontmatter, stripFrontmatter } from "./utils/frontmatter.ts";
32
42
  export { convertToPng } from "./utils/image-convert.ts";
33
43
  export { formatDimensionNote, type ResizedImage, resizeImage } from "./utils/image-resize.ts";
34
44
  export { getShellConfig } from "./utils/shell.ts";
35
- export { type AcquireWorkRunOptions, acquireWorkRun, createWorkRunId, getProcessWorkRun, getWorkRoot, getWorkRunDir, getWorkTenantDir, PI_WORK_ROOT_ENV, pruneWorkTenant, type WorkRetentionOptions, type WorkRunLease, } from "./utils/work-directory.ts";
45
+ export { type AcquireWorkRunOptions, acquireWorkRun, assertPortablePathSegment, boundedWorkRetention, createWorkRunId, getProcessWorkRun, getWorkRoot, getWorkRunDir, getWorkTenantDir, PI_WORK_ROOT_ENV, pruneWorkTenant, type WorkRetentionOptions, type WorkRunLease, } from "./utils/work-directory.ts";
36
46
  //# sourceMappingURL=index.d.ts.map