@software-dlc/cli 0.157.2

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 (701) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +105 -0
  3. package/README.md +31 -0
  4. package/dist/checkout.d.ts +43 -0
  5. package/dist/checkout.d.ts.map +1 -0
  6. package/dist/checkout.js +92 -0
  7. package/dist/checkout.js.map +1 -0
  8. package/dist/cli-arguments.d.ts +13 -0
  9. package/dist/cli-arguments.d.ts.map +1 -0
  10. package/dist/cli-arguments.js +67 -0
  11. package/dist/cli-arguments.js.map +1 -0
  12. package/dist/cli-branch-history.d.ts +48 -0
  13. package/dist/cli-branch-history.d.ts.map +1 -0
  14. package/dist/cli-branch-history.js +319 -0
  15. package/dist/cli-branch-history.js.map +1 -0
  16. package/dist/cli-branches.d.ts +22 -0
  17. package/dist/cli-branches.d.ts.map +1 -0
  18. package/dist/cli-branches.js +59 -0
  19. package/dist/cli-branches.js.map +1 -0
  20. package/dist/cli-deploy.d.ts +14 -0
  21. package/dist/cli-deploy.d.ts.map +1 -0
  22. package/dist/cli-deploy.js +164 -0
  23. package/dist/cli-deploy.js.map +1 -0
  24. package/dist/cli-health.d.ts +3 -0
  25. package/dist/cli-health.d.ts.map +1 -0
  26. package/dist/cli-health.js +73 -0
  27. package/dist/cli-health.js.map +1 -0
  28. package/dist/cli-help.d.ts +21 -0
  29. package/dist/cli-help.d.ts.map +1 -0
  30. package/dist/cli-help.js +176 -0
  31. package/dist/cli-help.js.map +1 -0
  32. package/dist/cli-login.d.ts +76 -0
  33. package/dist/cli-login.d.ts.map +1 -0
  34. package/dist/cli-login.js +634 -0
  35. package/dist/cli-login.js.map +1 -0
  36. package/dist/cli-operation.d.ts +2 -0
  37. package/dist/cli-operation.d.ts.map +1 -0
  38. package/dist/cli-operation.js +66 -0
  39. package/dist/cli-operation.js.map +1 -0
  40. package/dist/cli-org.d.ts +12 -0
  41. package/dist/cli-org.d.ts.map +1 -0
  42. package/dist/cli-org.js +218 -0
  43. package/dist/cli-org.js.map +1 -0
  44. package/dist/cli-rebuild.d.ts +20 -0
  45. package/dist/cli-rebuild.d.ts.map +1 -0
  46. package/dist/cli-rebuild.js +29 -0
  47. package/dist/cli-rebuild.js.map +1 -0
  48. package/dist/cli-reset.d.ts +27 -0
  49. package/dist/cli-reset.d.ts.map +1 -0
  50. package/dist/cli-reset.js +44 -0
  51. package/dist/cli-reset.js.map +1 -0
  52. package/dist/cli-snapshot.d.ts +398 -0
  53. package/dist/cli-snapshot.d.ts.map +1 -0
  54. package/dist/cli-snapshot.js +45 -0
  55. package/dist/cli-snapshot.js.map +1 -0
  56. package/dist/cli-task-context.d.ts +3 -0
  57. package/dist/cli-task-context.d.ts.map +1 -0
  58. package/dist/cli-task-context.js +112 -0
  59. package/dist/cli-task-context.js.map +1 -0
  60. package/dist/cli.d.ts +3 -0
  61. package/dist/cli.d.ts.map +1 -0
  62. package/dist/cli.js +1004 -0
  63. package/dist/cli.js.map +1 -0
  64. package/dist/graph-packages-lock.d.ts +169 -0
  65. package/dist/graph-packages-lock.d.ts.map +1 -0
  66. package/dist/graph-packages-lock.js +503 -0
  67. package/dist/graph-packages-lock.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +2 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/local/aggregate-preflight.d.ts +12 -0
  73. package/dist/local/aggregate-preflight.d.ts.map +1 -0
  74. package/dist/local/aggregate-preflight.js +22 -0
  75. package/dist/local/aggregate-preflight.js.map +1 -0
  76. package/dist/local/allow-mcp.d.ts +77 -0
  77. package/dist/local/allow-mcp.d.ts.map +1 -0
  78. package/dist/local/allow-mcp.js +394 -0
  79. package/dist/local/allow-mcp.js.map +1 -0
  80. package/dist/local/api-client.d.ts +15 -0
  81. package/dist/local/api-client.d.ts.map +1 -0
  82. package/dist/local/api-client.js +87 -0
  83. package/dist/local/api-client.js.map +1 -0
  84. package/dist/local/app-contract-readers.d.ts +229 -0
  85. package/dist/local/app-contract-readers.d.ts.map +1 -0
  86. package/dist/local/app-contract-readers.js +450 -0
  87. package/dist/local/app-contract-readers.js.map +1 -0
  88. package/dist/local/app-org-reader.d.ts +21 -0
  89. package/dist/local/app-org-reader.d.ts.map +1 -0
  90. package/dist/local/app-org-reader.js +66 -0
  91. package/dist/local/app-org-reader.js.map +1 -0
  92. package/dist/local/app-shell-readers.d.ts +96 -0
  93. package/dist/local/app-shell-readers.d.ts.map +1 -0
  94. package/dist/local/app-shell-readers.js +381 -0
  95. package/dist/local/app-shell-readers.js.map +1 -0
  96. package/dist/local/app-tasks-read.d.ts +202 -0
  97. package/dist/local/app-tasks-read.d.ts.map +1 -0
  98. package/dist/local/app-tasks-read.js +290 -0
  99. package/dist/local/app-tasks-read.js.map +1 -0
  100. package/dist/local/app-worktrees.d.ts +69 -0
  101. package/dist/local/app-worktrees.d.ts.map +1 -0
  102. package/dist/local/app-worktrees.js +554 -0
  103. package/dist/local/app-worktrees.js.map +1 -0
  104. package/dist/local/base-sync-manifest.d.ts +12 -0
  105. package/dist/local/base-sync-manifest.d.ts.map +1 -0
  106. package/dist/local/base-sync-manifest.js +57 -0
  107. package/dist/local/base-sync-manifest.js.map +1 -0
  108. package/dist/local/blast-radius.d.ts +191 -0
  109. package/dist/local/blast-radius.d.ts.map +1 -0
  110. package/dist/local/blast-radius.js +585 -0
  111. package/dist/local/blast-radius.js.map +1 -0
  112. package/dist/local/canonical.d.ts +2 -0
  113. package/dist/local/canonical.d.ts.map +1 -0
  114. package/dist/local/canonical.js +2 -0
  115. package/dist/local/canonical.js.map +1 -0
  116. package/dist/local/config.d.ts +22 -0
  117. package/dist/local/config.d.ts.map +1 -0
  118. package/dist/local/config.js +57 -0
  119. package/dist/local/config.js.map +1 -0
  120. package/dist/local/document-commands.d.ts +163 -0
  121. package/dist/local/document-commands.d.ts.map +1 -0
  122. package/dist/local/document-commands.js +620 -0
  123. package/dist/local/document-commands.js.map +1 -0
  124. package/dist/local/document-embeds.d.ts +21 -0
  125. package/dist/local/document-embeds.d.ts.map +1 -0
  126. package/dist/local/document-embeds.js +38 -0
  127. package/dist/local/document-embeds.js.map +1 -0
  128. package/dist/local/environment-context.d.ts +39 -0
  129. package/dist/local/environment-context.d.ts.map +1 -0
  130. package/dist/local/environment-context.js +193 -0
  131. package/dist/local/environment-context.js.map +1 -0
  132. package/dist/local/environment-exclude.d.ts +7 -0
  133. package/dist/local/environment-exclude.d.ts.map +1 -0
  134. package/dist/local/environment-exclude.js +82 -0
  135. package/dist/local/environment-exclude.js.map +1 -0
  136. package/dist/local/environment-sidecar.d.ts +126 -0
  137. package/dist/local/environment-sidecar.d.ts.map +1 -0
  138. package/dist/local/environment-sidecar.js +442 -0
  139. package/dist/local/environment-sidecar.js.map +1 -0
  140. package/dist/local/environment-switch.d.ts +22 -0
  141. package/dist/local/environment-switch.d.ts.map +1 -0
  142. package/dist/local/environment-switch.js +385 -0
  143. package/dist/local/environment-switch.js.map +1 -0
  144. package/dist/local/exact-remote-projection.d.ts +17 -0
  145. package/dist/local/exact-remote-projection.d.ts.map +1 -0
  146. package/dist/local/exact-remote-projection.js +53 -0
  147. package/dist/local/exact-remote-projection.js.map +1 -0
  148. package/dist/local/experimental/path-object-store.d.ts +66 -0
  149. package/dist/local/experimental/path-object-store.d.ts.map +1 -0
  150. package/dist/local/experimental/path-object-store.js +135 -0
  151. package/dist/local/experimental/path-object-store.js.map +1 -0
  152. package/dist/local/external-worktree-binding.d.ts +21 -0
  153. package/dist/local/external-worktree-binding.d.ts.map +1 -0
  154. package/dist/local/external-worktree-binding.js +56 -0
  155. package/dist/local/external-worktree-binding.js.map +1 -0
  156. package/dist/local/folder-members.d.ts +34 -0
  157. package/dist/local/folder-members.d.ts.map +1 -0
  158. package/dist/local/folder-members.js +168 -0
  159. package/dist/local/folder-members.js.map +1 -0
  160. package/dist/local/git-ref-authority.d.ts +11 -0
  161. package/dist/local/git-ref-authority.d.ts.map +1 -0
  162. package/dist/local/git-ref-authority.js +76 -0
  163. package/dist/local/git-ref-authority.js.map +1 -0
  164. package/dist/local/git.d.ts +88 -0
  165. package/dist/local/git.d.ts.map +1 -0
  166. package/dist/local/git.js +413 -0
  167. package/dist/local/git.js.map +1 -0
  168. package/dist/local/graph-read.d.ts +168 -0
  169. package/dist/local/graph-read.d.ts.map +1 -0
  170. package/dist/local/graph-read.js +360 -0
  171. package/dist/local/graph-read.js.map +1 -0
  172. package/dist/local/graph-sync.d.ts +39 -0
  173. package/dist/local/graph-sync.d.ts.map +1 -0
  174. package/dist/local/graph-sync.js +186 -0
  175. package/dist/local/graph-sync.js.map +1 -0
  176. package/dist/local/guide-commands.d.ts +79 -0
  177. package/dist/local/guide-commands.d.ts.map +1 -0
  178. package/dist/local/guide-commands.js +247 -0
  179. package/dist/local/guide-commands.js.map +1 -0
  180. package/dist/local/health-files.d.ts +24 -0
  181. package/dist/local/health-files.d.ts.map +1 -0
  182. package/dist/local/health-files.js +133 -0
  183. package/dist/local/health-files.js.map +1 -0
  184. package/dist/local/health-inspection.d.ts +12 -0
  185. package/dist/local/health-inspection.d.ts.map +1 -0
  186. package/dist/local/health-inspection.js +407 -0
  187. package/dist/local/health-inspection.js.map +1 -0
  188. package/dist/local/health-policy.d.ts +11 -0
  189. package/dist/local/health-policy.d.ts.map +1 -0
  190. package/dist/local/health-policy.js +257 -0
  191. package/dist/local/health-policy.js.map +1 -0
  192. package/dist/local/health-projection.d.ts +14 -0
  193. package/dist/local/health-projection.d.ts.map +1 -0
  194. package/dist/local/health-projection.js +102 -0
  195. package/dist/local/health-projection.js.map +1 -0
  196. package/dist/local/health-schema.d.ts +338 -0
  197. package/dist/local/health-schema.d.ts.map +1 -0
  198. package/dist/local/health-schema.js +213 -0
  199. package/dist/local/health-schema.js.map +1 -0
  200. package/dist/local/health-store.d.ts +61 -0
  201. package/dist/local/health-store.d.ts.map +1 -0
  202. package/dist/local/health-store.js +218 -0
  203. package/dist/local/health-store.js.map +1 -0
  204. package/dist/local/index.d.ts +66 -0
  205. package/dist/local/index.d.ts.map +1 -0
  206. package/dist/local/index.js +66 -0
  207. package/dist/local/index.js.map +1 -0
  208. package/dist/local/journey-commands.d.ts +65 -0
  209. package/dist/local/journey-commands.d.ts.map +1 -0
  210. package/dist/local/journey-commands.js +138 -0
  211. package/dist/local/journey-commands.js.map +1 -0
  212. package/dist/local/local-org-store.d.ts +46 -0
  213. package/dist/local/local-org-store.d.ts.map +1 -0
  214. package/dist/local/local-org-store.js +132 -0
  215. package/dist/local/local-org-store.js.map +1 -0
  216. package/dist/local/local-org.d.ts +389 -0
  217. package/dist/local/local-org.d.ts.map +1 -0
  218. package/dist/local/local-org.js +855 -0
  219. package/dist/local/local-org.js.map +1 -0
  220. package/dist/local/media-upload.d.ts +5 -0
  221. package/dist/local/media-upload.d.ts.map +1 -0
  222. package/dist/local/media-upload.js +41 -0
  223. package/dist/local/media-upload.js.map +1 -0
  224. package/dist/local/operation.d.ts +155 -0
  225. package/dist/local/operation.d.ts.map +1 -0
  226. package/dist/local/operation.js +340 -0
  227. package/dist/local/operation.js.map +1 -0
  228. package/dist/local/ownership-reader-schema.d.ts +117 -0
  229. package/dist/local/ownership-reader-schema.d.ts.map +1 -0
  230. package/dist/local/ownership-reader-schema.js +105 -0
  231. package/dist/local/ownership-reader-schema.js.map +1 -0
  232. package/dist/local/ownership-reader-worker.d.ts +2 -0
  233. package/dist/local/ownership-reader-worker.d.ts.map +1 -0
  234. package/dist/local/ownership-reader-worker.js +341 -0
  235. package/dist/local/ownership-reader-worker.js.map +1 -0
  236. package/dist/local/ownership-reader.d.ts +10 -0
  237. package/dist/local/ownership-reader.d.ts.map +1 -0
  238. package/dist/local/ownership-reader.js +93 -0
  239. package/dist/local/ownership-reader.js.map +1 -0
  240. package/dist/local/package-uses-check.d.ts +33 -0
  241. package/dist/local/package-uses-check.d.ts.map +1 -0
  242. package/dist/local/package-uses-check.js +62 -0
  243. package/dist/local/package-uses-check.js.map +1 -0
  244. package/dist/local/pending-recovery.d.ts +22 -0
  245. package/dist/local/pending-recovery.d.ts.map +1 -0
  246. package/dist/local/pending-recovery.js +171 -0
  247. package/dist/local/pending-recovery.js.map +1 -0
  248. package/dist/local/portable-commit-store.d.ts +28 -0
  249. package/dist/local/portable-commit-store.d.ts.map +1 -0
  250. package/dist/local/portable-commit-store.js +187 -0
  251. package/dist/local/portable-commit-store.js.map +1 -0
  252. package/dist/local/portable-commit.d.ts +109 -0
  253. package/dist/local/portable-commit.d.ts.map +1 -0
  254. package/dist/local/portable-commit.js +209 -0
  255. package/dist/local/portable-commit.js.map +1 -0
  256. package/dist/local/portable-remote.d.ts +432 -0
  257. package/dist/local/portable-remote.d.ts.map +1 -0
  258. package/dist/local/portable-remote.js +280 -0
  259. package/dist/local/portable-remote.js.map +1 -0
  260. package/dist/local/project-deleted.d.ts +4 -0
  261. package/dist/local/project-deleted.d.ts.map +1 -0
  262. package/dist/local/project-deleted.js +13 -0
  263. package/dist/local/project-deleted.js.map +1 -0
  264. package/dist/local/projection.d.ts +166 -0
  265. package/dist/local/projection.d.ts.map +1 -0
  266. package/dist/local/projection.js +709 -0
  267. package/dist/local/projection.js.map +1 -0
  268. package/dist/local/read-operation.d.ts +3 -0
  269. package/dist/local/read-operation.d.ts.map +1 -0
  270. package/dist/local/read-operation.js +19 -0
  271. package/dist/local/read-operation.js.map +1 -0
  272. package/dist/local/rebuild.d.ts +11 -0
  273. package/dist/local/rebuild.d.ts.map +1 -0
  274. package/dist/local/rebuild.js +42 -0
  275. package/dist/local/rebuild.js.map +1 -0
  276. package/dist/local/remote-base.d.ts +25 -0
  277. package/dist/local/remote-base.d.ts.map +1 -0
  278. package/dist/local/remote-base.js +68 -0
  279. package/dist/local/remote-base.js.map +1 -0
  280. package/dist/local/save-layout-worker.d.ts +19 -0
  281. package/dist/local/save-layout-worker.d.ts.map +1 -0
  282. package/dist/local/save-layout-worker.js +28 -0
  283. package/dist/local/save-layout-worker.js.map +1 -0
  284. package/dist/local/save-layout.d.ts +84 -0
  285. package/dist/local/save-layout.d.ts.map +1 -0
  286. package/dist/local/save-layout.js +221 -0
  287. package/dist/local/save-layout.js.map +1 -0
  288. package/dist/local/scope-impact.d.ts +31 -0
  289. package/dist/local/scope-impact.d.ts.map +1 -0
  290. package/dist/local/scope-impact.js +32 -0
  291. package/dist/local/scope-impact.js.map +1 -0
  292. package/dist/local/source-evidence/filesystem-worker.d.ts +2 -0
  293. package/dist/local/source-evidence/filesystem-worker.d.ts.map +1 -0
  294. package/dist/local/source-evidence/filesystem-worker.js +139 -0
  295. package/dist/local/source-evidence/filesystem-worker.js.map +1 -0
  296. package/dist/local/source-evidence/processes.d.ts +20 -0
  297. package/dist/local/source-evidence/processes.d.ts.map +1 -0
  298. package/dist/local/source-evidence/processes.js +133 -0
  299. package/dist/local/source-evidence/processes.js.map +1 -0
  300. package/dist/local/source-evidence/protocol.d.ts +52 -0
  301. package/dist/local/source-evidence/protocol.d.ts.map +1 -0
  302. package/dist/local/source-evidence/protocol.js +72 -0
  303. package/dist/local/source-evidence/protocol.js.map +1 -0
  304. package/dist/local/source-evidence/reader.d.ts +14 -0
  305. package/dist/local/source-evidence/reader.d.ts.map +1 -0
  306. package/dist/local/source-evidence/reader.js +308 -0
  307. package/dist/local/source-evidence/reader.js.map +1 -0
  308. package/dist/local/source-evidence/schema.d.ts +2504 -0
  309. package/dist/local/source-evidence/schema.d.ts.map +1 -0
  310. package/dist/local/source-evidence/schema.js +99 -0
  311. package/dist/local/source-evidence/schema.js.map +1 -0
  312. package/dist/local/source-policy/loader.d.ts +29 -0
  313. package/dist/local/source-policy/loader.d.ts.map +1 -0
  314. package/dist/local/source-policy/loader.js +209 -0
  315. package/dist/local/source-policy/loader.js.map +1 -0
  316. package/dist/local/source-policy/process.d.ts +7 -0
  317. package/dist/local/source-policy/process.d.ts.map +1 -0
  318. package/dist/local/source-policy/process.js +53 -0
  319. package/dist/local/source-policy/process.js.map +1 -0
  320. package/dist/local/source-policy/protocol.d.ts +27 -0
  321. package/dist/local/source-policy/protocol.d.ts.map +1 -0
  322. package/dist/local/source-policy/protocol.js +48 -0
  323. package/dist/local/source-policy/protocol.js.map +1 -0
  324. package/dist/local/source-policy/worker.d.ts +2 -0
  325. package/dist/local/source-policy/worker.d.ts.map +1 -0
  326. package/dist/local/source-policy/worker.js +100 -0
  327. package/dist/local/source-policy/worker.js.map +1 -0
  328. package/dist/local/state-directory.d.ts +17 -0
  329. package/dist/local/state-directory.d.ts.map +1 -0
  330. package/dist/local/state-directory.js +68 -0
  331. package/dist/local/state-directory.js.map +1 -0
  332. package/dist/local/store-database.d.ts +13 -0
  333. package/dist/local/store-database.d.ts.map +1 -0
  334. package/dist/local/store-database.js +187 -0
  335. package/dist/local/store-database.js.map +1 -0
  336. package/dist/local/store.d.ts +181 -0
  337. package/dist/local/store.d.ts.map +1 -0
  338. package/dist/local/store.js +585 -0
  339. package/dist/local/store.js.map +1 -0
  340. package/dist/local/sync.d.ts +47 -0
  341. package/dist/local/sync.d.ts.map +1 -0
  342. package/dist/local/sync.js +518 -0
  343. package/dist/local/sync.js.map +1 -0
  344. package/dist/local/task-context-inspection.d.ts +23 -0
  345. package/dist/local/task-context-inspection.d.ts.map +1 -0
  346. package/dist/local/task-context-inspection.js +165 -0
  347. package/dist/local/task-context-inspection.js.map +1 -0
  348. package/dist/local/task-context-observations.d.ts +9553 -0
  349. package/dist/local/task-context-observations.d.ts.map +1 -0
  350. package/dist/local/task-context-observations.js +232 -0
  351. package/dist/local/task-context-observations.js.map +1 -0
  352. package/dist/local/task-context-provider.d.ts +18 -0
  353. package/dist/local/task-context-provider.d.ts.map +1 -0
  354. package/dist/local/task-context-provider.js +231 -0
  355. package/dist/local/task-context-provider.js.map +1 -0
  356. package/dist/local/task-context-schema.d.ts +847 -0
  357. package/dist/local/task-context-schema.d.ts.map +1 -0
  358. package/dist/local/task-context-schema.js +305 -0
  359. package/dist/local/task-context-schema.js.map +1 -0
  360. package/dist/local/task-context-source.d.ts +16 -0
  361. package/dist/local/task-context-source.d.ts.map +1 -0
  362. package/dist/local/task-context-source.js +45 -0
  363. package/dist/local/task-context-source.js.map +1 -0
  364. package/dist/local/task-context.d.ts +14 -0
  365. package/dist/local/task-context.d.ts.map +1 -0
  366. package/dist/local/task-context.js +570 -0
  367. package/dist/local/task-context.js.map +1 -0
  368. package/dist/local/test-commands.d.ts +71 -0
  369. package/dist/local/test-commands.d.ts.map +1 -0
  370. package/dist/local/test-commands.js +292 -0
  371. package/dist/local/test-commands.js.map +1 -0
  372. package/dist/local/tree-save.d.ts +117 -0
  373. package/dist/local/tree-save.d.ts.map +1 -0
  374. package/dist/local/tree-save.js +615 -0
  375. package/dist/local/tree-save.js.map +1 -0
  376. package/dist/local/variants.d.ts +125 -0
  377. package/dist/local/variants.d.ts.map +1 -0
  378. package/dist/local/variants.js +267 -0
  379. package/dist/local/variants.js.map +1 -0
  380. package/dist/local/workspace-admission.d.ts +61 -0
  381. package/dist/local/workspace-admission.d.ts.map +1 -0
  382. package/dist/local/workspace-admission.js +112 -0
  383. package/dist/local/workspace-admission.js.map +1 -0
  384. package/dist/local/workspace-authority-guard.d.ts +18 -0
  385. package/dist/local/workspace-authority-guard.d.ts.map +1 -0
  386. package/dist/local/workspace-authority-guard.js +69 -0
  387. package/dist/local/workspace-authority-guard.js.map +1 -0
  388. package/dist/local/workspace-authority.d.ts +33 -0
  389. package/dist/local/workspace-authority.d.ts.map +1 -0
  390. package/dist/local/workspace-authority.js +33 -0
  391. package/dist/local/workspace-authority.js.map +1 -0
  392. package/dist/local/workspace-branch-runtime.d.ts +61 -0
  393. package/dist/local/workspace-branch-runtime.d.ts.map +1 -0
  394. package/dist/local/workspace-branch-runtime.js +216 -0
  395. package/dist/local/workspace-branch-runtime.js.map +1 -0
  396. package/dist/local/workspace-built-content.d.ts +137 -0
  397. package/dist/local/workspace-built-content.d.ts.map +1 -0
  398. package/dist/local/workspace-built-content.js +393 -0
  399. package/dist/local/workspace-built-content.js.map +1 -0
  400. package/dist/local/workspace-claim-status-read.d.ts +53 -0
  401. package/dist/local/workspace-claim-status-read.d.ts.map +1 -0
  402. package/dist/local/workspace-claim-status-read.js +118 -0
  403. package/dist/local/workspace-claim-status-read.js.map +1 -0
  404. package/dist/local/workspace-claim-status.d.ts +172 -0
  405. package/dist/local/workspace-claim-status.d.ts.map +1 -0
  406. package/dist/local/workspace-claim-status.js +721 -0
  407. package/dist/local/workspace-claim-status.js.map +1 -0
  408. package/dist/local/workspace-claim-views.d.ts +45 -0
  409. package/dist/local/workspace-claim-views.d.ts.map +1 -0
  410. package/dist/local/workspace-claim-views.js +45 -0
  411. package/dist/local/workspace-claim-views.js.map +1 -0
  412. package/dist/local/workspace-cli.d.ts +46 -0
  413. package/dist/local/workspace-cli.d.ts.map +1 -0
  414. package/dist/local/workspace-cli.js +1524 -0
  415. package/dist/local/workspace-cli.js.map +1 -0
  416. package/dist/local/workspace-commit-resolver.d.ts +19 -0
  417. package/dist/local/workspace-commit-resolver.d.ts.map +1 -0
  418. package/dist/local/workspace-commit-resolver.js +47 -0
  419. package/dist/local/workspace-commit-resolver.js.map +1 -0
  420. package/dist/local/workspace-decision-store.d.ts +184 -0
  421. package/dist/local/workspace-decision-store.d.ts.map +1 -0
  422. package/dist/local/workspace-decision-store.js +510 -0
  423. package/dist/local/workspace-decision-store.js.map +1 -0
  424. package/dist/local/workspace-environment-runtime.d.ts +107 -0
  425. package/dist/local/workspace-environment-runtime.d.ts.map +1 -0
  426. package/dist/local/workspace-environment-runtime.js +135 -0
  427. package/dist/local/workspace-environment-runtime.js.map +1 -0
  428. package/dist/local/workspace-evidence-drop.d.ts +21 -0
  429. package/dist/local/workspace-evidence-drop.d.ts.map +1 -0
  430. package/dist/local/workspace-evidence-drop.js +58 -0
  431. package/dist/local/workspace-evidence-drop.js.map +1 -0
  432. package/dist/local/workspace-evidence-sign-tool.d.ts +20 -0
  433. package/dist/local/workspace-evidence-sign-tool.d.ts.map +1 -0
  434. package/dist/local/workspace-evidence-sign-tool.js +85 -0
  435. package/dist/local/workspace-evidence-sign-tool.js.map +1 -0
  436. package/dist/local/workspace-evidence-status.d.ts +89 -0
  437. package/dist/local/workspace-evidence-status.d.ts.map +1 -0
  438. package/dist/local/workspace-evidence-status.js +141 -0
  439. package/dist/local/workspace-evidence-status.js.map +1 -0
  440. package/dist/local/workspace-evidence.d.ts +145 -0
  441. package/dist/local/workspace-evidence.d.ts.map +1 -0
  442. package/dist/local/workspace-evidence.js +347 -0
  443. package/dist/local/workspace-evidence.js.map +1 -0
  444. package/dist/local/workspace-graph-store.d.ts +32 -0
  445. package/dist/local/workspace-graph-store.d.ts.map +1 -0
  446. package/dist/local/workspace-graph-store.js +249 -0
  447. package/dist/local/workspace-graph-store.js.map +1 -0
  448. package/dist/local/workspace-handoff.d.ts +32 -0
  449. package/dist/local/workspace-handoff.d.ts.map +1 -0
  450. package/dist/local/workspace-handoff.js +144 -0
  451. package/dist/local/workspace-handoff.js.map +1 -0
  452. package/dist/local/workspace-history-journal.d.ts +70 -0
  453. package/dist/local/workspace-history-journal.d.ts.map +1 -0
  454. package/dist/local/workspace-history-journal.js +131 -0
  455. package/dist/local/workspace-history-journal.js.map +1 -0
  456. package/dist/local/workspace-history-store.d.ts +98 -0
  457. package/dist/local/workspace-history-store.d.ts.map +1 -0
  458. package/dist/local/workspace-history-store.js +632 -0
  459. package/dist/local/workspace-history-store.js.map +1 -0
  460. package/dist/local/workspace-history-types.d.ts +307 -0
  461. package/dist/local/workspace-history-types.d.ts.map +1 -0
  462. package/dist/local/workspace-history-types.js +2 -0
  463. package/dist/local/workspace-history-types.js.map +1 -0
  464. package/dist/local/workspace-integration-runtime.d.ts +48 -0
  465. package/dist/local/workspace-integration-runtime.d.ts.map +1 -0
  466. package/dist/local/workspace-integration-runtime.js +419 -0
  467. package/dist/local/workspace-integration-runtime.js.map +1 -0
  468. package/dist/local/workspace-lock.d.ts +7 -0
  469. package/dist/local/workspace-lock.d.ts.map +1 -0
  470. package/dist/local/workspace-lock.js +211 -0
  471. package/dist/local/workspace-lock.js.map +1 -0
  472. package/dist/local/workspace-merge.d.ts +77 -0
  473. package/dist/local/workspace-merge.d.ts.map +1 -0
  474. package/dist/local/workspace-merge.js +703 -0
  475. package/dist/local/workspace-merge.js.map +1 -0
  476. package/dist/local/workspace-mixed-history.d.ts +33 -0
  477. package/dist/local/workspace-mixed-history.d.ts.map +1 -0
  478. package/dist/local/workspace-mixed-history.js +107 -0
  479. package/dist/local/workspace-mixed-history.js.map +1 -0
  480. package/dist/local/workspace-overlap-allocation.d.ts +33 -0
  481. package/dist/local/workspace-overlap-allocation.d.ts.map +1 -0
  482. package/dist/local/workspace-overlap-allocation.js +69 -0
  483. package/dist/local/workspace-overlap-allocation.js.map +1 -0
  484. package/dist/local/workspace-overlap-impact.d.ts +46 -0
  485. package/dist/local/workspace-overlap-impact.d.ts.map +1 -0
  486. package/dist/local/workspace-overlap-impact.js +162 -0
  487. package/dist/local/workspace-overlap-impact.js.map +1 -0
  488. package/dist/local/workspace-overlap.d.ts +109 -0
  489. package/dist/local/workspace-overlap.d.ts.map +1 -0
  490. package/dist/local/workspace-overlap.js +327 -0
  491. package/dist/local/workspace-overlap.js.map +1 -0
  492. package/dist/local/workspace-paths.d.ts +4 -0
  493. package/dist/local/workspace-paths.d.ts.map +1 -0
  494. package/dist/local/workspace-paths.js +8 -0
  495. package/dist/local/workspace-paths.js.map +1 -0
  496. package/dist/local/workspace-pick-runtime.d.ts +70 -0
  497. package/dist/local/workspace-pick-runtime.d.ts.map +1 -0
  498. package/dist/local/workspace-pick-runtime.js +177 -0
  499. package/dist/local/workspace-pick-runtime.js.map +1 -0
  500. package/dist/local/workspace-pick-store.d.ts +33 -0
  501. package/dist/local/workspace-pick-store.d.ts.map +1 -0
  502. package/dist/local/workspace-pick-store.js +43 -0
  503. package/dist/local/workspace-pick-store.js.map +1 -0
  504. package/dist/local/workspace-pick.d.ts +73 -0
  505. package/dist/local/workspace-pick.d.ts.map +1 -0
  506. package/dist/local/workspace-pick.js +253 -0
  507. package/dist/local/workspace-pick.js.map +1 -0
  508. package/dist/local/workspace-portable-authoring.d.ts +43 -0
  509. package/dist/local/workspace-portable-authoring.d.ts.map +1 -0
  510. package/dist/local/workspace-portable-authoring.js +128 -0
  511. package/dist/local/workspace-portable-authoring.js.map +1 -0
  512. package/dist/local/workspace-prune.d.ts +63 -0
  513. package/dist/local/workspace-prune.d.ts.map +1 -0
  514. package/dist/local/workspace-prune.js +267 -0
  515. package/dist/local/workspace-prune.js.map +1 -0
  516. package/dist/local/workspace-remote-fetch.d.ts +82 -0
  517. package/dist/local/workspace-remote-fetch.d.ts.map +1 -0
  518. package/dist/local/workspace-remote-fetch.js +409 -0
  519. package/dist/local/workspace-remote-fetch.js.map +1 -0
  520. package/dist/local/workspace-remote-provider.d.ts +97 -0
  521. package/dist/local/workspace-remote-provider.d.ts.map +1 -0
  522. package/dist/local/workspace-remote-provider.js +400 -0
  523. package/dist/local/workspace-remote-provider.js.map +1 -0
  524. package/dist/local/workspace-remote-pull-request-journal.d.ts +49 -0
  525. package/dist/local/workspace-remote-pull-request-journal.d.ts.map +1 -0
  526. package/dist/local/workspace-remote-pull-request-journal.js +63 -0
  527. package/dist/local/workspace-remote-pull-request-journal.js.map +1 -0
  528. package/dist/local/workspace-remote-pull-request.d.ts +36 -0
  529. package/dist/local/workspace-remote-pull-request.d.ts.map +1 -0
  530. package/dist/local/workspace-remote-pull-request.js +158 -0
  531. package/dist/local/workspace-remote-pull-request.js.map +1 -0
  532. package/dist/local/workspace-remote-push.d.ts +88 -0
  533. package/dist/local/workspace-remote-push.d.ts.map +1 -0
  534. package/dist/local/workspace-remote-push.js +297 -0
  535. package/dist/local/workspace-remote-push.js.map +1 -0
  536. package/dist/local/workspace-remote-topic-journal.d.ts +56 -0
  537. package/dist/local/workspace-remote-topic-journal.d.ts.map +1 -0
  538. package/dist/local/workspace-remote-topic-journal.js +121 -0
  539. package/dist/local/workspace-remote-topic-journal.js.map +1 -0
  540. package/dist/local/workspace-remote-topic.d.ts +45 -0
  541. package/dist/local/workspace-remote-topic.d.ts.map +1 -0
  542. package/dist/local/workspace-remote-topic.js +204 -0
  543. package/dist/local/workspace-remote-topic.js.map +1 -0
  544. package/dist/local/workspace-remote-transfer.d.ts +76 -0
  545. package/dist/local/workspace-remote-transfer.d.ts.map +1 -0
  546. package/dist/local/workspace-remote-transfer.js +270 -0
  547. package/dist/local/workspace-remote-transfer.js.map +1 -0
  548. package/dist/local/workspace-resolution.d.ts +145 -0
  549. package/dist/local/workspace-resolution.d.ts.map +1 -0
  550. package/dist/local/workspace-resolution.js +479 -0
  551. package/dist/local/workspace-resolution.js.map +1 -0
  552. package/dist/local/workspace-resolver-provider.d.ts +72 -0
  553. package/dist/local/workspace-resolver-provider.d.ts.map +1 -0
  554. package/dist/local/workspace-resolver-provider.js +312 -0
  555. package/dist/local/workspace-resolver-provider.js.map +1 -0
  556. package/dist/local/workspace-runtime-handoff.d.ts +52 -0
  557. package/dist/local/workspace-runtime-handoff.d.ts.map +1 -0
  558. package/dist/local/workspace-runtime-handoff.js +237 -0
  559. package/dist/local/workspace-runtime-handoff.js.map +1 -0
  560. package/dist/local/workspace-runtime-lease.d.ts +26 -0
  561. package/dist/local/workspace-runtime-lease.d.ts.map +1 -0
  562. package/dist/local/workspace-runtime-lease.js +123 -0
  563. package/dist/local/workspace-runtime-lease.js.map +1 -0
  564. package/dist/local/workspace-runtime.d.ts +690 -0
  565. package/dist/local/workspace-runtime.d.ts.map +1 -0
  566. package/dist/local/workspace-runtime.js +2124 -0
  567. package/dist/local/workspace-runtime.js.map +1 -0
  568. package/dist/local/workspace-scope.d.ts +70 -0
  569. package/dist/local/workspace-scope.d.ts.map +1 -0
  570. package/dist/local/workspace-scope.js +206 -0
  571. package/dist/local/workspace-scope.js.map +1 -0
  572. package/dist/local/workspace-sources.d.ts +159 -0
  573. package/dist/local/workspace-sources.d.ts.map +1 -0
  574. package/dist/local/workspace-sources.js +570 -0
  575. package/dist/local/workspace-sources.js.map +1 -0
  576. package/dist/local/workspace-store-database.d.ts +5 -0
  577. package/dist/local/workspace-store-database.d.ts.map +1 -0
  578. package/dist/local/workspace-store-database.js +726 -0
  579. package/dist/local/workspace-store-database.js.map +1 -0
  580. package/dist/local/workspace-store.d.ts +261 -0
  581. package/dist/local/workspace-store.d.ts.map +1 -0
  582. package/dist/local/workspace-store.js +831 -0
  583. package/dist/local/workspace-store.js.map +1 -0
  584. package/dist/local/workspace-topology-runtime.d.ts +27 -0
  585. package/dist/local/workspace-topology-runtime.d.ts.map +1 -0
  586. package/dist/local/workspace-topology-runtime.js +396 -0
  587. package/dist/local/workspace-topology-runtime.js.map +1 -0
  588. package/dist/local/workspace-topology.d.ts +140 -0
  589. package/dist/local/workspace-topology.d.ts.map +1 -0
  590. package/dist/local/workspace-topology.js +359 -0
  591. package/dist/local/workspace-topology.js.map +1 -0
  592. package/dist/local/workspace-upstream-inspection.d.ts +60 -0
  593. package/dist/local/workspace-upstream-inspection.d.ts.map +1 -0
  594. package/dist/local/workspace-upstream-inspection.js +189 -0
  595. package/dist/local/workspace-upstream-inspection.js.map +1 -0
  596. package/dist/local/workspace-upstream-runtime.d.ts +91 -0
  597. package/dist/local/workspace-upstream-runtime.d.ts.map +1 -0
  598. package/dist/local/workspace-upstream-runtime.js +270 -0
  599. package/dist/local/workspace-upstream-runtime.js.map +1 -0
  600. package/dist/local/workspace-upstream-store.d.ts +51 -0
  601. package/dist/local/workspace-upstream-store.d.ts.map +1 -0
  602. package/dist/local/workspace-upstream-store.js +475 -0
  603. package/dist/local/workspace-upstream-store.js.map +1 -0
  604. package/dist/local/workspace-viewer-server.d.ts +136 -0
  605. package/dist/local/workspace-viewer-server.d.ts.map +1 -0
  606. package/dist/local/workspace-viewer-server.js +1097 -0
  607. package/dist/local/workspace-viewer-server.js.map +1 -0
  608. package/dist/local/workspace-viewer-snapshot.d.ts +49 -0
  609. package/dist/local/workspace-viewer-snapshot.d.ts.map +1 -0
  610. package/dist/local/workspace-viewer-snapshot.js +91 -0
  611. package/dist/local/workspace-viewer-snapshot.js.map +1 -0
  612. package/dist/local/worktree-projection.d.ts +76 -0
  613. package/dist/local/worktree-projection.d.ts.map +1 -0
  614. package/dist/local/worktree-projection.js +470 -0
  615. package/dist/local/worktree-projection.js.map +1 -0
  616. package/dist/mcp/client-identity.d.ts +8 -0
  617. package/dist/mcp/client-identity.d.ts.map +1 -0
  618. package/dist/mcp/client-identity.js +33 -0
  619. package/dist/mcp/client-identity.js.map +1 -0
  620. package/dist/mcp/graph-to-code.d.ts +53 -0
  621. package/dist/mcp/graph-to-code.d.ts.map +1 -0
  622. package/dist/mcp/graph-to-code.js +1624 -0
  623. package/dist/mcp/graph-to-code.js.map +1 -0
  624. package/dist/mcp/index.d.ts +3 -0
  625. package/dist/mcp/index.d.ts.map +1 -0
  626. package/dist/mcp/index.js +3 -0
  627. package/dist/mcp/index.js.map +1 -0
  628. package/dist/mcp/stdio/graph-to-code.d.ts +3 -0
  629. package/dist/mcp/stdio/graph-to-code.d.ts.map +1 -0
  630. package/dist/mcp/stdio/graph-to-code.js +55 -0
  631. package/dist/mcp/stdio/graph-to-code.js.map +1 -0
  632. package/dist/mcp/stdio/worktree.d.ts +3 -0
  633. package/dist/mcp/stdio/worktree.d.ts.map +1 -0
  634. package/dist/mcp/stdio/worktree.js +67 -0
  635. package/dist/mcp/stdio/worktree.js.map +1 -0
  636. package/dist/mcp/worktree-claim-status.d.ts +162 -0
  637. package/dist/mcp/worktree-claim-status.d.ts.map +1 -0
  638. package/dist/mcp/worktree-claim-status.js +113 -0
  639. package/dist/mcp/worktree-claim-status.js.map +1 -0
  640. package/dist/mcp/worktree-dispatch.d.ts +13 -0
  641. package/dist/mcp/worktree-dispatch.d.ts.map +1 -0
  642. package/dist/mcp/worktree-dispatch.js +52 -0
  643. package/dist/mcp/worktree-dispatch.js.map +1 -0
  644. package/dist/mcp/worktree-errors.d.ts +15 -0
  645. package/dist/mcp/worktree-errors.d.ts.map +1 -0
  646. package/dist/mcp/worktree-errors.js +17 -0
  647. package/dist/mcp/worktree-errors.js.map +1 -0
  648. package/dist/mcp/worktree-health.d.ts +12 -0
  649. package/dist/mcp/worktree-health.d.ts.map +1 -0
  650. package/dist/mcp/worktree-health.js +32 -0
  651. package/dist/mcp/worktree-health.js.map +1 -0
  652. package/dist/mcp/worktree-results.d.ts +15 -0
  653. package/dist/mcp/worktree-results.d.ts.map +1 -0
  654. package/dist/mcp/worktree-results.js +12 -0
  655. package/dist/mcp/worktree-results.js.map +1 -0
  656. package/dist/mcp/worktree-task-context.d.ts +57 -0
  657. package/dist/mcp/worktree-task-context.d.ts.map +1 -0
  658. package/dist/mcp/worktree-task-context.js +45 -0
  659. package/dist/mcp/worktree-task-context.js.map +1 -0
  660. package/dist/mcp/worktree-tools.d.ts +2648 -0
  661. package/dist/mcp/worktree-tools.d.ts.map +1 -0
  662. package/dist/mcp/worktree-tools.js +192 -0
  663. package/dist/mcp/worktree-tools.js.map +1 -0
  664. package/dist/mcp/worktree.d.ts +33 -0
  665. package/dist/mcp/worktree.d.ts.map +1 -0
  666. package/dist/mcp/worktree.js +551 -0
  667. package/dist/mcp/worktree.js.map +1 -0
  668. package/dist/own-package.d.ts +13 -0
  669. package/dist/own-package.d.ts.map +1 -0
  670. package/dist/own-package.js +32 -0
  671. package/dist/own-package.js.map +1 -0
  672. package/dist/packages-browse.d.ts +107 -0
  673. package/dist/packages-browse.d.ts.map +1 -0
  674. package/dist/packages-browse.js +646 -0
  675. package/dist/packages-browse.js.map +1 -0
  676. package/dist/packages-cli.d.ts +8 -0
  677. package/dist/packages-cli.d.ts.map +1 -0
  678. package/dist/packages-cli.js +184 -0
  679. package/dist/packages-cli.js.map +1 -0
  680. package/dist/packages-uses.d.ts +46 -0
  681. package/dist/packages-uses.d.ts.map +1 -0
  682. package/dist/packages-uses.js +737 -0
  683. package/dist/packages-uses.js.map +1 -0
  684. package/dist/portable.d.ts +7 -0
  685. package/dist/portable.d.ts.map +1 -0
  686. package/dist/portable.js +14 -0
  687. package/dist/portable.js.map +1 -0
  688. package/dist/quiet-warnings.d.ts +3 -0
  689. package/dist/quiet-warnings.d.ts.map +1 -0
  690. package/dist/quiet-warnings.js +21 -0
  691. package/dist/quiet-warnings.js.map +1 -0
  692. package/dist/view-seam.d.ts +62 -0
  693. package/dist/view-seam.d.ts.map +1 -0
  694. package/dist/view-seam.js +70 -0
  695. package/dist/view-seam.js.map +1 -0
  696. package/generated/graph-packages/index.json +5 -0
  697. package/graph-packages.lock.json +4 -0
  698. package/package.json +81 -0
  699. package/viewer/assets/index-BZKGDARF.css +1 -0
  700. package/viewer/assets/index-DWu0CbZZ.js +272 -0
  701. package/viewer/index.html +13 -0
@@ -0,0 +1,709 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, readdir, rename, rm, rmdir, stat, writeFile } from 'node:fs/promises';
3
+ import { basename, dirname, isAbsolute, join, relative, sep } from 'node:path';
4
+ import { encodeEvidenceMeta, isEvidenceBoundaryEnabled, markEvidenceFormatUpgrade, upgradeGraphEvidenceFormat, portable_graph_edge_schema, portable_graph_node_schema, portable_graph_path_relation_schema, portable_graph_path_schema, portable_graph_schema, withoutEvidenceTransientState } from '@software-dlc/graph/schema';
5
+ import { validateBuiltGraph } from '@software-dlc/graph/validator';
6
+ import { diffPortableGraphs } from '@software-dlc/graph/computation';
7
+ import { canonicalizePortableGraph, stringifyCanonicalGraph, stringifyCanonicalJson } from './canonical.js';
8
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
9
+ export const DEFAULT_PROJECTION_DIRECTORY_NAME = 'sdlc';
10
+ /** The graph's package uses (graph-packages.md, Use), only while it has some. */
11
+ export const PACKAGE_USES_FILE = 'package-uses.json';
12
+ const ENTITY_CONFIG = {
13
+ node: {
14
+ directory: 'nodes',
15
+ graph_key: 'nodes',
16
+ safe_parse: (value) => portable_graph_node_schema.safeParse(value)
17
+ },
18
+ edge: {
19
+ directory: 'edges',
20
+ graph_key: 'edges',
21
+ safe_parse: (value) => portable_graph_edge_schema.safeParse(value)
22
+ },
23
+ path: {
24
+ directory: 'paths',
25
+ graph_key: 'paths',
26
+ safe_parse: (value) => portable_graph_path_schema.safeParse(value)
27
+ },
28
+ path_relation: {
29
+ directory: 'path-relations',
30
+ graph_key: 'path_relations',
31
+ safe_parse: (value) => portable_graph_path_relation_schema.safeParse(value)
32
+ }
33
+ };
34
+ /** Every invalid entity file of a projection, reported together instead of the first one found. */
35
+ export class ProjectionEntityErrors extends Error {
36
+ errors;
37
+ constructor(errors) {
38
+ super([
39
+ `The projection has ${errors.length} invalid entity ${errors.length === 1 ? 'field' : 'fields'}:`,
40
+ ...errors.map((error) => ` ${error.relative_path} (${error.entity_kind} ${error.entity_id})${error.field_path ? ` ${error.field_path}` : ''}: ${error.message}`)
41
+ ].join('\n'));
42
+ this.name = 'ProjectionEntityErrors';
43
+ this.errors = errors;
44
+ }
45
+ }
46
+ const ENTITY_KINDS = Object.keys(ENTITY_CONFIG);
47
+ function entityRelativePath(kind, id) {
48
+ return `${ENTITY_CONFIG[kind].directory}/${id}.json`;
49
+ }
50
+ function graphEntities(graph, kind) {
51
+ const key = ENTITY_CONFIG[kind].graph_key;
52
+ return (graph[key] ?? []);
53
+ }
54
+ function parseJson(value, source) {
55
+ try {
56
+ return JSON.parse(value);
57
+ }
58
+ catch (error) {
59
+ const message = error instanceof Error ? error.message : String(error);
60
+ throw new Error(`Invalid JSON in ${source}: ${message}`);
61
+ }
62
+ }
63
+ async function pathExists(path) {
64
+ try {
65
+ await stat(path);
66
+ return true;
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
70
+ return false;
71
+ }
72
+ throw error;
73
+ }
74
+ }
75
+ export async function writeJsonAtomically(path, value) {
76
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
77
+ const temporary_path = `${path}.tmp-${randomUUID()}`;
78
+ try {
79
+ await writeFile(temporary_path, `${stringifyCanonicalJson(value, 2)}\n`, {
80
+ encoding: 'utf8',
81
+ mode: 0o600,
82
+ flag: 'wx'
83
+ });
84
+ await rename(temporary_path, path);
85
+ }
86
+ catch (error) {
87
+ await rm(temporary_path, { force: true });
88
+ throw error;
89
+ }
90
+ }
91
+ async function assertManagedDirectoryEntries(directory) {
92
+ if (!(await pathExists(directory)))
93
+ return;
94
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
95
+ if (!entry.isFile() || !entry.name.endsWith('.json')) {
96
+ throw new Error(`Managed projection directory contains unsupported entry: ${join(directory, entry.name)}`);
97
+ }
98
+ }
99
+ }
100
+ async function materializeEntityKind(input) {
101
+ const directory = join(input.projection_dir, ENTITY_CONFIG[input.kind].directory);
102
+ await mkdir(directory, { recursive: true, mode: 0o700 });
103
+ await assertManagedDirectoryEntries(directory);
104
+ const desired_names = new Set();
105
+ for (const entity of input.entities) {
106
+ input.check?.();
107
+ const name = `${entity.id}.json`;
108
+ desired_names.add(name);
109
+ await writeJsonAtomically(join(directory, name), entity);
110
+ }
111
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
112
+ if (entry.isFile() &&
113
+ entry.name.endsWith('.json') &&
114
+ !desired_names.has(entry.name)) {
115
+ input.check?.();
116
+ await rm(join(directory, entry.name));
117
+ }
118
+ }
119
+ }
120
+ export function resolveProjectionDirectory(input) {
121
+ return (input.override ??
122
+ join(input.repository_root, DEFAULT_PROJECTION_DIRECTORY_NAME));
123
+ }
124
+ export async function projectionHasManagedContent(projection_dir) {
125
+ if (await pathExists(join(projection_dir, 'tags.json')))
126
+ return true;
127
+ if (await pathExists(join(projection_dir, PACKAGE_USES_FILE)))
128
+ return true;
129
+ for (const kind of ENTITY_KINDS) {
130
+ const directory = join(projection_dir, ENTITY_CONFIG[kind].directory);
131
+ if (!(await pathExists(directory)))
132
+ continue;
133
+ if ((await readdir(directory)).some((name) => name.endsWith('.json'))) {
134
+ return true;
135
+ }
136
+ }
137
+ return false;
138
+ }
139
+ /**
140
+ * Undo an empty projection written into a directory that held no managed
141
+ * content: remove tags.json and the managed directories while they are still
142
+ * empty, and the projection directory itself only when nothing else is left.
143
+ */
144
+ export async function removeEmptyGraphProjection(projection_dir) {
145
+ await rm(join(projection_dir, 'tags.json'), { force: true });
146
+ await rm(join(projection_dir, PACKAGE_USES_FILE), { force: true });
147
+ await rm(join(projection_dir, PROJECTION_MANIFEST_FILE), { force: true });
148
+ for (const name of [
149
+ ...ENTITY_KINDS.map((kind) => ENTITY_CONFIG[kind].directory),
150
+ 'scratch'
151
+ ]) {
152
+ await removeEmptyDirectory(join(projection_dir, name));
153
+ }
154
+ await removeEmptyDirectory(projection_dir);
155
+ }
156
+ async function removeEmptyDirectory(path) {
157
+ if (!(await pathExists(path)))
158
+ return;
159
+ if ((await readdir(path)).length > 0)
160
+ return;
161
+ await rmdir(path);
162
+ }
163
+ /** Comparison authority belongs to the server, never editable projection metadata. */
164
+ function withoutWorktreeBuildOverride(meta) {
165
+ if (!meta || !('worktree_build_override' in meta))
166
+ return meta;
167
+ const { worktree_build_override: _override, ...retained } = meta;
168
+ return retained;
169
+ }
170
+ /** Strips in-memory evidence and comparison markers from entities. */
171
+ function withoutGraphEvidenceTransientState(graph) {
172
+ return {
173
+ ...graph,
174
+ nodes: graph.nodes.map((node) => ({
175
+ ...node,
176
+ data: {
177
+ ...node.data,
178
+ meta: withoutWorktreeBuildOverride(withoutEvidenceTransientState(node.data.meta))
179
+ }
180
+ })),
181
+ edges: graph.edges.map((edge) => edge.data
182
+ ? {
183
+ ...edge,
184
+ data: {
185
+ ...edge.data,
186
+ meta: withoutEvidenceTransientState(edge.data.meta)
187
+ }
188
+ }
189
+ : edge)
190
+ };
191
+ }
192
+ /**
193
+ * Evidence as storage holds it: a decoded legacy value is presented as the
194
+ * legacy value alone and current evidence without its decode marker, so
195
+ * unchanged entities never differ from their stored form.
196
+ */
197
+ function storedGraphEvidence(graph) {
198
+ if (!isEvidenceBoundaryEnabled())
199
+ return graph;
200
+ return {
201
+ ...graph,
202
+ nodes: graph.nodes.map((node) => ({
203
+ ...node,
204
+ data: {
205
+ ...node.data,
206
+ meta: node.data.meta && encodeEvidenceMeta(node.data.meta)
207
+ }
208
+ })),
209
+ edges: graph.edges.map((edge) => edge.data
210
+ ? {
211
+ ...edge,
212
+ data: {
213
+ ...edge.data,
214
+ meta: edge.data.meta && encodeEvidenceMeta(edge.data.meta)
215
+ }
216
+ }
217
+ : edge)
218
+ };
219
+ }
220
+ /**
221
+ * Projection files show evidence as stored. `--upgrade-evidence` converts
222
+ * every legacy entity to the latest contract as one reviewable change;
223
+ * without it, legacy evidence is shown and saved unchanged.
224
+ */
225
+ function presentProjectionEvidence(input_graph, upgrade_evidence) {
226
+ const graph = isEvidenceBoundaryEnabled() && upgrade_evidence
227
+ ? upgradeGraphEvidenceFormat(input_graph).graph
228
+ : storedGraphEvidence(input_graph);
229
+ return withoutGraphEvidenceTransientState(graph);
230
+ }
231
+ /**
232
+ * The local projection is current-format by construction, so every save
233
+ * states the explicit upgrade intent; the server keeps untouched legacy
234
+ * evidence only for clients that cannot retain it.
235
+ */
236
+ export function prepareProjectionEvidenceForSave(graph) {
237
+ return isEvidenceBoundaryEnabled() ? markEvidenceFormatUpgrade(graph) : graph;
238
+ }
239
+ /**
240
+ * Present only in a scoped projection (workspace attach): the entities it
241
+ * holds. Every other entity is read from the workspace head.
242
+ */
243
+ export const PROJECTION_MANIFEST_FILE = 'projection.json';
244
+ function emptyProjectionScope() {
245
+ return { node: [], edge: [], path: [], path_relation: [] };
246
+ }
247
+ /** The entities a task scope names, whichever of their fields it covers. */
248
+ export function projectionScopeOfTaskScope(task_scope) {
249
+ const scope = emptyProjectionScope();
250
+ for (const rule of task_scope.rules) {
251
+ if (!ENTITY_KINDS.includes(rule.entity_kind))
252
+ continue;
253
+ scope[rule.entity_kind].push(rule.entity_id);
254
+ }
255
+ return scope;
256
+ }
257
+ function mergeProjectionScopes(...scopes) {
258
+ const merged = emptyProjectionScope();
259
+ for (const kind of ENTITY_KINDS) {
260
+ merged[kind] = [...new Set(scopes.flatMap((scope) => scope[kind]))].sort();
261
+ }
262
+ return merged;
263
+ }
264
+ async function readProjectionManifest(projection_dir, access) {
265
+ // Found by listing, as package-uses.json is: an access may refuse a missing path.
266
+ if (!(await access.exists(projection_dir)))
267
+ return null;
268
+ const present = (await access.entries(projection_dir)).some((entry) => entry.is_file && entry.name === PROJECTION_MANIFEST_FILE);
269
+ if (!present)
270
+ return null;
271
+ const manifest = parseJson(await access.read(join(projection_dir, PROJECTION_MANIFEST_FILE)), PROJECTION_MANIFEST_FILE);
272
+ if (manifest?.version !== 1 ||
273
+ !manifest.scope ||
274
+ ENTITY_KINDS.some((kind) => !Array.isArray(manifest.scope?.[kind]))) {
275
+ throw new Error(`Unsupported ${PROJECTION_MANIFEST_FILE}.`);
276
+ }
277
+ return manifest;
278
+ }
279
+ async function projectionEntityIdsOnDisk(projection_dir) {
280
+ const scope = emptyProjectionScope();
281
+ for (const kind of ENTITY_KINDS) {
282
+ const directory = join(projection_dir, ENTITY_CONFIG[kind].directory);
283
+ if (!(await pathExists(directory)))
284
+ continue;
285
+ scope[kind] = (await readdir(directory))
286
+ .filter((name) => name.endsWith('.json'))
287
+ .map((name) => basename(name, '.json'));
288
+ }
289
+ return scope;
290
+ }
291
+ /** Whether the projection holds only a scope (workspace attach) instead of the whole graph. */
292
+ export async function isScopedProjection(projection_dir) {
293
+ return ((await readProjectionManifest(projection_dir, DEFAULT_READ_ACCESS)) !== null);
294
+ }
295
+ function presentValidatedGraph(input_graph, upgrade_evidence) {
296
+ const graph = presentProjectionEvidence(canonicalizePortableGraph(portable_graph_schema.parse(input_graph)), upgrade_evidence);
297
+ const validation = validateProjectionGraph(graph);
298
+ if (!validation.is_valid) {
299
+ throw new Error(`Remote worktree graph failed local validation: ${validation.issues
300
+ .filter((issue) => issue.status === 'broken')
301
+ .map((issue) => `${issue.code}: ${issue.message}`)
302
+ .join('; ')}`);
303
+ }
304
+ return graph;
305
+ }
306
+ /**
307
+ * Writes the graph's projection. With `scope`, only those entities are
308
+ * written, with tags and package uses, and projection.json lists them. A
309
+ * projection that already holds a scope keeps it, with any entity the
310
+ * projection added, unless `full` asks for the whole graph again.
311
+ */
312
+ export async function materializeGraphProjection(input) {
313
+ const graph = presentValidatedGraph(input.graph, input.upgrade_evidence === true);
314
+ let scope = input.scope
315
+ ? mergeProjectionScopes(input.scope)
316
+ : null;
317
+ if (!scope && !input.full) {
318
+ const existing = await readProjectionManifest(input.projection_dir, DEFAULT_READ_ACCESS);
319
+ if (existing) {
320
+ scope = mergeProjectionScopes(existing.scope, await projectionEntityIdsOnDisk(input.projection_dir));
321
+ }
322
+ }
323
+ input.check?.();
324
+ await mkdir(input.projection_dir, { recursive: true, mode: 0o700 });
325
+ for (const kind of ENTITY_KINDS) {
326
+ input.check?.();
327
+ const selected = scope ? new Set(scope[kind]) : null;
328
+ // The manifest keeps every scoped id, present in the graph or not, so a
329
+ // scoped entity created later still reads from its file, and its
330
+ // deletion as a deletion.
331
+ const entities = graphEntities(graph, kind).filter((entity) => !selected || selected.has(entity.id));
332
+ await materializeEntityKind({
333
+ projection_dir: input.projection_dir,
334
+ kind,
335
+ entities,
336
+ check: input.check
337
+ });
338
+ }
339
+ if (scope) {
340
+ await writeJsonAtomically(join(input.projection_dir, PROJECTION_MANIFEST_FILE), {
341
+ version: 1,
342
+ scope
343
+ });
344
+ }
345
+ else {
346
+ await rm(join(input.projection_dir, PROJECTION_MANIFEST_FILE), {
347
+ force: true
348
+ });
349
+ }
350
+ input.check?.();
351
+ await writeJsonAtomically(join(input.projection_dir, 'tags.json'), graph.tags ?? []);
352
+ // Present only while the graph uses a package, as the graph's key is.
353
+ if (graph.package_uses?.length) {
354
+ await writeJsonAtomically(join(input.projection_dir, PACKAGE_USES_FILE), graph.package_uses);
355
+ }
356
+ else {
357
+ await rm(join(input.projection_dir, PACKAGE_USES_FILE), { force: true });
358
+ }
359
+ await mkdir(join(input.projection_dir, 'scratch'), {
360
+ recursive: true,
361
+ mode: 0o700
362
+ });
363
+ return graph;
364
+ }
365
+ /**
366
+ * Adds entities to a scoped projection when its task scope grows: writes the
367
+ * file of each newly scoped entity the graph has and the projection lacks,
368
+ * leaving every existing file, edited or not, as it is.
369
+ */
370
+ export async function extendScopedProjection(input) {
371
+ const manifest = await readProjectionManifest(input.projection_dir, DEFAULT_READ_ACCESS);
372
+ if (!manifest)
373
+ throw new Error('The projection holds the whole graph.');
374
+ // Presented as materializing writes it, but not validated as a whole: the
375
+ // graph may carry uncommitted edits, which only a commit validates.
376
+ const graph = presentProjectionEvidence(canonicalizePortableGraph(portable_graph_schema.parse(input.graph)), false);
377
+ const on_disk = await projectionEntityIdsOnDisk(input.projection_dir);
378
+ const added = emptyProjectionScope();
379
+ for (const kind of ENTITY_KINDS) {
380
+ // A listed entity whose file is missing was deleted; never restore it.
381
+ const held = new Set([...on_disk[kind], ...manifest.scope[kind]]);
382
+ const wanted = new Set(input.scope[kind]);
383
+ for (const entity of graphEntities(graph, kind)) {
384
+ if (!wanted.has(entity.id) || held.has(entity.id))
385
+ continue;
386
+ await writeJsonAtomically(join(input.projection_dir, entityRelativePath(kind, entity.id)), entity);
387
+ added[kind].push(entity.id);
388
+ }
389
+ }
390
+ // Every newly scoped id is listed, written or not, as materializing lists it.
391
+ await writeJsonAtomically(join(input.projection_dir, PROJECTION_MANIFEST_FILE), {
392
+ version: 1,
393
+ scope: mergeProjectionScopes(manifest.scope, input.scope, on_disk)
394
+ });
395
+ return added;
396
+ }
397
+ /**
398
+ * Lists in a scoped projection's manifest every entity file it holds, so an
399
+ * entity created in the projection and committed reads as deleted, not as
400
+ * the head has it, once its file is removed. A whole projection is left as
401
+ * it is.
402
+ */
403
+ export async function recordScopedProjectionFiles(projection_dir) {
404
+ const manifest = await readProjectionManifest(projection_dir, DEFAULT_READ_ACCESS);
405
+ if (!manifest)
406
+ return;
407
+ await writeJsonAtomically(join(projection_dir, PROJECTION_MANIFEST_FILE), {
408
+ version: 1,
409
+ scope: mergeProjectionScopes(manifest.scope, await projectionEntityIdsOnDisk(projection_dir))
410
+ });
411
+ }
412
+ /** Whether a projection.json is present, readable or not. */
413
+ export async function hasProjectionManifest(projection_dir) {
414
+ return pathExists(join(projection_dir, PROJECTION_MANIFEST_FILE));
415
+ }
416
+ const DEFAULT_READ_ACCESS = {
417
+ exists: pathExists,
418
+ read: (path) => readFile(path, 'utf8'),
419
+ entries: async (path) => (await readdir(path, { withFileTypes: true })).map((entry) => ({
420
+ name: entry.name,
421
+ is_file: entry.isFile()
422
+ }))
423
+ };
424
+ async function readProjectionEntities(input) {
425
+ const config = ENTITY_CONFIG[input.kind];
426
+ const directory = join(input.projection_dir, config.directory);
427
+ if (!(await input.access.exists(directory))) {
428
+ throw new Error(`Managed projection directory is missing: ${config.directory}`);
429
+ }
430
+ const entries = await input.access.entries(directory);
431
+ if (entries.some((entry) => !entry.is_file || !entry.name.endsWith('.json')))
432
+ throw new Error('Unsupported projection entry.');
433
+ const entities = [];
434
+ const errors = [];
435
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
436
+ const id = basename(entry.name, '.json');
437
+ if (!UUID_PATTERN.test(id)) {
438
+ throw new Error(`Projection filename must be a stable UUID: ${entry.name}`);
439
+ }
440
+ const relative_path = entityRelativePath(input.kind, id);
441
+ const fileError = (field_path, message) => errors.push({
442
+ entity_kind: input.kind,
443
+ entity_id: id,
444
+ relative_path,
445
+ field_path,
446
+ message
447
+ });
448
+ let value;
449
+ try {
450
+ value = parseJson(await input.access.read(join(directory, entry.name)), relative_path);
451
+ }
452
+ catch (error) {
453
+ if (!(error instanceof Error) ||
454
+ !error.message.startsWith('Invalid JSON'))
455
+ throw error;
456
+ fileError('', error.message);
457
+ continue;
458
+ }
459
+ const parsed = config.safe_parse(value);
460
+ if (!parsed.success) {
461
+ // The schema can check one field more than once; a field that fails
462
+ // the same way twice is one invalid field.
463
+ const reported = new Set();
464
+ for (const issue of parsed.error.issues) {
465
+ const field_path = issue.path.map(String).join('.');
466
+ const key = JSON.stringify([field_path, issue.message]);
467
+ if (reported.has(key))
468
+ continue;
469
+ reported.add(key);
470
+ fileError(field_path, issue.message);
471
+ }
472
+ continue;
473
+ }
474
+ if (parsed.data.id !== id) {
475
+ fileError('id', `Projection entity id ${parsed.data.id} does not match filename ${entry.name}.`);
476
+ continue;
477
+ }
478
+ entities.push(parsed.data);
479
+ }
480
+ return { entities, errors };
481
+ }
482
+ /**
483
+ * Composes the projection's files into one graph. A scoped projection
484
+ * (projection.json) composes only over `base`, its workspace's head: the
485
+ * entities it lists or holds come from their files, a listed entity whose
486
+ * file is gone reads as deleted, and every other entity comes from the base.
487
+ */
488
+ export async function composeGraphProjection(projection_dir, access = DEFAULT_READ_ACCESS, options = {}) {
489
+ const tags_path = join(projection_dir, 'tags.json');
490
+ if (!(await access.exists(tags_path))) {
491
+ throw new Error('Managed projection tags.json is missing.');
492
+ }
493
+ const manifest = await readProjectionManifest(projection_dir, access);
494
+ if (manifest && !options.base) {
495
+ throw new Error(`This projection holds only its workspace's task scope (${PROJECTION_MANIFEST_FILE}); read it through its workspace, for example sdlc workspace status.`);
496
+ }
497
+ const base = manifest && options.base ? await options.base() : null;
498
+ const entity_results = await Promise.allSettled(ENTITY_KINDS.map((kind) => readProjectionEntities({ projection_dir, kind, access }).then((read) => ({
499
+ kind,
500
+ ...read
501
+ }))));
502
+ const entity_groups = entity_results.map((result) => {
503
+ if (result.status === 'rejected')
504
+ throw result.reason;
505
+ return result.value;
506
+ });
507
+ const entity_errors = entity_groups.flatMap((group) => group.errors);
508
+ if (entity_errors.length > 0)
509
+ throw new ProjectionEntityErrors(entity_errors);
510
+ const graph_input = {
511
+ nodes: [],
512
+ edges: [],
513
+ paths: [],
514
+ path_relations: [],
515
+ tags: parseJson(await access.read(tags_path), 'tags.json')
516
+ };
517
+ // The file is optional, so it is found by listing the folder: an access may treat a
518
+ // missing path it is asked about as an incomplete projection (health inspection does).
519
+ const package_uses_path = join(projection_dir, PACKAGE_USES_FILE);
520
+ const has_package_uses = (await access.entries(projection_dir)).some((entry) => entry.is_file && entry.name === PACKAGE_USES_FILE);
521
+ if (has_package_uses) {
522
+ graph_input.package_uses = parseJson(await access.read(package_uses_path), PACKAGE_USES_FILE);
523
+ }
524
+ for (const group of entity_groups) {
525
+ if (manifest && base) {
526
+ const held = new Set([
527
+ ...manifest.scope[group.kind],
528
+ ...group.entities.map((entity) => entity.id)
529
+ ]);
530
+ group.entities = [
531
+ ...graphEntities(base, group.kind).filter((entity) => !held.has(entity.id)),
532
+ ...group.entities
533
+ ];
534
+ }
535
+ if (group.kind === 'node')
536
+ graph_input.nodes = group.entities;
537
+ if (group.kind === 'edge')
538
+ graph_input.edges = group.entities;
539
+ if (group.kind === 'path')
540
+ graph_input.paths = group.entities;
541
+ if (group.kind === 'path_relation') {
542
+ graph_input.path_relations =
543
+ group.entities;
544
+ }
545
+ }
546
+ const graph = canonicalizePortableGraph(portable_graph_schema.parse({
547
+ ...graph_input,
548
+ nodes: graph_input.nodes.map((node) => ({
549
+ ...node,
550
+ data: {
551
+ ...node.data,
552
+ meta: withoutWorktreeBuildOverride(node.data.meta)
553
+ }
554
+ }))
555
+ }));
556
+ const graph_json = stringifyCanonicalGraph(graph);
557
+ return {
558
+ graph,
559
+ graph_json,
560
+ graph_hash: createHash('sha256').update(graph_json).digest('hex')
561
+ };
562
+ }
563
+ /**
564
+ * With `node_parents`, every node's parent is checked as a hosted apply of the
565
+ * whole graph checks it; local workspace commits ask for it, while a graph
566
+ * pulled from or bound to a hosted branch keeps the hosted save's rules.
567
+ */
568
+ export function validateProjectionGraph(graph, options = {}) {
569
+ const validation = validateBuiltGraph(graph, { id_policy: 'uuid', node_parents: options.node_parents });
570
+ return { is_valid: validation.is_valid, issues: validation.issues };
571
+ }
572
+ function entityMap(graph, kind) {
573
+ return new Map(graphEntities(graph, kind).map((entity) => [entity.id, entity]));
574
+ }
575
+ export function graphHasProjectionEntity(graph, intent) {
576
+ return entityMap(graph, intent.entity_kind).has(intent.entity_id);
577
+ }
578
+ export function restoreMissingProjectionEntities(input) {
579
+ const current_graph = canonicalizePortableGraph(portable_graph_schema.parse(input.current_graph));
580
+ const source_graph = canonicalizePortableGraph(portable_graph_schema.parse(input.source_graph));
581
+ const restored_graph = {
582
+ ...current_graph,
583
+ nodes: [...current_graph.nodes],
584
+ edges: [...current_graph.edges],
585
+ paths: [...(current_graph.paths ?? [])],
586
+ path_relations: [...(current_graph.path_relations ?? [])]
587
+ };
588
+ for (const kind of ENTITY_KINDS) {
589
+ const current_entities = entityMap(current_graph, kind);
590
+ const source_entities = entityMap(source_graph, kind);
591
+ for (const entry of input.entries) {
592
+ if (entry.entity_kind !== kind || current_entities.has(entry.entity_id)) {
593
+ continue;
594
+ }
595
+ const source_entity = source_entities.get(entry.entity_id);
596
+ if (!source_entity) {
597
+ throw new Error(`Recovery source is missing ${entry.entity_kind} ${entry.entity_id}.`);
598
+ }
599
+ current_entities.set(entry.entity_id, source_entity);
600
+ }
601
+ const restored_entities = [...current_entities.values()];
602
+ if (kind === 'node') {
603
+ restored_graph.nodes = restored_entities;
604
+ }
605
+ else if (kind === 'edge') {
606
+ restored_graph.edges = restored_entities;
607
+ }
608
+ else if (kind === 'path') {
609
+ restored_graph.paths = restored_entities;
610
+ }
611
+ else {
612
+ restored_graph.path_relations =
613
+ restored_entities;
614
+ }
615
+ }
616
+ return canonicalizePortableGraph(portable_graph_schema.parse(restored_graph));
617
+ }
618
+ function deletionKey(intent) {
619
+ return `${intent.entity_kind}:${intent.entity_id}`;
620
+ }
621
+ export function diffProjectionGraphs(input) {
622
+ // The decode marker is in-memory state, never a projection change.
623
+ const semantic_diff = diffPortableGraphs({
624
+ ...input,
625
+ base_graph: withoutGraphEvidenceTransientState(storedGraphEvidence(input.base_graph)),
626
+ current_graph: withoutGraphEvidenceTransientState(input.current_graph)
627
+ });
628
+ const deleted = [];
629
+ const missing_unrecorded = [];
630
+ const deletion_keys = new Set((input.deletion_intents ?? []).map(deletionKey));
631
+ const projectionEntry = (entry) => ({
632
+ ...entry,
633
+ relative_path: entityRelativePath(entry.entity_kind, entry.entity_id)
634
+ });
635
+ for (const semantic_entry of semantic_diff.deleted) {
636
+ const entry = projectionEntry(semantic_entry);
637
+ if (deletion_keys.has(deletionKey(entry)))
638
+ deleted.push(entry);
639
+ else
640
+ missing_unrecorded.push(entry);
641
+ }
642
+ const sort_entries = (entries) => entries.sort((left, right) => left.relative_path.localeCompare(right.relative_path));
643
+ return {
644
+ added: sort_entries(semantic_diff.added.map(projectionEntry)),
645
+ modified: sort_entries(semantic_diff.modified.map(projectionEntry)),
646
+ deleted: sort_entries(deleted),
647
+ missing_unrecorded: sort_entries(missing_unrecorded),
648
+ tags_changed: semantic_diff.tags_changed,
649
+ ...(semantic_diff.package_uses_changed
650
+ ? { package_uses_changed: true }
651
+ : {})
652
+ };
653
+ }
654
+ export function projectionDiffHasChanges(diff) {
655
+ return (diff.added.length > 0 ||
656
+ diff.modified.length > 0 ||
657
+ diff.deleted.length > 0 ||
658
+ diff.missing_unrecorded.length > 0 ||
659
+ diff.tags_changed ||
660
+ diff.package_uses_changed === true);
661
+ }
662
+ export function parseProjectionEntityPath(input) {
663
+ if (isAbsolute(input.path)) {
664
+ throw new Error('Projection entity path must be relative to sdlc/.');
665
+ }
666
+ const normalized = input.path.split('/').join(sep);
667
+ const absolute_path = join(input.projection_dir, normalized);
668
+ const relative_path = relative(input.projection_dir, absolute_path)
669
+ .split(sep)
670
+ .join('/');
671
+ if (relative_path.startsWith('../') || relative_path === '..') {
672
+ throw new Error('Projection entity path must stay inside sdlc/.');
673
+ }
674
+ for (const kind of ENTITY_KINDS) {
675
+ const match = relative_path.match(new RegExp(`^${ENTITY_CONFIG[kind].directory}/([0-9a-f-]+)\\.json$`, 'i'));
676
+ if (!match)
677
+ continue;
678
+ const entity_id = match[1] ?? '';
679
+ if (!UUID_PATTERN.test(entity_id)) {
680
+ throw new Error('Projection entity path must use a stable UUID filename.');
681
+ }
682
+ return { entity_kind: kind, entity_id, relative_path };
683
+ }
684
+ throw new Error('Projection entity path must identify a JSON file under nodes, edges, paths, or path-relations.');
685
+ }
686
+ /**
687
+ * Removes one entity file. A file already deleted by hand is accepted when
688
+ * the projection holds its entity (a scoped projection holds only its
689
+ * manifest's scope; compose fills the rest from the base) and `allow_missing`
690
+ * says the entity is still in the base, so the caller can record the deletion
691
+ * the commit or save asks for.
692
+ */
693
+ export async function removeProjectionEntity(input) {
694
+ const entry = parseProjectionEntityPath({
695
+ projection_dir: input.projection_dir,
696
+ path: input.relative_path
697
+ });
698
+ const path = join(input.projection_dir, entry.relative_path);
699
+ if (!(await pathExists(path))) {
700
+ const manifest = await readProjectionManifest(input.projection_dir, DEFAULT_READ_ACCESS);
701
+ const held = !manifest || manifest.scope[entry.entity_kind].includes(entry.entity_id);
702
+ if (held && input.allow_missing?.(entry))
703
+ return entry;
704
+ throw new Error(`Projection entity does not exist: ${entry.relative_path}`);
705
+ }
706
+ await rm(path);
707
+ return entry;
708
+ }
709
+ //# sourceMappingURL=projection.js.map