looply-cli 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (785) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -3
  3. package/dist/.src-hash +1 -0
  4. package/dist/acceptance-observe.d.ts +108 -0
  5. package/dist/acceptance-observe.d.ts.map +1 -0
  6. package/dist/acceptance-observe.js +152 -0
  7. package/dist/acceptance-observe.js.map +1 -0
  8. package/dist/agent-cmd.d.ts +131 -0
  9. package/dist/agent-cmd.d.ts.map +1 -0
  10. package/dist/agent-cmd.js +154 -0
  11. package/dist/agent-cmd.js.map +1 -0
  12. package/dist/agent-contained.d.ts +114 -0
  13. package/dist/agent-contained.d.ts.map +1 -0
  14. package/dist/agent-contained.js +292 -0
  15. package/dist/agent-contained.js.map +1 -0
  16. package/dist/agent-driver.d.ts +130 -0
  17. package/dist/agent-driver.d.ts.map +1 -0
  18. package/dist/agent-driver.js +170 -0
  19. package/dist/agent-driver.js.map +1 -0
  20. package/dist/agent-envelope.d.ts +94 -0
  21. package/dist/agent-envelope.d.ts.map +1 -0
  22. package/dist/agent-envelope.js +214 -0
  23. package/dist/agent-envelope.js.map +1 -0
  24. package/dist/agent-exec.d.ts +182 -0
  25. package/dist/agent-exec.d.ts.map +1 -0
  26. package/dist/agent-exec.js +125 -0
  27. package/dist/agent-exec.js.map +1 -0
  28. package/dist/agent-runtime.d.ts +23 -0
  29. package/dist/agent-runtime.d.ts.map +1 -0
  30. package/dist/agent-runtime.js +143 -0
  31. package/dist/agent-runtime.js.map +1 -0
  32. package/dist/approval-gate-read.d.ts +66 -0
  33. package/dist/approval-gate-read.d.ts.map +1 -0
  34. package/dist/approval-gate-read.js +138 -0
  35. package/dist/approval-gate-read.js.map +1 -0
  36. package/dist/approval-resolution.d.ts +87 -0
  37. package/dist/approval-resolution.d.ts.map +1 -0
  38. package/dist/approval-resolution.js +100 -0
  39. package/dist/approval-resolution.js.map +1 -0
  40. package/dist/approval-resumes.d.ts +102 -0
  41. package/dist/approval-resumes.d.ts.map +1 -0
  42. package/dist/approval-resumes.js +167 -0
  43. package/dist/approval-resumes.js.map +1 -0
  44. package/dist/ask-brain.d.ts +167 -0
  45. package/dist/ask-brain.d.ts.map +1 -0
  46. package/dist/ask-brain.js +355 -0
  47. package/dist/ask-brain.js.map +1 -0
  48. package/dist/autonomy-authority.d.ts +80 -0
  49. package/dist/autonomy-authority.d.ts.map +1 -0
  50. package/dist/autonomy-authority.js +82 -0
  51. package/dist/autonomy-authority.js.map +1 -0
  52. package/dist/autonomy-controller.d.ts +321 -0
  53. package/dist/autonomy-controller.d.ts.map +1 -0
  54. package/dist/autonomy-controller.js +517 -0
  55. package/dist/autonomy-controller.js.map +1 -0
  56. package/dist/autonomy-store.d.ts +327 -0
  57. package/dist/autonomy-store.d.ts.map +1 -0
  58. package/dist/autonomy-store.js +581 -0
  59. package/dist/autonomy-store.js.map +1 -0
  60. package/dist/autonomy-tick.d.ts +257 -0
  61. package/dist/autonomy-tick.d.ts.map +1 -0
  62. package/dist/autonomy-tick.js +616 -0
  63. package/dist/autonomy-tick.js.map +1 -0
  64. package/dist/bin.d.ts +3 -0
  65. package/dist/bin.d.ts.map +1 -0
  66. package/dist/bin.js +2719 -0
  67. package/dist/bin.js.map +1 -0
  68. package/dist/brain-advice.d.ts +21 -0
  69. package/dist/brain-advice.d.ts.map +1 -0
  70. package/dist/brain-advice.js +51 -0
  71. package/dist/brain-advice.js.map +1 -0
  72. package/dist/candidate-replay-runtime.d.ts +125 -0
  73. package/dist/candidate-replay-runtime.d.ts.map +1 -0
  74. package/dist/candidate-replay-runtime.js +188 -0
  75. package/dist/candidate-replay-runtime.js.map +1 -0
  76. package/dist/checkout-carry.d.ts +76 -0
  77. package/dist/checkout-carry.d.ts.map +1 -0
  78. package/dist/checkout-carry.js +125 -0
  79. package/dist/checkout-carry.js.map +1 -0
  80. package/dist/citation-readers.d.ts +26 -0
  81. package/dist/citation-readers.d.ts.map +1 -0
  82. package/dist/citation-readers.js +102 -0
  83. package/dist/citation-readers.js.map +1 -0
  84. package/dist/command-receipts.d.ts +79 -0
  85. package/dist/command-receipts.d.ts.map +1 -0
  86. package/dist/command-receipts.js +143 -0
  87. package/dist/command-receipts.js.map +1 -0
  88. package/dist/command-runner.d.ts +32 -0
  89. package/dist/command-runner.d.ts.map +1 -0
  90. package/dist/command-runner.js +108 -0
  91. package/dist/command-runner.js.map +1 -0
  92. package/dist/compatible-sets.d.ts +67 -0
  93. package/dist/compatible-sets.d.ts.map +1 -0
  94. package/dist/compatible-sets.js +81 -0
  95. package/dist/compatible-sets.js.map +1 -0
  96. package/dist/compile-check.d.ts +31 -0
  97. package/dist/compile-check.d.ts.map +1 -0
  98. package/dist/compile-check.js +34 -0
  99. package/dist/compile-check.js.map +1 -0
  100. package/dist/compile-store.d.ts +16 -0
  101. package/dist/compile-store.d.ts.map +1 -0
  102. package/dist/compile-store.js +21 -0
  103. package/dist/compile-store.js.map +1 -0
  104. package/dist/completion.d.ts +106 -0
  105. package/dist/completion.d.ts.map +1 -0
  106. package/dist/completion.js +131 -0
  107. package/dist/completion.js.map +1 -0
  108. package/dist/config.d.ts +549 -0
  109. package/dist/config.d.ts.map +1 -0
  110. package/dist/config.js +763 -0
  111. package/dist/config.js.map +1 -0
  112. package/dist/control-file.d.ts +142 -0
  113. package/dist/control-file.d.ts.map +1 -0
  114. package/dist/control-file.js +144 -0
  115. package/dist/control-file.js.map +1 -0
  116. package/dist/coordinator-state.d.ts +131 -0
  117. package/dist/coordinator-state.d.ts.map +1 -0
  118. package/dist/coordinator-state.js +380 -0
  119. package/dist/coordinator-state.js.map +1 -0
  120. package/dist/coordinator.d.ts +95 -0
  121. package/dist/coordinator.d.ts.map +1 -0
  122. package/dist/coordinator.js +97 -0
  123. package/dist/coordinator.js.map +1 -0
  124. package/dist/cursor-store.d.ts +53 -0
  125. package/dist/cursor-store.d.ts.map +1 -0
  126. package/dist/cursor-store.js +98 -0
  127. package/dist/cursor-store.js.map +1 -0
  128. package/dist/daemon-cmd.d.ts +239 -0
  129. package/dist/daemon-cmd.d.ts.map +1 -0
  130. package/dist/daemon-cmd.js +1751 -0
  131. package/dist/daemon-cmd.js.map +1 -0
  132. package/dist/daemon-lock.d.ts +140 -0
  133. package/dist/daemon-lock.d.ts.map +1 -0
  134. package/dist/daemon-lock.js +352 -0
  135. package/dist/daemon-lock.js.map +1 -0
  136. package/dist/daemon-recovery.d.ts +78 -0
  137. package/dist/daemon-recovery.d.ts.map +1 -0
  138. package/dist/daemon-recovery.js +161 -0
  139. package/dist/daemon-recovery.js.map +1 -0
  140. package/dist/daemon.d.ts +368 -0
  141. package/dist/daemon.d.ts.map +1 -0
  142. package/dist/daemon.js +601 -0
  143. package/dist/daemon.js.map +1 -0
  144. package/dist/declared-response-shape.d.ts +93 -0
  145. package/dist/declared-response-shape.d.ts.map +1 -0
  146. package/dist/declared-response-shape.js +200 -0
  147. package/dist/declared-response-shape.js.map +1 -0
  148. package/dist/declared-surfaces.d.ts +16 -0
  149. package/dist/declared-surfaces.d.ts.map +1 -0
  150. package/dist/declared-surfaces.js +19 -0
  151. package/dist/declared-surfaces.js.map +1 -0
  152. package/dist/depends-review.d.ts +113 -0
  153. package/dist/depends-review.d.ts.map +1 -0
  154. package/dist/depends-review.js +110 -0
  155. package/dist/depends-review.js.map +1 -0
  156. package/dist/doctor.d.ts +91 -0
  157. package/dist/doctor.d.ts.map +1 -0
  158. package/dist/doctor.js +71 -0
  159. package/dist/doctor.js.map +1 -0
  160. package/dist/edge-approval.d.ts +105 -0
  161. package/dist/edge-approval.d.ts.map +1 -0
  162. package/dist/edge-approval.js +100 -0
  163. package/dist/edge-approval.js.map +1 -0
  164. package/dist/evidence-cache.d.ts +45 -0
  165. package/dist/evidence-cache.d.ts.map +1 -0
  166. package/dist/evidence-cache.js +90 -0
  167. package/dist/evidence-cache.js.map +1 -0
  168. package/dist/evidence-cmd.d.ts +133 -0
  169. package/dist/evidence-cmd.d.ts.map +1 -0
  170. package/dist/evidence-cmd.js +347 -0
  171. package/dist/evidence-cmd.js.map +1 -0
  172. package/dist/evidence-facts.d.ts +40 -0
  173. package/dist/evidence-facts.d.ts.map +1 -0
  174. package/dist/evidence-facts.js +114 -0
  175. package/dist/evidence-facts.js.map +1 -0
  176. package/dist/exclusive-lock.d.ts +52 -0
  177. package/dist/exclusive-lock.d.ts.map +1 -0
  178. package/dist/exclusive-lock.js +150 -0
  179. package/dist/exclusive-lock.js.map +1 -0
  180. package/dist/exec-domains.d.ts +140 -0
  181. package/dist/exec-domains.d.ts.map +1 -0
  182. package/dist/exec-domains.js +287 -0
  183. package/dist/exec-domains.js.map +1 -0
  184. package/dist/exemption-store.d.ts +197 -0
  185. package/dist/exemption-store.d.ts.map +1 -0
  186. package/dist/exemption-store.js +266 -0
  187. package/dist/exemption-store.js.map +1 -0
  188. package/dist/explicit-start-gate.d.ts +96 -0
  189. package/dist/explicit-start-gate.d.ts.map +1 -0
  190. package/dist/explicit-start-gate.js +103 -0
  191. package/dist/explicit-start-gate.js.map +1 -0
  192. package/dist/fs-trouble.d.ts +70 -0
  193. package/dist/fs-trouble.d.ts.map +1 -0
  194. package/dist/fs-trouble.js +98 -0
  195. package/dist/fs-trouble.js.map +1 -0
  196. package/dist/gate.d.ts +278 -0
  197. package/dist/gate.d.ts.map +1 -0
  198. package/dist/gate.js +278 -0
  199. package/dist/gate.js.map +1 -0
  200. package/dist/git-driver.d.ts +519 -0
  201. package/dist/git-driver.d.ts.map +1 -0
  202. package/dist/git-driver.js +900 -0
  203. package/dist/git-driver.js.map +1 -0
  204. package/dist/git-push-executor.d.ts +41 -0
  205. package/dist/git-push-executor.d.ts.map +1 -0
  206. package/dist/git-push-executor.js +142 -0
  207. package/dist/git-push-executor.js.map +1 -0
  208. package/dist/glob.d.ts +26 -0
  209. package/dist/glob.d.ts.map +1 -0
  210. package/dist/glob.js +93 -0
  211. package/dist/glob.js.map +1 -0
  212. package/dist/goal-adaptive.d.ts +295 -0
  213. package/dist/goal-adaptive.d.ts.map +1 -0
  214. package/dist/goal-adaptive.js +393 -0
  215. package/dist/goal-adaptive.js.map +1 -0
  216. package/dist/goal-compile.d.ts +342 -0
  217. package/dist/goal-compile.d.ts.map +1 -0
  218. package/dist/goal-compile.js +444 -0
  219. package/dist/goal-compile.js.map +1 -0
  220. package/dist/goal-depends-executor.d.ts +55 -0
  221. package/dist/goal-depends-executor.d.ts.map +1 -0
  222. package/dist/goal-depends-executor.js +202 -0
  223. package/dist/goal-depends-executor.js.map +1 -0
  224. package/dist/goal-execution-evidence.d.ts +135 -0
  225. package/dist/goal-execution-evidence.d.ts.map +1 -0
  226. package/dist/goal-execution-evidence.js +159 -0
  227. package/dist/goal-execution-evidence.js.map +1 -0
  228. package/dist/goal-gap.d.ts +140 -0
  229. package/dist/goal-gap.d.ts.map +1 -0
  230. package/dist/goal-gap.js +197 -0
  231. package/dist/goal-gap.js.map +1 -0
  232. package/dist/goal-met-target.d.ts +98 -0
  233. package/dist/goal-met-target.d.ts.map +1 -0
  234. package/dist/goal-met-target.js +92 -0
  235. package/dist/goal-met-target.js.map +1 -0
  236. package/dist/goal-ownership.d.ts +416 -0
  237. package/dist/goal-ownership.d.ts.map +1 -0
  238. package/dist/goal-ownership.js +576 -0
  239. package/dist/goal-ownership.js.map +1 -0
  240. package/dist/goal-runs.d.ts +82 -0
  241. package/dist/goal-runs.d.ts.map +1 -0
  242. package/dist/goal-runs.js +120 -0
  243. package/dist/goal-runs.js.map +1 -0
  244. package/dist/goal-store.d.ts +146 -0
  245. package/dist/goal-store.d.ts.map +1 -0
  246. package/dist/goal-store.js +294 -0
  247. package/dist/goal-store.js.map +1 -0
  248. package/dist/goal-view.d.ts +156 -0
  249. package/dist/goal-view.d.ts.map +1 -0
  250. package/dist/goal-view.js +499 -0
  251. package/dist/goal-view.js.map +1 -0
  252. package/dist/governed-approvals.d.ts +152 -0
  253. package/dist/governed-approvals.d.ts.map +1 -0
  254. package/dist/governed-approvals.js +246 -0
  255. package/dist/governed-approvals.js.map +1 -0
  256. package/dist/governed-broker.d.ts +169 -0
  257. package/dist/governed-broker.d.ts.map +1 -0
  258. package/dist/governed-broker.js +196 -0
  259. package/dist/governed-broker.js.map +1 -0
  260. package/dist/governed-run.d.ts +220 -0
  261. package/dist/governed-run.d.ts.map +1 -0
  262. package/dist/governed-run.js +406 -0
  263. package/dist/governed-run.js.map +1 -0
  264. package/dist/grant-reconcile.d.ts +63 -0
  265. package/dist/grant-reconcile.d.ts.map +1 -0
  266. package/dist/grant-reconcile.js +121 -0
  267. package/dist/grant-reconcile.js.map +1 -0
  268. package/dist/index-for-head.d.ts +56 -0
  269. package/dist/index-for-head.d.ts.map +1 -0
  270. package/dist/index-for-head.js +103 -0
  271. package/dist/index-for-head.js.map +1 -0
  272. package/dist/index.d.ts +39 -0
  273. package/dist/index.d.ts.map +1 -0
  274. package/dist/index.js +55 -0
  275. package/dist/index.js.map +1 -0
  276. package/dist/init-detect.d.ts +39 -0
  277. package/dist/init-detect.d.ts.map +1 -0
  278. package/dist/init-detect.js +188 -0
  279. package/dist/init-detect.js.map +1 -0
  280. package/dist/integration-deps.d.ts +62 -0
  281. package/dist/integration-deps.d.ts.map +1 -0
  282. package/dist/integration-deps.js +251 -0
  283. package/dist/integration-deps.js.map +1 -0
  284. package/dist/integration-runtime.d.ts +458 -0
  285. package/dist/integration-runtime.d.ts.map +1 -0
  286. package/dist/integration-runtime.js +681 -0
  287. package/dist/integration-runtime.js.map +1 -0
  288. package/dist/integration.d.ts +45 -0
  289. package/dist/integration.d.ts.map +1 -0
  290. package/dist/integration.js +87 -0
  291. package/dist/integration.js.map +1 -0
  292. package/dist/integrator.d.ts +84 -0
  293. package/dist/integrator.d.ts.map +1 -0
  294. package/dist/integrator.js +193 -0
  295. package/dist/integrator.js.map +1 -0
  296. package/dist/lane-claims.d.ts +174 -0
  297. package/dist/lane-claims.d.ts.map +1 -0
  298. package/dist/lane-claims.js +218 -0
  299. package/dist/lane-claims.js.map +1 -0
  300. package/dist/lane-coverage.d.ts +87 -0
  301. package/dist/lane-coverage.d.ts.map +1 -0
  302. package/dist/lane-coverage.js +129 -0
  303. package/dist/lane-coverage.js.map +1 -0
  304. package/dist/ledger-replay.d.ts +115 -0
  305. package/dist/ledger-replay.d.ts.map +1 -0
  306. package/dist/ledger-replay.js +155 -0
  307. package/dist/ledger-replay.js.map +1 -0
  308. package/dist/ledger-store.d.ts +68 -0
  309. package/dist/ledger-store.d.ts.map +1 -0
  310. package/dist/ledger-store.js +111 -0
  311. package/dist/ledger-store.js.map +1 -0
  312. package/dist/loop-safety-observer.d.ts +132 -0
  313. package/dist/loop-safety-observer.d.ts.map +1 -0
  314. package/dist/loop-safety-observer.js +76 -0
  315. package/dist/loop-safety-observer.js.map +1 -0
  316. package/dist/loop-safety-store.d.ts +339 -0
  317. package/dist/loop-safety-store.d.ts.map +1 -0
  318. package/dist/loop-safety-store.js +800 -0
  319. package/dist/loop-safety-store.js.map +1 -0
  320. package/dist/machine-store.d.ts +54 -0
  321. package/dist/machine-store.d.ts.map +1 -0
  322. package/dist/machine-store.js +149 -0
  323. package/dist/machine-store.js.map +1 -0
  324. package/dist/mcp-main.d.ts +2 -0
  325. package/dist/mcp-main.d.ts.map +1 -0
  326. package/dist/mcp-main.js +116 -0
  327. package/dist/mcp-main.js.map +1 -0
  328. package/dist/mcp-server.d.ts +72 -0
  329. package/dist/mcp-server.d.ts.map +1 -0
  330. package/dist/mcp-server.js +259 -0
  331. package/dist/mcp-server.js.map +1 -0
  332. package/dist/model-routing.d.ts +75 -0
  333. package/dist/model-routing.d.ts.map +1 -0
  334. package/dist/model-routing.js +108 -0
  335. package/dist/model-routing.js.map +1 -0
  336. package/dist/model-transport.d.ts +188 -0
  337. package/dist/model-transport.d.ts.map +1 -0
  338. package/dist/model-transport.js +625 -0
  339. package/dist/model-transport.js.map +1 -0
  340. package/dist/notify-cadence.d.ts +55 -0
  341. package/dist/notify-cadence.d.ts.map +1 -0
  342. package/dist/notify-cadence.js +68 -0
  343. package/dist/notify-cadence.js.map +1 -0
  344. package/dist/notify-channel.d.ts +69 -0
  345. package/dist/notify-channel.d.ts.map +1 -0
  346. package/dist/notify-channel.js +151 -0
  347. package/dist/notify-channel.js.map +1 -0
  348. package/dist/notify.d.ts +71 -0
  349. package/dist/notify.d.ts.map +1 -0
  350. package/dist/notify.js +125 -0
  351. package/dist/notify.js.map +1 -0
  352. package/dist/observation-inventory.d.ts +65 -0
  353. package/dist/observation-inventory.d.ts.map +1 -0
  354. package/dist/observation-inventory.js +139 -0
  355. package/dist/observation-inventory.js.map +1 -0
  356. package/dist/owned-children.d.ts +45 -0
  357. package/dist/owned-children.d.ts.map +1 -0
  358. package/dist/owned-children.js +64 -0
  359. package/dist/owned-children.js.map +1 -0
  360. package/dist/packet-for-goal.d.ts +19 -0
  361. package/dist/packet-for-goal.d.ts.map +1 -0
  362. package/dist/packet-for-goal.js +32 -0
  363. package/dist/packet-for-goal.js.map +1 -0
  364. package/dist/pair-cmd.d.ts +85 -0
  365. package/dist/pair-cmd.d.ts.map +1 -0
  366. package/dist/pair-cmd.js +205 -0
  367. package/dist/pair-cmd.js.map +1 -0
  368. package/dist/partial-asker.d.ts +96 -0
  369. package/dist/partial-asker.d.ts.map +1 -0
  370. package/dist/partial-asker.js +117 -0
  371. package/dist/partial-asker.js.map +1 -0
  372. package/dist/pdf-text-lines.d.ts +17 -0
  373. package/dist/pdf-text-lines.d.ts.map +1 -0
  374. package/dist/pdf-text-lines.js +70 -0
  375. package/dist/pdf-text-lines.js.map +1 -0
  376. package/dist/pdf-text-worker.d.ts +2 -0
  377. package/dist/pdf-text-worker.d.ts.map +1 -0
  378. package/dist/pdf-text-worker.js +81 -0
  379. package/dist/pdf-text-worker.js.map +1 -0
  380. package/dist/pdf-text.d.ts +56 -0
  381. package/dist/pdf-text.d.ts.map +1 -0
  382. package/dist/pdf-text.js +64 -0
  383. package/dist/pdf-text.js.map +1 -0
  384. package/dist/pending-action.d.ts +154 -0
  385. package/dist/pending-action.d.ts.map +1 -0
  386. package/dist/pending-action.js +148 -0
  387. package/dist/pending-action.js.map +1 -0
  388. package/dist/preemptor.d.ts +40 -0
  389. package/dist/preemptor.d.ts.map +1 -0
  390. package/dist/preemptor.js +49 -0
  391. package/dist/preemptor.js.map +1 -0
  392. package/dist/programme-mode.d.ts +29 -0
  393. package/dist/programme-mode.d.ts.map +1 -0
  394. package/dist/programme-mode.js +50 -0
  395. package/dist/programme-mode.js.map +1 -0
  396. package/dist/progress-view.d.ts +14 -0
  397. package/dist/progress-view.d.ts.map +1 -0
  398. package/dist/progress-view.js +114 -0
  399. package/dist/progress-view.js.map +1 -0
  400. package/dist/project-graph-builder.d.ts +81 -0
  401. package/dist/project-graph-builder.d.ts.map +1 -0
  402. package/dist/project-graph-builder.js +246 -0
  403. package/dist/project-graph-builder.js.map +1 -0
  404. package/dist/project-graph-runtime.d.ts +86 -0
  405. package/dist/project-graph-runtime.d.ts.map +1 -0
  406. package/dist/project-graph-runtime.js +112 -0
  407. package/dist/project-graph-runtime.js.map +1 -0
  408. package/dist/project-index-builder.d.ts +96 -0
  409. package/dist/project-index-builder.d.ts.map +1 -0
  410. package/dist/project-index-builder.js +298 -0
  411. package/dist/project-index-builder.js.map +1 -0
  412. package/dist/project-index-facts.d.ts +51 -0
  413. package/dist/project-index-facts.d.ts.map +1 -0
  414. package/dist/project-index-facts.js +117 -0
  415. package/dist/project-index-facts.js.map +1 -0
  416. package/dist/project-index-store.d.ts +97 -0
  417. package/dist/project-index-store.d.ts.map +1 -0
  418. package/dist/project-index-store.js +140 -0
  419. package/dist/project-index-store.js.map +1 -0
  420. package/dist/project-memory-store.d.ts +127 -0
  421. package/dist/project-memory-store.d.ts.map +1 -0
  422. package/dist/project-memory-store.js +302 -0
  423. package/dist/project-memory-store.js.map +1 -0
  424. package/dist/proposal-store.d.ts +14 -0
  425. package/dist/proposal-store.d.ts.map +1 -0
  426. package/dist/proposal-store.js +19 -0
  427. package/dist/proposal-store.js.map +1 -0
  428. package/dist/prover.d.ts +80 -0
  429. package/dist/prover.d.ts.map +1 -0
  430. package/dist/prover.js +137 -0
  431. package/dist/prover.js.map +1 -0
  432. package/dist/provider-identity-store.d.ts +34 -0
  433. package/dist/provider-identity-store.d.ts.map +1 -0
  434. package/dist/provider-identity-store.js +72 -0
  435. package/dist/provider-identity-store.js.map +1 -0
  436. package/dist/provider-identity.d.ts +104 -0
  437. package/dist/provider-identity.d.ts.map +1 -0
  438. package/dist/provider-identity.js +167 -0
  439. package/dist/provider-identity.js.map +1 -0
  440. package/dist/provider-limit.d.ts +79 -0
  441. package/dist/provider-limit.d.ts.map +1 -0
  442. package/dist/provider-limit.js +148 -0
  443. package/dist/provider-limit.js.map +1 -0
  444. package/dist/provider-preflight.d.ts +171 -0
  445. package/dist/provider-preflight.d.ts.map +1 -0
  446. package/dist/provider-preflight.js +395 -0
  447. package/dist/provider-preflight.js.map +1 -0
  448. package/dist/provider-state.d.ts +120 -0
  449. package/dist/provider-state.d.ts.map +1 -0
  450. package/dist/provider-state.js +182 -0
  451. package/dist/provider-state.js.map +1 -0
  452. package/dist/providers.d.ts +132 -0
  453. package/dist/providers.d.ts.map +1 -0
  454. package/dist/providers.js +161 -0
  455. package/dist/providers.js.map +1 -0
  456. package/dist/publication-recorder.d.ts +117 -0
  457. package/dist/publication-recorder.d.ts.map +1 -0
  458. package/dist/publication-recorder.js +124 -0
  459. package/dist/publication-recorder.js.map +1 -0
  460. package/dist/pursuit-delivery.d.ts +24 -0
  461. package/dist/pursuit-delivery.d.ts.map +1 -0
  462. package/dist/pursuit-delivery.js +38 -0
  463. package/dist/pursuit-delivery.js.map +1 -0
  464. package/dist/queue-store.d.ts +132 -0
  465. package/dist/queue-store.d.ts.map +1 -0
  466. package/dist/queue-store.js +185 -0
  467. package/dist/queue-store.js.map +1 -0
  468. package/dist/queue-summary.d.ts +14 -0
  469. package/dist/queue-summary.d.ts.map +1 -0
  470. package/dist/queue-summary.js +82 -0
  471. package/dist/queue-summary.js.map +1 -0
  472. package/dist/queue-view.d.ts +20 -0
  473. package/dist/queue-view.d.ts.map +1 -0
  474. package/dist/queue-view.js +163 -0
  475. package/dist/queue-view.js.map +1 -0
  476. package/dist/queue-write-lease.d.ts +106 -0
  477. package/dist/queue-write-lease.d.ts.map +1 -0
  478. package/dist/queue-write-lease.js +282 -0
  479. package/dist/queue-write-lease.js.map +1 -0
  480. package/dist/rails-home.d.ts +162 -0
  481. package/dist/rails-home.d.ts.map +1 -0
  482. package/dist/rails-home.js +452 -0
  483. package/dist/rails-home.js.map +1 -0
  484. package/dist/rails-migrations.d.ts +75 -0
  485. package/dist/rails-migrations.d.ts.map +1 -0
  486. package/dist/rails-migrations.js +199 -0
  487. package/dist/rails-migrations.js.map +1 -0
  488. package/dist/rails-stores.d.ts +49 -0
  489. package/dist/rails-stores.d.ts.map +1 -0
  490. package/dist/rails-stores.js +100 -0
  491. package/dist/rails-stores.js.map +1 -0
  492. package/dist/reaper.d.ts +69 -0
  493. package/dist/reaper.d.ts.map +1 -0
  494. package/dist/reaper.js +152 -0
  495. package/dist/reaper.js.map +1 -0
  496. package/dist/record-store.d.ts +36 -0
  497. package/dist/record-store.d.ts.map +1 -0
  498. package/dist/record-store.js +78 -0
  499. package/dist/record-store.js.map +1 -0
  500. package/dist/recovery-io.d.ts +50 -0
  501. package/dist/recovery-io.d.ts.map +1 -0
  502. package/dist/recovery-io.js +122 -0
  503. package/dist/recovery-io.js.map +1 -0
  504. package/dist/recovery.d.ts +146 -0
  505. package/dist/recovery.d.ts.map +1 -0
  506. package/dist/recovery.js +110 -0
  507. package/dist/recovery.js.map +1 -0
  508. package/dist/redraw.d.ts +34 -0
  509. package/dist/redraw.d.ts.map +1 -0
  510. package/dist/redraw.js +62 -0
  511. package/dist/redraw.js.map +1 -0
  512. package/dist/rejected-evidence.d.ts +255 -0
  513. package/dist/rejected-evidence.d.ts.map +1 -0
  514. package/dist/rejected-evidence.js +324 -0
  515. package/dist/rejected-evidence.js.map +1 -0
  516. package/dist/report-cmd.d.ts +32 -0
  517. package/dist/report-cmd.d.ts.map +1 -0
  518. package/dist/report-cmd.js +201 -0
  519. package/dist/report-cmd.js.map +1 -0
  520. package/dist/repos-cmd.d.ts +80 -0
  521. package/dist/repos-cmd.d.ts.map +1 -0
  522. package/dist/repos-cmd.js +240 -0
  523. package/dist/repos-cmd.js.map +1 -0
  524. package/dist/request-body-shape.d.ts +93 -0
  525. package/dist/request-body-shape.d.ts.map +1 -0
  526. package/dist/request-body-shape.js +407 -0
  527. package/dist/request-body-shape.js.map +1 -0
  528. package/dist/requirement-claims.d.ts +89 -0
  529. package/dist/requirement-claims.d.ts.map +1 -0
  530. package/dist/requirement-claims.js +92 -0
  531. package/dist/requirement-claims.js.map +1 -0
  532. package/dist/retention-apply-runtime.d.ts +105 -0
  533. package/dist/retention-apply-runtime.d.ts.map +1 -0
  534. package/dist/retention-apply-runtime.js +269 -0
  535. package/dist/retention-apply-runtime.js.map +1 -0
  536. package/dist/reverify.d.ts +41 -0
  537. package/dist/reverify.d.ts.map +1 -0
  538. package/dist/reverify.js +69 -0
  539. package/dist/reverify.js.map +1 -0
  540. package/dist/round-records.d.ts +65 -0
  541. package/dist/round-records.d.ts.map +1 -0
  542. package/dist/round-records.js +61 -0
  543. package/dist/round-records.js.map +1 -0
  544. package/dist/round-runner.d.ts +924 -0
  545. package/dist/round-runner.d.ts.map +1 -0
  546. package/dist/round-runner.js +1693 -0
  547. package/dist/round-runner.js.map +1 -0
  548. package/dist/run-approval.d.ts +180 -0
  549. package/dist/run-approval.d.ts.map +1 -0
  550. package/dist/run-approval.js +199 -0
  551. package/dist/run-approval.js.map +1 -0
  552. package/dist/run-cmd.d.ts +359 -0
  553. package/dist/run-cmd.d.ts.map +1 -0
  554. package/dist/run-cmd.js +4418 -0
  555. package/dist/run-cmd.js.map +1 -0
  556. package/dist/run-delivery.d.ts +71 -0
  557. package/dist/run-delivery.d.ts.map +1 -0
  558. package/dist/run-delivery.js +104 -0
  559. package/dist/run-delivery.js.map +1 -0
  560. package/dist/run-ended.d.ts +75 -0
  561. package/dist/run-ended.d.ts.map +1 -0
  562. package/dist/run-ended.js +27 -0
  563. package/dist/run-ended.js.map +1 -0
  564. package/dist/run-ending-locator.d.ts +125 -0
  565. package/dist/run-ending-locator.d.ts.map +1 -0
  566. package/dist/run-ending-locator.js +133 -0
  567. package/dist/run-ending-locator.js.map +1 -0
  568. package/dist/run-launcher.d.ts +459 -0
  569. package/dist/run-launcher.d.ts.map +1 -0
  570. package/dist/run-launcher.js +652 -0
  571. package/dist/run-launcher.js.map +1 -0
  572. package/dist/run-lease.d.ts +208 -0
  573. package/dist/run-lease.d.ts.map +1 -0
  574. package/dist/run-lease.js +301 -0
  575. package/dist/run-lease.js.map +1 -0
  576. package/dist/run-refusal-marks.d.ts +189 -0
  577. package/dist/run-refusal-marks.d.ts.map +1 -0
  578. package/dist/run-refusal-marks.js +249 -0
  579. package/dist/run-refusal-marks.js.map +1 -0
  580. package/dist/run-start-marks.d.ts +153 -0
  581. package/dist/run-start-marks.d.ts.map +1 -0
  582. package/dist/run-start-marks.js +269 -0
  583. package/dist/run-start-marks.js.map +1 -0
  584. package/dist/scan-cmd.d.ts +14 -0
  585. package/dist/scan-cmd.d.ts.map +1 -0
  586. package/dist/scan-cmd.js +270 -0
  587. package/dist/scan-cmd.js.map +1 -0
  588. package/dist/scan-events.d.ts +50 -0
  589. package/dist/scan-events.d.ts.map +1 -0
  590. package/dist/scan-events.js +91 -0
  591. package/dist/scan-events.js.map +1 -0
  592. package/dist/scan.d.ts +191 -0
  593. package/dist/scan.d.ts.map +1 -0
  594. package/dist/scan.js +417 -0
  595. package/dist/scan.js.map +1 -0
  596. package/dist/scope-rule.d.ts +148 -0
  597. package/dist/scope-rule.d.ts.map +1 -0
  598. package/dist/scope-rule.js +121 -0
  599. package/dist/scope-rule.js.map +1 -0
  600. package/dist/self-repo-id.d.ts +18 -0
  601. package/dist/self-repo-id.d.ts.map +1 -0
  602. package/dist/self-repo-id.js +70 -0
  603. package/dist/self-repo-id.js.map +1 -0
  604. package/dist/server-client.d.ts +766 -0
  605. package/dist/server-client.d.ts.map +1 -0
  606. package/dist/server-client.js +475 -0
  607. package/dist/server-client.js.map +1 -0
  608. package/dist/session-adapter-runtime.d.ts +195 -0
  609. package/dist/session-adapter-runtime.d.ts.map +1 -0
  610. package/dist/session-adapter-runtime.js +373 -0
  611. package/dist/session-adapter-runtime.js.map +1 -0
  612. package/dist/session-checkpoint-runtime.d.ts +62 -0
  613. package/dist/session-checkpoint-runtime.d.ts.map +1 -0
  614. package/dist/session-checkpoint-runtime.js +268 -0
  615. package/dist/session-checkpoint-runtime.js.map +1 -0
  616. package/dist/session-control-transport.d.ts +106 -0
  617. package/dist/session-control-transport.d.ts.map +1 -0
  618. package/dist/session-control-transport.js +232 -0
  619. package/dist/session-control-transport.js.map +1 -0
  620. package/dist/session-observation-store.d.ts +98 -0
  621. package/dist/session-observation-store.d.ts.map +1 -0
  622. package/dist/session-observation-store.js +155 -0
  623. package/dist/session-observation-store.js.map +1 -0
  624. package/dist/session-observe-runtime.d.ts +123 -0
  625. package/dist/session-observe-runtime.d.ts.map +1 -0
  626. package/dist/session-observe-runtime.js +317 -0
  627. package/dist/session-observe-runtime.js.map +1 -0
  628. package/dist/session-store.d.ts +98 -0
  629. package/dist/session-store.d.ts.map +1 -0
  630. package/dist/session-store.js +116 -0
  631. package/dist/session-store.js.map +1 -0
  632. package/dist/sessions-cmd.d.ts +202 -0
  633. package/dist/sessions-cmd.d.ts.map +1 -0
  634. package/dist/sessions-cmd.js +609 -0
  635. package/dist/sessions-cmd.js.map +1 -0
  636. package/dist/settings-overlay.d.ts +53 -0
  637. package/dist/settings-overlay.d.ts.map +1 -0
  638. package/dist/settings-overlay.js +175 -0
  639. package/dist/settings-overlay.js.map +1 -0
  640. package/dist/setup-prompt.d.ts +34 -0
  641. package/dist/setup-prompt.d.ts.map +1 -0
  642. package/dist/setup-prompt.js +92 -0
  643. package/dist/setup-prompt.js.map +1 -0
  644. package/dist/setup.d.ts +103 -0
  645. package/dist/setup.d.ts.map +1 -0
  646. package/dist/setup.js +283 -0
  647. package/dist/setup.js.map +1 -0
  648. package/dist/shared-grants.d.ts +164 -0
  649. package/dist/shared-grants.d.ts.map +1 -0
  650. package/dist/shared-grants.js +242 -0
  651. package/dist/shared-grants.js.map +1 -0
  652. package/dist/signals.d.ts +55 -0
  653. package/dist/signals.d.ts.map +1 -0
  654. package/dist/signals.js +85 -0
  655. package/dist/signals.js.map +1 -0
  656. package/dist/source-cmd.d.ts +201 -0
  657. package/dist/source-cmd.d.ts.map +1 -0
  658. package/dist/source-cmd.js +684 -0
  659. package/dist/source-cmd.js.map +1 -0
  660. package/dist/source-verdict.d.ts +99 -0
  661. package/dist/source-verdict.d.ts.map +1 -0
  662. package/dist/source-verdict.js +182 -0
  663. package/dist/source-verdict.js.map +1 -0
  664. package/dist/spend-ledger.d.ts +350 -0
  665. package/dist/spend-ledger.d.ts.map +1 -0
  666. package/dist/spend-ledger.js +546 -0
  667. package/dist/spend-ledger.js.map +1 -0
  668. package/dist/stale-run-sweep.d.ts +79 -0
  669. package/dist/stale-run-sweep.d.ts.map +1 -0
  670. package/dist/stale-run-sweep.js +116 -0
  671. package/dist/stale-run-sweep.js.map +1 -0
  672. package/dist/start-attempts.d.ts +385 -0
  673. package/dist/start-attempts.d.ts.map +1 -0
  674. package/dist/start-attempts.js +613 -0
  675. package/dist/start-attempts.js.map +1 -0
  676. package/dist/status-cmd.d.ts +28 -0
  677. package/dist/status-cmd.d.ts.map +1 -0
  678. package/dist/status-cmd.js +116 -0
  679. package/dist/status-cmd.js.map +1 -0
  680. package/dist/stop-follow-up.d.ts +107 -0
  681. package/dist/stop-follow-up.d.ts.map +1 -0
  682. package/dist/stop-follow-up.js +172 -0
  683. package/dist/stop-follow-up.js.map +1 -0
  684. package/dist/surface-lease.d.ts +118 -0
  685. package/dist/surface-lease.d.ts.map +1 -0
  686. package/dist/surface-lease.js +485 -0
  687. package/dist/surface-lease.js.map +1 -0
  688. package/dist/sync.d.ts +54 -0
  689. package/dist/sync.d.ts.map +1 -0
  690. package/dist/sync.js +93 -0
  691. package/dist/sync.js.map +1 -0
  692. package/dist/syncing-ledger.d.ts +45 -0
  693. package/dist/syncing-ledger.d.ts.map +1 -0
  694. package/dist/syncing-ledger.js +53 -0
  695. package/dist/syncing-ledger.js.map +1 -0
  696. package/dist/temp-fixtures.d.ts +68 -0
  697. package/dist/temp-fixtures.d.ts.map +1 -0
  698. package/dist/temp-fixtures.js +38 -0
  699. package/dist/temp-fixtures.js.map +1 -0
  700. package/dist/token-window.d.ts +84 -0
  701. package/dist/token-window.d.ts.map +1 -0
  702. package/dist/token-window.js +143 -0
  703. package/dist/token-window.js.map +1 -0
  704. package/dist/tool-bridge.d.ts +177 -0
  705. package/dist/tool-bridge.d.ts.map +1 -0
  706. package/dist/tool-bridge.js +329 -0
  707. package/dist/tool-bridge.js.map +1 -0
  708. package/dist/tool-call-record.d.ts +197 -0
  709. package/dist/tool-call-record.d.ts.map +1 -0
  710. package/dist/tool-call-record.js +276 -0
  711. package/dist/tool-call-record.js.map +1 -0
  712. package/dist/tool-protocol.d.ts +135 -0
  713. package/dist/tool-protocol.d.ts.map +1 -0
  714. package/dist/tool-protocol.js +104 -0
  715. package/dist/tool-protocol.js.map +1 -0
  716. package/dist/tool-worker.d.ts +3 -0
  717. package/dist/tool-worker.d.ts.map +1 -0
  718. package/dist/tool-worker.js +478 -0
  719. package/dist/tool-worker.js.map +1 -0
  720. package/dist/toolchain-mirror.d.ts +86 -0
  721. package/dist/toolchain-mirror.d.ts.map +1 -0
  722. package/dist/toolchain-mirror.js +307 -0
  723. package/dist/toolchain-mirror.js.map +1 -0
  724. package/dist/trusted-git.d.ts +243 -0
  725. package/dist/trusted-git.d.ts.map +1 -0
  726. package/dist/trusted-git.js +920 -0
  727. package/dist/trusted-git.js.map +1 -0
  728. package/dist/ui.d.ts +76 -0
  729. package/dist/ui.d.ts.map +1 -0
  730. package/dist/ui.js +118 -0
  731. package/dist/ui.js.map +1 -0
  732. package/dist/untrusted-exec.d.ts +275 -0
  733. package/dist/untrusted-exec.d.ts.map +1 -0
  734. package/dist/untrusted-exec.js +479 -0
  735. package/dist/untrusted-exec.js.map +1 -0
  736. package/dist/untrusted-gate.d.ts +73 -0
  737. package/dist/untrusted-gate.d.ts.map +1 -0
  738. package/dist/untrusted-gate.js +226 -0
  739. package/dist/untrusted-gate.js.map +1 -0
  740. package/dist/uploader.d.ts +153 -0
  741. package/dist/uploader.d.ts.map +1 -0
  742. package/dist/uploader.js +204 -0
  743. package/dist/uploader.js.map +1 -0
  744. package/dist/verifier.d.ts +66 -0
  745. package/dist/verifier.d.ts.map +1 -0
  746. package/dist/verifier.js +170 -0
  747. package/dist/verifier.js.map +1 -0
  748. package/dist/verify-apply.d.ts +26 -0
  749. package/dist/verify-apply.d.ts.map +1 -0
  750. package/dist/verify-apply.js +36 -0
  751. package/dist/verify-apply.js.map +1 -0
  752. package/dist/verify-cmd.d.ts +44 -0
  753. package/dist/verify-cmd.d.ts.map +1 -0
  754. package/dist/verify-cmd.js +125 -0
  755. package/dist/verify-cmd.js.map +1 -0
  756. package/dist/verify-pass.d.ts +73 -0
  757. package/dist/verify-pass.d.ts.map +1 -0
  758. package/dist/verify-pass.js +103 -0
  759. package/dist/verify-pass.js.map +1 -0
  760. package/dist/welcome.d.ts +43 -0
  761. package/dist/welcome.d.ts.map +1 -0
  762. package/dist/welcome.js +116 -0
  763. package/dist/welcome.js.map +1 -0
  764. package/dist/workspace-provisioner.d.ts +65 -0
  765. package/dist/workspace-provisioner.d.ts.map +1 -0
  766. package/dist/workspace-provisioner.js +66 -0
  767. package/dist/workspace-provisioner.js.map +1 -0
  768. package/dist/workspace-quarantine.d.ts +64 -0
  769. package/dist/workspace-quarantine.d.ts.map +1 -0
  770. package/dist/workspace-quarantine.js +156 -0
  771. package/dist/workspace-quarantine.js.map +1 -0
  772. package/dist/workspace-residue-sweep.d.ts +113 -0
  773. package/dist/workspace-residue-sweep.d.ts.map +1 -0
  774. package/dist/workspace-residue-sweep.js +158 -0
  775. package/dist/workspace-residue-sweep.js.map +1 -0
  776. package/dist/workspace.d.ts +639 -0
  777. package/dist/workspace.d.ts.map +1 -0
  778. package/dist/workspace.js +2026 -0
  779. package/dist/workspace.js.map +1 -0
  780. package/package.json +54 -6
  781. package/win/CredProbe.cs +64 -0
  782. package/win/FakeClaude.cs +56 -0
  783. package/win/HandleProbe.cs +116 -0
  784. package/win/TokenProbe.cs +53 -0
  785. package/win/appcontainer.ps1 +500 -0
@@ -0,0 +1,684 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXIT = exports.SOURCE_USAGE = void 0;
4
+ exports.kindForFile = kindForFile;
5
+ exports.clientRefFor = clientRefFor;
6
+ exports.sourceCommand = sourceCommand;
7
+ exports.anchorLabel = anchorLabel;
8
+ exports.dispositionLabel = dispositionLabel;
9
+ exports.attestationLabel = attestationLabel;
10
+ exports.renderSource = renderSource;
11
+ exports.renderCoverage = renderCoverage;
12
+ exports.nodeSourceDeps = nodeSourceDeps;
13
+ const crypto_1 = require("crypto");
14
+ const node_fs_1 = require("node:fs");
15
+ const node_path_1 = require("node:path");
16
+ const core_1 = require("@looply/core");
17
+ const index_for_head_1 = require("./index-for-head");
18
+ const machine_store_1 = require("./machine-store");
19
+ const pdf_text_1 = require("./pdf-text");
20
+ const server_client_1 = require("./server-client");
21
+ const source_verdict_1 = require("./source-verdict");
22
+ /**
23
+ * `looply source` — hand a document to the project from the machine that holds it.
24
+ *
25
+ * ─────────────────────────────────────────────────────────────────────────────
26
+ * WHY THIS IS A CLI VERB AND NOT A PHONE SCREEN
27
+ *
28
+ * A plan lives beside the repository, on the developer's disk. Handing it over
29
+ * is a file operation, and the machine that holds the file is the natural
30
+ * caller — the same reason project creation is a machine act. The phone reads
31
+ * what was handed over; it does not type documents.
32
+ *
33
+ * ⚠️ LOCAL REFUSALS COME FIRST. The kind is decided from the extension, the
34
+ * file is read, and the same `whyUnreadable` and size bound the server applies
35
+ * are applied HERE, before pairing is even looked at — so a person gets the
36
+ * real answer ("no text layer", "this file has a NUL byte") without a network
37
+ * round trip, and an unpaired machine is told to pair only when the document
38
+ * itself was fine.
39
+ *
40
+ * A PDF is read HERE, on the machine that holds it (`pdf-text.ts`): its text
41
+ * layer goes to the server page by page, and the file's own sha256 travels
42
+ * beside it as provenance. A scanned PDF — no text layer — is refused with
43
+ * the reason, never sent as an empty document.
44
+ *
45
+ * 🔴 THE CONTENT IS DATA. Nothing in this file interprets the document. The
46
+ * text goes to the server verbatim; the server derives the statements with the
47
+ * same extractor the fixture tests hold to account.
48
+ *
49
+ * `clientRef` is derived from the content's sha256, so running the command
50
+ * twice on the same file is the same request twice — the server answers with
51
+ * the source it already has and this prints "already stored".
52
+ *
53
+ * `looply source reconcile <id>` measures where each requirement stands against
54
+ * THIS repository: the project index of HEAD's tree (the same one a run
55
+ * builds) is read here, `@looply/core`'s reconciler decides — absent, a
56
+ * candidate place to look, conflicting, or blocked — and the result is handed
57
+ * over keyed by the tree. Nothing here, on the machine or on the server, says
58
+ * "implemented": that is a person's attestation with evidence, a later verb.
59
+ */
60
+ exports.SOURCE_USAGE = `usage:
61
+ looply source add <file> [--name <name>] hand a Markdown (.md), plain-text (.txt) or PDF (.pdf, with a text layer) document to this project
62
+ looply source list what this project has been given
63
+ looply source show <id> one source: its statements, what each one IS, where it came from, and where each requirement stands
64
+ looply source reconcile <id> measure where each requirement stands against this repository (HEAD's tree), and record it
65
+ looply source coverage <id> which requirements no goal serves, which are served, and which a person evidenced
66
+ looply source plan <id> [--dry-run] propose goals from this document’s requirements, grouped by its headings, and set them
67
+ looply source verdict <id> the final verdict on the integrated tree: COMPLETE, or every unmet requirement
68
+ `;
69
+ /** Exit codes, in the sysexits tradition the rest of the CLI follows for 64. */
70
+ exports.EXIT = {
71
+ ok: 0,
72
+ refused: 1,
73
+ usage: 64,
74
+ unreadable: 65,
75
+ noInput: 66,
76
+ unavailable: 69,
77
+ };
78
+ /** Which kind a file is, decided from its extension alone — and by name what it is not. */
79
+ function kindForFile(path) {
80
+ const ext = (0, node_path_1.extname)(path).toLowerCase();
81
+ if (ext === '.md' || ext === '.markdown')
82
+ return { ok: true, kind: 'markdown' };
83
+ if (ext === '.txt' || ext === '.text')
84
+ return { ok: true, kind: 'text' };
85
+ if (ext === '.pdf')
86
+ return { ok: true, kind: 'pdf' };
87
+ const shown = ext === '' ? 'a file with no extension' : `${ext} files`;
88
+ return { ok: false, because: `${shown} are not supported; Markdown (.md), plain text (.txt) and PDF (.pdf) are` };
89
+ }
90
+ /** The idempotency key for a document: its own bytes. */
91
+ function clientRefFor(sha256) {
92
+ return `cli:${sha256}`;
93
+ }
94
+ async function sourceCommand(argv, deps) {
95
+ const [sub, ...rest] = argv;
96
+ if (sub === 'add')
97
+ return add(rest, deps);
98
+ if (sub === 'list')
99
+ return list(deps);
100
+ if (sub === 'show')
101
+ return show(rest, deps);
102
+ if (sub === 'reconcile')
103
+ return reconcile(rest, deps);
104
+ if (sub === 'coverage')
105
+ return coverage(rest, deps);
106
+ if (sub === 'plan')
107
+ return plan(rest, deps);
108
+ if (sub === 'verdict')
109
+ return verdict(rest, deps);
110
+ deps.err(sub === undefined ? exports.SOURCE_USAGE : `looply source: unknown subcommand ${JSON.stringify(sub)}\n\n${exports.SOURCE_USAGE}`);
111
+ return exports.EXIT.usage;
112
+ }
113
+ async function add(argv, deps) {
114
+ const nameAt = argv.indexOf('--name');
115
+ const nameGiven = nameAt >= 0 ? argv[nameAt + 1] : undefined;
116
+ const positional = argv
117
+ .filter((_, i) => nameAt < 0 || (i !== nameAt && i !== nameAt + 1))
118
+ .filter((a) => !a.startsWith('--'));
119
+ const file = positional[0];
120
+ if (!file) {
121
+ deps.err(`looply source add: which file?\n\n${exports.SOURCE_USAGE}`);
122
+ return exports.EXIT.usage;
123
+ }
124
+ if (nameAt >= 0 && !nameGiven) {
125
+ deps.err('looply source add: --name needs a value');
126
+ return exports.EXIT.usage;
127
+ }
128
+ // 1. The kind, by name — before reading anything.
129
+ const kind = kindForFile(file);
130
+ if (!kind.ok) {
131
+ deps.err(`looply source add: ${kind.because}`);
132
+ return exports.EXIT.unreadable;
133
+ }
134
+ // 2. The bytes, where they live — and for a PDF, its text layer, read here.
135
+ const absolute = (0, node_path_1.resolve)(deps.cwd(), file);
136
+ let content;
137
+ let pages;
138
+ let originSha256;
139
+ if (kind.kind === 'pdf') {
140
+ let bytes;
141
+ try {
142
+ bytes = deps.readBytes(absolute);
143
+ }
144
+ catch {
145
+ deps.err(`looply source add: cannot read ${absolute}`);
146
+ return exports.EXIT.noInput;
147
+ }
148
+ const read = await deps.pdfPages(bytes);
149
+ if (!read.ok) {
150
+ deps.err(`looply source add: ${read.because}`);
151
+ return exports.EXIT.unreadable;
152
+ }
153
+ pages = read.pages;
154
+ originSha256 = (0, crypto_1.createHash)('sha256').update(bytes).digest('hex');
155
+ // ⚠️ THE SAME RULE THE SERVER STORES BY, called rather than repeated — the
156
+ // byte count printed below is then the one the server will hold, instead of
157
+ // a second composition that only a person comparing them by eye could catch
158
+ // drifting.
159
+ content = (0, core_1.pdfContent)(pages);
160
+ }
161
+ else {
162
+ try {
163
+ content = deps.readFile(absolute);
164
+ }
165
+ catch {
166
+ deps.err(`looply source add: cannot read ${absolute}`);
167
+ return exports.EXIT.noInput;
168
+ }
169
+ }
170
+ // 3. The same refusals the server would make, made here first.
171
+ for (const [where, text] of pages ? pages.map((p) => [`page ${p.page}: `, p.text]) : [['', content]]) {
172
+ const because = (0, core_1.whyUnreadable)(text);
173
+ if (because !== null && !(pages && text.trim().length === 0)) {
174
+ deps.err(`looply source add: ${where}${because}`);
175
+ return exports.EXIT.unreadable;
176
+ }
177
+ }
178
+ const { sha256, byteLength } = (0, core_1.sourceDigest)(content);
179
+ if (byteLength > core_1.MAX_SOURCE_BYTES) {
180
+ deps.err(`looply source add: the file is ${byteLength} bytes of text; the limit is ${core_1.MAX_SOURCE_BYTES}`);
181
+ return exports.EXIT.unreadable;
182
+ }
183
+ // 4. Only now: who am I, and which project is this?
184
+ const who = deps.identity();
185
+ if (who.kind === 'unpaired') {
186
+ deps.err('looply source add: this machine is not paired yet — run `looply pair` first');
187
+ return exports.EXIT.unavailable;
188
+ }
189
+ if (who.kind === 'unregistered') {
190
+ deps.err('looply source add: this repository is not registered with the server yet — run `looply daemon --once` here first');
191
+ return exports.EXIT.unavailable;
192
+ }
193
+ const name = (nameGiven ?? (0, node_path_1.basename)(file)).trim();
194
+ try {
195
+ const r = await deps.client(who.serverUrl, who.token).createSource(who.projectId, {
196
+ clientRef: clientRefFor(originSha256 ?? sha256),
197
+ name,
198
+ kind: kind.kind,
199
+ ...(pages ? { pages, originSha256 } : { content }),
200
+ });
201
+ const n = r.statements.length;
202
+ deps.out(`source ${r.source.id} ${r.source.kind} ${n} statement${n === 1 ? '' : 's'} sha256 ${r.source.sha256.slice(0, 12)}… ${r.deduplicated ? '(already stored)' : '(stored)'}`);
203
+ deps.out(pages
204
+ ? ` ${name}: ${pages.length} page${pages.length === 1 ? '' : 's'} of text layer, ${byteLength} bytes; file sha256 ${(originSha256 ?? '').slice(0, 12)}…. \`looply source list\` shows what this project has been given.`
205
+ : ` ${name}: ${byteLength} bytes, verbatim. \`looply source list\` shows what this project has been given.`);
206
+ return exports.EXIT.ok;
207
+ }
208
+ catch (e) {
209
+ return reportServerError('add', e, deps);
210
+ }
211
+ }
212
+ async function list(deps) {
213
+ const who = deps.identity();
214
+ if (who.kind === 'unpaired') {
215
+ deps.err('looply source list: this machine is not paired yet — run `looply pair` first');
216
+ return exports.EXIT.unavailable;
217
+ }
218
+ if (who.kind === 'unregistered') {
219
+ deps.err('looply source list: this repository is not registered with the server yet — run `looply daemon --once` here first');
220
+ return exports.EXIT.unavailable;
221
+ }
222
+ try {
223
+ const r = await deps.client(who.serverUrl, who.token).sources(who.projectId);
224
+ if (r.sources.length === 0) {
225
+ deps.out('no sources yet — hand one over with: looply source add <file>');
226
+ return exports.EXIT.ok;
227
+ }
228
+ deps.out('sources for this project, newest first:');
229
+ for (const s of r.sources) {
230
+ deps.out(` ${s.id} ${s.kind.padEnd(8)} ${String(s.byteLength).padStart(8)} bytes ${s.name} ${s.createdAt}`);
231
+ }
232
+ return exports.EXIT.ok;
233
+ }
234
+ catch (e) {
235
+ return reportServerError('list', e, deps);
236
+ }
237
+ }
238
+ /** Where a statement is, in the reader's own terms: `p2 L4-5` for a pdf, `L7` otherwise. */
239
+ function anchorLabel(s) {
240
+ const lines = s.anchor.lineStart === s.anchor.lineEnd ? `L${s.anchor.lineStart}` : `L${s.anchor.lineStart}-${s.anchor.lineEnd}`;
241
+ return s.anchor.page === undefined ? lines : `p${s.anchor.page} ${lines}`;
242
+ }
243
+ const firstLine = (text, max = 96) => {
244
+ const line = text.split('\n')[0] ?? '';
245
+ return line.length > max ? `${line.slice(0, max - 1)}…` : line;
246
+ };
247
+ /** Where a requirement stands, on one line under it: what was found, or why nothing could be said. */
248
+ function dispositionLabel(d) {
249
+ const first = d.anchors[0];
250
+ const at = first === undefined ? '' : `${first.path}${first.line === undefined ? '' : `:${first.line}`}`;
251
+ const more = d.anchors.length - 1;
252
+ const kept = d.candidatesTotal > d.anchors.length ? ` (${d.candidatesTotal} in all, ${d.anchors.length} kept)` : '';
253
+ switch (d.disposition) {
254
+ case 'candidate':
255
+ return `candidate ${at}${more > 0 ? ` +${more} more` : ''}${kept} — a place to look, not evidence`;
256
+ case 'absent':
257
+ return `absent nothing in the repository names: ${d.terms.join(', ')}`;
258
+ case 'conflicting':
259
+ return `conflicting contradicted by #${d.conflictsWith ?? '?'} — the document disagrees with itself`;
260
+ case 'blocked':
261
+ return d.rule === 'only-unparsed'
262
+ ? `blocked only unparsed files name it: ${d.anchors.map((a) => a.path).join(', ')}${kept}`
263
+ : d.rule === 'no-index'
264
+ ? 'blocked no project index could be built'
265
+ : d.rule === 'nothing-parsed'
266
+ ? // Says what was wrong with the INSTRUMENT, because that is what a person
267
+ // has to fix. "nothing names it" would send them looking at the document.
268
+ 'blocked no file in this repository could be parsed — nothing was searched'
269
+ : 'blocked nothing to look for (no terms)';
270
+ default:
271
+ return `${d.disposition} (attested by a person)`;
272
+ }
273
+ }
274
+ /** A person's word, on one line: what they said, who, at which tree, and the first place they pointed at. */
275
+ function attestationLabel(a, earlierTree) {
276
+ const first = a.anchors[0];
277
+ const at = first === undefined ? '' : ` — ${first.path}${first.line === undefined ? '' : `:${first.line}`}${a.anchors.length > 1 ? ` +${a.anchors.length - 1} more` : ''}`;
278
+ return `attested ${a.disposition} by ${a.attestedBy} at tree ${a.treeSha.slice(0, 12)}…${at}${earlierTree ? ' (attested at an EARLIER tree than the latest measurement)' : ''}`;
279
+ }
280
+ /**
281
+ * One source, as a person reads it: requirements first (what is forbidden
282
+ * marked as such), then constraints, questions, exclusions (which need
283
+ * authority), duplicates pointing at their first occurrence, and how much is
284
+ * context. Every line carries its anchor so the document can be opened to it;
285
+ * every requirement and constraint carries where it stands against the
286
+ * repository, when that was measured.
287
+ */
288
+ function renderSource(detail) {
289
+ const { source, statements, classifications, classifierVersion, dispositions, reconciledAt, attestations } = detail;
290
+ const standing = new Map(dispositions.map((d) => [d.ordinal, d]));
291
+ const words = new Map(attestations.map((a) => [a.ordinal, a]));
292
+ const byOrdinal = new Map(statements.map((s) => [s.ordinal, s]));
293
+ const out = [];
294
+ out.push(`source ${source.id} ${source.name} ${source.kind} ${statements.length} statement${statements.length === 1 ? '' : 's'} sha256 ${source.sha256.slice(0, 12)}…${source.originSha256 ? ` file ${source.originSha256.slice(0, 12)}…` : ''}`);
295
+ if (classifierVersion === null || classifications.length === 0) {
296
+ out.push(' not classified yet — run: looply source classify <id> (or hand it over again)');
297
+ for (const s of statements)
298
+ out.push(` #${s.ordinal} ${anchorLabel(s).padEnd(10)} ${firstLine(s.text)}`);
299
+ return out;
300
+ }
301
+ out.push(` classified by rules, version ${classifierVersion}. What each statement IS — not whether the repository does it.`);
302
+ out.push(reconciledAt === null
303
+ ? ` not reconciled against the repository yet — run: looply source reconcile ${source.id}`
304
+ : ` reconciled at tree ${reconciledAt.treeSha.slice(0, 12)}… (reconciler v${reconciledAt.reconcilerVersion}): a candidate is a place to look, not evidence; nothing here says implemented.`);
305
+ const group = (cls) => classifications.filter((c) => c.class === cls);
306
+ const line = (c, tag) => {
307
+ const s = byOrdinal.get(c.ordinal);
308
+ return ` #${String(c.ordinal).padEnd(3)} ${tag.padEnd(9)} ${(s ? anchorLabel(s) : '?').padEnd(10)} ${s ? firstLine(s.text) : '(statement missing)'}`;
309
+ };
310
+ // A person's word first, dated by its tree against the latest measurement; the measurement under it.
311
+ const stands = (c) => {
312
+ const s = (0, core_1.standingOf)(standing.get(c.ordinal), words.get(c.ordinal), reconciledAt?.treeSha ?? null);
313
+ if (s.kind === 'unreconciled')
314
+ return [];
315
+ if (s.kind === 'measured')
316
+ return [` ↳ ${dispositionLabel(s.measured)}`];
317
+ return [` ↳ ${attestationLabel(s.attestation, s.earlierTree)}`, ...(s.measured === undefined ? [] : [` ${dispositionLabel(s.measured)}`])];
318
+ };
319
+ const reqs = group('requirement');
320
+ out.push(`requirements (${reqs.length}):`);
321
+ /**
322
+ * 🔴 THE WORD THE DOCUMENT USED, NOT THE STRONGEST ONE AVAILABLE. Every modal
323
+ * printed as MUST until now, so a reader could not tell an obligation from a
324
+ * recommendation — and under strict Programme Mode only one of those can block
325
+ * a COMPLETE. `isMandatory` decides it in one place for every consumer.
326
+ */
327
+ for (const c of reqs) {
328
+ const strong = (0, core_1.isMandatory)(c);
329
+ const negative = c.polarity === 'negative';
330
+ const label = strong ? (negative ? 'MUST NOT' : 'MUST') : negative ? 'SHOULD NOT' : 'SHOULD';
331
+ out.push(line(c, label), ...stands(c));
332
+ }
333
+ const cons = group('constraint');
334
+ out.push(`constraints (${cons.length}):`);
335
+ for (const c of cons)
336
+ out.push(line(c, 'limit'), ...stands(c));
337
+ const qs = group('question');
338
+ out.push(`questions (${qs.length}) — answers are missing information, not missing authority:`);
339
+ for (const c of qs) {
340
+ out.push(line(c, 'ask'));
341
+ /**
342
+ * 🔴 WHAT THE SAME STATEMENT DID SETTLE, IF ANYTHING.
343
+ *
344
+ * *"The retry limit must be configurable; the default is TBD"* is one
345
+ * question and one decided obligation, and printing only the first shows a
346
+ * person a document that decided less than it did. The classifier records
347
+ * both halves; this is where the second one stops being invisible.
348
+ */
349
+ if (c.unresolved?.settled !== undefined)
350
+ out.push(` settled: ${c.unresolved.settled}`);
351
+ }
352
+ const exs = group('exclusion');
353
+ out.push(`exclusions (${exs.length}) — excluding scope needs authority:`);
354
+ for (const c of exs)
355
+ out.push(line(c, 'excluded'));
356
+ const dups = group('duplicate');
357
+ if (dups.length > 0) {
358
+ out.push(`duplicates (${dups.length}):`);
359
+ for (const c of dups)
360
+ out.push(line(c, `= #${c.duplicateOf ?? '?'}`));
361
+ }
362
+ const ctx = group('context');
363
+ out.push(`context: ${ctx.length} statement${ctx.length === 1 ? '' : 's'} (headings, code, prose that demands nothing)`);
364
+ return out;
365
+ }
366
+ async function show(argv, deps) {
367
+ const id = argv.find((a) => !a.startsWith('--'));
368
+ if (!id) {
369
+ deps.err(`looply source show: which source?\n\n${exports.SOURCE_USAGE}`);
370
+ return exports.EXIT.usage;
371
+ }
372
+ const who = deps.identity();
373
+ if (who.kind === 'unpaired') {
374
+ deps.err('looply source show: this machine is not paired yet — run `looply pair` first');
375
+ return exports.EXIT.unavailable;
376
+ }
377
+ if (who.kind === 'unregistered') {
378
+ deps.err('looply source show: this repository is not registered with the server yet — run `looply daemon --once` here first');
379
+ return exports.EXIT.unavailable;
380
+ }
381
+ try {
382
+ const detail = await deps.client(who.serverUrl, who.token).sourceDetail(who.projectId, id);
383
+ for (const l of renderSource(detail))
384
+ deps.out(l);
385
+ return exports.EXIT.ok;
386
+ }
387
+ catch (e) {
388
+ return reportServerError('show', e, deps);
389
+ }
390
+ }
391
+ /**
392
+ * Measure where each requirement of a source stands against THIS repository,
393
+ * and hand the measurement over keyed by HEAD's tree.
394
+ *
395
+ * ⚠️ THE REPOSITORY COMES FIRST, BEFORE PAIRING: a directory that is not a
396
+ * repository with a commit has no tree to key a measurement by, and a person
397
+ * is told that before being told to pair. The index is the run's own
398
+ * (`index-for-head.ts`), so this and a run measure the same thing.
399
+ */
400
+ async function reconcile(argv, deps) {
401
+ const id = argv.find((a) => !a.startsWith('--'));
402
+ if (!id) {
403
+ deps.err(`looply source reconcile: which source?\n\n${exports.SOURCE_USAGE}`);
404
+ return exports.EXIT.usage;
405
+ }
406
+ const index = await deps.index(deps.cwd());
407
+ if (!index.ok) {
408
+ deps.err(`looply source reconcile: ${index.because}`);
409
+ return exports.EXIT.unreadable;
410
+ }
411
+ const who = deps.identity();
412
+ if (who.kind === 'unpaired') {
413
+ deps.err('looply source reconcile: this machine is not paired yet — run `looply pair` first');
414
+ return exports.EXIT.unavailable;
415
+ }
416
+ if (who.kind === 'unregistered') {
417
+ deps.err('looply source reconcile: this repository is not registered with the server yet — run `looply daemon --once` here first');
418
+ return exports.EXIT.unavailable;
419
+ }
420
+ try {
421
+ const client = deps.client(who.serverUrl, who.token);
422
+ const detail = await client.sourceDetail(who.projectId, id);
423
+ if (detail.classifierVersion === null) {
424
+ deps.err(`looply source reconcile: source ${id} was never classified, so nothing says which statements are requirements — hand it over again first`);
425
+ return exports.EXIT.refused;
426
+ }
427
+ const dispositions = (0, core_1.reconcileStatements)({
428
+ statements: detail.statements,
429
+ classifications: detail.classifications,
430
+ index: index.snapshot,
431
+ });
432
+ const r = await client.reconcileSource(who.projectId, id, {
433
+ treeSha: index.treeSha,
434
+ reconcilerVersion: core_1.RECONCILER_VERSION,
435
+ dispositions,
436
+ });
437
+ const n = (kind) => r.dispositions.filter((d) => d.disposition === kind).length;
438
+ deps.out(`source ${id} reconciled at tree ${index.treeSha.slice(0, 12)}… ${r.dispositions.length} requirement${r.dispositions.length === 1 ? '' : 's'}/constraint${r.dispositions.length === 1 ? '' : 's'} measured ${r.created ? '(recorded)' : '(already on record for this tree)'}`);
439
+ deps.out(` candidate ${n('candidate')} · absent ${n('absent')} · conflicting ${n('conflicting')} · blocked ${n('blocked')} — a candidate is a place to look, not evidence; nothing here says implemented. \`looply source show ${id}\` lists them.`);
440
+ return exports.EXIT.ok;
441
+ }
442
+ catch (e) {
443
+ return reportServerError('reconcile', e, deps);
444
+ }
445
+ }
446
+ /**
447
+ * What is covered and by whom, as a person reads it: what NOBODY serves first,
448
+ * then what is served but not yet evidenced, then partial, then evidenced —
449
+ * each with its anchor and the goals that name it. Nothing here counts a
450
+ * finished queue as coverage.
451
+ */
452
+ function renderCoverage(c) {
453
+ const n = c.requirements.length;
454
+ const out = [];
455
+ out.push(`coverage of ${c.sourceId} ${c.name} ${n} requirement${n === 1 ? '' : 's'}/constraint${n === 1 ? '' : 's'} ${c.reconciledAt === null ? 'not measured against the repository yet' : `measured at tree ${c.reconciledAt.treeSha.slice(0, 12)}…`}`);
456
+ const line = (r) => {
457
+ const a = { ordinal: r.ordinal, kind: 'paragraph', text: r.text, anchor: r.anchor };
458
+ const who = r.goals.length === 0 ? '' : ` — ${r.goals.map((g) => `${g.id} (${g.state} v${g.version})`).join(', ')}`;
459
+ /**
460
+ * 🔴 THE WORD THE DOCUMENT USED — the same correction `show` already had.
461
+ *
462
+ * This read `r.class === 'requirement' ? 'MUST' : 'limit'`, so every
463
+ * advisory printed as an obligation. `show` asks `isMandatory`; this could
464
+ * not, because the row did not carry the answer. It does now.
465
+ */
466
+ const label = r.class !== 'requirement'
467
+ ? 'limit'
468
+ : r.mandatory
469
+ ? r.negative
470
+ ? 'MUST NOT'
471
+ : 'MUST'
472
+ : r.negative
473
+ ? 'SHOULD NOT'
474
+ : 'SHOULD';
475
+ return ` #${String(r.ordinal).padEnd(3)} ${label.padEnd(6)} ${anchorLabel(a).padEnd(10)} ${firstLine(r.text)}${who}`;
476
+ };
477
+ const group = (kind) => c.requirements.filter((r) => r.coverage === kind);
478
+ const section = (title, kind) => {
479
+ const rows = group(kind);
480
+ out.push(`${title} (${rows.length}):`);
481
+ for (const r of rows)
482
+ out.push(line(r));
483
+ };
484
+ section('unserved — no goal names these', 'unserved');
485
+ section('served, not yet evidenced', 'served');
486
+ section('partial — a person said so', 'partial');
487
+ section('evidenced — a person attested implemented-and-evidenced at the measured tree', 'evidenced');
488
+ section('evidenced at an EARLIER tree than the latest measurement', 'evidenced-at-an-earlier-tree');
489
+ return out;
490
+ }
491
+ async function coverage(argv, deps) {
492
+ const id = argv.find((a) => !a.startsWith('--'));
493
+ if (!id) {
494
+ deps.err(`looply source coverage: which source?\n\n${exports.SOURCE_USAGE}`);
495
+ return exports.EXIT.usage;
496
+ }
497
+ const who = deps.identity();
498
+ if (who.kind === 'unpaired') {
499
+ deps.err('looply source coverage: this machine is not paired yet — run `looply pair` first');
500
+ return exports.EXIT.unavailable;
501
+ }
502
+ if (who.kind === 'unregistered') {
503
+ deps.err('looply source coverage: this repository is not registered with the server yet — run `looply daemon --once` here first');
504
+ return exports.EXIT.unavailable;
505
+ }
506
+ try {
507
+ const c = await deps.client(who.serverUrl, who.token).coverage(who.projectId, id);
508
+ for (const l of renderCoverage(c))
509
+ deps.out(l);
510
+ return exports.EXIT.ok;
511
+ }
512
+ catch (e) {
513
+ return reportServerError('coverage', e, deps);
514
+ }
515
+ }
516
+ /**
517
+ * Turn a document into goals.
518
+ *
519
+ * 🔴 THE PROPOSAL IS THE PRODUCT’S, NOT THE OPERATOR’S. `proposeGoals` reads the
520
+ * document’s own heading structure and groups its requirements under it; nothing
521
+ * here writes goal text by hand. Every goal carries the requirement ordinals it
522
+ * serves, so `looply source coverage` can answer which requirements a goal is for
523
+ * without anybody restating the link.
524
+ *
525
+ * ⚠️ `--dry-run` PRINTS AND WRITES NOTHING, and it is the first thing a person
526
+ * should run. An import that sets twenty goals is not something to discover after
527
+ * the fact.
528
+ *
529
+ * ⚠️ RE-RUNNING IS SAFE AND SAYS SO. `clientRef` is derived from the ordinals, and
530
+ * `POST /goals` is idempotent on it, so a second run reports every goal as
531
+ * `already set` rather than doubling the list. The count of each is printed
532
+ * because a silent no-op and a silent double look identical from the outside.
533
+ */
534
+ async function plan(argv, deps) {
535
+ const dryRun = argv.includes('--dry-run');
536
+ const id = argv.find((a) => !a.startsWith('--'));
537
+ if (!id) {
538
+ deps.err(`looply source plan: which source?\n\n${exports.SOURCE_USAGE}`);
539
+ return exports.EXIT.usage;
540
+ }
541
+ const who = deps.identity();
542
+ if (who.kind === 'unpaired') {
543
+ deps.err('looply source plan: this machine is not paired yet — run `looply pair` first');
544
+ return exports.EXIT.unavailable;
545
+ }
546
+ if (who.kind === 'unregistered') {
547
+ deps.err('looply source plan: this repository is not registered with the server yet — run `looply daemon --once` here first');
548
+ return exports.EXIT.unavailable;
549
+ }
550
+ const client = deps.client(who.serverUrl, who.token);
551
+ let detail;
552
+ try {
553
+ detail = await client.sourceDetail(who.projectId, id);
554
+ }
555
+ catch (e) {
556
+ return reportServerError('plan', e, deps);
557
+ }
558
+ const proposed = (0, core_1.proposeGoals)({
559
+ sourceId: detail.source.id,
560
+ statements: detail.statements,
561
+ classifications: detail.classifications,
562
+ });
563
+ if (proposed.length === 0) {
564
+ deps.out(`source ${detail.source.id} ${detail.source.name} no requirements or constraints — nothing to propose`);
565
+ return exports.EXIT.ok;
566
+ }
567
+ const served = proposed.reduce((n, p) => n + p.requirements.length, 0);
568
+ deps.out(`source ${detail.source.id} ${detail.source.name} ${proposed.length} goal${proposed.length === 1 ? "" : "s"} proposed, ` +
569
+ `serving ${served} requirement${served === 1 ? "" : "s"}, grouped by the document’s headings`);
570
+ for (const p of proposed) {
571
+ deps.out(` ${p.clientRef}`);
572
+ for (const line of p.text.split(`\n`))
573
+ deps.out(` ${line}`);
574
+ }
575
+ if (dryRun) {
576
+ deps.out(' --dry-run: nothing was set. Run without it to set these goals.');
577
+ return exports.EXIT.ok;
578
+ }
579
+ let created = 0;
580
+ let already = 0;
581
+ for (const p of proposed) {
582
+ try {
583
+ const r = await client.createGoal(who.projectId, {
584
+ clientRef: p.clientRef,
585
+ text: p.text,
586
+ // The full canonical address of every obligation, table rows included —
587
+ // never rebuilt from bare ordinals, which is how a row lost its `row`.
588
+ requirements: [...p.requirements],
589
+ });
590
+ if (r.deduplicated)
591
+ already += 1;
592
+ else
593
+ created += 1;
594
+ deps.out(` ${r.deduplicated ? "already set" : "set"} ${r.goal.id} ${p.clientRef}`);
595
+ }
596
+ catch (e) {
597
+ // 🔴 STOPS AT THE FIRST REFUSAL, and reports what was already set. Carrying
598
+ // on would leave a half-imported document with no record of where it broke,
599
+ // and a re-run is safe precisely because the refs are deterministic.
600
+ deps.err(`looply source plan: stopped after ${created} set, ${already} already set`);
601
+ return reportServerError('plan', e, deps);
602
+ }
603
+ }
604
+ deps.out(` ${created} set, ${already} already set`);
605
+ return exports.EXIT.ok;
606
+ }
607
+ /**
608
+ * The owner's definition of done, asked of the whole document on the last integrated commit
609
+ * (`source-verdict.ts`). Exit 0 only for COMPLETE; 1 names what is unmet; 69 when nothing can be
610
+ * judged — never a verdict read from a lookup that failed.
611
+ */
612
+ async function verdict(argv, deps) {
613
+ const id = argv.find((a) => !a.startsWith('--'));
614
+ if (!id) {
615
+ deps.err(`looply source verdict: which source?\n\n${exports.SOURCE_USAGE}`);
616
+ return exports.EXIT.usage;
617
+ }
618
+ const who = deps.identity();
619
+ if (who.kind === 'unpaired') {
620
+ deps.err('looply source verdict: this machine is not paired yet — run `looply pair` first');
621
+ return exports.EXIT.unavailable;
622
+ }
623
+ if (who.kind === 'unregistered') {
624
+ deps.err('looply source verdict: this repository is not registered with the server yet — run `looply daemon --once` here first');
625
+ return exports.EXIT.unavailable;
626
+ }
627
+ if (deps.verdict === undefined) {
628
+ deps.err('looply source verdict: this build cannot read the integration lane');
629
+ return exports.EXIT.unavailable;
630
+ }
631
+ try {
632
+ const v = await (0, source_verdict_1.sourceVerdict)(id, deps.verdict(deps.cwd(), who));
633
+ for (const line of (0, source_verdict_1.renderVerdict)(id, v))
634
+ deps.out(line);
635
+ return v.kind === 'unavailable' ? exports.EXIT.unavailable : v.complete ? exports.EXIT.ok : exports.EXIT.refused;
636
+ }
637
+ catch (e) {
638
+ // F33: nothing judged is never NOT COMPLETE (1) — every failure to judge is 69, whatever threw.
639
+ deps.err(`looply source verdict: could not judge — ${e.message}`);
640
+ return exports.EXIT.unavailable;
641
+ }
642
+ }
643
+ function reportServerError(verb, e, deps) {
644
+ if (e instanceof server_client_1.ServerError) {
645
+ if (e.status === 0) {
646
+ deps.err(`looply source ${verb}: ${e.message}`);
647
+ return exports.EXIT.unavailable;
648
+ }
649
+ deps.err(`looply source ${verb}: the server refused (${e.status}): ${e.message}`);
650
+ return exports.EXIT.refused;
651
+ }
652
+ throw e;
653
+ }
654
+ /* istanbul ignore next — real fs, real identity file, real client; the logic is tested through deps */
655
+ function nodeSourceDeps() {
656
+ return {
657
+ cwd: () => process.cwd(),
658
+ readFile: (p) => (0, node_fs_1.readFileSync)(p, 'utf8'),
659
+ readBytes: (p) => new Uint8Array((0, node_fs_1.readFileSync)(p)),
660
+ pdfPages: (bytes) => (0, pdf_text_1.extractPdfPages)(bytes),
661
+ identity: () => {
662
+ const store = new machine_store_1.MachineStore((0, machine_store_1.machineFilePath)());
663
+ let identity;
664
+ try {
665
+ identity = store.load();
666
+ }
667
+ catch {
668
+ return { kind: 'unpaired' };
669
+ }
670
+ if (!identity)
671
+ return { kind: 'unpaired' };
672
+ const projectId = store.projectFor((0, machine_store_1.repoPathHash)(process.cwd(), (t) => (0, crypto_1.createHash)('sha256').update(t, 'utf8').digest('hex')));
673
+ if (!projectId)
674
+ return { kind: 'unregistered' };
675
+ return { kind: 'ok', serverUrl: identity.serverUrl, token: identity.token, projectId };
676
+ },
677
+ index: (cwd) => (0, index_for_head_1.indexForHead)(cwd),
678
+ client: (serverUrl, token) => new server_client_1.ServerClient({ baseUrl: serverUrl }).withToken(token),
679
+ out: (line) => process.stdout.write(line + '\n'),
680
+ err: (line) => process.stderr.write(line + '\n'),
681
+ verdict: (cwd, who) => (0, source_verdict_1.nodeVerdictDeps)(cwd, who),
682
+ };
683
+ }
684
+ //# sourceMappingURL=source-cmd.js.map