ctxr-cli 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 (390) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/dist/adapter.d.ts +18 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +4 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/adapters/builtin/index.d.ts +10 -0
  8. package/dist/adapters/builtin/index.d.ts.map +1 -0
  9. package/dist/adapters/builtin/index.js +11 -0
  10. package/dist/adapters/builtin/index.js.map +1 -0
  11. package/dist/adapters/forge/github.d.ts +9 -0
  12. package/dist/adapters/forge/github.d.ts.map +1 -0
  13. package/dist/adapters/forge/github.js +36 -0
  14. package/dist/adapters/forge/github.js.map +1 -0
  15. package/dist/adapters/forge/types.d.ts +23 -0
  16. package/dist/adapters/forge/types.d.ts.map +1 -0
  17. package/dist/adapters/forge/types.js +2 -0
  18. package/dist/adapters/forge/types.js.map +1 -0
  19. package/dist/adapters/harness/claude-code.d.ts +9 -0
  20. package/dist/adapters/harness/claude-code.d.ts.map +1 -0
  21. package/dist/adapters/harness/claude-code.js +42 -0
  22. package/dist/adapters/harness/claude-code.js.map +1 -0
  23. package/dist/adapters/identity/claude-code.d.ts +11 -0
  24. package/dist/adapters/identity/claude-code.d.ts.map +1 -0
  25. package/dist/adapters/identity/claude-code.js +18 -0
  26. package/dist/adapters/identity/claude-code.js.map +1 -0
  27. package/dist/adapters/registry.d.ts +16 -0
  28. package/dist/adapters/registry.d.ts.map +1 -0
  29. package/dist/adapters/registry.js +29 -0
  30. package/dist/adapters/registry.js.map +1 -0
  31. package/dist/adapters/types.d.ts +65 -0
  32. package/dist/adapters/types.d.ts.map +1 -0
  33. package/dist/adapters/types.js +12 -0
  34. package/dist/adapters/types.js.map +1 -0
  35. package/dist/bin.d.ts +3 -0
  36. package/dist/bin.d.ts.map +1 -0
  37. package/dist/bin.js +6 -0
  38. package/dist/bin.js.map +1 -0
  39. package/dist/commands/adapters-generate.d.ts +23 -0
  40. package/dist/commands/adapters-generate.d.ts.map +1 -0
  41. package/dist/commands/adapters-generate.js +59 -0
  42. package/dist/commands/adapters-generate.js.map +1 -0
  43. package/dist/commands/archive.d.ts +28 -0
  44. package/dist/commands/archive.d.ts.map +1 -0
  45. package/dist/commands/archive.js +66 -0
  46. package/dist/commands/archive.js.map +1 -0
  47. package/dist/commands/catalog-build.d.ts +7 -0
  48. package/dist/commands/catalog-build.d.ts.map +1 -0
  49. package/dist/commands/catalog-build.js +15 -0
  50. package/dist/commands/catalog-build.js.map +1 -0
  51. package/dist/commands/catalog-check.d.ts +22 -0
  52. package/dist/commands/catalog-check.d.ts.map +1 -0
  53. package/dist/commands/catalog-check.js +49 -0
  54. package/dist/commands/catalog-check.js.map +1 -0
  55. package/dist/commands/catalog-show.d.ts +13 -0
  56. package/dist/commands/catalog-show.d.ts.map +1 -0
  57. package/dist/commands/catalog-show.js +19 -0
  58. package/dist/commands/catalog-show.js.map +1 -0
  59. package/dist/commands/check.d.ts +22 -0
  60. package/dist/commands/check.d.ts.map +1 -0
  61. package/dist/commands/check.js +43 -0
  62. package/dist/commands/check.js.map +1 -0
  63. package/dist/commands/doctor.d.ts +27 -0
  64. package/dist/commands/doctor.d.ts.map +1 -0
  65. package/dist/commands/doctor.js +53 -0
  66. package/dist/commands/doctor.js.map +1 -0
  67. package/dist/commands/graph-build.d.ts +24 -0
  68. package/dist/commands/graph-build.d.ts.map +1 -0
  69. package/dist/commands/graph-build.js +36 -0
  70. package/dist/commands/graph-build.js.map +1 -0
  71. package/dist/commands/graph-query.d.ts +41 -0
  72. package/dist/commands/graph-query.d.ts.map +1 -0
  73. package/dist/commands/graph-query.js +63 -0
  74. package/dist/commands/graph-query.js.map +1 -0
  75. package/dist/commands/ingest.d.ts +28 -0
  76. package/dist/commands/ingest.d.ts.map +1 -0
  77. package/dist/commands/ingest.js +60 -0
  78. package/dist/commands/ingest.js.map +1 -0
  79. package/dist/commands/init.d.ts +28 -0
  80. package/dist/commands/init.d.ts.map +1 -0
  81. package/dist/commands/init.js +203 -0
  82. package/dist/commands/init.js.map +1 -0
  83. package/dist/commands/lint.d.ts +30 -0
  84. package/dist/commands/lint.d.ts.map +1 -0
  85. package/dist/commands/lint.js +48 -0
  86. package/dist/commands/lint.js.map +1 -0
  87. package/dist/commands/migrate.d.ts +30 -0
  88. package/dist/commands/migrate.d.ts.map +1 -0
  89. package/dist/commands/migrate.js +56 -0
  90. package/dist/commands/migrate.js.map +1 -0
  91. package/dist/commands/note-resolve.d.ts +14 -0
  92. package/dist/commands/note-resolve.d.ts.map +1 -0
  93. package/dist/commands/note-resolve.js +24 -0
  94. package/dist/commands/note-resolve.js.map +1 -0
  95. package/dist/commands/rollup-gather.d.ts +21 -0
  96. package/dist/commands/rollup-gather.d.ts.map +1 -0
  97. package/dist/commands/rollup-gather.js +40 -0
  98. package/dist/commands/rollup-gather.js.map +1 -0
  99. package/dist/commands/rollup-write.d.ts +25 -0
  100. package/dist/commands/rollup-write.d.ts.map +1 -0
  101. package/dist/commands/rollup-write.js +43 -0
  102. package/dist/commands/rollup-write.js.map +1 -0
  103. package/dist/commands/session-abandon.d.ts +13 -0
  104. package/dist/commands/session-abandon.d.ts.map +1 -0
  105. package/dist/commands/session-abandon.js +22 -0
  106. package/dist/commands/session-abandon.js.map +1 -0
  107. package/dist/commands/session-list.d.ts +14 -0
  108. package/dist/commands/session-list.d.ts.map +1 -0
  109. package/dist/commands/session-list.js +19 -0
  110. package/dist/commands/session-list.js.map +1 -0
  111. package/dist/commands/session-reap.d.ts +22 -0
  112. package/dist/commands/session-reap.d.ts.map +1 -0
  113. package/dist/commands/session-reap.js +47 -0
  114. package/dist/commands/session-reap.js.map +1 -0
  115. package/dist/commands/session-start.d.ts +18 -0
  116. package/dist/commands/session-start.d.ts.map +1 -0
  117. package/dist/commands/session-start.js +36 -0
  118. package/dist/commands/session-start.js.map +1 -0
  119. package/dist/commands/session-submit.d.ts +27 -0
  120. package/dist/commands/session-submit.d.ts.map +1 -0
  121. package/dist/commands/session-submit.js +68 -0
  122. package/dist/commands/session-submit.js.map +1 -0
  123. package/dist/commands/source-check.d.ts +21 -0
  124. package/dist/commands/source-check.d.ts.map +1 -0
  125. package/dist/commands/source-check.js +54 -0
  126. package/dist/commands/source-check.js.map +1 -0
  127. package/dist/commands/source-hash.d.ts +14 -0
  128. package/dist/commands/source-hash.d.ts.map +1 -0
  129. package/dist/commands/source-hash.js +34 -0
  130. package/dist/commands/source-hash.js.map +1 -0
  131. package/dist/commands/update.d.ts +17 -0
  132. package/dist/commands/update.d.ts.map +1 -0
  133. package/dist/commands/update.js +25 -0
  134. package/dist/commands/update.js.map +1 -0
  135. package/dist/commands/verify.d.ts +23 -0
  136. package/dist/commands/verify.d.ts.map +1 -0
  137. package/dist/commands/verify.js +126 -0
  138. package/dist/commands/verify.js.map +1 -0
  139. package/dist/config/defaults.d.ts +69 -0
  140. package/dist/config/defaults.d.ts.map +1 -0
  141. package/dist/config/defaults.js +71 -0
  142. package/dist/config/defaults.js.map +1 -0
  143. package/dist/config/load.d.ts +11 -0
  144. package/dist/config/load.d.ts.map +1 -0
  145. package/dist/config/load.js +49 -0
  146. package/dist/config/load.js.map +1 -0
  147. package/dist/config/render.d.ts +9 -0
  148. package/dist/config/render.d.ts.map +1 -0
  149. package/dist/config/render.js +15 -0
  150. package/dist/config/render.js.map +1 -0
  151. package/dist/config/schema.d.ts +124 -0
  152. package/dist/config/schema.d.ts.map +1 -0
  153. package/dist/config/schema.js +142 -0
  154. package/dist/config/schema.js.map +1 -0
  155. package/dist/core/agents-doc.d.ts +80 -0
  156. package/dist/core/agents-doc.d.ts.map +1 -0
  157. package/dist/core/agents-doc.js +207 -0
  158. package/dist/core/agents-doc.js.map +1 -0
  159. package/dist/core/catalog/build.d.ts +49 -0
  160. package/dist/core/catalog/build.d.ts.map +1 -0
  161. package/dist/core/catalog/build.js +113 -0
  162. package/dist/core/catalog/build.js.map +1 -0
  163. package/dist/core/catalog/model.d.ts +33 -0
  164. package/dist/core/catalog/model.d.ts.map +1 -0
  165. package/dist/core/catalog/model.js +58 -0
  166. package/dist/core/catalog/model.js.map +1 -0
  167. package/dist/core/checks/catalog-checks.d.ts +4 -0
  168. package/dist/core/checks/catalog-checks.d.ts.map +1 -0
  169. package/dist/core/checks/catalog-checks.js +65 -0
  170. package/dist/core/checks/catalog-checks.js.map +1 -0
  171. package/dist/core/checks/identity-checks.d.ts +11 -0
  172. package/dist/core/checks/identity-checks.d.ts.map +1 -0
  173. package/dist/core/checks/identity-checks.js +39 -0
  174. package/dist/core/checks/identity-checks.js.map +1 -0
  175. package/dist/core/checks/integrity-checks.d.ts +23 -0
  176. package/dist/core/checks/integrity-checks.d.ts.map +1 -0
  177. package/dist/core/checks/integrity-checks.js +132 -0
  178. package/dist/core/checks/integrity-checks.js.map +1 -0
  179. package/dist/core/checks/manifest.d.ts +7 -0
  180. package/dist/core/checks/manifest.d.ts.map +1 -0
  181. package/dist/core/checks/manifest.js +20 -0
  182. package/dist/core/checks/manifest.js.map +1 -0
  183. package/dist/core/checks/organize-checks.d.ts +18 -0
  184. package/dist/core/checks/organize-checks.d.ts.map +1 -0
  185. package/dist/core/checks/organize-checks.js +97 -0
  186. package/dist/core/checks/organize-checks.js.map +1 -0
  187. package/dist/core/checks/registry.d.ts +24 -0
  188. package/dist/core/checks/registry.d.ts.map +1 -0
  189. package/dist/core/checks/registry.js +33 -0
  190. package/dist/core/checks/registry.js.map +1 -0
  191. package/dist/core/checks/types.d.ts +72 -0
  192. package/dist/core/checks/types.d.ts.map +1 -0
  193. package/dist/core/checks/types.js +4 -0
  194. package/dist/core/checks/types.js.map +1 -0
  195. package/dist/core/checks/write-lifecycle-checks.d.ts +24 -0
  196. package/dist/core/checks/write-lifecycle-checks.d.ts.map +1 -0
  197. package/dist/core/checks/write-lifecycle-checks.js +205 -0
  198. package/dist/core/checks/write-lifecycle-checks.js.map +1 -0
  199. package/dist/core/command.d.ts +23 -0
  200. package/dist/core/command.d.ts.map +1 -0
  201. package/dist/core/command.js +2 -0
  202. package/dist/core/command.js.map +1 -0
  203. package/dist/core/content/canonicalize.d.ts +14 -0
  204. package/dist/core/content/canonicalize.d.ts.map +1 -0
  205. package/dist/core/content/canonicalize.js +34 -0
  206. package/dist/core/content/canonicalize.js.map +1 -0
  207. package/dist/core/conventions.d.ts +21 -0
  208. package/dist/core/conventions.d.ts.map +1 -0
  209. package/dist/core/conventions.js +73 -0
  210. package/dist/core/conventions.js.map +1 -0
  211. package/dist/core/disclosure/model.d.ts +18 -0
  212. package/dist/core/disclosure/model.d.ts.map +1 -0
  213. package/dist/core/disclosure/model.js +45 -0
  214. package/dist/core/disclosure/model.js.map +1 -0
  215. package/dist/core/env.d.ts +40 -0
  216. package/dist/core/env.d.ts.map +1 -0
  217. package/dist/core/env.js +24 -0
  218. package/dist/core/env.js.map +1 -0
  219. package/dist/core/envelope.d.ts +46 -0
  220. package/dist/core/envelope.d.ts.map +1 -0
  221. package/dist/core/envelope.js +21 -0
  222. package/dist/core/envelope.js.map +1 -0
  223. package/dist/core/errors.d.ts +96 -0
  224. package/dist/core/errors.d.ts.map +1 -0
  225. package/dist/core/errors.js +267 -0
  226. package/dist/core/errors.js.map +1 -0
  227. package/dist/core/exit-codes.d.ts +32 -0
  228. package/dist/core/exit-codes.d.ts.map +1 -0
  229. package/dist/core/exit-codes.js +31 -0
  230. package/dist/core/exit-codes.js.map +1 -0
  231. package/dist/core/fs/atomic.d.ts +10 -0
  232. package/dist/core/fs/atomic.d.ts.map +1 -0
  233. package/dist/core/fs/atomic.js +31 -0
  234. package/dist/core/fs/atomic.js.map +1 -0
  235. package/dist/core/fs/fenced-region.d.ts +47 -0
  236. package/dist/core/fs/fenced-region.d.ts.map +1 -0
  237. package/dist/core/fs/fenced-region.js +122 -0
  238. package/dist/core/fs/fenced-region.js.map +1 -0
  239. package/dist/core/git/exec.d.ts +28 -0
  240. package/dist/core/git/exec.d.ts.map +1 -0
  241. package/dist/core/git/exec.js +21 -0
  242. package/dist/core/git/exec.js.map +1 -0
  243. package/dist/core/git/repo.d.ts +63 -0
  244. package/dist/core/git/repo.d.ts.map +1 -0
  245. package/dist/core/git/repo.js +91 -0
  246. package/dist/core/git/repo.js.map +1 -0
  247. package/dist/core/git/staged.d.ts +10 -0
  248. package/dist/core/git/staged.d.ts.map +1 -0
  249. package/dist/core/git/staged.js +49 -0
  250. package/dist/core/git/staged.js.map +1 -0
  251. package/dist/core/git/worktree.d.ts +29 -0
  252. package/dist/core/git/worktree.d.ts.map +1 -0
  253. package/dist/core/git/worktree.js +61 -0
  254. package/dist/core/git/worktree.js.map +1 -0
  255. package/dist/core/graph/model.d.ts +43 -0
  256. package/dist/core/graph/model.d.ts.map +1 -0
  257. package/dist/core/graph/model.js +60 -0
  258. package/dist/core/graph/model.js.map +1 -0
  259. package/dist/core/graph/persist.d.ts +7 -0
  260. package/dist/core/graph/persist.d.ts.map +1 -0
  261. package/dist/core/graph/persist.js +23 -0
  262. package/dist/core/graph/persist.js.map +1 -0
  263. package/dist/core/graph/query.d.ts +16 -0
  264. package/dist/core/graph/query.d.ts.map +1 -0
  265. package/dist/core/graph/query.js +91 -0
  266. package/dist/core/graph/query.js.map +1 -0
  267. package/dist/core/graph/visibility-filter.d.ts +13 -0
  268. package/dist/core/graph/visibility-filter.d.ts.map +1 -0
  269. package/dist/core/graph/visibility-filter.js +26 -0
  270. package/dist/core/graph/visibility-filter.js.map +1 -0
  271. package/dist/core/hooks.d.ts +34 -0
  272. package/dist/core/hooks.d.ts.map +1 -0
  273. package/dist/core/hooks.js +89 -0
  274. package/dist/core/hooks.js.map +1 -0
  275. package/dist/core/identity.d.ts +14 -0
  276. package/dist/core/identity.d.ts.map +1 -0
  277. package/dist/core/identity.js +36 -0
  278. package/dist/core/identity.js.map +1 -0
  279. package/dist/core/ingest/identity.d.ts +15 -0
  280. package/dist/core/ingest/identity.d.ts.map +1 -0
  281. package/dist/core/ingest/identity.js +17 -0
  282. package/dist/core/ingest/identity.js.map +1 -0
  283. package/dist/core/ingest/model.d.ts +17 -0
  284. package/dist/core/ingest/model.d.ts.map +1 -0
  285. package/dist/core/ingest/model.js +24 -0
  286. package/dist/core/ingest/model.js.map +1 -0
  287. package/dist/core/json-config-merge.d.ts +13 -0
  288. package/dist/core/json-config-merge.d.ts.map +1 -0
  289. package/dist/core/json-config-merge.js +43 -0
  290. package/dist/core/json-config-merge.js.map +1 -0
  291. package/dist/core/markers.d.ts +17 -0
  292. package/dist/core/markers.d.ts.map +1 -0
  293. package/dist/core/markers.js +16 -0
  294. package/dist/core/markers.js.map +1 -0
  295. package/dist/core/migrations/registry.d.ts +6 -0
  296. package/dist/core/migrations/registry.d.ts.map +1 -0
  297. package/dist/core/migrations/registry.js +8 -0
  298. package/dist/core/migrations/registry.js.map +1 -0
  299. package/dist/core/migrations/rename-visibility-field.d.ts +3 -0
  300. package/dist/core/migrations/rename-visibility-field.d.ts.map +1 -0
  301. package/dist/core/migrations/rename-visibility-field.js +62 -0
  302. package/dist/core/migrations/rename-visibility-field.js.map +1 -0
  303. package/dist/core/migrations/types.d.ts +27 -0
  304. package/dist/core/migrations/types.d.ts.map +1 -0
  305. package/dist/core/migrations/types.js +2 -0
  306. package/dist/core/migrations/types.js.map +1 -0
  307. package/dist/core/notes/checks.d.ts +20 -0
  308. package/dist/core/notes/checks.d.ts.map +1 -0
  309. package/dist/core/notes/checks.js +58 -0
  310. package/dist/core/notes/checks.js.map +1 -0
  311. package/dist/core/notes/list.d.ts +26 -0
  312. package/dist/core/notes/list.d.ts.map +1 -0
  313. package/dist/core/notes/list.js +84 -0
  314. package/dist/core/notes/list.js.map +1 -0
  315. package/dist/core/notes/parse.d.ts +12 -0
  316. package/dist/core/notes/parse.d.ts.map +1 -0
  317. package/dist/core/notes/parse.js +36 -0
  318. package/dist/core/notes/parse.js.map +1 -0
  319. package/dist/core/notes/render.d.ts +7 -0
  320. package/dist/core/notes/render.d.ts.map +1 -0
  321. package/dist/core/notes/render.js +13 -0
  322. package/dist/core/notes/render.js.map +1 -0
  323. package/dist/core/notes/visibility.d.ts +26 -0
  324. package/dist/core/notes/visibility.d.ts.map +1 -0
  325. package/dist/core/notes/visibility.js +41 -0
  326. package/dist/core/notes/visibility.js.map +1 -0
  327. package/dist/core/procedures.d.ts +44 -0
  328. package/dist/core/procedures.d.ts.map +1 -0
  329. package/dist/core/procedures.js +154 -0
  330. package/dist/core/procedures.js.map +1 -0
  331. package/dist/core/queue.d.ts +16 -0
  332. package/dist/core/queue.d.ts.map +1 -0
  333. package/dist/core/queue.js +75 -0
  334. package/dist/core/queue.js.map +1 -0
  335. package/dist/core/reconcile.d.ts +18 -0
  336. package/dist/core/reconcile.d.ts.map +1 -0
  337. package/dist/core/reconcile.js +49 -0
  338. package/dist/core/reconcile.js.map +1 -0
  339. package/dist/core/records.d.ts +16 -0
  340. package/dist/core/records.d.ts.map +1 -0
  341. package/dist/core/records.js +36 -0
  342. package/dist/core/records.js.map +1 -0
  343. package/dist/core/reporter.d.ts +20 -0
  344. package/dist/core/reporter.d.ts.map +1 -0
  345. package/dist/core/reporter.js +25 -0
  346. package/dist/core/reporter.js.map +1 -0
  347. package/dist/core/root.d.ts +24 -0
  348. package/dist/core/root.d.ts.map +1 -0
  349. package/dist/core/root.js +51 -0
  350. package/dist/core/root.js.map +1 -0
  351. package/dist/core/security/secrets.d.ts +17 -0
  352. package/dist/core/security/secrets.d.ts.map +1 -0
  353. package/dist/core/security/secrets.js +21 -0
  354. package/dist/core/security/secrets.js.map +1 -0
  355. package/dist/core/session.d.ts +15 -0
  356. package/dist/core/session.d.ts.map +1 -0
  357. package/dist/core/session.js +27 -0
  358. package/dist/core/session.js.map +1 -0
  359. package/dist/core/store.d.ts +15 -0
  360. package/dist/core/store.d.ts.map +1 -0
  361. package/dist/core/store.js +19 -0
  362. package/dist/core/store.js.map +1 -0
  363. package/dist/index.d.ts +13 -0
  364. package/dist/index.d.ts.map +1 -0
  365. package/dist/index.js +7 -0
  366. package/dist/index.js.map +1 -0
  367. package/dist/prompt/inquirer-prompter.d.ts +14 -0
  368. package/dist/prompt/inquirer-prompter.d.ts.map +1 -0
  369. package/dist/prompt/inquirer-prompter.js +27 -0
  370. package/dist/prompt/inquirer-prompter.js.map +1 -0
  371. package/dist/prompt/prompter.d.ts +24 -0
  372. package/dist/prompt/prompter.d.ts.map +1 -0
  373. package/dist/prompt/prompter.js +2 -0
  374. package/dist/prompt/prompter.js.map +1 -0
  375. package/dist/run.d.ts +16 -0
  376. package/dist/run.d.ts.map +1 -0
  377. package/dist/run.js +464 -0
  378. package/dist/run.js.map +1 -0
  379. package/dist/taxonomy/profiles.d.ts +31 -0
  380. package/dist/taxonomy/profiles.d.ts.map +1 -0
  381. package/dist/taxonomy/profiles.js +45 -0
  382. package/dist/taxonomy/profiles.js.map +1 -0
  383. package/dist/version.d.ts +3 -0
  384. package/dist/version.d.ts.map +1 -0
  385. package/dist/version.js +3 -0
  386. package/dist/version.js.map +1 -0
  387. package/package.json +56 -0
  388. package/templates/.gitkeep +0 -0
  389. package/templates/hooks/pre-commit.sh +21 -0
  390. package/templates/hooks/pre-push.sh +24 -0
@@ -0,0 +1,63 @@
1
+ import type { GitRunner } from './exec.js';
2
+ /**
3
+ * Enumerates every way contexture is allowed to write via git. `init` is the
4
+ * sole construction site for `'bootstrap'` — there is no session/worktree
5
+ * machinery yet at that point in the store's life. Every later write
6
+ * (Phase 2 onward) uses `'session'`. `'derived'` is never commit-capable —
7
+ * derived artifacts never ride a commit at all. Declaring this now, as a
8
+ * type every commit-capable operation must accept and can reject `'derived'`
9
+ * against, keeps `init`'s direct-commit behavior an enumerated exception
10
+ * rather than a precedent for "just commit directly" to imitate later.
11
+ */
12
+ export type WriteMode = {
13
+ kind: 'bootstrap';
14
+ } | {
15
+ kind: 'session';
16
+ worktree: string;
17
+ branch: string;
18
+ } | {
19
+ kind: 'derived';
20
+ };
21
+ export type ToplevelStatus = {
22
+ kind: 'this-dir';
23
+ toplevel: string;
24
+ } | {
25
+ kind: 'ancestor';
26
+ toplevel: string;
27
+ } | {
28
+ kind: 'none';
29
+ };
30
+ /** Distinguishes "root is already a repo", "root is inside another repo", and "no repo at all". */
31
+ export declare function findToplevel(git: GitRunner, cwd: string): Promise<ToplevelStatus>;
32
+ /** context-store spec: every non-init command refuses to operate on a root not inside a git repo. */
33
+ export declare function isInsideGitRepo(git: GitRunner, cwd: string): Promise<boolean>;
34
+ /**
35
+ * Whether git has an explicit author identity available, from either source
36
+ * it actually uses at commit time: `GIT_AUTHOR_*`/`GIT_COMMITTER_*`
37
+ * env vars, or `git config user.email`/`user.name`. If neither, init
38
+ * refuses (exit 2, naming the two config commands) rather than letting git
39
+ * fall through to its own guessed `user@hostname` identity — that guess is
40
+ * itself the fallback the fail-loud contract forbids, and it would put a
41
+ * fake name in permanent history.
42
+ */
43
+ export declare function hasGitIdentity(git: GitRunner, cwd: string, env: Readonly<Record<string, string | undefined>>): Promise<boolean>;
44
+ export declare function gitInit(git: GitRunner, cwd: string): Promise<void>;
45
+ export declare function currentBranch(git: GitRunner, cwd: string): Promise<string>;
46
+ /** Explicit pathspecs only — never `-A` — so `init` stages exactly the scaffold it wrote. */
47
+ export declare function addPaths(git: GitRunner, cwd: string, paths: readonly string[]): Promise<void>;
48
+ export declare function hasStagedChanges(git: GitRunner, cwd: string): Promise<boolean>;
49
+ /**
50
+ * context-store spec: relocating a note is a single tracked rename, not
51
+ * delete+create — this is what makes `git log --follow` on the new path
52
+ * return the note's full prior history. Used by archive (Phase 7).
53
+ */
54
+ export declare function movePath(git: GitRunner, cwd: string, from: string, to: string): Promise<void>;
55
+ /** Whether `relativePath` is tracked by git — `git mv` refuses an untracked path, so callers check this first to fail with a specific, named error instead of a raw git stderr passthrough. */
56
+ export declare function isTracked(git: GitRunner, cwd: string, relativePath: string): Promise<boolean>;
57
+ /** Skips the commit (returns null) when nothing is staged — what makes re-init idempotent. */
58
+ export declare function commitIfStaged(git: GitRunner, cwd: string, mode: WriteMode, message: string): Promise<string | null>;
59
+ /** Pushes a session branch to the remote — never the default branch, which the installed hook refuses anyway. */
60
+ export declare function pushBranch(git: GitRunner, cwd: string, branch: string, remote?: string): Promise<void>;
61
+ /** Whole-tree dirty check (staged AND unstaged) — distinct from hasStagedChanges, used by session reap. */
62
+ export declare function isWorkingTreeClean(git: GitRunner, cwd: string): Promise<boolean>;
63
+ //# sourceMappingURL=repo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../src/core/git/repo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,mGAAmG;AACnG,wBAAsB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAQvF;AAED,qGAAqG;AACrG,wBAAsB,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnF;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAChD,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF;AAED,6FAA6F;AAC7F,wBAAsB,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnG;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpF;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnG;AAED,+LAA+L;AAC/L,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnG;AAED,8FAA8F;AAC9F,wBAAsB,cAAc,CAClC,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQxB;AAED,iHAAiH;AACjH,wBAAsB,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9G;AAED,2GAA2G;AAC3G,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtF"}
@@ -0,0 +1,91 @@
1
+ import path from 'node:path';
2
+ /** Distinguishes "root is already a repo", "root is inside another repo", and "no repo at all". */
3
+ export async function findToplevel(git, cwd) {
4
+ const result = await git.run(['rev-parse', '--show-toplevel'], { cwd, allowFailure: true });
5
+ if (result.exitCode !== 0)
6
+ return { kind: 'none' };
7
+ const toplevel = result.stdout.trim();
8
+ if (path.resolve(toplevel) === path.resolve(cwd)) {
9
+ return { kind: 'this-dir', toplevel };
10
+ }
11
+ return { kind: 'ancestor', toplevel };
12
+ }
13
+ /** context-store spec: every non-init command refuses to operate on a root not inside a git repo. */
14
+ export async function isInsideGitRepo(git, cwd) {
15
+ const result = await git.run(['rev-parse', '--is-inside-work-tree'], { cwd, allowFailure: true });
16
+ return result.exitCode === 0 && result.stdout.trim() === 'true';
17
+ }
18
+ /**
19
+ * Whether git has an explicit author identity available, from either source
20
+ * it actually uses at commit time: `GIT_AUTHOR_*`/`GIT_COMMITTER_*`
21
+ * env vars, or `git config user.email`/`user.name`. If neither, init
22
+ * refuses (exit 2, naming the two config commands) rather than letting git
23
+ * fall through to its own guessed `user@hostname` identity — that guess is
24
+ * itself the fallback the fail-loud contract forbids, and it would put a
25
+ * fake name in permanent history.
26
+ */
27
+ export async function hasGitIdentity(git, cwd, env) {
28
+ const hasCompleteEnvIdentity = Boolean(env.GIT_AUTHOR_NAME && env.GIT_AUTHOR_EMAIL && env.GIT_COMMITTER_NAME && env.GIT_COMMITTER_EMAIL);
29
+ if (hasCompleteEnvIdentity)
30
+ return true;
31
+ const email = await git.run(['config', 'user.email'], { cwd, allowFailure: true });
32
+ const name = await git.run(['config', 'user.name'], { cwd, allowFailure: true });
33
+ return (email.exitCode === 0 &&
34
+ email.stdout.trim().length > 0 &&
35
+ name.exitCode === 0 &&
36
+ name.stdout.trim().length > 0);
37
+ }
38
+ export async function gitInit(git, cwd) {
39
+ // Deliberately no `-b <name>`: the operator's own `init.defaultBranch`
40
+ // config wins. The branch name is learned afterward via `currentBranch`,
41
+ // so nothing in this codebase hardcodes "main".
42
+ await git.run(['init'], { cwd });
43
+ }
44
+ export async function currentBranch(git, cwd) {
45
+ const result = await git.run(['symbolic-ref', '--short', 'HEAD'], { cwd });
46
+ return result.stdout.trim();
47
+ }
48
+ /** Explicit pathspecs only — never `-A` — so `init` stages exactly the scaffold it wrote. */
49
+ export async function addPaths(git, cwd, paths) {
50
+ if (paths.length === 0)
51
+ return;
52
+ await git.run(['add', '--', ...paths], { cwd });
53
+ }
54
+ export async function hasStagedChanges(git, cwd) {
55
+ const result = await git.run(['diff', '--cached', '--quiet'], { cwd, allowFailure: true });
56
+ return result.exitCode === 1; // git diff --quiet: 0 = no differences, 1 = differences found
57
+ }
58
+ /**
59
+ * context-store spec: relocating a note is a single tracked rename, not
60
+ * delete+create — this is what makes `git log --follow` on the new path
61
+ * return the note's full prior history. Used by archive (Phase 7).
62
+ */
63
+ export async function movePath(git, cwd, from, to) {
64
+ await git.run(['mv', from, to], { cwd });
65
+ }
66
+ /** Whether `relativePath` is tracked by git — `git mv` refuses an untracked path, so callers check this first to fail with a specific, named error instead of a raw git stderr passthrough. */
67
+ export async function isTracked(git, cwd, relativePath) {
68
+ const result = await git.run(['ls-files', '--error-unmatch', '--', relativePath], { cwd, allowFailure: true });
69
+ return result.exitCode === 0;
70
+ }
71
+ /** Skips the commit (returns null) when nothing is staged — what makes re-init idempotent. */
72
+ export async function commitIfStaged(git, cwd, mode, message) {
73
+ if (mode.kind === 'derived') {
74
+ throw new Error('Internal error: attempted to commit with WriteMode "derived".');
75
+ }
76
+ if (!(await hasStagedChanges(git, cwd)))
77
+ return null;
78
+ await git.run(['commit', '-m', message], { cwd });
79
+ const result = await git.run(['rev-parse', 'HEAD'], { cwd });
80
+ return result.stdout.trim();
81
+ }
82
+ /** Pushes a session branch to the remote — never the default branch, which the installed hook refuses anyway. */
83
+ export async function pushBranch(git, cwd, branch, remote = 'origin') {
84
+ await git.run(['push', '--set-upstream', remote, branch], { cwd });
85
+ }
86
+ /** Whole-tree dirty check (staged AND unstaged) — distinct from hasStagedChanges, used by session reap. */
87
+ export async function isWorkingTreeClean(git, cwd) {
88
+ const result = await git.run(['status', '--porcelain'], { cwd });
89
+ return result.stdout.trim().length === 0;
90
+ }
91
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../../../src/core/git/repo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { StagedFile } from '../checks/types.js';
2
+ import type { GitRunner } from './exec.js';
3
+ /**
4
+ * Gathers every staged (index) change: path, status, added/removed line
5
+ * counts, and (for non-deleted files under a size cap) the staged content
6
+ * itself — computed once, up front, so each staged-scope check is a pure
7
+ * function of the CheckContext rather than re-invoking git per check.
8
+ */
9
+ export declare function getStagedFiles(git: GitRunner, cwd: string): Promise<StagedFile[]>;
10
+ //# sourceMappingURL=staged.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staged.d.ts","sourceRoot":"","sources":["../../../src/core/git/staged.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAU3C;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuCvF"}
@@ -0,0 +1,49 @@
1
+ const MAX_CONTENT_BYTES = 2 * 1024 * 1024; // 2MB — large staged files aren't scanned, not silently skipped-and-passed
2
+ function parseStatusLetter(code) {
3
+ const letter = code.charAt(0);
4
+ if (letter === 'A' || letter === 'M' || letter === 'D' || letter === 'R')
5
+ return letter;
6
+ return '?';
7
+ }
8
+ /**
9
+ * Gathers every staged (index) change: path, status, added/removed line
10
+ * counts, and (for non-deleted files under a size cap) the staged content
11
+ * itself — computed once, up front, so each staged-scope check is a pure
12
+ * function of the CheckContext rather than re-invoking git per check.
13
+ */
14
+ export async function getStagedFiles(git, cwd) {
15
+ const [statusResult, numstatResult] = await Promise.all([
16
+ git.run(['diff', '--cached', '--name-status'], { cwd }),
17
+ git.run(['diff', '--cached', '--numstat'], { cwd }),
18
+ ]);
19
+ const statusByPath = new Map();
20
+ for (const line of statusResult.stdout.split('\n').filter(Boolean)) {
21
+ const fields = line.split('\t');
22
+ const code = fields[0];
23
+ const targetPath = fields[fields.length - 1]; // renames: "R100\told\tnew" — last field is the new path
24
+ statusByPath.set(targetPath, parseStatusLetter(code));
25
+ }
26
+ const files = [];
27
+ for (const line of numstatResult.stdout.split('\n').filter(Boolean)) {
28
+ const fields = line.split('\t');
29
+ const added = fields[0];
30
+ const removed = fields[1];
31
+ const targetPath = fields.slice(2).join('\t');
32
+ files.push({
33
+ path: targetPath,
34
+ status: statusByPath.get(targetPath) ?? '?',
35
+ addedLines: added === '-' ? null : Number(added),
36
+ removedLines: removed === '-' ? null : Number(removed),
37
+ });
38
+ }
39
+ await Promise.all(files.map(async (file) => {
40
+ if (file.status === 'D')
41
+ return;
42
+ const result = await git.run(['show', `:${file.path}`], { cwd, allowFailure: true });
43
+ if (result.exitCode === 0 && Buffer.byteLength(result.stdout, 'utf8') <= MAX_CONTENT_BYTES) {
44
+ file.content = result.stdout;
45
+ }
46
+ }));
47
+ return files;
48
+ }
49
+ //# sourceMappingURL=staged.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staged.js","sourceRoot":"","sources":["../../../src/core/git/staged.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { GitRunner } from './exec.js';
2
+ export declare function hasRemote(git: GitRunner, cwd: string, name?: string): Promise<boolean>;
3
+ /**
4
+ * write-lifecycle spec: a session worktree is cut from a freshly fetched
5
+ * default branch, when a remote exists. Returns false (rather than
6
+ * throwing) when the fetch doesn't succeed — most commonly a remote that
7
+ * exists but is still empty (nothing pushed yet, the common case for a
8
+ * brand-new project) — so the caller can degrade to the local branch
9
+ * instead of crashing on an honest, expected state.
10
+ */
11
+ export declare function fetchOrigin(git: GitRunner, cwd: string, branch: string, remote?: string): Promise<boolean>;
12
+ export declare function addWorktree(git: GitRunner, cwd: string, worktreePath: string, newBranch: string, startPoint: string): Promise<void>;
13
+ export declare function removeWorktree(git: GitRunner, cwd: string, worktreePath: string, opts?: {
14
+ force?: boolean;
15
+ }): Promise<void>;
16
+ export declare function pruneWorktrees(git: GitRunner, cwd: string): Promise<void>;
17
+ export declare function deleteBranch(git: GitRunner, cwd: string, branch: string, opts?: {
18
+ force?: boolean;
19
+ }): Promise<void>;
20
+ export interface WorktreeInfo {
21
+ path: string;
22
+ branch: string | null;
23
+ head: string;
24
+ locked: boolean;
25
+ }
26
+ /** Parses `git worktree list --porcelain`'s block format (blocks separated by a blank line). */
27
+ export declare function parseWorktreeList(porcelain: string): WorktreeInfo[];
28
+ export declare function listWorktrees(git: GitRunner, cwd: string): Promise<WorktreeInfo[]>;
29
+ //# sourceMappingURL=worktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../../src/core/git/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,wBAAsB,SAAS,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAI9F;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlH;AAED,wBAAsB,WAAW,CAC/B,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,cAAc,CAClC,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE,CAkBnE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAGxF"}
@@ -0,0 +1,61 @@
1
+ export async function hasRemote(git, cwd, name = 'origin') {
2
+ const result = await git.run(['remote'], { cwd, allowFailure: true });
3
+ if (result.exitCode !== 0)
4
+ return false;
5
+ return result.stdout.split('\n').includes(name);
6
+ }
7
+ /**
8
+ * write-lifecycle spec: a session worktree is cut from a freshly fetched
9
+ * default branch, when a remote exists. Returns false (rather than
10
+ * throwing) when the fetch doesn't succeed — most commonly a remote that
11
+ * exists but is still empty (nothing pushed yet, the common case for a
12
+ * brand-new project) — so the caller can degrade to the local branch
13
+ * instead of crashing on an honest, expected state.
14
+ */
15
+ export async function fetchOrigin(git, cwd, branch, remote = 'origin') {
16
+ const result = await git.run(['fetch', remote, branch], { cwd, allowFailure: true });
17
+ return result.exitCode === 0;
18
+ }
19
+ export async function addWorktree(git, cwd, worktreePath, newBranch, startPoint) {
20
+ await git.run(['worktree', 'add', '-b', newBranch, worktreePath, startPoint], { cwd });
21
+ }
22
+ export async function removeWorktree(git, cwd, worktreePath, opts = {}) {
23
+ const args = ['worktree', 'remove', worktreePath, ...(opts.force ? ['--force'] : [])];
24
+ await git.run(args, { cwd });
25
+ }
26
+ export async function pruneWorktrees(git, cwd) {
27
+ await git.run(['worktree', 'prune'], { cwd });
28
+ }
29
+ export async function deleteBranch(git, cwd, branch, opts = {}) {
30
+ await git.run(['branch', opts.force ? '-D' : '-d', branch], { cwd });
31
+ }
32
+ /** Parses `git worktree list --porcelain`'s block format (blocks separated by a blank line). */
33
+ export function parseWorktreeList(porcelain) {
34
+ const blocks = porcelain.split('\n\n').map((b) => b.trim()).filter(Boolean);
35
+ const infos = [];
36
+ for (const block of blocks) {
37
+ const lines = block.split('\n');
38
+ let worktreePath = '';
39
+ let head = '';
40
+ let branch = null;
41
+ let locked = false;
42
+ for (const line of lines) {
43
+ if (line.startsWith('worktree '))
44
+ worktreePath = line.slice('worktree '.length);
45
+ else if (line.startsWith('HEAD '))
46
+ head = line.slice('HEAD '.length);
47
+ else if (line.startsWith('branch '))
48
+ branch = line.slice('branch '.length).replace(/^refs\/heads\//, '');
49
+ else if (line === 'locked' || line.startsWith('locked '))
50
+ locked = true;
51
+ }
52
+ if (worktreePath)
53
+ infos.push({ path: worktreePath, branch, head, locked });
54
+ }
55
+ return infos;
56
+ }
57
+ export async function listWorktrees(git, cwd) {
58
+ const result = await git.run(['worktree', 'list', '--porcelain'], { cwd });
59
+ return parseWorktreeList(result.stdout);
60
+ }
61
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../../src/core/git/worktree.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { Note } from '../notes/list.js';
2
+ /**
3
+ * context-retrieval spec: node identity is the note's path relative to the
4
+ * store root — never the filename stem — so two notes sharing a filename in
5
+ * different directories are two distinct nodes (the failure mode this
6
+ * fixes: pkm's original stem-based graph silently merged such notes).
7
+ */
8
+ export interface GraphNode {
9
+ id: string;
10
+ path: string;
11
+ }
12
+ export type DanglingReason = 'not_found' | 'ambiguous';
13
+ export interface DanglingLink {
14
+ from: string;
15
+ target: string;
16
+ reason: DanglingReason;
17
+ }
18
+ export interface GraphEdge {
19
+ src: string;
20
+ dst: string;
21
+ type: 'link';
22
+ }
23
+ export interface GraphBuildResult {
24
+ nodes: GraphNode[];
25
+ edges: GraphEdge[];
26
+ dangling: DanglingLink[];
27
+ }
28
+ export declare function extractLinkTargets(body: string): string[];
29
+ /**
30
+ * Builds the graph from an in-memory note list, so the fatal-collision path
31
+ * is directly testable by injecting two notes with an identical `.path` —
32
+ * a real `listNotes()` result can never produce this (paths are unique
33
+ * filesystem keys), so this is a defensive check on the invariant, not a
34
+ * scenario reachable through normal use.
35
+ *
36
+ * Wikilinks are resolved by filename stem (Obsidian's own convention, which
37
+ * pkm's content already relies on). An AMBIGUOUS stem — two notes sharing a
38
+ * filename — does not fail the build; it degrades to a reported dangling
39
+ * link, consistent with "two same-named notes are a valid, expected state"
40
+ * (the node-identity requirement's own scenario).
41
+ */
42
+ export declare function buildGraphFromNotes(notes: readonly Note[]): GraphBuildResult;
43
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/core/graph/model.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,gBAAgB,CAkC5E"}
@@ -0,0 +1,60 @@
1
+ import path from 'node:path';
2
+ import { GraphIdentityCollisionError } from '../errors.js';
3
+ const WIKILINK_RE = /\[\[([^\]|#]+)/g;
4
+ export function extractLinkTargets(body) {
5
+ const targets = [];
6
+ let match;
7
+ WIKILINK_RE.lastIndex = 0;
8
+ while ((match = WIKILINK_RE.exec(body))) {
9
+ targets.push(match[1].trim());
10
+ }
11
+ return targets;
12
+ }
13
+ /**
14
+ * Builds the graph from an in-memory note list, so the fatal-collision path
15
+ * is directly testable by injecting two notes with an identical `.path` —
16
+ * a real `listNotes()` result can never produce this (paths are unique
17
+ * filesystem keys), so this is a defensive check on the invariant, not a
18
+ * scenario reachable through normal use.
19
+ *
20
+ * Wikilinks are resolved by filename stem (Obsidian's own convention, which
21
+ * pkm's content already relies on). An AMBIGUOUS stem — two notes sharing a
22
+ * filename — does not fail the build; it degrades to a reported dangling
23
+ * link, consistent with "two same-named notes are a valid, expected state"
24
+ * (the node-identity requirement's own scenario).
25
+ */
26
+ export function buildGraphFromNotes(notes) {
27
+ const idCounts = new Map();
28
+ for (const note of notes)
29
+ idCounts.set(note.path, (idCounts.get(note.path) ?? 0) + 1);
30
+ const collisions = [...idCounts.entries()].filter(([, count]) => count > 1).map(([id]) => id);
31
+ if (collisions.length > 0) {
32
+ throw new GraphIdentityCollisionError(collisions);
33
+ }
34
+ const stemIndex = new Map();
35
+ for (const note of notes) {
36
+ const stem = path.basename(note.path, '.md');
37
+ const list = stemIndex.get(stem) ?? [];
38
+ list.push(note.path);
39
+ stemIndex.set(stem, list);
40
+ }
41
+ const nodes = notes.map((n) => ({ id: n.path, path: n.path }));
42
+ const edges = [];
43
+ const dangling = [];
44
+ for (const note of notes) {
45
+ for (const target of extractLinkTargets(note.body)) {
46
+ const resolved = stemIndex.get(target);
47
+ if (!resolved) {
48
+ dangling.push({ from: note.path, target, reason: 'not_found' });
49
+ }
50
+ else if (resolved.length > 1) {
51
+ dangling.push({ from: note.path, target, reason: 'ambiguous' });
52
+ }
53
+ else {
54
+ edges.push({ src: note.path, dst: resolved[0], type: 'link' });
55
+ }
56
+ }
57
+ }
58
+ return { nodes, edges, dangling };
59
+ }
60
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/graph/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Store } from '../store.js';
2
+ import type { GraphBuildResult } from './model.js';
3
+ /** A derived artifact, atomically written, under the home directory's cache subpath (the default derived path). */
4
+ export declare function graphFilePath(store: Store): string;
5
+ export declare function writeGraph(store: Store, graph: GraphBuildResult): Promise<void>;
6
+ export declare function readGraph(store: Store): Promise<GraphBuildResult | null>;
7
+ //# sourceMappingURL=persist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../../src/core/graph/persist.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,mHAAmH;AACnH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAElD;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAO9E"}
@@ -0,0 +1,23 @@
1
+ import { mkdir, readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { writeFileAtomic } from '../fs/atomic.js';
4
+ /** A derived artifact, atomically written, under the home directory's cache subpath (the default derived path). */
5
+ export function graphFilePath(store) {
6
+ return path.join(store.root, '.contexture', 'cache', 'graph.json');
7
+ }
8
+ export async function writeGraph(store, graph) {
9
+ const filePath = graphFilePath(store);
10
+ await mkdir(path.dirname(filePath), { recursive: true });
11
+ await writeFileAtomic(filePath, `${JSON.stringify(graph, null, 2)}\n`);
12
+ }
13
+ export async function readGraph(store) {
14
+ try {
15
+ return JSON.parse(await readFile(graphFilePath(store), 'utf8'));
16
+ }
17
+ catch (err) {
18
+ if (err.code === 'ENOENT')
19
+ return null;
20
+ throw err;
21
+ }
22
+ }
23
+ //# sourceMappingURL=persist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.js","sourceRoot":"","sources":["../../../src/core/graph/persist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD,mHAAmH;AACnH,MAAM,UAAU,aAAa,CAAC,KAAY;IACxC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAY,EAAE,KAAuB;IACpE,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,eAAe,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAY;IAC1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAqB,CAAC;IACtF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAClE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { GraphBuildResult } from './model.js';
2
+ export type Direction = 'in' | 'out' | 'both';
3
+ export interface NeighborsOptions {
4
+ depth?: number;
5
+ direction?: Direction;
6
+ }
7
+ export declare function neighbors(graph: GraphBuildResult, nodeId: string, opts?: NeighborsOptions): string[];
8
+ export declare function shortestPath(graph: GraphBuildResult, from: string, to: string): string[] | null;
9
+ export interface HubEntry {
10
+ id: string;
11
+ backlinks: number;
12
+ }
13
+ export declare function hubs(graph: GraphBuildResult, top: number): HubEntry[];
14
+ export declare function orphans(graph: GraphBuildResult): string[];
15
+ export declare function subgraph(graph: GraphBuildResult, ids: readonly string[]): GraphBuildResult;
16
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/core/graph/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAgB9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,MAAM,EAAE,CAoBxG;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CA0B/F;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,CAQrE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAOzD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAO1F"}
@@ -0,0 +1,91 @@
1
+ function buildAdjacency(graph, direction) {
2
+ const adjacency = new Map();
3
+ const add = (a, b) => {
4
+ const list = adjacency.get(a) ?? [];
5
+ list.push(b);
6
+ adjacency.set(a, list);
7
+ };
8
+ for (const edge of graph.edges) {
9
+ if (direction === 'out' || direction === 'both')
10
+ add(edge.src, edge.dst);
11
+ if (direction === 'in' || direction === 'both')
12
+ add(edge.dst, edge.src);
13
+ }
14
+ return adjacency;
15
+ }
16
+ export function neighbors(graph, nodeId, opts = {}) {
17
+ const depth = opts.depth ?? 1;
18
+ const adjacency = buildAdjacency(graph, opts.direction ?? 'both');
19
+ let frontier = new Set([nodeId]);
20
+ const visited = new Set([nodeId]);
21
+ for (let i = 0; i < depth && frontier.size > 0; i += 1) {
22
+ const next = new Set();
23
+ for (const id of frontier) {
24
+ for (const neighbor of adjacency.get(id) ?? []) {
25
+ if (!visited.has(neighbor)) {
26
+ next.add(neighbor);
27
+ visited.add(neighbor);
28
+ }
29
+ }
30
+ }
31
+ frontier = next;
32
+ }
33
+ visited.delete(nodeId);
34
+ return [...visited].sort();
35
+ }
36
+ export function shortestPath(graph, from, to) {
37
+ if (from === to)
38
+ return [from];
39
+ const adjacency = buildAdjacency(graph, 'both');
40
+ const queue = [from];
41
+ const cameFrom = new Map();
42
+ const visited = new Set([from]);
43
+ while (queue.length > 0) {
44
+ const current = queue.shift();
45
+ for (const neighbor of adjacency.get(current) ?? []) {
46
+ if (visited.has(neighbor))
47
+ continue;
48
+ visited.add(neighbor);
49
+ cameFrom.set(neighbor, current);
50
+ if (neighbor === to) {
51
+ const result = [to];
52
+ let node = to;
53
+ while (cameFrom.has(node)) {
54
+ node = cameFrom.get(node);
55
+ result.unshift(node);
56
+ }
57
+ return result;
58
+ }
59
+ queue.push(neighbor);
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ export function hubs(graph, top) {
65
+ const counts = new Map();
66
+ for (const node of graph.nodes)
67
+ counts.set(node.id, 0);
68
+ for (const edge of graph.edges)
69
+ counts.set(edge.dst, (counts.get(edge.dst) ?? 0) + 1);
70
+ return [...counts.entries()]
71
+ .map(([id, backlinks]) => ({ id, backlinks }))
72
+ .sort((a, b) => b.backlinks - a.backlinks || a.id.localeCompare(b.id))
73
+ .slice(0, top);
74
+ }
75
+ export function orphans(graph) {
76
+ const linked = new Set();
77
+ for (const edge of graph.edges) {
78
+ linked.add(edge.src);
79
+ linked.add(edge.dst);
80
+ }
81
+ return graph.nodes.map((n) => n.id).filter((id) => !linked.has(id)).sort();
82
+ }
83
+ export function subgraph(graph, ids) {
84
+ const idSet = new Set(ids);
85
+ return {
86
+ nodes: graph.nodes.filter((n) => idSet.has(n.id)),
87
+ edges: graph.edges.filter((e) => idSet.has(e.src) && idSet.has(e.dst)),
88
+ dangling: graph.dangling.filter((d) => idSet.has(d.from)),
89
+ };
90
+ }
91
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/core/graph/query.ts"],"names":[],"mappings":"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"}