@telora/daemon 0.22.104 → 0.22.132

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 (482) hide show
  1. package/build-info.json +4 -3
  2. package/dist/completion/commit-verdict-release.d.ts +49 -0
  3. package/dist/completion/commit-verdict-release.d.ts.map +1 -0
  4. package/dist/completion/commit-verdict-release.js +240 -0
  5. package/dist/completion/commit-verdict-release.js.map +1 -0
  6. package/dist/completion/completion-phase-registry.d.ts +10 -4
  7. package/dist/completion/completion-phase-registry.d.ts.map +1 -1
  8. package/dist/completion/completion-phase-registry.js +19 -7
  9. package/dist/completion/completion-phase-registry.js.map +1 -1
  10. package/dist/completion/detector.d.ts.map +1 -1
  11. package/dist/completion/detector.js +1 -0
  12. package/dist/completion/detector.js.map +1 -1
  13. package/dist/completion/event-entry-phases.d.ts +6 -3
  14. package/dist/completion/event-entry-phases.d.ts.map +1 -1
  15. package/dist/completion/event-entry-phases.js +135 -76
  16. package/dist/completion/event-entry-phases.js.map +1 -1
  17. package/dist/completion/event-phases.d.ts +24 -3
  18. package/dist/completion/event-phases.d.ts.map +1 -1
  19. package/dist/completion/event-phases.js +9 -9
  20. package/dist/completion/event-phases.js.map +1 -1
  21. package/dist/completion/event.d.ts +8 -0
  22. package/dist/completion/event.d.ts.map +1 -1
  23. package/dist/completion/event.js +47 -21
  24. package/dist/completion/event.js.map +1 -1
  25. package/dist/completion/exit-classification.d.ts.map +1 -1
  26. package/dist/completion/exit-classification.js +1 -0
  27. package/dist/completion/exit-classification.js.map +1 -1
  28. package/dist/completion/merge-phase.d.ts +21 -9
  29. package/dist/completion/merge-phase.d.ts.map +1 -1
  30. package/dist/completion/merge-phase.js +35 -10
  31. package/dist/completion/merge-phase.js.map +1 -1
  32. package/dist/completion/review-auto-approval-record.d.ts +19 -0
  33. package/dist/completion/review-auto-approval-record.d.ts.map +1 -0
  34. package/dist/completion/review-auto-approval-record.js +102 -0
  35. package/dist/completion/review-auto-approval-record.js.map +1 -0
  36. package/dist/completion/review-cycle-cap.d.ts +62 -0
  37. package/dist/completion/review-cycle-cap.d.ts.map +1 -0
  38. package/dist/completion/review-cycle-cap.js +180 -0
  39. package/dist/completion/review-cycle-cap.js.map +1 -0
  40. package/dist/completion/review-exit-deps.d.ts +17 -2
  41. package/dist/completion/review-exit-deps.d.ts.map +1 -1
  42. package/dist/completion/review-exit-deps.js +19 -2
  43. package/dist/completion/review-exit-deps.js.map +1 -1
  44. package/dist/completion/review-exit-escalations.d.ts +45 -23
  45. package/dist/completion/review-exit-escalations.d.ts.map +1 -1
  46. package/dist/completion/review-exit-escalations.js +15 -74
  47. package/dist/completion/review-exit-escalations.js.map +1 -1
  48. package/dist/completion/review-exit-evidence.d.ts +9 -0
  49. package/dist/completion/review-exit-evidence.d.ts.map +1 -1
  50. package/dist/completion/review-exit-evidence.js +4 -1
  51. package/dist/completion/review-exit-evidence.js.map +1 -1
  52. package/dist/completion/review-exit-foreign-findings.d.ts +151 -0
  53. package/dist/completion/review-exit-foreign-findings.d.ts.map +1 -0
  54. package/dist/completion/review-exit-foreign-findings.js +474 -0
  55. package/dist/completion/review-exit-foreign-findings.js.map +1 -0
  56. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  57. package/dist/completion/review-exit-phase.js +71 -64
  58. package/dist/completion/review-exit-phase.js.map +1 -1
  59. package/dist/completion/review-exit-progress.d.ts +20 -0
  60. package/dist/completion/review-exit-progress.d.ts.map +1 -1
  61. package/dist/completion/review-exit-progress.js +28 -19
  62. package/dist/completion/review-exit-progress.js.map +1 -1
  63. package/dist/completion/review-exit-rehoming.d.ts +5 -0
  64. package/dist/completion/review-exit-rehoming.d.ts.map +1 -1
  65. package/dist/completion/review-exit-rehoming.js.map +1 -1
  66. package/dist/completion/review-exit-verdict-gate.d.ts +202 -0
  67. package/dist/completion/review-exit-verdict-gate.d.ts.map +1 -0
  68. package/dist/completion/review-exit-verdict-gate.js +228 -0
  69. package/dist/completion/review-exit-verdict-gate.js.map +1 -0
  70. package/dist/completion/review-next-step.d.ts +62 -0
  71. package/dist/completion/review-next-step.d.ts.map +1 -0
  72. package/dist/completion/review-next-step.js +63 -0
  73. package/dist/completion/review-next-step.js.map +1 -0
  74. package/dist/completion/session-hold-sweep-deps.d.ts +17 -0
  75. package/dist/completion/session-hold-sweep-deps.d.ts.map +1 -0
  76. package/dist/completion/session-hold-sweep-deps.js +89 -0
  77. package/dist/completion/session-hold-sweep-deps.js.map +1 -0
  78. package/dist/completion/session-hold.d.ts +180 -0
  79. package/dist/completion/session-hold.d.ts.map +1 -0
  80. package/dist/completion/session-hold.js +238 -0
  81. package/dist/completion/session-hold.js.map +1 -0
  82. package/dist/completion/state-cascade.d.ts +19 -0
  83. package/dist/completion/state-cascade.d.ts.map +1 -1
  84. package/dist/completion/state-cascade.js +85 -31
  85. package/dist/completion/state-cascade.js.map +1 -1
  86. package/dist/completion/team-lifecycle.d.ts +35 -2
  87. package/dist/completion/team-lifecycle.d.ts.map +1 -1
  88. package/dist/completion/team-lifecycle.js +165 -94
  89. package/dist/completion/team-lifecycle.js.map +1 -1
  90. package/dist/completion/team-phase.d.ts +27 -15
  91. package/dist/completion/team-phase.d.ts.map +1 -1
  92. package/dist/completion/team-phase.js +34 -15
  93. package/dist/completion/team-phase.js.map +1 -1
  94. package/dist/delivery/commit-verdict-hold.d.ts +55 -0
  95. package/dist/delivery/commit-verdict-hold.d.ts.map +1 -0
  96. package/dist/delivery/commit-verdict-hold.js +118 -0
  97. package/dist/delivery/commit-verdict-hold.js.map +1 -0
  98. package/dist/directive/directive-dispatch.d.ts.map +1 -1
  99. package/dist/directive/directive-dispatch.js +10 -3
  100. package/dist/directive/directive-dispatch.js.map +1 -1
  101. package/dist/directive/directive-executor.d.ts.map +1 -1
  102. package/dist/directive/directive-executor.js +1 -0
  103. package/dist/directive/directive-executor.js.map +1 -1
  104. package/dist/directive/directive-queue.d.ts.map +1 -1
  105. package/dist/directive/directive-queue.js +6 -1
  106. package/dist/directive/directive-queue.js.map +1 -1
  107. package/dist/directive/phase-sync.d.ts +29 -2
  108. package/dist/directive/phase-sync.d.ts.map +1 -1
  109. package/dist/directive/phase-sync.js +30 -6
  110. package/dist/directive/phase-sync.js.map +1 -1
  111. package/dist/drift/artifact-ref-shape.d.ts +34 -0
  112. package/dist/drift/artifact-ref-shape.d.ts.map +1 -0
  113. package/dist/drift/artifact-ref-shape.js +94 -0
  114. package/dist/drift/artifact-ref-shape.js.map +1 -0
  115. package/dist/drift/drift-eval-loop.d.ts +7 -0
  116. package/dist/drift/drift-eval-loop.d.ts.map +1 -1
  117. package/dist/drift/drift-eval-loop.js +34 -5
  118. package/dist/drift/drift-eval-loop.js.map +1 -1
  119. package/dist/drift/drift-evaluator.d.ts.map +1 -1
  120. package/dist/drift/drift-evaluator.js +8 -3
  121. package/dist/drift/drift-evaluator.js.map +1 -1
  122. package/dist/focus/awaiting-slot.d.ts +34 -0
  123. package/dist/focus/awaiting-slot.d.ts.map +1 -0
  124. package/dist/focus/awaiting-slot.js +26 -0
  125. package/dist/focus/awaiting-slot.js.map +1 -0
  126. package/dist/focus/focus-lifecycle.js +2 -2
  127. package/dist/focus/focus-lifecycle.js.map +1 -1
  128. package/dist/focus/focus-phase.d.ts.map +1 -1
  129. package/dist/focus/focus-phase.js +3 -1
  130. package/dist/focus/focus-phase.js.map +1 -1
  131. package/dist/focus/focus-spawn-decision.d.ts +62 -0
  132. package/dist/focus/focus-spawn-decision.d.ts.map +1 -0
  133. package/dist/focus/focus-spawn-decision.js +41 -0
  134. package/dist/focus/focus-spawn-decision.js.map +1 -0
  135. package/dist/focus/focus-team-state.d.ts.map +1 -1
  136. package/dist/focus/focus-team-state.js +1 -13
  137. package/dist/focus/focus-team-state.js.map +1 -1
  138. package/dist/focus/listener-spawn.d.ts +16 -55
  139. package/dist/focus/listener-spawn.d.ts.map +1 -1
  140. package/dist/focus/listener-spawn.js +102 -64
  141. package/dist/focus/listener-spawn.js.map +1 -1
  142. package/dist/focus/listener-state.d.ts.map +1 -1
  143. package/dist/focus/listener-state.js +4 -1
  144. package/dist/focus/listener-state.js.map +1 -1
  145. package/dist/focus/listener.d.ts +41 -2
  146. package/dist/focus/listener.d.ts.map +1 -1
  147. package/dist/focus/listener.js +135 -83
  148. package/dist/focus/listener.js.map +1 -1
  149. package/dist/focus/pending-spawn-pass-deps.d.ts +69 -0
  150. package/dist/focus/pending-spawn-pass-deps.d.ts.map +1 -0
  151. package/dist/focus/pending-spawn-pass-deps.js +34 -0
  152. package/dist/focus/pending-spawn-pass-deps.js.map +1 -0
  153. package/dist/focus/pending-spawn-review-next-step.d.ts +83 -0
  154. package/dist/focus/pending-spawn-review-next-step.d.ts.map +1 -0
  155. package/dist/focus/pending-spawn-review-next-step.js +325 -0
  156. package/dist/focus/pending-spawn-review-next-step.js.map +1 -0
  157. package/dist/focus/review-cycle-cap-hold.d.ts +132 -0
  158. package/dist/focus/review-cycle-cap-hold.d.ts.map +1 -0
  159. package/dist/focus/review-cycle-cap-hold.js +178 -0
  160. package/dist/focus/review-cycle-cap-hold.js.map +1 -0
  161. package/dist/focus/team-actionable-work.js +2 -2
  162. package/dist/focus/verify-open-issues.d.ts +22 -0
  163. package/dist/focus/verify-open-issues.d.ts.map +1 -1
  164. package/dist/focus/verify-open-issues.js +118 -57
  165. package/dist/focus/verify-open-issues.js.map +1 -1
  166. package/dist/focus/verify-routing-passes.d.ts +32 -0
  167. package/dist/focus/verify-routing-passes.d.ts.map +1 -0
  168. package/dist/focus/verify-routing-passes.js +18 -0
  169. package/dist/focus/verify-routing-passes.js.map +1 -0
  170. package/dist/git/index.d.ts.map +1 -1
  171. package/dist/git/index.js +9 -5
  172. package/dist/git/index.js.map +1 -1
  173. package/dist/merge/focus-merge.d.ts +16 -2
  174. package/dist/merge/focus-merge.d.ts.map +1 -1
  175. package/dist/merge/focus-merge.js +53 -30
  176. package/dist/merge/focus-merge.js.map +1 -1
  177. package/dist/merge/merge-back-loop.d.ts +5 -0
  178. package/dist/merge/merge-back-loop.d.ts.map +1 -1
  179. package/dist/merge/merge-back-loop.js +17 -8
  180. package/dist/merge/merge-back-loop.js.map +1 -1
  181. package/dist/merge/merge-gate-coverage.d.ts +94 -0
  182. package/dist/merge/merge-gate-coverage.d.ts.map +1 -0
  183. package/dist/merge/merge-gate-coverage.js +217 -0
  184. package/dist/merge/merge-gate-coverage.js.map +1 -0
  185. package/dist/prompt/focus-prompt-builder.d.ts.map +1 -1
  186. package/dist/prompt/focus-prompt-builder.js +6 -0
  187. package/dist/prompt/focus-prompt-builder.js.map +1 -1
  188. package/dist/prompt/prompt-listing.d.ts.map +1 -1
  189. package/dist/prompt/prompt-listing.js +8 -0
  190. package/dist/prompt/prompt-listing.js.map +1 -1
  191. package/dist/prompt/team-prompt-base.d.ts.map +1 -1
  192. package/dist/prompt/team-prompt-base.js +5 -1
  193. package/dist/prompt/team-prompt-base.js.map +1 -1
  194. package/dist/prompt-sections/execution-sections.d.ts.map +1 -1
  195. package/dist/prompt-sections/execution-sections.js +14 -39
  196. package/dist/prompt-sections/execution-sections.js.map +1 -1
  197. package/dist/prompt-sections/gate-ownership.d.ts +36 -0
  198. package/dist/prompt-sections/gate-ownership.d.ts.map +1 -0
  199. package/dist/prompt-sections/gate-ownership.js +68 -0
  200. package/dist/prompt-sections/gate-ownership.js.map +1 -0
  201. package/dist/prompt-sections/gate-verdict-section.d.ts +58 -0
  202. package/dist/prompt-sections/gate-verdict-section.d.ts.map +1 -0
  203. package/dist/prompt-sections/gate-verdict-section.js +88 -0
  204. package/dist/prompt-sections/gate-verdict-section.js.map +1 -0
  205. package/dist/prompt-sections/persona-sections.d.ts +10 -0
  206. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  207. package/dist/prompt-sections/persona-sections.js +35 -11
  208. package/dist/prompt-sections/persona-sections.js.map +1 -1
  209. package/dist/prompt-sections/shared.js +1 -1
  210. package/dist/prompt-sections/shared.js.map +1 -1
  211. package/dist/queries/agent-resolvable-promotion.d.ts +6 -3
  212. package/dist/queries/agent-resolvable-promotion.d.ts.map +1 -1
  213. package/dist/queries/agent-resolvable-promotion.js +20 -9
  214. package/dist/queries/agent-resolvable-promotion.js.map +1 -1
  215. package/dist/queries/deliveries.d.ts +46 -4
  216. package/dist/queries/deliveries.d.ts.map +1 -1
  217. package/dist/queries/deliveries.js +69 -16
  218. package/dist/queries/deliveries.js.map +1 -1
  219. package/dist/queries/delivery-gate-state.d.ts +151 -1
  220. package/dist/queries/delivery-gate-state.d.ts.map +1 -1
  221. package/dist/queries/delivery-gate-state.js +95 -14
  222. package/dist/queries/delivery-gate-state.js.map +1 -1
  223. package/dist/queries/delivery-write-discipline.d.ts +65 -0
  224. package/dist/queries/delivery-write-discipline.d.ts.map +1 -0
  225. package/dist/queries/delivery-write-discipline.js +101 -0
  226. package/dist/queries/delivery-write-discipline.js.map +1 -0
  227. package/dist/queries/escalation-consumption.d.ts +11 -0
  228. package/dist/queries/escalation-consumption.d.ts.map +1 -1
  229. package/dist/queries/escalation-consumption.js +22 -0
  230. package/dist/queries/escalation-consumption.js.map +1 -1
  231. package/dist/queries/escalation-spool.d.ts +75 -0
  232. package/dist/queries/escalation-spool.d.ts.map +1 -0
  233. package/dist/queries/escalation-spool.js +232 -0
  234. package/dist/queries/escalation-spool.js.map +1 -0
  235. package/dist/queries/escalation-suppression.d.ts.map +1 -1
  236. package/dist/queries/escalation-suppression.js +2 -0
  237. package/dist/queries/escalation-suppression.js.map +1 -1
  238. package/dist/queries/escalations.js +1 -1
  239. package/dist/queries/filing-observation.d.ts.map +1 -1
  240. package/dist/queries/filing-observation.js +2 -0
  241. package/dist/queries/filing-observation.js.map +1 -1
  242. package/dist/queries/focus-discovery.d.ts +4 -4
  243. package/dist/queries/focus-discovery.d.ts.map +1 -1
  244. package/dist/queries/focus-discovery.js +1 -0
  245. package/dist/queries/focus-discovery.js.map +1 -1
  246. package/dist/queries/focus-review-approval.d.ts +84 -0
  247. package/dist/queries/focus-review-approval.d.ts.map +1 -0
  248. package/dist/queries/focus-review-approval.js +158 -0
  249. package/dist/queries/focus-review-approval.js.map +1 -0
  250. package/dist/queries/focuses.d.ts +6 -5
  251. package/dist/queries/focuses.d.ts.map +1 -1
  252. package/dist/queries/focuses.js +9 -5
  253. package/dist/queries/focuses.js.map +1 -1
  254. package/dist/queries/incident-correlation.d.ts +5 -4
  255. package/dist/queries/incident-correlation.d.ts.map +1 -1
  256. package/dist/queries/incident-correlation.js +11 -5
  257. package/dist/queries/incident-correlation.js.map +1 -1
  258. package/dist/queries/issues.d.ts.map +1 -1
  259. package/dist/queries/issues.js +2 -1
  260. package/dist/queries/issues.js.map +1 -1
  261. package/dist/queries/loop-refusal-observation.d.ts +64 -0
  262. package/dist/queries/loop-refusal-observation.d.ts.map +1 -0
  263. package/dist/queries/loop-refusal-observation.js +137 -0
  264. package/dist/queries/loop-refusal-observation.js.map +1 -0
  265. package/dist/queries/schemas.d.ts +9 -0
  266. package/dist/queries/schemas.d.ts.map +1 -1
  267. package/dist/queries/schemas.js +11 -3
  268. package/dist/queries/schemas.js.map +1 -1
  269. package/dist/queries/shared.js +1 -1
  270. package/dist/queries/verification.d.ts.map +1 -1
  271. package/dist/queries/verification.js +1 -15
  272. package/dist/queries/verification.js.map +1 -1
  273. package/dist/queries/wire-contract.generated.d.ts +3 -0
  274. package/dist/queries/wire-contract.generated.d.ts.map +1 -1
  275. package/dist/queries/wire-contract.generated.js +3 -0
  276. package/dist/queries/wire-contract.generated.js.map +1 -1
  277. package/dist/resolvers/assembly-engine.d.ts.map +1 -1
  278. package/dist/resolvers/assembly-engine.js +3 -1
  279. package/dist/resolvers/assembly-engine.js.map +1 -1
  280. package/dist/resolvers/git-diff-against-base.d.ts +5 -2
  281. package/dist/resolvers/git-diff-against-base.d.ts.map +1 -1
  282. package/dist/resolvers/git-diff-against-base.js +121 -39
  283. package/dist/resolvers/git-diff-against-base.js.map +1 -1
  284. package/dist/resolvers/shared/git-diff.d.ts +2 -0
  285. package/dist/resolvers/shared/git-diff.d.ts.map +1 -1
  286. package/dist/resolvers/shared/git-diff.js +5 -1
  287. package/dist/resolvers/shared/git-diff.js.map +1 -1
  288. package/dist/resolvers/shared/review-window-commits.d.ts +96 -0
  289. package/dist/resolvers/shared/review-window-commits.d.ts.map +1 -0
  290. package/dist/resolvers/shared/review-window-commits.js +262 -0
  291. package/dist/resolvers/shared/review-window-commits.js.map +1 -0
  292. package/dist/session/session-lineage.d.ts.map +1 -1
  293. package/dist/session/session-lineage.js +4 -1
  294. package/dist/session/session-lineage.js.map +1 -1
  295. package/dist/shell/fail-stop.d.ts +18 -0
  296. package/dist/shell/fail-stop.d.ts.map +1 -0
  297. package/dist/shell/fail-stop.js +53 -0
  298. package/dist/shell/fail-stop.js.map +1 -0
  299. package/dist/shell/graceful-shutdown.d.ts +48 -0
  300. package/dist/shell/graceful-shutdown.d.ts.map +1 -0
  301. package/dist/shell/graceful-shutdown.js +152 -0
  302. package/dist/shell/graceful-shutdown.js.map +1 -0
  303. package/dist/shell/heartbeat.d.ts.map +1 -1
  304. package/dist/shell/heartbeat.js +5 -4
  305. package/dist/shell/heartbeat.js.map +1 -1
  306. package/dist/shell/log.d.ts.map +1 -1
  307. package/dist/shell/log.js +4 -1
  308. package/dist/shell/log.js.map +1 -1
  309. package/dist/shell/stop-request.d.ts.map +1 -1
  310. package/dist/shell/stop-request.js +2 -1
  311. package/dist/shell/stop-request.js.map +1 -1
  312. package/dist/shell/unified-shell.d.ts.map +1 -1
  313. package/dist/shell/unified-shell.js +41 -114
  314. package/dist/shell/unified-shell.js.map +1 -1
  315. package/dist/spawn/lifecycle.d.ts +12 -0
  316. package/dist/spawn/lifecycle.d.ts.map +1 -1
  317. package/dist/spawn/lifecycle.js +25 -21
  318. package/dist/spawn/lifecycle.js.map +1 -1
  319. package/dist/spawn/prompt-assembly.d.ts +19 -1
  320. package/dist/spawn/prompt-assembly.d.ts.map +1 -1
  321. package/dist/spawn/prompt-assembly.js +70 -21
  322. package/dist/spawn/prompt-assembly.js.map +1 -1
  323. package/dist/spawn/review-hold-park.d.ts.map +1 -1
  324. package/dist/spawn/review-hold-park.js +18 -8
  325. package/dist/spawn/review-hold-park.js.map +1 -1
  326. package/dist/spawn/spawn-cooldown.d.ts.map +1 -1
  327. package/dist/spawn/spawn-cooldown.js +4 -0
  328. package/dist/spawn/spawn-cooldown.js.map +1 -1
  329. package/dist/spawn/spawn-decision.d.ts.map +1 -1
  330. package/dist/spawn/spawn-decision.js +2 -1
  331. package/dist/spawn/spawn-decision.js.map +1 -1
  332. package/dist/spawn/worktree-session.d.ts +6 -0
  333. package/dist/spawn/worktree-session.d.ts.map +1 -1
  334. package/dist/spawn/worktree-session.js +15 -2
  335. package/dist/spawn/worktree-session.js.map +1 -1
  336. package/dist/testing/fixtures/index.d.ts +10 -1
  337. package/dist/testing/fixtures/index.d.ts.map +1 -1
  338. package/dist/testing/fixtures/index.js +59 -1
  339. package/dist/testing/fixtures/index.js.map +1 -1
  340. package/dist/testing/fixtures/pending-spawn-world.d.ts +34 -0
  341. package/dist/testing/fixtures/pending-spawn-world.d.ts.map +1 -0
  342. package/dist/testing/fixtures/pending-spawn-world.js +92 -0
  343. package/dist/testing/fixtures/pending-spawn-world.js.map +1 -0
  344. package/dist/types/index.js +1 -1
  345. package/dist/verify/commit-gate-configured.d.ts +86 -0
  346. package/dist/verify/commit-gate-configured.d.ts.map +1 -0
  347. package/dist/verify/commit-gate-configured.js +234 -0
  348. package/dist/verify/commit-gate-configured.js.map +1 -0
  349. package/dist/verify/commit-verdict-record.d.ts +98 -0
  350. package/dist/verify/commit-verdict-record.d.ts.map +1 -0
  351. package/dist/verify/commit-verdict-record.js +297 -0
  352. package/dist/verify/commit-verdict-record.js.map +1 -0
  353. package/dist/verify/explicit-gate-outcome.d.ts +161 -0
  354. package/dist/verify/explicit-gate-outcome.d.ts.map +1 -0
  355. package/dist/verify/explicit-gate-outcome.js +215 -0
  356. package/dist/verify/explicit-gate-outcome.js.map +1 -0
  357. package/dist/verify/explicit-rearm.d.ts +27 -0
  358. package/dist/verify/explicit-rearm.d.ts.map +1 -0
  359. package/dist/verify/explicit-rearm.js +161 -0
  360. package/dist/verify/explicit-rearm.js.map +1 -0
  361. package/dist/verify/explicit-run-ledger.d.ts +26 -0
  362. package/dist/verify/explicit-run-ledger.d.ts.map +1 -0
  363. package/dist/verify/explicit-run-ledger.js +93 -0
  364. package/dist/verify/explicit-run-ledger.js.map +1 -0
  365. package/dist/verify/failure-signature.d.ts.map +1 -1
  366. package/dist/verify/failure-signature.js +5 -1
  367. package/dist/verify/failure-signature.js.map +1 -1
  368. package/dist/verify/gate-run-registry.d.ts +105 -0
  369. package/dist/verify/gate-run-registry.d.ts.map +1 -0
  370. package/dist/verify/gate-run-registry.js +111 -0
  371. package/dist/verify/gate-run-registry.js.map +1 -0
  372. package/dist/verify/gate-verdict-source.d.ts +68 -0
  373. package/dist/verify/gate-verdict-source.d.ts.map +1 -0
  374. package/dist/verify/gate-verdict-source.js +143 -0
  375. package/dist/verify/gate-verdict-source.js.map +1 -0
  376. package/dist/verify/judged-commit-gate.d.ts +11 -0
  377. package/dist/verify/judged-commit-gate.d.ts.map +1 -0
  378. package/dist/verify/judged-commit-gate.js +48 -0
  379. package/dist/verify/judged-commit-gate.js.map +1 -0
  380. package/dist/verify/rework-judgment.d.ts +58 -0
  381. package/dist/verify/rework-judgment.d.ts.map +1 -0
  382. package/dist/verify/rework-judgment.js +54 -0
  383. package/dist/verify/rework-judgment.js.map +1 -0
  384. package/dist/verify/verification-attribution.d.ts +105 -0
  385. package/dist/verify/verification-attribution.d.ts.map +1 -0
  386. package/dist/verify/verification-attribution.js +322 -0
  387. package/dist/verify/verification-attribution.js.map +1 -0
  388. package/dist/verify/verification-baseline-run.d.ts +123 -0
  389. package/dist/verify/verification-baseline-run.d.ts.map +1 -0
  390. package/dist/verify/verification-baseline-run.js +386 -0
  391. package/dist/verify/verification-baseline-run.js.map +1 -0
  392. package/dist/verify/verification-baseline.d.ts +79 -33
  393. package/dist/verify/verification-baseline.d.ts.map +1 -1
  394. package/dist/verify/verification-baseline.js +99 -106
  395. package/dist/verify/verification-baseline.js.map +1 -1
  396. package/dist/verify/verification-checkout.d.ts +13 -0
  397. package/dist/verify/verification-checkout.d.ts.map +1 -1
  398. package/dist/verify/verification-checkout.js +39 -2
  399. package/dist/verify/verification-checkout.js.map +1 -1
  400. package/dist/verify/verification-commit-sharing.d.ts +84 -0
  401. package/dist/verify/verification-commit-sharing.d.ts.map +1 -0
  402. package/dist/verify/verification-commit-sharing.js +416 -0
  403. package/dist/verify/verification-commit-sharing.js.map +1 -0
  404. package/dist/verify/verification-config.d.ts.map +1 -1
  405. package/dist/verify/verification-config.js +12 -2
  406. package/dist/verify/verification-config.js.map +1 -1
  407. package/dist/verify/verification-default-on.d.ts +27 -11
  408. package/dist/verify/verification-default-on.d.ts.map +1 -1
  409. package/dist/verify/verification-default-on.js +159 -29
  410. package/dist/verify/verification-default-on.js.map +1 -1
  411. package/dist/verify/verification-deps-default.d.ts.map +1 -1
  412. package/dist/verify/verification-deps-default.js +49 -42
  413. package/dist/verify/verification-deps-default.js.map +1 -1
  414. package/dist/verify/verification-deps.d.ts +69 -4
  415. package/dist/verify/verification-deps.d.ts.map +1 -1
  416. package/dist/verify/verification-deterministic.d.ts +15 -2
  417. package/dist/verify/verification-deterministic.d.ts.map +1 -1
  418. package/dist/verify/verification-deterministic.js +12 -3
  419. package/dist/verify/verification-deterministic.js.map +1 -1
  420. package/dist/verify/verification-diagnostics.d.ts +16 -0
  421. package/dist/verify/verification-diagnostics.d.ts.map +1 -0
  422. package/dist/verify/verification-diagnostics.js +219 -0
  423. package/dist/verify/verification-diagnostics.js.map +1 -0
  424. package/dist/verify/verification-engine.d.ts +12 -8
  425. package/dist/verify/verification-engine.d.ts.map +1 -1
  426. package/dist/verify/verification-engine.js +110 -92
  427. package/dist/verify/verification-engine.js.map +1 -1
  428. package/dist/verify/verification-evidence-unavailable-feedback.d.ts +2 -1
  429. package/dist/verify/verification-evidence-unavailable-feedback.d.ts.map +1 -1
  430. package/dist/verify/verification-evidence-unavailable-feedback.js +14 -4
  431. package/dist/verify/verification-evidence-unavailable-feedback.js.map +1 -1
  432. package/dist/verify/verification-failure-parser.d.ts +37 -3
  433. package/dist/verify/verification-failure-parser.d.ts.map +1 -1
  434. package/dist/verify/verification-failure-parser.js +66 -3
  435. package/dist/verify/verification-failure-parser.js.map +1 -1
  436. package/dist/verify/verification-feedback.d.ts +21 -34
  437. package/dist/verify/verification-feedback.d.ts.map +1 -1
  438. package/dist/verify/verification-feedback.js +37 -88
  439. package/dist/verify/verification-feedback.js.map +1 -1
  440. package/dist/verify/verification-gate-stages.d.ts +110 -0
  441. package/dist/verify/verification-gate-stages.d.ts.map +1 -0
  442. package/dist/verify/verification-gate-stages.js +179 -0
  443. package/dist/verify/verification-gate-stages.js.map +1 -0
  444. package/dist/verify/verification-history-reset.d.ts +61 -0
  445. package/dist/verify/verification-history-reset.d.ts.map +1 -0
  446. package/dist/verify/verification-history-reset.js +90 -0
  447. package/dist/verify/verification-history-reset.js.map +1 -0
  448. package/dist/verify/verification-manifest.d.ts.map +1 -1
  449. package/dist/verify/verification-manifest.js +2 -1
  450. package/dist/verify/verification-manifest.js.map +1 -1
  451. package/dist/verify/verification-rework-messages.d.ts +19 -0
  452. package/dist/verify/verification-rework-messages.d.ts.map +1 -0
  453. package/dist/verify/verification-rework-messages.js +52 -0
  454. package/dist/verify/verification-rework-messages.js.map +1 -0
  455. package/dist/worktree/install-inputs.d.ts +89 -0
  456. package/dist/worktree/install-inputs.d.ts.map +1 -0
  457. package/dist/worktree/install-inputs.js +625 -0
  458. package/dist/worktree/install-inputs.js.map +1 -0
  459. package/dist/worktree/install-script-effects.d.ts +30 -0
  460. package/dist/worktree/install-script-effects.d.ts.map +1 -0
  461. package/dist/worktree/install-script-effects.js +524 -0
  462. package/dist/worktree/install-script-effects.js.map +1 -0
  463. package/dist/worktree/install-script-tokens.d.ts +57 -0
  464. package/dist/worktree/install-script-tokens.d.ts.map +1 -0
  465. package/dist/worktree/install-script-tokens.js +299 -0
  466. package/dist/worktree/install-script-tokens.js.map +1 -0
  467. package/dist/worktree/provision.d.ts +27 -4
  468. package/dist/worktree/provision.d.ts.map +1 -1
  469. package/dist/worktree/provision.js +46 -7
  470. package/dist/worktree/provision.js.map +1 -1
  471. package/dist/worktree/safety.d.ts +11 -0
  472. package/dist/worktree/safety.d.ts.map +1 -1
  473. package/dist/worktree/safety.js +20 -3
  474. package/dist/worktree/safety.js.map +1 -1
  475. package/dist/worktree/verify-interlock.d.ts.map +1 -1
  476. package/dist/worktree/verify-interlock.js +3 -1
  477. package/dist/worktree/verify-interlock.js.map +1 -1
  478. package/dist/worktree/worktree-package-provisioning.d.ts +75 -0
  479. package/dist/worktree/worktree-package-provisioning.d.ts.map +1 -0
  480. package/dist/worktree/worktree-package-provisioning.js +362 -0
  481. package/dist/worktree/worktree-package-provisioning.js.map +1 -0
  482. package/package.json +1 -1
@@ -0,0 +1,625 @@
1
+ // PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
2
+ // Pinned by: packages/daemon/src/worktree/install-inputs.test.ts
3
+ // PINNED-BY-END
4
+ /**
5
+ * What one `npm ci` CONSUMES from the repo: the single install-input model behind
6
+ * both the provisioning fingerprint (worktree/worktree-package-provisioning.ts --
7
+ * is a reused worktree's install current?) and the baseline dependency parity
8
+ * (verify/verification-baseline-run.ts -- do the focus worktree's installs stand
9
+ * for the base's?).
10
+ *
11
+ * Why one model (TEL-9). Both used to read only manifests: parity compared an
12
+ * install lifecycle command STRING, the fingerprint hashed lockfile + package.json.
13
+ * An unchanged `postinstall: node scripts/patch.cjs` whose script changed was
14
+ * therefore comparable AND current: HEAD's `npm ci` mutated node_modules one way,
15
+ * the base checkout borrowed those modules, and a red the focus's script caused
16
+ * reproduced on the base and was demoted. Two answers over two input sets can
17
+ * disagree; one set cannot.
18
+ *
19
+ * Design: static reference resolution, not a base install. The inventory of this
20
+ * repo (2026-09-15) drove it. Its install roots (tracked lockfiles) are the root,
21
+ * packages/daemon, packages/daemon-core, mcp/telora-products and
22
+ * starters/aurora-shell; across them there is exactly ONE install lifecycle
23
+ * script -- mcp/telora-products `postinstall: node scripts/postinstall.js || true`,
24
+ * a builtins-only ESM file -- and no prepare/husky, no gypfile, no binding.gyp,
25
+ * no workspaces or in-repo links (mcp/telora-ai's `postinstall: telora-ai
26
+ * setup-hooks` has no lockfile, so no install runs it). Following `node <file>`
27
+ * and what it loads keeps base attribution live for every focus that leaves that
28
+ * script alone. Building the base under its own inputs would instead cost an
29
+ * `npm ci` of every root per base commit (minutes on the daemon hosts, and
30
+ * registry-dependent), and the fingerprint would still need this input set.
31
+ *
32
+ * The model, for an install root R (a directory holding a tracked
33
+ * package-lock.json or npm-shrinkwrap.json):
34
+ * - MANIFESTS: R's lockfiles and .npmrc, and the package.json and binding.gyp
35
+ * of every package the install touches -- R, and each in-repo package R's
36
+ * lockfile lists (a workspace member or `file:` link, whose lifecycle
37
+ * scripts npm runs too);
38
+ * - CONSUMED: what each touched package's install lifecycle scripts read. A
39
+ * command is split on `&&` `||` `;` `|` `&` and newlines into simple
40
+ * commands, each followed: `node <file>` (the file, its transitive RELATIVE
41
+ * requires/imports, every string-literal token naming a tracked path, and
42
+ * what its code reads, lists, copies and spawns -- worktree/install-script-effects.ts:
43
+ * each builtin fs call's path and child_process command, resolved
44
+ * statically to literal paths and commands, the commands followed in turn);
45
+ * `sh|bash <file>` / `sh -c <cmd>` / `./<file>` (the script, its lines
46
+ * followed as commands); `npm run <x>` (expanded into pre<x>, x, post<x>);
47
+ * `patch-package` (its patch directory); `node-gyp` (a native build);
48
+ * every other argument token that names a tracked file or directory is
49
+ * consumed. {@link READS_NOTHING} lists, each with its reason, the commands
50
+ * that read no install-relevant source;
51
+ * - THE MANIFEST, WHOLE: a JS file that reaches the environment (`env`,
52
+ * `npm_package_*`, `process` as a value) consumes its package's package.json,
53
+ * every byte of it: npm exports the manifest to lifecycle scripts as
54
+ * npm_package_* (config, version, ...), which the install-intent projection
55
+ * parity compares does not carry;
56
+ * - NATIVE ADDON: a package with a binding.gyp or `gypfile: true` (npm's
57
+ * implicit `node-gyp rebuild`) consumes every tracked file under it;
58
+ * - a JS file that addresses paths relative to its own location or the
59
+ * working directory (`__dirname`, `import.meta`, `process.cwd`) consumes
60
+ * every tracked file under its package.
61
+ * A path under the home or temp directory, or an absolute one, is host state,
62
+ * not a tracked input.
63
+ *
64
+ * Fail closed. Whatever the model cannot follow is UNRESOLVABLE: shell expansion
65
+ * (`$npm_package_config_mode` included), redirection or globbing; an environment
66
+ * assignment; a node flag or inline program; an unknown program (a node_modules
67
+ * bin can read anything); a relative import that names no tracked file; an import
68
+ * of in-repo package source by bare name, of a registry package (its functions
69
+ * can read any path), or of a builtin whose file access the scan does not follow;
70
+ * dynamic code loading (`require(expr)`, `import(expr)`, `eval`, `createRequire`,
71
+ * `process.chdir`); a file read, listing, copy or spawn whose path or command
72
+ * the script computes in a way that does not resolve to literals (a computed
73
+ * string, a variable bound more than once, an aliased fs function, a glob, a
74
+ * spawn `cwd`), and source the scan cannot tokenize; an unreadable lockfile or
75
+ * manifest. An unresolvable install's CONSUMED set widens to every tracked file
76
+ * of the REPOSITORY, not only R -- what the model cannot follow can read outside
77
+ * its root -- so the fingerprint changes when any of them does, and parity
78
+ * refuses it outright. Tracked files only: the model reads what git tracks, never
79
+ * untracked output.
80
+ *
81
+ * @module worktree/install-inputs
82
+ */
83
+ import { createHash } from 'node:crypto';
84
+ import { readFileSync } from 'node:fs';
85
+ import { builtinModules } from 'node:module';
86
+ import { join, posix } from 'node:path';
87
+ import { runGitSync } from '../git/types.js';
88
+ import { FOLLOWED_BUILTIN_MODULES, readScriptEffects } from './install-script-effects.js';
89
+ /** The lockfiles that make a directory an install root (npm ci prefers the shrinkwrap). */
90
+ export const INSTALL_LOCKFILES = ['npm-shrinkwrap.json', 'package-lock.json'];
91
+ /**
92
+ * The package.json scripts an install runs, at any depth. npm documents the
93
+ * `npm ci` / `npm install` order in `npm help scripts` ("Life Cycle Operations":
94
+ * preinstall, install, postinstall, prepublish, preprepare, prepare, postprepare;
95
+ * "Life Cycle Scripts": `dependencies` runs after any operation that modifies
96
+ * node_modules), and npm 10's source runs exactly these:
97
+ * - the root, after the tree is reified (lib/commands/ci.js, install.js):
98
+ * preinstall, install, postinstall, prepublish, preprepare, prepare, postprepare;
99
+ * - the root, whenever node_modules changed -- which `npm ci` always does
100
+ * (@npmcli/arborist reify.js): predependencies, dependencies, postdependencies;
101
+ * - every workspace and in-repo `file:` link (@npmcli/arborist rebuild.js):
102
+ * preinstall, prepare, install, postinstall -- and `prepare` again for a
103
+ * directory dependency packed under install-links (pacote dir.js).
104
+ * The pack scripts (prepack, postpack) are not in it: pacote runs "*only*
105
+ * prepare" when it packs a directory dependency, and the CLI runs them for
106
+ * pack/publish; a git dependency runs them from its remote manifest, which the
107
+ * lockfile pins. Every other script is gate or tool source the checkout pins.
108
+ */
109
+ export const INSTALL_LIFECYCLE_SCRIPTS = [
110
+ 'preinstall', 'install', 'postinstall', 'prepublish', 'preprepare', 'prepare', 'postprepare',
111
+ 'predependencies', 'dependencies', 'postdependencies',
112
+ ];
113
+ /** The fingerprint format; a marker holding any other value (an older format) is never current. */
114
+ export const INSTALL_FINGERPRINT_FORMAT = 'install-inputs/v2';
115
+ /** A bound on the files one install's scan follows; past it the install is unresolvable. */
116
+ const MAX_SCANNED_FILES = 256;
117
+ /** A bound on nested `npm run` expansion. */
118
+ const MAX_SCRIPT_DEPTH = 16;
119
+ const DEPENDENCY_DIR = 'node_modules';
120
+ const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
121
+ /** Normalize `rel` against a repo-relative `dir`; null when it leaves the repo or is absolute. */
122
+ function joinRel(dir, rel) {
123
+ if (rel.startsWith('/'))
124
+ return null;
125
+ const joined = posix.normalize(dir === '' ? rel : `${dir}/${rel}`).replace(/\/+$/, '');
126
+ if (joined === '..' || joined.startsWith('../'))
127
+ return null;
128
+ return joined === '.' ? '' : joined;
129
+ }
130
+ const underNodeModules = (path) => path.split('/').includes(DEPENDENCY_DIR);
131
+ /**
132
+ * A tree over a tracked path list and a byte reader. Paths under a node_modules
133
+ * segment are not install inputs and are dropped; `read` answers null for an
134
+ * untracked path without calling the reader.
135
+ */
136
+ export function trackedInstallTree(paths, read) {
137
+ const files = [...new Set(paths.filter((path) => path.length > 0 && !underNodeModules(path)))].sort();
138
+ const tracked = new Set(files);
139
+ const filesUnder = (dir) => {
140
+ if (dir === '')
141
+ return [...files];
142
+ const prefix = `${dir}/`;
143
+ let low = 0;
144
+ let high = files.length;
145
+ while (low < high) {
146
+ const mid = (low + high) >> 1;
147
+ if (files[mid] < prefix)
148
+ low = mid + 1;
149
+ else
150
+ high = mid;
151
+ }
152
+ const found = [];
153
+ for (let index = low; index < files.length && files[index].startsWith(prefix); index++)
154
+ found.push(files[index]);
155
+ return found;
156
+ };
157
+ return { has: (path) => tracked.has(path), filesUnder, read: (path) => (tracked.has(path) ? read(path) : null) };
158
+ }
159
+ /** A working-tree file's bytes; null when it is gone (a tracked file deleted in the worktree). */
160
+ function readWorkingFile(path) {
161
+ try {
162
+ return readFileSync(path);
163
+ }
164
+ catch (err) {
165
+ const code = err.code;
166
+ if (code === 'ENOENT' || code === 'ENOTDIR')
167
+ return null;
168
+ throw err;
169
+ }
170
+ }
171
+ /**
172
+ * A worktree's tracked tree as its installs read it: git's tracked paths, their
173
+ * bytes from the working tree. Null when git cannot list the worktree.
174
+ */
175
+ export function readWorktreeInstallTree(worktreePath, runGit = runGitSync) {
176
+ const listed = runGit(['ls-files', '-z'], worktreePath);
177
+ if (!listed.success)
178
+ return null;
179
+ return trackedInstallTree(listed.output.split('\0'), (path) => readWorkingFile(join(worktreePath, path)));
180
+ }
181
+ /** Every install root of the tree: the directories holding a tracked lockfile ('' = the repo root). Sorted. */
182
+ export function listInstallRoots(tree) {
183
+ const roots = new Set();
184
+ for (const path of tree.filesUnder('')) {
185
+ if (INSTALL_LOCKFILES.includes(posix.basename(path))) {
186
+ const dir = posix.dirname(path);
187
+ roots.add(dir === '.' ? '' : dir);
188
+ }
189
+ }
190
+ return [...roots].sort();
191
+ }
192
+ function fail(walk, manifest, reason) {
193
+ walk.unresolvable.push({ manifest, reason });
194
+ }
195
+ const clip = (text) => (text.length > 120 ? `${text.slice(0, 117)}...` : text);
196
+ function readText(walk, path) {
197
+ return walk.tree.read(path)?.toString('utf8') ?? null;
198
+ }
199
+ function consumeTree(walk, dir) {
200
+ for (const file of walk.tree.filesUnder(dir))
201
+ walk.consumed.add(file);
202
+ }
203
+ /** A JSON object from a tracked file: the object, null when absent, or 'invalid'. */
204
+ function readJsonObject(walk, path) {
205
+ const text = readText(walk, path);
206
+ if (text === null)
207
+ return null;
208
+ try {
209
+ const parsed = JSON.parse(text);
210
+ return isPlainObject(parsed) ? parsed : 'invalid';
211
+ }
212
+ catch {
213
+ return 'invalid';
214
+ }
215
+ }
216
+ /**
217
+ * The packages an install at `root` touches (module doc) and the names it links
218
+ * to in-repo source, read from its lockfile. A lockfile the model cannot read is
219
+ * unresolvable, and the root alone is followed.
220
+ */
221
+ function readTouchedPackages(walk, root) {
222
+ const dirs = [root];
223
+ const linkedNames = new Set();
224
+ const lockPath = INSTALL_LOCKFILES.map((name) => joinRel(root, name) ?? name).find((path) => walk.tree.has(path));
225
+ if (lockPath === undefined)
226
+ return { dirs, linkedNames };
227
+ const lock = readJsonObject(walk, lockPath);
228
+ if (lock === null)
229
+ return { dirs, linkedNames };
230
+ if (lock === 'invalid' || (!isPlainObject(lock.packages) && lock.dependencies !== undefined)) {
231
+ fail(walk, lockPath, `${lockPath} is not a lockfile whose in-repo packages the model can read`);
232
+ return { dirs, linkedNames };
233
+ }
234
+ for (const [key, entry] of Object.entries(isPlainObject(lock.packages) ? lock.packages : {})) {
235
+ if (key === '')
236
+ continue;
237
+ const segments = key.split('/');
238
+ if (segments.includes(DEPENDENCY_DIR)) {
239
+ if (isPlainObject(entry) && entry.link === true)
240
+ linkedNames.add(key.slice(key.lastIndexOf(`${DEPENDENCY_DIR}/`) + DEPENDENCY_DIR.length + 1));
241
+ continue;
242
+ }
243
+ const dir = joinRel(root, key);
244
+ if (dir === null)
245
+ fail(walk, lockPath, `${lockPath} links ${key}, outside the repo`);
246
+ else if (!dirs.includes(dir))
247
+ dirs.push(dir);
248
+ }
249
+ return { dirs, linkedNames };
250
+ }
251
+ /** Follow one touched package: its manifests, a native build, and its install lifecycle scripts. */
252
+ function followPackage(walk, dir, linkedNames) {
253
+ const manifestPath = joinRel(dir, 'package.json') ?? 'package.json';
254
+ const gypPath = joinRel(dir, 'binding.gyp') ?? 'binding.gyp';
255
+ if (walk.tree.has(gypPath))
256
+ walk.manifests.add(gypPath);
257
+ if (!walk.tree.has(manifestPath)) {
258
+ if (walk.tree.has(gypPath))
259
+ consumeTree(walk, dir);
260
+ return;
261
+ }
262
+ walk.manifests.add(manifestPath);
263
+ const manifest = readJsonObject(walk, manifestPath);
264
+ if (manifest === null || manifest === 'invalid' || (manifest.scripts !== undefined && !isPlainObject(manifest.scripts))) {
265
+ fail(walk, manifestPath, `${manifestPath} is not a manifest whose install scripts the model can read`);
266
+ return;
267
+ }
268
+ if (walk.tree.has(gypPath) || manifest.gypfile === true)
269
+ consumeTree(walk, dir);
270
+ const scope = {
271
+ dir,
272
+ manifest: manifestPath,
273
+ scripts: isPlainObject(manifest.scripts) ? manifest.scripts : {},
274
+ ownName: typeof manifest.name === 'string' ? manifest.name : null,
275
+ linkedNames,
276
+ expanding: new Set(),
277
+ };
278
+ for (const script of INSTALL_LIFECYCLE_SCRIPTS) {
279
+ const body = scope.scripts[script];
280
+ if (body === undefined)
281
+ continue;
282
+ if (typeof body !== 'string')
283
+ fail(walk, manifestPath, `${manifestPath} scripts.${script} is not a command`);
284
+ else
285
+ resolveCommand(walk, scope, body, `scripts.${script}`);
286
+ }
287
+ }
288
+ /**
289
+ * What an install at `root` consumes (module doc). Throws when a tracked input
290
+ * cannot be read (the caller reports the tree unreadable).
291
+ */
292
+ export function readInstallInputs(tree, root) {
293
+ const walk = { tree, manifests: new Set(), consumed: new Set(), scanned: new Set(), unresolvable: [] };
294
+ for (const name of [...INSTALL_LOCKFILES, '.npmrc']) {
295
+ const path = joinRel(root, name);
296
+ if (path !== null && tree.has(path))
297
+ walk.manifests.add(path);
298
+ }
299
+ const touched = readTouchedPackages(walk, root);
300
+ for (const dir of touched.dirs)
301
+ followPackage(walk, dir, touched.linkedNames);
302
+ // An input the model cannot follow can address any tracked path -- a nested
303
+ // install's `../../shared.json` included -- so the fallback is the whole repository.
304
+ if (walk.unresolvable.length > 0)
305
+ consumeTree(walk, '');
306
+ return { manifests: [...walk.manifests].sort(), consumed: [...walk.consumed].sort(), unresolvable: walk.unresolvable };
307
+ }
308
+ /**
309
+ * The provisioning fingerprint of an install at `root`: every manifest and
310
+ * consumed file, path and bytes, under {@link INSTALL_FINGERPRINT_FORMAT}. Equal
311
+ * fingerprints mean no input the install reads changed.
312
+ */
313
+ export function installInputsFingerprint(tree, root) {
314
+ const inputs = readInstallInputs(tree, root);
315
+ const hash = createHash('sha256').update(INSTALL_FINGERPRINT_FORMAT);
316
+ for (const path of [...new Set([...inputs.manifests, ...inputs.consumed])].sort()) {
317
+ const bytes = tree.read(path);
318
+ hash.update('\0').update(path).update('\0').update(bytes === null ? 'absent' : `${bytes.length}:`);
319
+ if (bytes !== null)
320
+ hash.update(bytes);
321
+ }
322
+ return `${INSTALL_FINGERPRINT_FORMAT}:${hash.digest('hex')}`;
323
+ }
324
+ // ---------------------------------------------------------------------------
325
+ // Commands
326
+ // ---------------------------------------------------------------------------
327
+ /** Shell syntax the model does not follow: expansion, substitution, redirection, globbing, escapes, comments. */
328
+ const UNFOLLOWED_SHELL = /[$`()<>*?[\]{}~\\!#]/;
329
+ /**
330
+ * Commands that read no tracked file an install's effect depends on, each with why.
331
+ * A command here is admitted with any arguments.
332
+ */
333
+ export const READS_NOTHING = new Map([
334
+ ['true', 'a shell no-op: the `|| true` that keeps an optional step from failing the install'],
335
+ ['false', 'a shell no-op'],
336
+ [':', 'a shell no-op'],
337
+ ['exit', 'ends the script'],
338
+ ['echo', 'prints its arguments; no expansion is admitted, so it reads nothing'],
339
+ ['set', 'sets shell options (`set -e`)'],
340
+ ['which', 'prints where a program name resolves on PATH; reads no file content'],
341
+ ['husky', 'installs git hooks (`husky`, `husky install`): sets core.hooksPath and writes hook shims under .husky, never reads source into node_modules'],
342
+ ]);
343
+ /** Split a command into simple commands of words; null when it uses shell syntax the model does not follow. */
344
+ export function splitShellCommands(command) {
345
+ if (UNFOLLOWED_SHELL.test(command))
346
+ return null;
347
+ const commands = [];
348
+ let words = [];
349
+ let word = '';
350
+ let quoted = false;
351
+ let quote = null;
352
+ const endWord = () => {
353
+ if (word.length > 0 || quoted)
354
+ words.push(word);
355
+ word = '';
356
+ quoted = false;
357
+ };
358
+ const endCommand = () => {
359
+ endWord();
360
+ if (words.length > 0)
361
+ commands.push(words);
362
+ words = [];
363
+ };
364
+ for (const char of command) {
365
+ if (quote !== null) {
366
+ if (char === quote)
367
+ quote = null;
368
+ else
369
+ word += char;
370
+ }
371
+ else if (char === '"' || char === "'") {
372
+ quote = char;
373
+ quoted = true;
374
+ }
375
+ else if (char === '&' || char === '|' || char === ';' || char === '\n') {
376
+ endCommand();
377
+ }
378
+ else if (/\s/.test(char)) {
379
+ endWord();
380
+ }
381
+ else {
382
+ word += char;
383
+ }
384
+ }
385
+ if (quote !== null)
386
+ return null;
387
+ endCommand();
388
+ return commands;
389
+ }
390
+ function resolveCommand(walk, scope, command, origin) {
391
+ const commands = splitShellCommands(command);
392
+ if (commands === null) {
393
+ fail(walk, scope.manifest, `${scope.manifest} ${origin}: \`${clip(command)}\` uses shell syntax the model does not follow`);
394
+ return;
395
+ }
396
+ for (const words of commands)
397
+ resolveSimpleCommand(walk, scope, words, origin);
398
+ }
399
+ function resolveSimpleCommand(walk, scope, words, origin) {
400
+ const [program = '', ...args] = words;
401
+ const unresolvable = (why) => fail(walk, scope.manifest, `${scope.manifest} ${origin}: \`${clip(words.join(' '))}\` ${why}`);
402
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(program))
403
+ return unresolvable('sets an environment variable the model does not follow');
404
+ if (READS_NOTHING.has(program))
405
+ return;
406
+ if (program === 'node')
407
+ return resolveNode(walk, scope, args, unresolvable);
408
+ if (program === 'sh' || program === 'bash')
409
+ return resolveShell(walk, scope, args, origin, unresolvable);
410
+ if (program === 'npm')
411
+ return resolveNpmRun(walk, scope, args, origin, unresolvable);
412
+ if (program === 'patch-package')
413
+ return resolvePatchPackage(walk, scope, args, unresolvable);
414
+ if (program === 'node-gyp')
415
+ return consumeTree(walk, scope.dir); // a native build reads the package's sources
416
+ if (program.includes('/'))
417
+ return resolveExecutable(walk, scope, program, args, origin, unresolvable);
418
+ unresolvable('runs a program the model does not follow (a bin can read any file)');
419
+ }
420
+ /** Resolve every argument token (or `--flag=value` value) that names a tracked file or directory. */
421
+ function resolveArgumentTokens(walk, scope, args) {
422
+ for (const arg of args)
423
+ resolveLiteralToken(walk, scope, scope.dir, arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : arg);
424
+ }
425
+ function resolveNode(walk, scope, args, unresolvable) {
426
+ const [entry, ...rest] = args;
427
+ if (entry === undefined || entry.startsWith('-'))
428
+ return unresolvable('passes node a flag or an inline program');
429
+ const file = resolveModuleFile(walk.tree, scope.dir, entry);
430
+ if (file === null)
431
+ return unresolvable(`runs ${entry}, which is not a tracked file`);
432
+ scanScript(walk, scope, file);
433
+ resolveArgumentTokens(walk, scope, rest);
434
+ }
435
+ function resolveShell(walk, scope, args, origin, unresolvable) {
436
+ const [first, ...rest] = args;
437
+ if (first === '-c' && rest[0] !== undefined) {
438
+ resolveCommand(walk, scope, rest[0], origin);
439
+ return resolveArgumentTokens(walk, scope, rest.slice(1));
440
+ }
441
+ if (first === undefined || first.startsWith('-'))
442
+ return unresolvable('passes the shell a flag the model does not follow');
443
+ const file = joinRel(scope.dir, first);
444
+ if (file === null || !walk.tree.has(file))
445
+ return unresolvable(`runs ${first}, which is not a tracked file`);
446
+ scanShellScript(walk, scope, file, origin);
447
+ resolveArgumentTokens(walk, scope, rest);
448
+ }
449
+ function resolveExecutable(walk, scope, program, args, origin, unresolvable) {
450
+ const file = joinRel(scope.dir, program);
451
+ if (file === null || !walk.tree.has(file))
452
+ return unresolvable(`runs ${program}, which is not a tracked file`);
453
+ const shebang = (readText(walk, file) ?? '').split('\n', 1)[0];
454
+ if (/^#!.*\bnode\b/.test(shebang))
455
+ scanScript(walk, scope, file);
456
+ else if (!shebang.startsWith('#!') || /^#!.*\b(?:sh|bash)\b/.test(shebang))
457
+ scanShellScript(walk, scope, file, origin);
458
+ else
459
+ return unresolvable(`runs ${program} under an interpreter the model does not follow`);
460
+ resolveArgumentTokens(walk, scope, args);
461
+ }
462
+ /** `npm run <x> [-- args]`: pre<x>, <x> and post<x>, as npm runs them. */
463
+ function resolveNpmRun(walk, scope, args, origin, unresolvable) {
464
+ const [sub, name, ...rest] = args;
465
+ if ((sub !== 'run' && sub !== 'run-script') || name === undefined || name.startsWith('-') || (rest.length > 0 && rest[0] !== '--')) {
466
+ return unresolvable('is an npm invocation the model does not follow (only `npm run <script> [-- args]`)');
467
+ }
468
+ for (const script of [`pre${name}`, name, `post${name}`]) {
469
+ const body = scope.scripts[script];
470
+ if (body === undefined && script !== name)
471
+ continue;
472
+ if (typeof body !== 'string')
473
+ return unresolvable(`runs scripts.${script}, which is not a command`);
474
+ if (scope.expanding.has(script) || scope.expanding.size >= MAX_SCRIPT_DEPTH)
475
+ return unresolvable('expands scripts recursively');
476
+ scope.expanding.add(script);
477
+ resolveCommand(walk, scope, body, `${origin} > scripts.${script}`);
478
+ scope.expanding.delete(script);
479
+ }
480
+ resolveArgumentTokens(walk, scope, rest.slice(1));
481
+ }
482
+ /** `patch-package` applies the patches in its patch directory (default `patches`) to node_modules. */
483
+ function resolvePatchPackage(walk, scope, args, unresolvable) {
484
+ let patchDir = 'patches';
485
+ for (let index = 0; index < args.length; index++) {
486
+ const arg = args[index];
487
+ if (arg === '--patch-dir' && args[index + 1] !== undefined)
488
+ patchDir = args[++index];
489
+ else if (arg !== '--error-on-fail' && arg !== '--error-on-warn')
490
+ return unresolvable(`passes patch-package ${arg}, a flag the model does not follow`);
491
+ }
492
+ const dir = joinRel(scope.dir, patchDir);
493
+ if (dir === null)
494
+ return unresolvable(`reads patches from ${patchDir}, outside the repo`);
495
+ consumeTree(walk, dir);
496
+ }
497
+ // ---------------------------------------------------------------------------
498
+ // Scripts
499
+ // ---------------------------------------------------------------------------
500
+ /** Code loading a static scan cannot follow. */
501
+ const DYNAMIC_LOADING = /\brequire\s*\(\s*[^'"\s)]|\bimport\s*\(\s*[^'"\s)]|\beval\s*\(|\bnew\s+Function\b|\bcreateRequire\b|\bmodule\.require\b|\bprocess\.dlopen\b|\bprocess\.chdir\b/;
502
+ /** Paths addressed relative to the script's location or the working directory: the whole package is in reach. */
503
+ const LOCATION_ANCHORED = /\b__dirname\b|\b__filename\b|\bimport\.meta\b|\bprocess\.cwd\b/;
504
+ const IMPORT_SPECIFIERS = [
505
+ /\brequire\s*\(\s*(['"])([^'"\n]+)\1\s*\)/g,
506
+ /\bimport\s*\(\s*(['"])([^'"\n]+)\1/g,
507
+ /\b(?:import|export)\s[^'"`;]*?\bfrom\s*(['"])([^'"\n]+)\1/g,
508
+ /\bimport\s*(['"])([^'"\n]+)\1/g,
509
+ ];
510
+ const STRING_LITERALS = /'((?:[^'\\\n]|\\.)*)'|"((?:[^"\\\n]|\\.)*)"|`((?:[^`\\]|\\.)*)`/g;
511
+ const MODULE_SUFFIXES = ['', '.js', '.cjs', '.mjs', '.json', '.ts', '.cts', '.mts', '/index.js', '/index.cjs', '/index.mjs', '/index.json'];
512
+ const SCANNED_SOURCE = /\.(?:[cm]?js|[cm]?ts)$|^[^.]*$/;
513
+ /** The tracked file `node` loads for `specifier` from `dir`, trying Node's extensions and index files. */
514
+ function resolveModuleFile(tree, dir, specifier) {
515
+ for (const suffix of MODULE_SUFFIXES) {
516
+ const candidate = joinRel(dir, `${specifier}${suffix}`);
517
+ if (candidate !== null && candidate !== '' && tree.has(candidate))
518
+ return candidate;
519
+ }
520
+ return null;
521
+ }
522
+ function scanShellScript(walk, scope, file, origin) {
523
+ if (!enterScan(walk, scope, file))
524
+ return;
525
+ const text = readText(walk, file) ?? '';
526
+ const body = text.split('\n').filter((line) => !line.trimStart().startsWith('#')).join('\n');
527
+ resolveCommand(walk, scope, body, `${origin} > ${file}`);
528
+ }
529
+ /** Mark `file` consumed and scanned; false when it already was, or the scan bound is spent (unresolvable). */
530
+ function enterScan(walk, scope, file) {
531
+ walk.consumed.add(file);
532
+ if (walk.scanned.has(file))
533
+ return false;
534
+ walk.scanned.add(file);
535
+ if (walk.scanned.size <= MAX_SCANNED_FILES)
536
+ return true;
537
+ fail(walk, scope.manifest, `${scope.manifest}: its install scripts load more than ${MAX_SCANNED_FILES} files`);
538
+ return false;
539
+ }
540
+ /** A JS entry: its content, its transitive relative imports, and every literal token naming a tracked path (module doc). */
541
+ function scanScript(walk, scope, file) {
542
+ if (!enterScan(walk, scope, file) || !SCANNED_SOURCE.test(posix.basename(file)))
543
+ return;
544
+ const text = readText(walk, file) ?? '';
545
+ const dynamic = DYNAMIC_LOADING.exec(text);
546
+ if (dynamic) {
547
+ fail(walk, scope.manifest, `${file} loads code the static scan cannot follow (\`${clip(dynamic[0])}\`)`);
548
+ return;
549
+ }
550
+ const effects = readScriptEffects(text, posix.basename(file));
551
+ if ('unresolvable' in effects) {
552
+ fail(walk, scope.manifest, `${file} ${effects.unresolvable}`);
553
+ return;
554
+ }
555
+ if (LOCATION_ANCHORED.test(text))
556
+ consumeTree(walk, scope.dir);
557
+ const from = posix.dirname(file) === '.' ? '' : posix.dirname(file);
558
+ for (const pattern of IMPORT_SPECIFIERS) {
559
+ for (const match of text.matchAll(pattern))
560
+ resolveImport(walk, scope, file, from, match[2]);
561
+ }
562
+ for (const match of text.matchAll(STRING_LITERALS)) {
563
+ const literal = (match[1] ?? match[2] ?? match[3] ?? '').replace(/\$\{[^}]*\}/g, ' ');
564
+ for (const token of literal.split(/\s+/))
565
+ resolveLiteralToken(walk, scope, from, token);
566
+ }
567
+ followScriptEffects(walk, scope, file, from, effects);
568
+ }
569
+ /** What a script's code reads, spawns and takes from the environment (worktree/install-script-effects.ts). */
570
+ function followScriptEffects(walk, scope, file, from, effects) {
571
+ if (effects.readsManifest)
572
+ walk.consumed.add(scope.manifest);
573
+ for (const read of effects.reads) {
574
+ const path = joinRel(read.anchor === 'cwd' ? scope.dir : from, read.path);
575
+ if (path === null)
576
+ fail(walk, scope.manifest, `${file} reads ${read.path}, outside the repo`);
577
+ else
578
+ consumePath(walk, scope, path);
579
+ }
580
+ for (const command of effects.commands)
581
+ resolveCommand(walk, scope, command, `${file} spawns`);
582
+ }
583
+ function resolveImport(walk, scope, file, from, specifier) {
584
+ if (specifier.startsWith('.')) {
585
+ const target = resolveModuleFile(walk.tree, from, specifier);
586
+ if (target === null)
587
+ fail(walk, scope.manifest, `${file} imports ${specifier}, which is not a tracked file`);
588
+ else
589
+ scanScript(walk, scope, target);
590
+ return;
591
+ }
592
+ if (specifier.startsWith('node:') || builtinModules.includes(specifier)) {
593
+ if (!FOLLOWED_BUILTIN_MODULES.has(specifier.replace(/^node:/, ''))) {
594
+ fail(walk, scope.manifest, `${file} imports ${specifier}, a builtin whose file access the scan does not follow`);
595
+ }
596
+ return;
597
+ }
598
+ const name = specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
599
+ const inRepo = /^[a-z][a-z0-9+.-]*:/i.test(specifier) || specifier.startsWith('/') || specifier.startsWith('#')
600
+ || name === scope.ownName || scope.linkedNames.has(name);
601
+ // The lockfile pins a registry package's code, not the paths its functions read -- the same reason an unknown bin is unresolvable.
602
+ fail(walk, scope.manifest, inRepo
603
+ ? `${file} imports ${specifier}, which the lockfile does not pin (in-repo or addressed source)`
604
+ : `${file} imports ${specifier}, a registry package whose file reads the scan does not follow`);
605
+ }
606
+ /** A token naming a tracked file or directory relative to the package or `from` (see {@link consumePath}). */
607
+ function resolveLiteralToken(walk, scope, from, token) {
608
+ if (token.length === 0 || token.startsWith('/') || token.includes('://'))
609
+ return;
610
+ for (const base of new Set([scope.dir, from])) {
611
+ const path = joinRel(base, token);
612
+ if (path !== null)
613
+ consumePath(walk, scope, path);
614
+ }
615
+ }
616
+ /** A tracked file (a JS source is scanned), or every tracked file under a directory (none for an untracked path). */
617
+ function consumePath(walk, scope, path) {
618
+ if (!walk.tree.has(path))
619
+ consumeTree(walk, path);
620
+ else if (/\.(?:[cm]?js|[cm]?ts)$/.test(path))
621
+ scanScript(walk, scope, path);
622
+ else
623
+ walk.consumed.add(path);
624
+ }
625
+ //# sourceMappingURL=install-inputs.js.map