light-plan 0.0.0-stage → 0.1.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 (963) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3181 -2
  3. package/assets/README.md +111 -0
  4. package/assets/agents/lpm-developer.md +468 -0
  5. package/assets/agents/lpm-planner.md +532 -0
  6. package/assets/harnesses/claude.yml +43 -0
  7. package/assets/harnesses/copilot.yml +54 -0
  8. package/assets/harnesses/reasonix.yml +49 -0
  9. package/assets/hcm/light-plan.yml +45 -0
  10. package/assets/skills/lpm-board-health.md +243 -0
  11. package/assets/skills/lpm-board-setup.md +354 -0
  12. package/assets/skills/lpm-delivery.md +344 -0
  13. package/assets/skills/lpm-planning.md +411 -0
  14. package/assets/skills/lpm-templates.md +144 -0
  15. package/assets/skills/lpm.md +267 -0
  16. package/dist/cli/agent-view.d.ts +27 -0
  17. package/dist/cli/agent-view.js +247 -0
  18. package/dist/cli/agent-view.js.map +1 -0
  19. package/dist/cli/commands/agent/assets.d.ts +64 -0
  20. package/dist/cli/commands/agent/assets.js +106 -0
  21. package/dist/cli/commands/agent/assets.js.map +1 -0
  22. package/dist/cli/commands/agent/glob.d.ts +25 -0
  23. package/dist/cli/commands/agent/glob.js +82 -0
  24. package/dist/cli/commands/agent/glob.js.map +1 -0
  25. package/dist/cli/commands/agent/index.d.ts +11 -0
  26. package/dist/cli/commands/agent/index.js +284 -0
  27. package/dist/cli/commands/agent/index.js.map +1 -0
  28. package/dist/cli/commands/agent/install.d.ts +59 -0
  29. package/dist/cli/commands/agent/install.js +131 -0
  30. package/dist/cli/commands/agent/install.js.map +1 -0
  31. package/dist/cli/commands/agent/mapping.d.ts +175 -0
  32. package/dist/cli/commands/agent/mapping.js +256 -0
  33. package/dist/cli/commands/agent/mapping.js.map +1 -0
  34. package/dist/cli/commands/check.d.ts +2 -0
  35. package/dist/cli/commands/check.js +81 -0
  36. package/dist/cli/commands/check.js.map +1 -0
  37. package/dist/cli/commands/comment.d.ts +2 -0
  38. package/dist/cli/commands/comment.js +104 -0
  39. package/dist/cli/commands/comment.js.map +1 -0
  40. package/dist/cli/commands/convert.d.ts +2 -0
  41. package/dist/cli/commands/convert.js +115 -0
  42. package/dist/cli/commands/convert.js.map +1 -0
  43. package/dist/cli/commands/copy.d.ts +2 -0
  44. package/dist/cli/commands/copy.js +69 -0
  45. package/dist/cli/commands/copy.js.map +1 -0
  46. package/dist/cli/commands/export.d.ts +11 -0
  47. package/dist/cli/commands/export.js +226 -0
  48. package/dist/cli/commands/export.js.map +1 -0
  49. package/dist/cli/commands/flag.d.ts +2 -0
  50. package/dist/cli/commands/flag.js +172 -0
  51. package/dist/cli/commands/flag.js.map +1 -0
  52. package/dist/cli/commands/git.d.ts +11 -0
  53. package/dist/cli/commands/git.js +357 -0
  54. package/dist/cli/commands/git.js.map +1 -0
  55. package/dist/cli/commands/hcm/bundle.d.ts +60 -0
  56. package/dist/cli/commands/hcm/bundle.js +166 -0
  57. package/dist/cli/commands/hcm/bundle.js.map +1 -0
  58. package/dist/cli/commands/hcm/index.d.ts +11 -0
  59. package/dist/cli/commands/hcm/index.js +162 -0
  60. package/dist/cli/commands/hcm/index.js.map +1 -0
  61. package/dist/cli/commands/init.d.ts +2 -0
  62. package/dist/cli/commands/init.js +81 -0
  63. package/dist/cli/commands/init.js.map +1 -0
  64. package/dist/cli/commands/insert.d.ts +2 -0
  65. package/dist/cli/commands/insert.js +70 -0
  66. package/dist/cli/commands/insert.js.map +1 -0
  67. package/dist/cli/commands/instructions.d.ts +7 -0
  68. package/dist/cli/commands/instructions.js +256 -0
  69. package/dist/cli/commands/instructions.js.map +1 -0
  70. package/dist/cli/commands/link.d.ts +2 -0
  71. package/dist/cli/commands/link.js +121 -0
  72. package/dist/cli/commands/link.js.map +1 -0
  73. package/dist/cli/commands/mcp/config.d.ts +71 -0
  74. package/dist/cli/commands/mcp/config.js +119 -0
  75. package/dist/cli/commands/mcp/config.js.map +1 -0
  76. package/dist/cli/commands/mcp/index.d.ts +9 -0
  77. package/dist/cli/commands/mcp/index.js +92 -0
  78. package/dist/cli/commands/mcp/index.js.map +1 -0
  79. package/dist/cli/commands/mcp/serve.d.ts +1 -0
  80. package/dist/cli/commands/mcp/serve.js +76 -0
  81. package/dist/cli/commands/mcp/serve.js.map +1 -0
  82. package/dist/cli/commands/mcp/setup.d.ts +1 -0
  83. package/dist/cli/commands/mcp/setup.js +83 -0
  84. package/dist/cli/commands/mcp/setup.js.map +1 -0
  85. package/dist/cli/commands/me.d.ts +2 -0
  86. package/dist/cli/commands/me.js +85 -0
  87. package/dist/cli/commands/me.js.map +1 -0
  88. package/dist/cli/commands/move.d.ts +2 -0
  89. package/dist/cli/commands/move.js +81 -0
  90. package/dist/cli/commands/move.js.map +1 -0
  91. package/dist/cli/commands/new.d.ts +2 -0
  92. package/dist/cli/commands/new.js +222 -0
  93. package/dist/cli/commands/new.js.map +1 -0
  94. package/dist/cli/commands/open.d.ts +2 -0
  95. package/dist/cli/commands/open.js +43 -0
  96. package/dist/cli/commands/open.js.map +1 -0
  97. package/dist/cli/commands/period.d.ts +10 -0
  98. package/dist/cli/commands/period.js +165 -0
  99. package/dist/cli/commands/period.js.map +1 -0
  100. package/dist/cli/commands/profile.d.ts +2 -0
  101. package/dist/cli/commands/profile.js +133 -0
  102. package/dist/cli/commands/profile.js.map +1 -0
  103. package/dist/cli/commands/queue.d.ts +2 -0
  104. package/dist/cli/commands/queue.js +582 -0
  105. package/dist/cli/commands/queue.js.map +1 -0
  106. package/dist/cli/commands/remote.d.ts +10 -0
  107. package/dist/cli/commands/remote.js +3142 -0
  108. package/dist/cli/commands/remote.js.map +1 -0
  109. package/dist/cli/commands/rm.d.ts +2 -0
  110. package/dist/cli/commands/rm.js +63 -0
  111. package/dist/cli/commands/rm.js.map +1 -0
  112. package/dist/cli/commands/set.d.ts +2 -0
  113. package/dist/cli/commands/set.js +139 -0
  114. package/dist/cli/commands/set.js.map +1 -0
  115. package/dist/cli/commands/split.d.ts +2 -0
  116. package/dist/cli/commands/split.js +90 -0
  117. package/dist/cli/commands/split.js.map +1 -0
  118. package/dist/cli/commands/task.d.ts +2 -0
  119. package/dist/cli/commands/task.js +298 -0
  120. package/dist/cli/commands/task.js.map +1 -0
  121. package/dist/cli/commands/team.d.ts +2 -0
  122. package/dist/cli/commands/team.js +114 -0
  123. package/dist/cli/commands/team.js.map +1 -0
  124. package/dist/cli/commands/template.d.ts +2 -0
  125. package/dist/cli/commands/template.js +338 -0
  126. package/dist/cli/commands/template.js.map +1 -0
  127. package/dist/cli/commands/ui.d.ts +2 -0
  128. package/dist/cli/commands/ui.js +98 -0
  129. package/dist/cli/commands/ui.js.map +1 -0
  130. package/dist/cli/commands/upstream.d.ts +2 -0
  131. package/dist/cli/commands/upstream.js +218 -0
  132. package/dist/cli/commands/upstream.js.map +1 -0
  133. package/dist/cli/context.d.ts +24 -0
  134. package/dist/cli/context.js +52 -0
  135. package/dist/cli/context.js.map +1 -0
  136. package/dist/cli/index.d.ts +2 -0
  137. package/dist/cli/index.js +208 -0
  138. package/dist/cli/index.js.map +1 -0
  139. package/dist/cli/live.d.ts +71 -0
  140. package/dist/cli/live.js +182 -0
  141. package/dist/cli/live.js.map +1 -0
  142. package/dist/cli/plan.d.ts +28 -0
  143. package/dist/cli/plan.js +76 -0
  144. package/dist/cli/plan.js.map +1 -0
  145. package/dist/cli/prompt.d.ts +60 -0
  146. package/dist/cli/prompt.js +185 -0
  147. package/dist/cli/prompt.js.map +1 -0
  148. package/dist/cli/ui.d.ts +65 -0
  149. package/dist/cli/ui.js +79 -0
  150. package/dist/cli/ui.js.map +1 -0
  151. package/dist/core/board/dependency-rollup.d.ts +54 -0
  152. package/dist/core/board/dependency-rollup.js +72 -0
  153. package/dist/core/board/dependency-rollup.js.map +1 -0
  154. package/dist/core/board/flag-rollup.d.ts +33 -0
  155. package/dist/core/board/flag-rollup.js +56 -0
  156. package/dist/core/board/flag-rollup.js.map +1 -0
  157. package/dist/core/board/index.d.ts +21 -0
  158. package/dist/core/board/index.js +22 -0
  159. package/dist/core/board/index.js.map +1 -0
  160. package/dist/core/board/load/cache.d.ts +52 -0
  161. package/dist/core/board/load/cache.js +105 -0
  162. package/dist/core/board/load/cache.js.map +1 -0
  163. package/dist/core/board/load/fields.d.ts +33 -0
  164. package/dist/core/board/load/fields.js +154 -0
  165. package/dist/core/board/load/fields.js.map +1 -0
  166. package/dist/core/board/load/scan.d.ts +39 -0
  167. package/dist/core/board/load/scan.js +88 -0
  168. package/dist/core/board/load/scan.js.map +1 -0
  169. package/dist/core/board/load/tree.d.ts +10 -0
  170. package/dist/core/board/load/tree.js +114 -0
  171. package/dist/core/board/load/tree.js.map +1 -0
  172. package/dist/core/board/load.d.ts +69 -0
  173. package/dist/core/board/load.js +204 -0
  174. package/dist/core/board/load.js.map +1 -0
  175. package/dist/core/board/query.d.ts +126 -0
  176. package/dist/core/board/query.js +291 -0
  177. package/dist/core/board/query.js.map +1 -0
  178. package/dist/core/board/registry.d.ts +51 -0
  179. package/dist/core/board/registry.js +98 -0
  180. package/dist/core/board/registry.js.map +1 -0
  181. package/dist/core/board/remote-scopes.d.ts +71 -0
  182. package/dist/core/board/remote-scopes.js +103 -0
  183. package/dist/core/board/remote-scopes.js.map +1 -0
  184. package/dist/core/board/rollup.d.ts +32 -0
  185. package/dist/core/board/rollup.js +67 -0
  186. package/dist/core/board/rollup.js.map +1 -0
  187. package/dist/core/board/scope.d.ts +81 -0
  188. package/dist/core/board/scope.js +134 -0
  189. package/dist/core/board/scope.js.map +1 -0
  190. package/dist/core/board/simulate.d.ts +138 -0
  191. package/dist/core/board/simulate.js +141 -0
  192. package/dist/core/board/simulate.js.map +1 -0
  193. package/dist/core/board/tasks/index.d.ts +25 -0
  194. package/dist/core/board/tasks/index.js +26 -0
  195. package/dist/core/board/tasks/index.js.map +1 -0
  196. package/dist/core/board/tasks/ranking.d.ts +155 -0
  197. package/dist/core/board/tasks/ranking.js +374 -0
  198. package/dist/core/board/tasks/ranking.js.map +1 -0
  199. package/dist/core/board/tasks/roster.d.ts +42 -0
  200. package/dist/core/board/tasks/roster.js +82 -0
  201. package/dist/core/board/tasks/roster.js.map +1 -0
  202. package/dist/core/board/tasks.d.ts +1 -0
  203. package/dist/core/board/tasks.js +2 -0
  204. package/dist/core/board/tasks.js.map +1 -0
  205. package/dist/core/config/index.d.ts +9 -0
  206. package/dist/core/config/index.js +10 -0
  207. package/dist/core/config/index.js.map +1 -0
  208. package/dist/core/config/lookup.d.ts +114 -0
  209. package/dist/core/config/lookup.js +221 -0
  210. package/dist/core/config/lookup.js.map +1 -0
  211. package/dist/core/config/remote-blocks.d.ts +17 -0
  212. package/dist/core/config/remote-blocks.js +47 -0
  213. package/dist/core/config/remote-blocks.js.map +1 -0
  214. package/dist/core/config/schema.d.ts +10 -0
  215. package/dist/core/config/schema.js +451 -0
  216. package/dist/core/config/schema.js.map +1 -0
  217. package/dist/core/errors.d.ts +23 -0
  218. package/dist/core/errors.js +31 -0
  219. package/dist/core/errors.js.map +1 -0
  220. package/dist/core/gitsync/hosts.d.ts +40 -0
  221. package/dist/core/gitsync/hosts.js +115 -0
  222. package/dist/core/gitsync/hosts.js.map +1 -0
  223. package/dist/core/gitsync/index.d.ts +25 -0
  224. package/dist/core/gitsync/index.js +25 -0
  225. package/dist/core/gitsync/index.js.map +1 -0
  226. package/dist/core/gitsync/integrate.d.ts +72 -0
  227. package/dist/core/gitsync/integrate.js +115 -0
  228. package/dist/core/gitsync/integrate.js.map +1 -0
  229. package/dist/core/gitsync/repo.d.ts +61 -0
  230. package/dist/core/gitsync/repo.js +213 -0
  231. package/dist/core/gitsync/repo.js.map +1 -0
  232. package/dist/core/gitsync/run.d.ts +58 -0
  233. package/dist/core/gitsync/run.js +102 -0
  234. package/dist/core/gitsync/run.js.map +1 -0
  235. package/dist/core/gitsync/status.d.ts +59 -0
  236. package/dist/core/gitsync/status.js +81 -0
  237. package/dist/core/gitsync/status.js.map +1 -0
  238. package/dist/core/gitsync/sync.d.ts +111 -0
  239. package/dist/core/gitsync/sync.js +275 -0
  240. package/dist/core/gitsync/sync.js.map +1 -0
  241. package/dist/core/index.d.ts +31 -0
  242. package/dist/core/index.js +32 -0
  243. package/dist/core/index.js.map +1 -0
  244. package/dist/core/instructions/analyze.d.ts +70 -0
  245. package/dist/core/instructions/analyze.js +275 -0
  246. package/dist/core/instructions/analyze.js.map +1 -0
  247. package/dist/core/instructions/builtin.d.ts +21 -0
  248. package/dist/core/instructions/builtin.js +133 -0
  249. package/dist/core/instructions/builtin.js.map +1 -0
  250. package/dist/core/instructions/context.d.ts +155 -0
  251. package/dist/core/instructions/context.js +209 -0
  252. package/dist/core/instructions/context.js.map +1 -0
  253. package/dist/core/instructions/index.d.ts +29 -0
  254. package/dist/core/instructions/index.js +30 -0
  255. package/dist/core/instructions/index.js.map +1 -0
  256. package/dist/core/instructions/instructions.d.ts +90 -0
  257. package/dist/core/instructions/instructions.js +179 -0
  258. package/dist/core/instructions/instructions.js.map +1 -0
  259. package/dist/core/instructions/template.d.ts +108 -0
  260. package/dist/core/instructions/template.js +252 -0
  261. package/dist/core/instructions/template.js.map +1 -0
  262. package/dist/core/model/attributes.d.ts +16 -0
  263. package/dist/core/model/attributes.js +119 -0
  264. package/dist/core/model/attributes.js.map +1 -0
  265. package/dist/core/model/index.d.ts +10 -0
  266. package/dist/core/model/index.js +11 -0
  267. package/dist/core/model/index.js.map +1 -0
  268. package/dist/core/model/links.d.ts +34 -0
  269. package/dist/core/model/links.js +114 -0
  270. package/dist/core/model/links.js.map +1 -0
  271. package/dist/core/model/profile.d.ts +31 -0
  272. package/dist/core/model/profile.js +8 -0
  273. package/dist/core/model/profile.js.map +1 -0
  274. package/dist/core/model/types.d.ts +441 -0
  275. package/dist/core/model/types.js +167 -0
  276. package/dist/core/model/types.js.map +1 -0
  277. package/dist/core/model/zod.d.ts +6 -0
  278. package/dist/core/model/zod.js +11 -0
  279. package/dist/core/model/zod.js.map +1 -0
  280. package/dist/core/operations/board-index.d.ts +45 -0
  281. package/dist/core/operations/board-index.js +147 -0
  282. package/dist/core/operations/board-index.js.map +1 -0
  283. package/dist/core/operations/claim.d.ts +69 -0
  284. package/dist/core/operations/claim.js +115 -0
  285. package/dist/core/operations/claim.js.map +1 -0
  286. package/dist/core/operations/comment.d.ts +30 -0
  287. package/dist/core/operations/comment.js +46 -0
  288. package/dist/core/operations/comment.js.map +1 -0
  289. package/dist/core/operations/create.d.ts +82 -0
  290. package/dist/core/operations/create.js +306 -0
  291. package/dist/core/operations/create.js.map +1 -0
  292. package/dist/core/operations/flag.d.ts +58 -0
  293. package/dist/core/operations/flag.js +95 -0
  294. package/dist/core/operations/flag.js.map +1 -0
  295. package/dist/core/operations/git-sync.d.ts +148 -0
  296. package/dist/core/operations/git-sync.js +341 -0
  297. package/dist/core/operations/git-sync.js.map +1 -0
  298. package/dist/core/operations/index.d.ts +44 -0
  299. package/dist/core/operations/index.js +45 -0
  300. package/dist/core/operations/index.js.map +1 -0
  301. package/dist/core/operations/init.d.ts +25 -0
  302. package/dist/core/operations/init.js +122 -0
  303. package/dist/core/operations/init.js.map +1 -0
  304. package/dist/core/operations/link.d.ts +40 -0
  305. package/dist/core/operations/link.js +131 -0
  306. package/dist/core/operations/link.js.map +1 -0
  307. package/dist/core/operations/move.d.ts +43 -0
  308. package/dist/core/operations/move.js +103 -0
  309. package/dist/core/operations/move.js.map +1 -0
  310. package/dist/core/operations/profile.d.ts +23 -0
  311. package/dist/core/operations/profile.js +26 -0
  312. package/dist/core/operations/profile.js.map +1 -0
  313. package/dist/core/operations/remotes-off.d.ts +12 -0
  314. package/dist/core/operations/remotes-off.js +67 -0
  315. package/dist/core/operations/remotes-off.js.map +1 -0
  316. package/dist/core/operations/remove.d.ts +18 -0
  317. package/dist/core/operations/remove.js +114 -0
  318. package/dist/core/operations/remove.js.map +1 -0
  319. package/dist/core/operations/retype.d.ts +25 -0
  320. package/dist/core/operations/retype.js +59 -0
  321. package/dist/core/operations/retype.js.map +1 -0
  322. package/dist/core/operations/rollup.d.ts +74 -0
  323. package/dist/core/operations/rollup.js +121 -0
  324. package/dist/core/operations/rollup.js.map +1 -0
  325. package/dist/core/operations/shared.d.ts +133 -0
  326. package/dist/core/operations/shared.js +383 -0
  327. package/dist/core/operations/shared.js.map +1 -0
  328. package/dist/core/operations/update.d.ts +43 -0
  329. package/dist/core/operations/update.js +161 -0
  330. package/dist/core/operations/update.js.map +1 -0
  331. package/dist/core/operations/user.d.ts +27 -0
  332. package/dist/core/operations/user.js +68 -0
  333. package/dist/core/operations/user.js.map +1 -0
  334. package/dist/core/profile/current.d.ts +35 -0
  335. package/dist/core/profile/current.js +31 -0
  336. package/dist/core/profile/current.js.map +1 -0
  337. package/dist/core/profile/index.d.ts +14 -0
  338. package/dist/core/profile/index.js +15 -0
  339. package/dist/core/profile/index.js.map +1 -0
  340. package/dist/core/profile/schema.d.ts +9 -0
  341. package/dist/core/profile/schema.js +100 -0
  342. package/dist/core/profile/schema.js.map +1 -0
  343. package/dist/core/storage/activity.d.ts +78 -0
  344. package/dist/core/storage/activity.js +131 -0
  345. package/dist/core/storage/activity.js.map +1 -0
  346. package/dist/core/storage/atomic.d.ts +34 -0
  347. package/dist/core/storage/atomic.js +117 -0
  348. package/dist/core/storage/atomic.js.map +1 -0
  349. package/dist/core/storage/comments.d.ts +39 -0
  350. package/dist/core/storage/comments.js +88 -0
  351. package/dist/core/storage/comments.js.map +1 -0
  352. package/dist/core/storage/document.d.ts +16 -0
  353. package/dist/core/storage/document.js +98 -0
  354. package/dist/core/storage/document.js.map +1 -0
  355. package/dist/core/storage/frontmatter.d.ts +16 -0
  356. package/dist/core/storage/frontmatter.js +33 -0
  357. package/dist/core/storage/frontmatter.js.map +1 -0
  358. package/dist/core/storage/git.d.ts +8 -0
  359. package/dist/core/storage/git.js +48 -0
  360. package/dist/core/storage/git.js.map +1 -0
  361. package/dist/core/storage/index.d.ts +27 -0
  362. package/dist/core/storage/index.js +28 -0
  363. package/dist/core/storage/index.js.map +1 -0
  364. package/dist/core/storage/local.d.ts +57 -0
  365. package/dist/core/storage/local.js +133 -0
  366. package/dist/core/storage/local.js.map +1 -0
  367. package/dist/core/storage/lock.d.ts +85 -0
  368. package/dist/core/storage/lock.js +364 -0
  369. package/dist/core/storage/lock.js.map +1 -0
  370. package/dist/core/storage/paths.d.ts +125 -0
  371. package/dist/core/storage/paths.js +202 -0
  372. package/dist/core/storage/paths.js.map +1 -0
  373. package/dist/core/storage/state.d.ts +32 -0
  374. package/dist/core/storage/state.js +71 -0
  375. package/dist/core/storage/state.js.map +1 -0
  376. package/dist/core/storage/templates.d.ts +29 -0
  377. package/dist/core/storage/templates.js +62 -0
  378. package/dist/core/storage/templates.js.map +1 -0
  379. package/dist/core/storage/views.d.ts +18 -0
  380. package/dist/core/storage/views.js +62 -0
  381. package/dist/core/storage/views.js.map +1 -0
  382. package/dist/core/validation/check.d.ts +4 -0
  383. package/dist/core/validation/check.js +22 -0
  384. package/dist/core/validation/check.js.map +1 -0
  385. package/dist/core/validation/checks/collection.d.ts +4 -0
  386. package/dist/core/validation/checks/collection.js +152 -0
  387. package/dist/core/validation/checks/collection.js.map +1 -0
  388. package/dist/core/validation/checks/counters.d.ts +3 -0
  389. package/dist/core/validation/checks/counters.js +23 -0
  390. package/dist/core/validation/checks/counters.js.map +1 -0
  391. package/dist/core/validation/checks/dependencies.d.ts +3 -0
  392. package/dist/core/validation/checks/dependencies.js +58 -0
  393. package/dist/core/validation/checks/dependencies.js.map +1 -0
  394. package/dist/core/validation/checks/gitignore.d.ts +10 -0
  395. package/dist/core/validation/checks/gitignore.js +22 -0
  396. package/dist/core/validation/checks/gitignore.js.map +1 -0
  397. package/dist/core/validation/checks/index-file.d.ts +8 -0
  398. package/dist/core/validation/checks/index-file.js +26 -0
  399. package/dist/core/validation/checks/index-file.js.map +1 -0
  400. package/dist/core/validation/checks/index.d.ts +20 -0
  401. package/dist/core/validation/checks/index.js +21 -0
  402. package/dist/core/validation/checks/index.js.map +1 -0
  403. package/dist/core/validation/checks/issues.d.ts +3 -0
  404. package/dist/core/validation/checks/issues.js +152 -0
  405. package/dist/core/validation/checks/issues.js.map +1 -0
  406. package/dist/core/validation/checks/periods.d.ts +3 -0
  407. package/dist/core/validation/checks/periods.js +89 -0
  408. package/dist/core/validation/checks/periods.js.map +1 -0
  409. package/dist/core/validation/checks/remotes.d.ts +20 -0
  410. package/dist/core/validation/checks/remotes.js +42 -0
  411. package/dist/core/validation/checks/remotes.js.map +1 -0
  412. package/dist/core/validation/checks/resources.d.ts +3 -0
  413. package/dist/core/validation/checks/resources.js +77 -0
  414. package/dist/core/validation/checks/resources.js.map +1 -0
  415. package/dist/core/validation/checks/rollup.d.ts +27 -0
  416. package/dist/core/validation/checks/rollup.js +53 -0
  417. package/dist/core/validation/checks/rollup.js.map +1 -0
  418. package/dist/core/validation/checks/squads.d.ts +3 -0
  419. package/dist/core/validation/checks/squads.js +42 -0
  420. package/dist/core/validation/checks/squads.js.map +1 -0
  421. package/dist/core/validation/checks/templates.d.ts +14 -0
  422. package/dist/core/validation/checks/templates.js +119 -0
  423. package/dist/core/validation/checks/templates.js.map +1 -0
  424. package/dist/core/validation/fix.d.ts +7 -0
  425. package/dist/core/validation/fix.js +273 -0
  426. package/dist/core/validation/fix.js.map +1 -0
  427. package/dist/core/validation/index.d.ts +7 -0
  428. package/dist/core/validation/index.js +8 -0
  429. package/dist/core/validation/index.js.map +1 -0
  430. package/dist/core/validation/shared.d.ts +47 -0
  431. package/dist/core/validation/shared.js +66 -0
  432. package/dist/core/validation/shared.js.map +1 -0
  433. package/dist/mcp/context.d.ts +70 -0
  434. package/dist/mcp/context.js +110 -0
  435. package/dist/mcp/context.js.map +1 -0
  436. package/dist/mcp/index.d.ts +49 -0
  437. package/dist/mcp/index.js +90 -0
  438. package/dist/mcp/index.js.map +1 -0
  439. package/dist/mcp/reply.d.ts +28 -0
  440. package/dist/mcp/reply.js +34 -0
  441. package/dist/mcp/reply.js.map +1 -0
  442. package/dist/mcp/tools/plan/create.d.ts +3 -0
  443. package/dist/mcp/tools/plan/create.js +128 -0
  444. package/dist/mcp/tools/plan/create.js.map +1 -0
  445. package/dist/mcp/tools/plan/delete.d.ts +3 -0
  446. package/dist/mcp/tools/plan/delete.js +35 -0
  447. package/dist/mcp/tools/plan/delete.js.map +1 -0
  448. package/dist/mcp/tools/plan/graph.d.ts +3 -0
  449. package/dist/mcp/tools/plan/graph.js +53 -0
  450. package/dist/mcp/tools/plan/graph.js.map +1 -0
  451. package/dist/mcp/tools/plan/index.d.ts +15 -0
  452. package/dist/mcp/tools/plan/index.js +16 -0
  453. package/dist/mcp/tools/plan/index.js.map +1 -0
  454. package/dist/mcp/tools/plan/link.d.ts +3 -0
  455. package/dist/mcp/tools/plan/link.js +46 -0
  456. package/dist/mcp/tools/plan/link.js.map +1 -0
  457. package/dist/mcp/tools/plan/registrar.d.ts +10 -0
  458. package/dist/mcp/tools/plan/registrar.js +24 -0
  459. package/dist/mcp/tools/plan/registrar.js.map +1 -0
  460. package/dist/mcp/tools/plan/reshape.d.ts +3 -0
  461. package/dist/mcp/tools/plan/reshape.js +95 -0
  462. package/dist/mcp/tools/plan/reshape.js.map +1 -0
  463. package/dist/mcp/tools/plan/timeline.d.ts +3 -0
  464. package/dist/mcp/tools/plan/timeline.js +68 -0
  465. package/dist/mcp/tools/plan/timeline.js.map +1 -0
  466. package/dist/mcp/tools/plan/upstream.d.ts +14 -0
  467. package/dist/mcp/tools/plan/upstream.js +69 -0
  468. package/dist/mcp/tools/plan/upstream.js.map +1 -0
  469. package/dist/mcp/tools/plan.d.ts +1 -0
  470. package/dist/mcp/tools/plan.js +2 -0
  471. package/dist/mcp/tools/plan.js.map +1 -0
  472. package/dist/mcp/tools/read.d.ts +3 -0
  473. package/dist/mcp/tools/read.js +339 -0
  474. package/dist/mcp/tools/read.js.map +1 -0
  475. package/dist/mcp/tools/remote.d.ts +3 -0
  476. package/dist/mcp/tools/remote.js +254 -0
  477. package/dist/mcp/tools/remote.js.map +1 -0
  478. package/dist/mcp/tools/templates.d.ts +12 -0
  479. package/dist/mcp/tools/templates.js +165 -0
  480. package/dist/mcp/tools/templates.js.map +1 -0
  481. package/dist/mcp/tools/work.d.ts +16 -0
  482. package/dist/mcp/tools/work.js +359 -0
  483. package/dist/mcp/tools/work.js.map +1 -0
  484. package/dist/remote/accounts.d.ts +158 -0
  485. package/dist/remote/accounts.js +207 -0
  486. package/dist/remote/accounts.js.map +1 -0
  487. package/dist/remote/adopt.d.ts +139 -0
  488. package/dist/remote/adopt.js +181 -0
  489. package/dist/remote/adopt.js.map +1 -0
  490. package/dist/remote/anchor.d.ts +35 -0
  491. package/dist/remote/anchor.js +53 -0
  492. package/dist/remote/anchor.js.map +1 -0
  493. package/dist/remote/attributes.d.ts +103 -0
  494. package/dist/remote/attributes.js +245 -0
  495. package/dist/remote/attributes.js.map +1 -0
  496. package/dist/remote/audit.d.ts +112 -0
  497. package/dist/remote/audit.js +215 -0
  498. package/dist/remote/audit.js.map +1 -0
  499. package/dist/remote/capabilities.d.ts +267 -0
  500. package/dist/remote/capabilities.js +225 -0
  501. package/dist/remote/capabilities.js.map +1 -0
  502. package/dist/remote/check.d.ts +49 -0
  503. package/dist/remote/check.js +356 -0
  504. package/dist/remote/check.js.map +1 -0
  505. package/dist/remote/comments.d.ts +86 -0
  506. package/dist/remote/comments.js +87 -0
  507. package/dist/remote/comments.js.map +1 -0
  508. package/dist/remote/config-file.d.ts +237 -0
  509. package/dist/remote/config-file.js +640 -0
  510. package/dist/remote/config-file.js.map +1 -0
  511. package/dist/remote/conflicts.d.ts +110 -0
  512. package/dist/remote/conflicts.js +188 -0
  513. package/dist/remote/conflicts.js.map +1 -0
  514. package/dist/remote/connection-catalogue.d.ts +65 -0
  515. package/dist/remote/connection-catalogue.js +66 -0
  516. package/dist/remote/connection-catalogue.js.map +1 -0
  517. package/dist/remote/connection.d.ts +84 -0
  518. package/dist/remote/connection.js +229 -0
  519. package/dist/remote/connection.js.map +1 -0
  520. package/dist/remote/coverage.d.ts +65 -0
  521. package/dist/remote/coverage.js +244 -0
  522. package/dist/remote/coverage.js.map +1 -0
  523. package/dist/remote/credentials.d.ts +95 -0
  524. package/dist/remote/credentials.js +210 -0
  525. package/dist/remote/credentials.js.map +1 -0
  526. package/dist/remote/execute.d.ts +178 -0
  527. package/dist/remote/execute.js +1245 -0
  528. package/dist/remote/execute.js.map +1 -0
  529. package/dist/remote/fingerprint.d.ts +172 -0
  530. package/dist/remote/fingerprint.js +337 -0
  531. package/dist/remote/fingerprint.js.map +1 -0
  532. package/dist/remote/fixtures.d.ts +176 -0
  533. package/dist/remote/fixtures.js +432 -0
  534. package/dist/remote/fixtures.js.map +1 -0
  535. package/dist/remote/guard.d.ts +90 -0
  536. package/dist/remote/guard.js +83 -0
  537. package/dist/remote/guard.js.map +1 -0
  538. package/dist/remote/hierarchy.d.ts +141 -0
  539. package/dist/remote/hierarchy.js +129 -0
  540. package/dist/remote/hierarchy.js.map +1 -0
  541. package/dist/remote/index.d.ts +145 -0
  542. package/dist/remote/index.js +146 -0
  543. package/dist/remote/index.js.map +1 -0
  544. package/dist/remote/inspect.d.ts +103 -0
  545. package/dist/remote/inspect.js +152 -0
  546. package/dist/remote/inspect.js.map +1 -0
  547. package/dist/remote/labels.d.ts +75 -0
  548. package/dist/remote/labels.js +137 -0
  549. package/dist/remote/labels.js.map +1 -0
  550. package/dist/remote/ladder.d.ts +145 -0
  551. package/dist/remote/ladder.js +387 -0
  552. package/dist/remote/ladder.js.map +1 -0
  553. package/dist/remote/ledger.d.ts +97 -0
  554. package/dist/remote/ledger.js +148 -0
  555. package/dist/remote/ledger.js.map +1 -0
  556. package/dist/remote/lifecycle.d.ts +175 -0
  557. package/dist/remote/lifecycle.js +274 -0
  558. package/dist/remote/lifecycle.js.map +1 -0
  559. package/dist/remote/links.d.ts +411 -0
  560. package/dist/remote/links.js +748 -0
  561. package/dist/remote/links.js.map +1 -0
  562. package/dist/remote/managed-block.d.ts +182 -0
  563. package/dist/remote/managed-block.js +406 -0
  564. package/dist/remote/managed-block.js.map +1 -0
  565. package/dist/remote/managed-comment.d.ts +104 -0
  566. package/dist/remote/managed-comment.js +92 -0
  567. package/dist/remote/managed-comment.js.map +1 -0
  568. package/dist/remote/mapping.d.ts +282 -0
  569. package/dist/remote/mapping.js +336 -0
  570. package/dist/remote/mapping.js.map +1 -0
  571. package/dist/remote/merge.d.ts +172 -0
  572. package/dist/remote/merge.js +221 -0
  573. package/dist/remote/merge.js.map +1 -0
  574. package/dist/remote/periods.d.ts +209 -0
  575. package/dist/remote/periods.js +224 -0
  576. package/dist/remote/periods.js.map +1 -0
  577. package/dist/remote/plan.d.ts +671 -0
  578. package/dist/remote/plan.js +1210 -0
  579. package/dist/remote/plan.js.map +1 -0
  580. package/dist/remote/policy.d.ts +67 -0
  581. package/dist/remote/policy.js +67 -0
  582. package/dist/remote/policy.js.map +1 -0
  583. package/dist/remote/preflight.d.ts +112 -0
  584. package/dist/remote/preflight.js +342 -0
  585. package/dist/remote/preflight.js.map +1 -0
  586. package/dist/remote/prerequisites.d.ts +113 -0
  587. package/dist/remote/prerequisites.js +161 -0
  588. package/dist/remote/prerequisites.js.map +1 -0
  589. package/dist/remote/provider.d.ts +802 -0
  590. package/dist/remote/provider.js +27 -0
  591. package/dist/remote/provider.js.map +1 -0
  592. package/dist/remote/providers/github/config.d.ts +84 -0
  593. package/dist/remote/providers/github/config.js +161 -0
  594. package/dist/remote/providers/github/config.js.map +1 -0
  595. package/dist/remote/providers/github/connector.d.ts +33 -0
  596. package/dist/remote/providers/github/connector.js +774 -0
  597. package/dist/remote/providers/github/connector.js.map +1 -0
  598. package/dist/remote/providers/github/edges.d.ts +29 -0
  599. package/dist/remote/providers/github/edges.js +56 -0
  600. package/dist/remote/providers/github/edges.js.map +1 -0
  601. package/dist/remote/providers/github/hierarchy.d.ts +21 -0
  602. package/dist/remote/providers/github/hierarchy.js +46 -0
  603. package/dist/remote/providers/github/hierarchy.js.map +1 -0
  604. package/dist/remote/providers/github/index.d.ts +26 -0
  605. package/dist/remote/providers/github/index.js +69 -0
  606. package/dist/remote/providers/github/index.js.map +1 -0
  607. package/dist/remote/providers/github/project-iteration.d.ts +71 -0
  608. package/dist/remote/providers/github/project-iteration.js +203 -0
  609. package/dist/remote/providers/github/project-iteration.js.map +1 -0
  610. package/dist/remote/providers/github/project-provision.d.ts +130 -0
  611. package/dist/remote/providers/github/project-provision.js +247 -0
  612. package/dist/remote/providers/github/project-provision.js.map +1 -0
  613. package/dist/remote/providers/github/project-status.d.ts +115 -0
  614. package/dist/remote/providers/github/project-status.js +317 -0
  615. package/dist/remote/providers/github/project-status.js.map +1 -0
  616. package/dist/remote/providers/github/projects.d.ts +181 -0
  617. package/dist/remote/providers/github/projects.js +481 -0
  618. package/dist/remote/providers/github/projects.js.map +1 -0
  619. package/dist/remote/providers/github/translator.d.ts +103 -0
  620. package/dist/remote/providers/github/translator.js +400 -0
  621. package/dist/remote/providers/github/translator.js.map +1 -0
  622. package/dist/remote/providers/jira/config.d.ts +96 -0
  623. package/dist/remote/providers/jira/config.js +200 -0
  624. package/dist/remote/providers/jira/config.js.map +1 -0
  625. package/dist/remote/providers/jira/connector.d.ts +42 -0
  626. package/dist/remote/providers/jira/connector.js +1688 -0
  627. package/dist/remote/providers/jira/connector.js.map +1 -0
  628. package/dist/remote/providers/jira/fields.d.ts +292 -0
  629. package/dist/remote/providers/jira/fields.js +463 -0
  630. package/dist/remote/providers/jira/fields.js.map +1 -0
  631. package/dist/remote/providers/jira/hierarchy.d.ts +28 -0
  632. package/dist/remote/providers/jira/hierarchy.js +60 -0
  633. package/dist/remote/providers/jira/hierarchy.js.map +1 -0
  634. package/dist/remote/providers/jira/index.d.ts +29 -0
  635. package/dist/remote/providers/jira/index.js +100 -0
  636. package/dist/remote/providers/jira/index.js.map +1 -0
  637. package/dist/remote/providers/jira/links.d.ts +41 -0
  638. package/dist/remote/providers/jira/links.js +102 -0
  639. package/dist/remote/providers/jira/links.js.map +1 -0
  640. package/dist/remote/providers/jira/sprints.d.ts +80 -0
  641. package/dist/remote/providers/jira/sprints.js +107 -0
  642. package/dist/remote/providers/jira/sprints.js.map +1 -0
  643. package/dist/remote/providers/jira/translator.d.ts +61 -0
  644. package/dist/remote/providers/jira/translator.js +382 -0
  645. package/dist/remote/providers/jira/translator.js.map +1 -0
  646. package/dist/remote/providers/jira/types.d.ts +112 -0
  647. package/dist/remote/providers/jira/types.js +160 -0
  648. package/dist/remote/providers/jira/types.js.map +1 -0
  649. package/dist/remote/providers/jira/vocabulary.d.ts +55 -0
  650. package/dist/remote/providers/jira/vocabulary.js +91 -0
  651. package/dist/remote/providers/jira/vocabulary.js.map +1 -0
  652. package/dist/remote/providers/jsonfile/config.d.ts +61 -0
  653. package/dist/remote/providers/jsonfile/config.js +83 -0
  654. package/dist/remote/providers/jsonfile/config.js.map +1 -0
  655. package/dist/remote/providers/jsonfile/connector.d.ts +34 -0
  656. package/dist/remote/providers/jsonfile/connector.js +251 -0
  657. package/dist/remote/providers/jsonfile/connector.js.map +1 -0
  658. package/dist/remote/providers/jsonfile/index.d.ts +38 -0
  659. package/dist/remote/providers/jsonfile/index.js +90 -0
  660. package/dist/remote/providers/jsonfile/index.js.map +1 -0
  661. package/dist/remote/providers/jsonfile/store.d.ts +59 -0
  662. package/dist/remote/providers/jsonfile/store.js +48 -0
  663. package/dist/remote/providers/jsonfile/store.js.map +1 -0
  664. package/dist/remote/providers/jsonfile/translator.d.ts +54 -0
  665. package/dist/remote/providers/jsonfile/translator.js +199 -0
  666. package/dist/remote/providers/jsonfile/translator.js.map +1 -0
  667. package/dist/remote/providers/linear/config.d.ts +83 -0
  668. package/dist/remote/providers/linear/config.js +140 -0
  669. package/dist/remote/providers/linear/config.js.map +1 -0
  670. package/dist/remote/providers/linear/connector.d.ts +36 -0
  671. package/dist/remote/providers/linear/connector.js +438 -0
  672. package/dist/remote/providers/linear/connector.js.map +1 -0
  673. package/dist/remote/providers/linear/estimate.d.ts +63 -0
  674. package/dist/remote/providers/linear/estimate.js +112 -0
  675. package/dist/remote/providers/linear/estimate.js.map +1 -0
  676. package/dist/remote/providers/linear/index.d.ts +31 -0
  677. package/dist/remote/providers/linear/index.js +75 -0
  678. package/dist/remote/providers/linear/index.js.map +1 -0
  679. package/dist/remote/providers/linear/labels.d.ts +51 -0
  680. package/dist/remote/providers/linear/labels.js +129 -0
  681. package/dist/remote/providers/linear/labels.js.map +1 -0
  682. package/dist/remote/providers/linear/states.d.ts +97 -0
  683. package/dist/remote/providers/linear/states.js +124 -0
  684. package/dist/remote/providers/linear/states.js.map +1 -0
  685. package/dist/remote/providers/linear/translator.d.ts +48 -0
  686. package/dist/remote/providers/linear/translator.js +343 -0
  687. package/dist/remote/providers/linear/translator.js.map +1 -0
  688. package/dist/remote/providers/linear/vocabulary.d.ts +27 -0
  689. package/dist/remote/providers/linear/vocabulary.js +42 -0
  690. package/dist/remote/providers/linear/vocabulary.js.map +1 -0
  691. package/dist/remote/provision.d.ts +45 -0
  692. package/dist/remote/provision.js +81 -0
  693. package/dist/remote/provision.js.map +1 -0
  694. package/dist/remote/pull.d.ts +52 -0
  695. package/dist/remote/pull.js +116 -0
  696. package/dist/remote/pull.js.map +1 -0
  697. package/dist/remote/readiness.d.ts +67 -0
  698. package/dist/remote/readiness.js +336 -0
  699. package/dist/remote/readiness.js.map +1 -0
  700. package/dist/remote/rebase.d.ts +157 -0
  701. package/dist/remote/rebase.js +255 -0
  702. package/dist/remote/rebase.js.map +1 -0
  703. package/dist/remote/reconcile.d.ts +115 -0
  704. package/dist/remote/reconcile.js +140 -0
  705. package/dist/remote/reconcile.js.map +1 -0
  706. package/dist/remote/redact.d.ts +70 -0
  707. package/dist/remote/redact.js +132 -0
  708. package/dist/remote/redact.js.map +1 -0
  709. package/dist/remote/registry.d.ts +32 -0
  710. package/dist/remote/registry.js +54 -0
  711. package/dist/remote/registry.js.map +1 -0
  712. package/dist/remote/remotes.d.ts +94 -0
  713. package/dist/remote/remotes.js +182 -0
  714. package/dist/remote/remotes.js.map +1 -0
  715. package/dist/remote/render.d.ts +147 -0
  716. package/dist/remote/render.js +683 -0
  717. package/dist/remote/render.js.map +1 -0
  718. package/dist/remote/report.d.ts +63 -0
  719. package/dist/remote/report.js +345 -0
  720. package/dist/remote/report.js.map +1 -0
  721. package/dist/remote/resolutions.d.ts +115 -0
  722. package/dist/remote/resolutions.js +217 -0
  723. package/dist/remote/resolutions.js.map +1 -0
  724. package/dist/remote/scaffold.d.ts +134 -0
  725. package/dist/remote/scaffold.js +370 -0
  726. package/dist/remote/scaffold.js.map +1 -0
  727. package/dist/remote/scope.d.ts +57 -0
  728. package/dist/remote/scope.js +91 -0
  729. package/dist/remote/scope.js.map +1 -0
  730. package/dist/remote/selection.d.ts +38 -0
  731. package/dist/remote/selection.js +50 -0
  732. package/dist/remote/selection.js.map +1 -0
  733. package/dist/remote/shape.d.ts +141 -0
  734. package/dist/remote/shape.js +220 -0
  735. package/dist/remote/shape.js.map +1 -0
  736. package/dist/remote/status.d.ts +104 -0
  737. package/dist/remote/status.js +238 -0
  738. package/dist/remote/status.js.map +1 -0
  739. package/dist/remote/sync.d.ts +182 -0
  740. package/dist/remote/sync.js +523 -0
  741. package/dist/remote/sync.js.map +1 -0
  742. package/dist/remote/transport/budget.d.ts +48 -0
  743. package/dist/remote/transport/budget.js +68 -0
  744. package/dist/remote/transport/budget.js.map +1 -0
  745. package/dist/remote/transport/connector.d.ts +115 -0
  746. package/dist/remote/transport/connector.js +21 -0
  747. package/dist/remote/transport/connector.js.map +1 -0
  748. package/dist/remote/transport/error.d.ts +88 -0
  749. package/dist/remote/transport/error.js +196 -0
  750. package/dist/remote/transport/error.js.map +1 -0
  751. package/dist/remote/transport/gh.d.ts +20 -0
  752. package/dist/remote/transport/gh.js +41 -0
  753. package/dist/remote/transport/gh.js.map +1 -0
  754. package/dist/remote/transport/graphql.d.ts +25 -0
  755. package/dist/remote/transport/graphql.js +81 -0
  756. package/dist/remote/transport/graphql.js.map +1 -0
  757. package/dist/remote/transport/http.d.ts +47 -0
  758. package/dist/remote/transport/http.js +195 -0
  759. package/dist/remote/transport/http.js.map +1 -0
  760. package/dist/remote/transport/index.d.ts +18 -0
  761. package/dist/remote/transport/index.js +19 -0
  762. package/dist/remote/transport/index.js.map +1 -0
  763. package/dist/remote/transport/process.d.ts +39 -0
  764. package/dist/remote/transport/process.js +121 -0
  765. package/dist/remote/transport/process.js.map +1 -0
  766. package/dist/remote/transport/rest.d.ts +22 -0
  767. package/dist/remote/transport/rest.js +57 -0
  768. package/dist/remote/transport/rest.js.map +1 -0
  769. package/dist/remote/transport/retry.d.ts +91 -0
  770. package/dist/remote/transport/retry.js +138 -0
  771. package/dist/remote/transport/retry.js.map +1 -0
  772. package/dist/remote/transport-error.d.ts +19 -0
  773. package/dist/remote/transport-error.js +22 -0
  774. package/dist/remote/transport-error.js.map +1 -0
  775. package/dist/remote/vocabulary.d.ts +126 -0
  776. package/dist/remote/vocabulary.js +57 -0
  777. package/dist/remote/vocabulary.js.map +1 -0
  778. package/dist/runner/config.d.ts +7 -0
  779. package/dist/runner/config.js +61 -0
  780. package/dist/runner/config.js.map +1 -0
  781. package/dist/runner/git.d.ts +19 -0
  782. package/dist/runner/git.js +26 -0
  783. package/dist/runner/git.js.map +1 -0
  784. package/dist/runner/index.d.ts +20 -0
  785. package/dist/runner/index.js +21 -0
  786. package/dist/runner/index.js.map +1 -0
  787. package/dist/runner/loop.d.ts +46 -0
  788. package/dist/runner/loop.js +243 -0
  789. package/dist/runner/loop.js.map +1 -0
  790. package/dist/runner/pi.d.ts +39 -0
  791. package/dist/runner/pi.js +276 -0
  792. package/dist/runner/pi.js.map +1 -0
  793. package/dist/runner/shell.d.ts +44 -0
  794. package/dist/runner/shell.js +174 -0
  795. package/dist/runner/shell.js.map +1 -0
  796. package/dist/runner/stats.d.ts +19 -0
  797. package/dist/runner/stats.js +58 -0
  798. package/dist/runner/stats.js.map +1 -0
  799. package/dist/runner/types.d.ts +218 -0
  800. package/dist/runner/types.js +37 -0
  801. package/dist/runner/types.js.map +1 -0
  802. package/dist/server/git.d.ts +8 -0
  803. package/dist/server/git.js +50 -0
  804. package/dist/server/git.js.map +1 -0
  805. package/dist/server/http/respond.d.ts +13 -0
  806. package/dist/server/http/respond.js +59 -0
  807. package/dist/server/http/respond.js.map +1 -0
  808. package/dist/server/http/router.d.ts +27 -0
  809. package/dist/server/http/router.js +48 -0
  810. package/dist/server/http/router.js.map +1 -0
  811. package/dist/server/http/static.d.ts +14 -0
  812. package/dist/server/http/static.js +55 -0
  813. package/dist/server/http/static.js.map +1 -0
  814. package/dist/server/index.d.ts +58 -0
  815. package/dist/server/index.js +124 -0
  816. package/dist/server/index.js.map +1 -0
  817. package/dist/server/routes/board.d.ts +8 -0
  818. package/dist/server/routes/board.js +19 -0
  819. package/dist/server/routes/board.js.map +1 -0
  820. package/dist/server/routes/comments.d.ts +13 -0
  821. package/dist/server/routes/comments.js +36 -0
  822. package/dist/server/routes/comments.js.map +1 -0
  823. package/dist/server/routes/flags.d.ts +16 -0
  824. package/dist/server/routes/flags.js +37 -0
  825. package/dist/server/routes/flags.js.map +1 -0
  826. package/dist/server/routes/git.d.ts +13 -0
  827. package/dist/server/routes/git.js +84 -0
  828. package/dist/server/routes/git.js.map +1 -0
  829. package/dist/server/routes/remotes.d.ts +36 -0
  830. package/dist/server/routes/remotes.js +749 -0
  831. package/dist/server/routes/remotes.js.map +1 -0
  832. package/dist/server/routes/views.d.ts +10 -0
  833. package/dist/server/routes/views.js +63 -0
  834. package/dist/server/routes/views.js.map +1 -0
  835. package/dist/server/views/schema.d.ts +2 -0
  836. package/dist/server/views/schema.js +121 -0
  837. package/dist/server/views/schema.js.map +1 -0
  838. package/dist/server/views/store.d.ts +17 -0
  839. package/dist/server/views/store.js +67 -0
  840. package/dist/server/views/store.js.map +1 -0
  841. package/dist/shared/adf.d.ts +83 -0
  842. package/dist/shared/adf.js +795 -0
  843. package/dist/shared/adf.js.map +1 -0
  844. package/dist/shared/blocking.d.ts +130 -0
  845. package/dist/shared/blocking.js +179 -0
  846. package/dist/shared/blocking.js.map +1 -0
  847. package/dist/shared/changes.d.ts +100 -0
  848. package/dist/shared/changes.js +112 -0
  849. package/dist/shared/changes.js.map +1 -0
  850. package/dist/shared/cohesion.d.ts +75 -0
  851. package/dist/shared/cohesion.js +132 -0
  852. package/dist/shared/cohesion.js.map +1 -0
  853. package/dist/shared/dependency-rollup.d.ts +91 -0
  854. package/dist/shared/dependency-rollup.js +132 -0
  855. package/dist/shared/dependency-rollup.js.map +1 -0
  856. package/dist/shared/errors.d.ts +23 -0
  857. package/dist/shared/errors.js +24 -0
  858. package/dist/shared/errors.js.map +1 -0
  859. package/dist/shared/flag-rollup.d.ts +88 -0
  860. package/dist/shared/flag-rollup.js +119 -0
  861. package/dist/shared/flag-rollup.js.map +1 -0
  862. package/dist/shared/git-sync.d.ts +90 -0
  863. package/dist/shared/git-sync.js +9 -0
  864. package/dist/shared/git-sync.js.map +1 -0
  865. package/dist/shared/index.d.ts +40 -0
  866. package/dist/shared/index.js +41 -0
  867. package/dist/shared/index.js.map +1 -0
  868. package/dist/shared/model.d.ts +218 -0
  869. package/dist/shared/model.js +95 -0
  870. package/dist/shared/model.js.map +1 -0
  871. package/dist/shared/period-query.d.ts +21 -0
  872. package/dist/shared/period-query.js +26 -0
  873. package/dist/shared/period-query.js.map +1 -0
  874. package/dist/shared/period-stance.d.ts +45 -0
  875. package/dist/shared/period-stance.js +50 -0
  876. package/dist/shared/period-stance.js.map +1 -0
  877. package/dist/shared/plans/breakdown.d.ts +66 -0
  878. package/dist/shared/plans/breakdown.js +186 -0
  879. package/dist/shared/plans/breakdown.js.map +1 -0
  880. package/dist/shared/plans/index.d.ts +21 -0
  881. package/dist/shared/plans/index.js +22 -0
  882. package/dist/shared/plans/index.js.map +1 -0
  883. package/dist/shared/plans/instantiate.d.ts +61 -0
  884. package/dist/shared/plans/instantiate.js +184 -0
  885. package/dist/shared/plans/instantiate.js.map +1 -0
  886. package/dist/shared/plans/reading.d.ts +79 -0
  887. package/dist/shared/plans/reading.js +149 -0
  888. package/dist/shared/plans/reading.js.map +1 -0
  889. package/dist/shared/plans/reparent.d.ts +54 -0
  890. package/dist/shared/plans/reparent.js +217 -0
  891. package/dist/shared/plans/reparent.js.map +1 -0
  892. package/dist/shared/plans/timeline.d.ts +93 -0
  893. package/dist/shared/plans/timeline.js +224 -0
  894. package/dist/shared/plans/timeline.js.map +1 -0
  895. package/dist/shared/plans/upstream.d.ts +67 -0
  896. package/dist/shared/plans/upstream.js +73 -0
  897. package/dist/shared/plans/upstream.js.map +1 -0
  898. package/dist/shared/remote-api.d.ts +413 -0
  899. package/dist/shared/remote-api.js +11 -0
  900. package/dist/shared/remote-api.js.map +1 -0
  901. package/dist/shared/remote-coverage.d.ts +120 -0
  902. package/dist/shared/remote-coverage.js +98 -0
  903. package/dist/shared/remote-coverage.js.map +1 -0
  904. package/dist/shared/remote-readiness.d.ts +162 -0
  905. package/dist/shared/remote-readiness.js +49 -0
  906. package/dist/shared/remote-readiness.js.map +1 -0
  907. package/dist/shared/remote-status.d.ts +268 -0
  908. package/dist/shared/remote-status.js +79 -0
  909. package/dist/shared/remote-status.js.map +1 -0
  910. package/dist/shared/rollup.d.ts +90 -0
  911. package/dist/shared/rollup.js +119 -0
  912. package/dist/shared/rollup.js.map +1 -0
  913. package/dist/shared/static.d.ts +65 -0
  914. package/dist/shared/static.js +107 -0
  915. package/dist/shared/static.js.map +1 -0
  916. package/dist/shared/template-params.d.ts +80 -0
  917. package/dist/shared/template-params.js +141 -0
  918. package/dist/shared/template-params.js.map +1 -0
  919. package/dist/shared/view.d.ts +105 -0
  920. package/dist/shared/view.js +44 -0
  921. package/dist/shared/view.js.map +1 -0
  922. package/dist/shared/work-unit.d.ts +34 -0
  923. package/dist/shared/work-unit.js +47 -0
  924. package/dist/shared/work-unit.js.map +1 -0
  925. package/dist/sync/apply.d.ts +21 -0
  926. package/dist/sync/apply.js +149 -0
  927. package/dist/sync/apply.js.map +1 -0
  928. package/dist/sync/dto.d.ts +9 -0
  929. package/dist/sync/dto.js +162 -0
  930. package/dist/sync/dto.js.map +1 -0
  931. package/dist/sync/index.d.ts +24 -0
  932. package/dist/sync/index.js +25 -0
  933. package/dist/sync/index.js.map +1 -0
  934. package/dist/sync/patch.d.ts +13 -0
  935. package/dist/sync/patch.js +212 -0
  936. package/dist/sync/patch.js.map +1 -0
  937. package/dist/sync/session.d.ts +31 -0
  938. package/dist/sync/session.js +55 -0
  939. package/dist/sync/session.js.map +1 -0
  940. package/dist/sync/static.d.ts +11 -0
  941. package/dist/sync/static.js +33 -0
  942. package/dist/sync/static.js.map +1 -0
  943. package/package.json +95 -4
  944. package/templates/blank.yml +71 -0
  945. package/templates/context/bug.md +107 -0
  946. package/templates/context/default.md +119 -0
  947. package/templates/context/epic.md +81 -0
  948. package/templates/context/feature.md +91 -0
  949. package/templates/context/research.md +87 -0
  950. package/templates/context/review.md +81 -0
  951. package/templates/context/story.md +94 -0
  952. package/templates/context/sub_task.md +108 -0
  953. package/templates/context/task.md +86 -0
  954. package/templates/context/test.md +73 -0
  955. package/templates/context/user_story.md +147 -0
  956. package/templates/kanban.yml +226 -0
  957. package/templates/scrum.yml +567 -0
  958. package/web/dist/assets/index-D0j8OnHq.js +35 -0
  959. package/web/dist/assets/index-DFL7v8aP.css +1 -0
  960. package/web/dist/index.html +13 -0
  961. package/web/dist-viewer/assets/index-Bcns6OuC.css +1 -0
  962. package/web/dist-viewer/assets/index-vVXzeiFo.js +7 -0
  963. package/web/dist-viewer/index.html +14 -0
@@ -0,0 +1,748 @@
1
+ /**
2
+ * The correspondence store — which document is which remote issue, and what it
3
+ * looked like last time both sides agreed.
4
+ *
5
+ * Lives under `.lpm/remotes/<name>/links.json`, committed like everything else.
6
+ * Its sibling `mapping.json` holds the mapping fingerprint every sync compares
7
+ * against (LP-370, `fingerprint.ts`).
8
+ *
9
+ * Why not a frontmatter field? `remote_id:` would be a breaking reserved field
10
+ * (it would shadow a user attribute of that name), it does not extend to two
11
+ * remotes, and it has nowhere to keep the base snapshot. Same reasoning that
12
+ * keeps derived inverses out of the documents.
13
+ *
14
+ * ## Merge safety
15
+ *
16
+ * Keys are written sorted and each link entry is a contiguous line-group, so
17
+ * two people syncing different issues on different branches produce a
18
+ * non-overlapping diff. The file ends with a trailing newline. A hand-edited
19
+ * or merge-mangled file is rejected with a `BoardError` naming the path and the
20
+ * offending key — never a bare JSON parse error.
21
+ *
22
+ * ## Concurrency
23
+ *
24
+ * Two syncs can race on this file (CI plus a laptop, two teammates). The
25
+ * design decision is **last-writer-wins with git as the backstop**: no lockfile
26
+ * in the per-remote folder. The store's public API (`loadLinkStore` /
27
+ * `saveLinkStore`) is free of the single-file assumption so a per-document split
28
+ * under `links/` remains an internal change if the single file proves
29
+ * conflict-prone in practice.
30
+ */
31
+ import { createHash } from 'node:crypto';
32
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
33
+ import path from 'node:path';
34
+ import { BoardError } from '../core/errors.js';
35
+ import { isManagedCommentBody } from './managed-comment.js';
36
+ import { MANAGED_BLOCK_BEGIN, MANAGED_BLOCK_END } from './managed-block.js';
37
+ // ---------------------------------------------------------------------------
38
+ // Managed-block convention
39
+ // ---------------------------------------------------------------------------
40
+ /**
41
+ * When a provider cannot hold a field natively it is encoded into a managed
42
+ * block inside the issue body. The block is our output, not their content —
43
+ * so it must be excluded when hashing the body for the base snapshot, or every
44
+ * push would look like a remote edit on the next pull.
45
+ *
46
+ * The delimiters are the one definition in `managed-block.ts`, shared with the
47
+ * codec that writes the block (LP-276) so the hash and the writer can never
48
+ * drift apart.
49
+ */
50
+ /** Escape regex metacharacters so a delimiter is matched literally. */
51
+ function escapeRegExp(text) {
52
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
53
+ }
54
+ /**
55
+ * Regex that matches a managed block and everything inside it. The block may
56
+ * appear at any position in the body and there may be at most one.
57
+ */
58
+ const MANAGED_BLOCK_RE = new RegExp(`${escapeRegExp(MANAGED_BLOCK_BEGIN)}[\\s\\S]*?${escapeRegExp(MANAGED_BLOCK_END)}`, 'g');
59
+ // ---------------------------------------------------------------------------
60
+ // I/O
61
+ // ---------------------------------------------------------------------------
62
+ /** The path to one remote's link store. */
63
+ export function linksPath(paths, remoteName) {
64
+ return path.join(paths.remotesDir, remoteName, 'links.json');
65
+ }
66
+ /**
67
+ * Read the link store from disk. A missing file is a valid empty store — the
68
+ * first sync creates it. A file that exists but cannot be parsed is a
69
+ * `BoardError` naming the path.
70
+ */
71
+ export function loadLinkStore(paths, remoteName) {
72
+ const file = linksPath(paths, remoteName);
73
+ let raw;
74
+ try {
75
+ raw = readFileSync(file, 'utf8');
76
+ }
77
+ catch {
78
+ // File does not exist yet — the first sync will create it.
79
+ return emptyStore();
80
+ }
81
+ let parsed;
82
+ try {
83
+ parsed = JSON.parse(raw);
84
+ }
85
+ catch (error) {
86
+ throw new BoardError(`Cannot parse link store: ${file}`, [
87
+ error.message,
88
+ 'Delete it to start fresh (all links will be lost), or repair the JSON.',
89
+ ]);
90
+ }
91
+ const store = parsed;
92
+ if (store.version !== 1) {
93
+ const newer = typeof store.version === 'number' && store.version > 1;
94
+ throw new BoardError(newer
95
+ ? `Link store at ${file} was written by a newer version of light-plan`
96
+ : `Unsupported link store version in ${file}`, newer
97
+ ? [
98
+ `This file is version ${store.version}; this build of light-plan understands version 1.`,
99
+ 'Upgrade light-plan to read this file, or delete it to start fresh (all links will be lost).',
100
+ ]
101
+ : [
102
+ `Found version ${JSON.stringify(store.version)}; expected 1.`,
103
+ 'Delete it to start fresh (all links will be lost), or repair the version field.',
104
+ ]);
105
+ }
106
+ const links = new Map();
107
+ const byRemote = new Map();
108
+ const tombstones = new Map();
109
+ // The recorded hierarchy encoding (LP-493): a per-remote fact, like the
110
+ // cursor. Absent on a store that has never synced.
111
+ let hierarchy;
112
+ if (store.hierarchy !== undefined && store.hierarchy !== null) {
113
+ const raw = store.hierarchy;
114
+ if (typeof raw !== 'object' ||
115
+ Array.isArray(raw) ||
116
+ (raw.kind !== 'sub-issues' && raw.kind !== 'labels') ||
117
+ typeof raw.nativeDepth !== 'number') {
118
+ throw new BoardError(`Invalid link store: ${file}`, [
119
+ `The hierarchy record is malformed (got ${JSON.stringify(store.hierarchy)}).`,
120
+ 'Delete the hierarchy field to let the next sync record a fresh one, or repair it.',
121
+ ]);
122
+ }
123
+ hierarchy = {
124
+ kind: raw.kind,
125
+ nativeDepth: raw.nativeDepth,
126
+ // The anchor is part of the carrier decision, so dropping it on read
127
+ // makes every twin look mis-parented on the next plan: the record says
128
+ // "root" (the absent default), the resolution says "leaf", and the push
129
+ // re-parents all of them, every time, for ever.
130
+ ...(raw.anchor === 'root' || raw.anchor === 'leaf'
131
+ ? { anchor: raw.anchor }
132
+ : {}),
133
+ };
134
+ }
135
+ if (store.links && typeof store.links === 'object') {
136
+ for (const [localId, entry] of Object.entries(store.links)) {
137
+ if (!entry || typeof entry !== 'object') {
138
+ throw new BoardError(`Invalid link store: ${file}`, [
139
+ `Link "${localId}" is not an object (got ${typeof entry}).`,
140
+ 'Delete it to start fresh (all links will be lost), or repair the entry.',
141
+ ]);
142
+ }
143
+ const link = entry;
144
+ // remoteId is the only hard-required field — without it there is no link.
145
+ if (typeof link.remoteId !== 'string' || !link.remoteId) {
146
+ throw new BoardError(`Invalid link store: ${file}`, [
147
+ `Link "${localId}" is missing a valid remoteId (got ${JSON.stringify(link.remoteId)}).`,
148
+ 'Every link must carry a non-empty remoteId string.',
149
+ 'Delete the entry to remove the link, or provide a valid remoteId.',
150
+ ]);
151
+ }
152
+ // Validate types of optional fields so a hand-edited file surfaces
153
+ // mistakes as BoardErrors rather than silently swallowing them.
154
+ validateLinkField(link, localId, 'remoteKey', 'string', file);
155
+ validateLinkField(link, localId, 'remoteUrl', 'string', file);
156
+ validateLinkField(link, localId, 'syncedAt', 'string', file);
157
+ validateLinkField(link, localId, 'remoteRev', 'string', file);
158
+ validateLinkField(link, localId, 'managedCommentId', 'string', file);
159
+ validateLinkField(link, localId, 'nodeId', 'string', file);
160
+ if (link.base !== undefined && link.base !== null) {
161
+ if (typeof link.base !== 'object') {
162
+ throw new BoardError(`Invalid link store: ${file}`, [
163
+ `Link "${localId}".base must be an object (got ${typeof link.base}).`,
164
+ 'Delete the base field to clear the snapshot, or provide a valid object.',
165
+ ]);
166
+ }
167
+ }
168
+ if (link.baseHash !== undefined && link.baseHash !== null) {
169
+ if (typeof link.baseHash !== 'string') {
170
+ throw new BoardError(`Invalid link store: ${file}`, [
171
+ `Link "${localId}".baseHash must be a string (got ${typeof link.baseHash}).`,
172
+ 'Delete the baseHash field to let it be recomputed, or provide a valid hash.',
173
+ ]);
174
+ }
175
+ }
176
+ const linkEntry = {
177
+ remoteId: link.remoteId,
178
+ remoteKey: typeof link.remoteKey === 'string' ? link.remoteKey : link.remoteId,
179
+ remoteUrl: typeof link.remoteUrl === 'string' ? link.remoteUrl : '',
180
+ syncedAt: typeof link.syncedAt === 'string' ? link.syncedAt : '',
181
+ remoteRev: typeof link.remoteRev === 'string' ? link.remoteRev : '',
182
+ };
183
+ if (typeof link.managedCommentId === 'string') {
184
+ linkEntry.managedCommentId = link.managedCommentId;
185
+ }
186
+ if (typeof link.nodeId === 'string') {
187
+ linkEntry.nodeId = link.nodeId;
188
+ }
189
+ // `null` is a value here — "filed with no remote parent" — so it is
190
+ // carried through rather than treated as absent.
191
+ if (typeof link.parentRemoteId === 'string' || link.parentRemoteId === null) {
192
+ linkEntry.parentRemoteId = link.parentRemoteId;
193
+ }
194
+ if (link.commentIds !== undefined && link.commentIds !== null) {
195
+ if (typeof link.commentIds !== 'object' || Array.isArray(link.commentIds)) {
196
+ throw new BoardError(`Invalid link store: ${file}`, [
197
+ `Link "${localId}".commentIds must be an object of comment ids (got ${Array.isArray(link.commentIds) ? 'an array' : typeof link.commentIds}).`,
198
+ 'Delete the commentIds field to clear the recorded ids, or provide a valid object.',
199
+ ]);
200
+ }
201
+ const commentIds = {};
202
+ for (const [index, commentId] of Object.entries(link.commentIds)) {
203
+ if (typeof commentId !== 'string') {
204
+ throw new BoardError(`Invalid link store: ${file}`, [
205
+ `Link "${localId}".commentIds["${index}"] must be a string (got ${typeof commentId}).`,
206
+ 'Delete the entry to clear it, or provide a valid comment id.',
207
+ ]);
208
+ }
209
+ commentIds[index] = commentId;
210
+ }
211
+ linkEntry.commentIds = commentIds;
212
+ }
213
+ if (link.base !== undefined && link.base !== null && typeof link.base === 'object') {
214
+ linkEntry.base = link.base;
215
+ }
216
+ if (typeof link.baseHash === 'string') {
217
+ linkEntry.baseHash = link.baseHash;
218
+ }
219
+ links.set(localId, linkEntry);
220
+ byRemote.set(linkEntry.remoteId, localId);
221
+ }
222
+ }
223
+ if (store.tombstones && typeof store.tombstones === 'object') {
224
+ for (const [localId, raw] of Object.entries(store.tombstones)) {
225
+ if (!raw || typeof raw !== 'object') {
226
+ throw new BoardError(`Invalid link store: ${file}`, [
227
+ `Tombstone "${localId}" is not an object (got ${typeof raw}).`,
228
+ 'Delete the tombstone to remove the decoupled marker, or repair the entry.',
229
+ ]);
230
+ }
231
+ const entry = raw;
232
+ validateLinkField(entry, localId, 'remoteKey', 'string', file);
233
+ validateLinkField(entry, localId, 'reason', 'string', file);
234
+ validateLinkField(entry, localId, 'at', 'string', file);
235
+ tombstones.set(localId, {
236
+ remoteKey: typeof entry.remoteKey === 'string' ? entry.remoteKey : '',
237
+ reason: typeof entry.reason === 'string' ? entry.reason : '',
238
+ at: typeof entry.at === 'string' ? entry.at : '',
239
+ });
240
+ }
241
+ }
242
+ // A document may not be both linked and decoupled — the two are opposites,
243
+ // and only a hand-edited or merge-mangled file could hold both. Reject it
244
+ // rather than let one silently outrank the other.
245
+ for (const localId of tombstones.keys()) {
246
+ if (links.has(localId)) {
247
+ throw new BoardError(`Invalid link store: ${file}`, [
248
+ `Document "${localId}" is both linked and decoupled.`,
249
+ 'Delete either the link or the tombstone — the two cannot both be true.',
250
+ ]);
251
+ }
252
+ }
253
+ return {
254
+ version: store.version,
255
+ cursor: typeof store.cursor === 'string' ? store.cursor : null,
256
+ links,
257
+ byRemote,
258
+ tombstones,
259
+ ...(hierarchy !== undefined ? { hierarchy } : {}),
260
+ ...(typeof store.consentedAt === 'string' && store.consentedAt !== ''
261
+ ? { consentedAt: store.consentedAt }
262
+ : {}),
263
+ };
264
+ }
265
+ /**
266
+ * Write the link store to disk. Creates the per-remote folder if it does not
267
+ * exist. Keys are written in sorted order so two people syncing different
268
+ * issues produce a mergeable diff.
269
+ */
270
+ export function saveLinkStore(paths, remoteName, store) {
271
+ const file = linksPath(paths, remoteName);
272
+ mkdirSync(path.dirname(file), { recursive: true });
273
+ // Build a plain object with sorted keys.
274
+ const sortedIds = [...store.links.keys()].sort();
275
+ const links = {};
276
+ for (const id of sortedIds) {
277
+ links[id] = store.links.get(id);
278
+ }
279
+ const onDisk = {
280
+ version: 1,
281
+ cursor: store.cursor,
282
+ links,
283
+ };
284
+ if (store.hierarchy !== undefined) {
285
+ onDisk.hierarchy = store.hierarchy;
286
+ }
287
+ if (store.consentedAt !== undefined) {
288
+ onDisk.consentedAt = store.consentedAt;
289
+ }
290
+ const tombstoneIds = [...store.tombstones.keys()].sort();
291
+ if (tombstoneIds.length > 0) {
292
+ const tombstones = {};
293
+ for (const id of tombstoneIds)
294
+ tombstones[id] = store.tombstones.get(id);
295
+ onDisk.tombstones = tombstones;
296
+ }
297
+ writeFileSync(file, `${JSON.stringify(onDisk, null, 2)}\n`, 'utf8');
298
+ }
299
+ // ---------------------------------------------------------------------------
300
+ // Queries
301
+ // ---------------------------------------------------------------------------
302
+ /** The remote twin of `localId`, or undefined when it is not linked. */
303
+ export function getLink(store, localId) {
304
+ return store.links.get(localId);
305
+ }
306
+ /** The tombstone for `localId`, when the document was deliberately decoupled. */
307
+ export function getTombstone(store, localId) {
308
+ return store.tombstones.get(localId);
309
+ }
310
+ /** True when `localId` was deliberately decoupled (LP-366 records these). */
311
+ export function isDecoupled(store, localId) {
312
+ return store.tombstones.has(localId);
313
+ }
314
+ /**
315
+ * Record (or replace) the tombstone for `localId`. A tombstone is the memory
316
+ * that a human dropped the link on purpose; it never names a living twin.
317
+ */
318
+ export function setTombstone(store, localId, tombstone) {
319
+ store.tombstones.set(localId, tombstone);
320
+ }
321
+ /**
322
+ * Remove the tombstone for `localId` — the document is free to be linked (and
323
+ * therefore filed) again. Returns true when there was one to remove.
324
+ */
325
+ export function clearTombstone(store, localId) {
326
+ return store.tombstones.delete(localId);
327
+ }
328
+ /**
329
+ * Decouple a document: drop its link (and with it the base snapshot — there is
330
+ * nothing left to be a base for) and record a tombstone carrying the last
331
+ * known remote key, the reason, and when it happened. The remote twin is
332
+ * never touched by this — decoupling is a local decision that leaves the
333
+ * remote issue alone.
334
+ *
335
+ * Works whether or not the document is currently linked: a never-linked
336
+ * document is decoupled with an empty remote key, which still marks it as
337
+ * "never file this". Returns the tombstone written.
338
+ */
339
+ export function decoupleLink(store, localId, reason, at) {
340
+ const link = store.links.get(localId);
341
+ const remoteKey = link?.remoteKey ?? '';
342
+ removeLink(store, localId); // drops the link, the base snapshot and the reverse index
343
+ const tombstone = { remoteKey, reason, at };
344
+ store.tombstones.set(localId, tombstone);
345
+ return tombstone;
346
+ }
347
+ /** The local id linked to `remoteId`, or undefined when it is not linked. */
348
+ export function getLocalId(store, remoteId) {
349
+ return store.byRemote.get(remoteId);
350
+ }
351
+ /** True when `localId` has a recorded remote twin. */
352
+ export function isLinked(store, localId) {
353
+ return store.links.has(localId);
354
+ }
355
+ // ---------------------------------------------------------------------------
356
+ // Mutations
357
+ // ---------------------------------------------------------------------------
358
+ /**
359
+ * Record (or replace) the remote twin of `localId`. If this local id was
360
+ * previously linked to a different remote id the old reverse entry is dropped.
361
+ */
362
+ export function setLink(store, localId, entry) {
363
+ const old = store.links.get(localId);
364
+ if (old && old.remoteId !== entry.remoteId) {
365
+ store.byRemote.delete(old.remoteId);
366
+ }
367
+ store.links.set(localId, entry);
368
+ store.byRemote.set(entry.remoteId, localId);
369
+ // A live link is the opposite of a tombstone: linking (or re-linking) a
370
+ // document ends its decoupled state, so the tombstone must not linger and
371
+ // outrank the link in the lifecycle resolver.
372
+ store.tombstones.delete(localId);
373
+ }
374
+ /**
375
+ * Remove the link for `localId`. Returns true when there was one to remove.
376
+ */
377
+ export function removeLink(store, localId) {
378
+ const entry = store.links.get(localId);
379
+ if (!entry)
380
+ return false;
381
+ store.byRemote.delete(entry.remoteId);
382
+ store.links.delete(localId);
383
+ return true;
384
+ }
385
+ /** The remote id of the managed comment recorded for `localId`, or undefined. */
386
+ export function getManagedCommentId(store, localId) {
387
+ return store.links.get(localId)?.managedCommentId;
388
+ }
389
+ /**
390
+ * True when a remote comment is the managed comment for `localId` — our own
391
+ * output, excluded from comment sync in both directions (LP-278). Known by
392
+ * id where the link store records it; by body where the id was lost. A push
393
+ * never re-posts it as a user comment, and a pull never imports it as one.
394
+ */
395
+ export function isManagedComment(store, localId, commentId, body) {
396
+ if (getManagedCommentId(store, localId) === commentId)
397
+ return true;
398
+ return isManagedCommentBody(body);
399
+ }
400
+ /**
401
+ * Record (or clear) the managed comment id for `localId`. A no-op when the
402
+ * document is not linked — the comment is an attribute of an existing link.
403
+ */
404
+ export function setManagedCommentId(store, localId, commentId) {
405
+ const link = store.links.get(localId);
406
+ if (!link)
407
+ return;
408
+ if (commentId === undefined)
409
+ delete link.managedCommentId;
410
+ else
411
+ link.managedCommentId = commentId;
412
+ }
413
+ // ---------------------------------------------------------------------------
414
+ // User-comment correspondence (LP-316)
415
+ // ---------------------------------------------------------------------------
416
+ /**
417
+ * The local comment indexes (1-based, as a string) already synced for
418
+ * `localId`, or an empty set when the document is unlinked or has none. The
419
+ * push posts only indexes absent from this set; a comment the log has since
420
+ * grown past (new entries appended below) is still present, because appends
421
+ * never shift the indexes recorded for earlier entries.
422
+ */
423
+ export function getSyncedCommentIndexes(store, localId) {
424
+ const record = store.links.get(localId)?.commentIds;
425
+ const indexes = new Set();
426
+ if (!record)
427
+ return indexes;
428
+ for (const key of Object.keys(record)) {
429
+ const index = Number(key);
430
+ if (Number.isInteger(index) && index > 0)
431
+ indexes.add(index);
432
+ }
433
+ return indexes;
434
+ }
435
+ /**
436
+ * The remote comment ids already synced for `localId`, or an empty set. The
437
+ * pull appends only remote ids absent from this set; the managed comment's id
438
+ * is deliberately not among them, so the caller still excludes it by body/id
439
+ * rather than trusting the absence to be meaningful.
440
+ */
441
+ export function getSyncedRemoteCommentIds(store, localId) {
442
+ const record = store.links.get(localId)?.commentIds;
443
+ const ids = new Set();
444
+ if (!record)
445
+ return ids;
446
+ for (const value of Object.values(record))
447
+ ids.add(value);
448
+ return ids;
449
+ }
450
+ /**
451
+ * Record that the local comment at `index` (1-based) is the remote comment
452
+ * `commentId` for `localId` (LP-316). A no-op when the document is not
453
+ * linked. Clearing a synced comment is not offered — the log is append-only
454
+ * and a recorded id stays recorded, so nothing is ever posted twice.
455
+ */
456
+ export function setCommentId(store, localId, index, commentId) {
457
+ const link = store.links.get(localId);
458
+ if (!link)
459
+ return;
460
+ if (link.commentIds === undefined)
461
+ link.commentIds = {};
462
+ link.commentIds[String(index)] = commentId;
463
+ }
464
+ /**
465
+ * Change the local id a link is keyed under. Does nothing when `oldId` has no
466
+ * link or when the two ids are equal, and overwrites any existing link at
467
+ * `newId` as the safe default — the caller must resolve that collision first.
468
+ */
469
+ export function rewriteLinkId(store, oldId, newId) {
470
+ if (oldId === newId)
471
+ return;
472
+ const entry = store.links.get(oldId);
473
+ if (!entry)
474
+ return;
475
+ // If newId already had a link the old one is dropped — that is the safe
476
+ // default, and the caller checks for collisions before calling.
477
+ const oldAtNew = store.links.get(newId);
478
+ if (oldAtNew)
479
+ store.byRemote.delete(oldAtNew.remoteId);
480
+ store.links.delete(oldId);
481
+ store.links.set(newId, entry);
482
+ store.byRemote.set(entry.remoteId, newId);
483
+ }
484
+ /**
485
+ * Report links whose local document no longer exists. Never prunes silently —
486
+ * the caller decides whether to call `removeLink` for each. The returned array
487
+ * is the list of local ids that have no matching document.
488
+ */
489
+ export function findMissingLinks(store, existingIds) {
490
+ const missing = [];
491
+ for (const localId of store.links.keys()) {
492
+ if (!existingIds.has(localId)) {
493
+ missing.push(localId);
494
+ }
495
+ }
496
+ return missing;
497
+ }
498
+ /**
499
+ * Remove every link whose local document is not in `existingIds`. Returns the
500
+ * ids that were pruned.
501
+ */
502
+ export function pruneMissingLinks(store, existingIds) {
503
+ const missing = findMissingLinks(store, existingIds);
504
+ for (const id of missing) {
505
+ removeLink(store, id);
506
+ }
507
+ return missing;
508
+ }
509
+ /**
510
+ * Tombstones whose local document no longer exists. Like `findMissingLinks`,
511
+ * never prunes silently — the caller decides. A tombstone left behind by a
512
+ * deleted document is dead weight, not a correctness bug, but `lpm check`
513
+ * reports it so the store stays honest.
514
+ */
515
+ export function findMissingTombstones(store, existingIds) {
516
+ const missing = [];
517
+ for (const localId of store.tombstones.keys()) {
518
+ if (!existingIds.has(localId))
519
+ missing.push(localId);
520
+ }
521
+ return missing;
522
+ }
523
+ /**
524
+ * Remove every tombstone whose local document is not in `existingIds`.
525
+ * Returns the ids that were pruned.
526
+ */
527
+ export function pruneMissingTombstones(store, existingIds) {
528
+ const missing = findMissingTombstones(store, existingIds);
529
+ for (const id of missing) {
530
+ store.tombstones.delete(id);
531
+ }
532
+ return missing;
533
+ }
534
+ /**
535
+ * Strip the managed block from a body, returning the text the remote side
536
+ * wrote — the content the hash should represent. When there is no managed
537
+ * block the body is returned unchanged.
538
+ */
539
+ export function stripManagedBlock(body) {
540
+ return body.replace(MANAGED_BLOCK_RE, '').trim();
541
+ }
542
+ /**
543
+ * Compute a stable hash of the *normalised* body — managed block excluded — so
544
+ * the base snapshot stores a short token rather than the full text. The
545
+ * returned string carries a `sha256:` prefix so a reader can tell a hash from
546
+ * a literal body value at a glance.
547
+ *
548
+ * The hash is over the trimmed text after the managed block is removed; two
549
+ * bodies that differ only in trailing whitespace outside the managed block
550
+ * produce the same hash.
551
+ *
552
+ * **Line endings are normalised first**, and that is not cosmetic. A board
553
+ * checked out on Windows has `
554
+ ` in every document; a remote hands its text
555
+ * back with `
556
+ `. Hashing them apart makes every document permanently *ahead*:
557
+ * the push rewrites all of them, the next push does it again, and two
558
+ * teammates on different operating systems fight over bodies neither has
559
+ * edited.
560
+ *
561
+ * `normalize` is the same argument made for a remote whose body format is not
562
+ * markdown (`Translator.normalizeBody`): Jira stores ADF, which has paragraphs
563
+ * but no source line breaks, so a hard-wrapped body comes back as one long
564
+ * line and would differ from itself for ever. Pass it when hashing a **board**
565
+ * body that will be compared against a base recorded from the remote's echo;
566
+ * never when hashing prose the remote just handed back, which has already been
567
+ * through that round trip.
568
+ */
569
+ export function hashBody(body, normalize) {
570
+ const stripped = stripManagedBlock(body).replace(/\r\n/g, '\n');
571
+ const normalised = normalize === undefined ? stripped : normalize(stripped).trim();
572
+ const hash = createHash('sha256').update(normalised, 'utf8').digest('hex');
573
+ return `sha256:${hash}`;
574
+ }
575
+ /**
576
+ * True when `value` looks like a body hash — a string that starts with
577
+ * `sha256:` followed by 64 hex digits.
578
+ */
579
+ export function isBodyHash(value) {
580
+ return typeof value === 'string' && /^sha256:[0-9a-f]{64}$/.test(value);
581
+ }
582
+ // ---------------------------------------------------------------------------
583
+ // Base snapshots
584
+ // ---------------------------------------------------------------------------
585
+ /**
586
+ * Compute the base snapshot for one document: every mapped field's value as it
587
+ * stands right now. The body is stored as a hash (`hashBody`), not as the full
588
+ * text. Fields carried in the managed block still appear under their local
589
+ * names — the base is vocabulary-agnostic.
590
+ *
591
+ * `mappedFields` is the set of local attribute names the mapping declares.
592
+ * Only those fields land in the snapshot; nothing else is included, because a
593
+ * field the mapping does not mention cannot diverge.
594
+ */
595
+ export function computeBase(document, mappedFields, normalizeBody) {
596
+ const base = {};
597
+ for (const field of mappedFields) {
598
+ if (field === 'body') {
599
+ base.body = hashBody(document.body, normalizeBody);
600
+ }
601
+ else if (field === 'title') {
602
+ base.title = document.title;
603
+ }
604
+ else if (field === 'status' ||
605
+ field === 'assignee' ||
606
+ field === 'period') {
607
+ base[field] = document[field] ?? null;
608
+ }
609
+ else if (field === 'dependsOn' ||
610
+ field === 'depends_on' ||
611
+ field === 'relatesTo' ||
612
+ field === 'relates_to' ||
613
+ field === 'relatedFiles' ||
614
+ field === 'related_files') {
615
+ // List fields — snapshot a sorted copy so the order is stable.
616
+ // Normalise the field name for lookup: the document shape uses
617
+ // camelCase, but the mapping may declare either spelling.
618
+ const lookupKey = field === 'depends_on' ? 'dependsOn' :
619
+ field === 'relates_to' ? 'relatesTo' :
620
+ field === 'related_files' ? 'relatedFiles' :
621
+ field;
622
+ const list = document[lookupKey];
623
+ base[field] = Array.isArray(list) ? [...list].sort() : [];
624
+ }
625
+ else {
626
+ // Config-declared attribute or unknown field.
627
+ base[field] = document.attributes[field] ?? null;
628
+ }
629
+ }
630
+ return base;
631
+ }
632
+ /**
633
+ * Update the base snapshot for one linked document. After a successful sync
634
+ * only the documents that landed should have their base updated — a partially
635
+ * failed sync must not snapshot work that did not reach the remote.
636
+ *
637
+ * The `base` value here should come from `computeBase`; the `baseHash` is
638
+ * derived from it automatically.
639
+ */
640
+ export function updateBase(store, localId, base, remoteRev, syncedAt) {
641
+ const link = store.links.get(localId);
642
+ if (!link)
643
+ return;
644
+ const hash = createHash('sha256')
645
+ .update(JSON.stringify(base), 'utf8')
646
+ .digest('hex');
647
+ link.base = base;
648
+ link.baseHash = `sha256:${hash}`;
649
+ link.remoteRev = remoteRev;
650
+ link.syncedAt = syncedAt;
651
+ }
652
+ // ---------------------------------------------------------------------------
653
+ // Cursor management
654
+ // ---------------------------------------------------------------------------
655
+ /**
656
+ * Return the cursor to hand to the provider on the next pull, or `null` when
657
+ * a full scan should be performed.
658
+ *
659
+ * A stored cursor lets the pull ask the remote only for issues updated since
660
+ * the last successful sync. The cursor is an opaque value the remote supplied
661
+ * — a page token, a timestamp, a revision hash — and its meaning is the
662
+ * provider's alone.
663
+ *
664
+ * When `fullSync` is `true` (the default on the CLI; `--changed` asks for the
665
+ * incremental listing instead) the stored cursor
666
+ * is ignored and `null` is returned, forcing a full listing. When the
667
+ * provider does not support incremental queries the caller should also pass
668
+ * `null` regardless; this function does not inspect capabilities — the caller
669
+ * knows which provider it is talking to.
670
+ */
671
+ export function getCursorForPull(store, opts) {
672
+ if (opts?.fullSync)
673
+ return null;
674
+ return store.cursor;
675
+ }
676
+ /**
677
+ * Advance the cursor to a value the **remote** supplied.
678
+ *
679
+ * The cursor must come from the remote's response (a `nextCursor` or
680
+ * equivalent field), never from `Date.now()`. Using local wall-clock time
681
+ * would miss edits made during the sync window whenever the clocks differ —
682
+ * every provider that supports incremental queries returns a server-side
683
+ * marker, and the caller must use it.
684
+ *
685
+ * This function does not validate the value at runtime; the contract is
686
+ * enforced by the pull planner, which is the only caller.
687
+ */
688
+ export function advanceCursor(store, cursor) {
689
+ store.cursor = cursor;
690
+ }
691
+ /**
692
+ * Reset the cursor to `null`, forcing the next pull to do a full scan.
693
+ *
694
+ * Safe to call at any time — a store with no cursor is a valid state (it is
695
+ * how every store starts). Useful after a failed pull, when the remote
696
+ * configuration changes, or when the operator wants to rebuild the link
697
+ * store from a fresh crawl.
698
+ */
699
+ export function clearCursor(store) {
700
+ store.cursor = null;
701
+ }
702
+ /**
703
+ * Record the one-time first-write consent (LP-350): a person confirmed that
704
+ * writing to this remote is intended, so the next sync no longer asks. Set
705
+ * once; an existing consent is never overwritten, because the confirmation is
706
+ * a fact about the remote, not about this particular run.
707
+ */
708
+ export function recordConsent(store, at) {
709
+ if (store.consentedAt === undefined)
710
+ store.consentedAt = at;
711
+ }
712
+ /** True when first-write consent has been recorded for this remote. */
713
+ export function isConsented(store) {
714
+ return store.consentedAt !== undefined;
715
+ }
716
+ // ---------------------------------------------------------------------------
717
+ // Validation
718
+ // ---------------------------------------------------------------------------
719
+ /**
720
+ * Validate that an optional field on a link entry has the expected type.
721
+ * Throws `BoardError` naming the path and the offending key when the field is
722
+ * present but of the wrong type — so a hand-edited or merge-mangled file
723
+ * surfaces the mistake rather than silently correcting it.
724
+ */
725
+ function validateLinkField(link, localId, field, expected, file) {
726
+ const value = link[field];
727
+ if (value === undefined || value === null)
728
+ return; // absent is fine
729
+ if (typeof value !== expected) {
730
+ throw new BoardError(`Invalid link store: ${file}`, [
731
+ `Link "${localId}".${field} must be a ${expected} (got ${typeof value}).`,
732
+ `Delete the ${field} field to clear it, or provide a valid ${expected}.`,
733
+ ]);
734
+ }
735
+ }
736
+ // ---------------------------------------------------------------------------
737
+ // Helpers
738
+ // ---------------------------------------------------------------------------
739
+ function emptyStore() {
740
+ return {
741
+ version: 1,
742
+ cursor: null,
743
+ links: new Map(),
744
+ byRemote: new Map(),
745
+ tombstones: new Map(),
746
+ };
747
+ }
748
+ //# sourceMappingURL=links.js.map