ctxr-cli 0.4.1 → 0.6.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 (235) hide show
  1. package/dist/adapter.d.ts +0 -1
  2. package/dist/adapter.d.ts.map +1 -1
  3. package/dist/adapter.js.map +1 -1
  4. package/dist/adapters/builtin/index.d.ts.map +1 -1
  5. package/dist/adapters/builtin/index.js +2 -2
  6. package/dist/adapters/builtin/index.js.map +1 -1
  7. package/dist/adapters/harness/claude-code.d.ts.map +1 -1
  8. package/dist/adapters/harness/claude-code.js +30 -14
  9. package/dist/adapters/harness/claude-code.js.map +1 -1
  10. package/dist/adapters/harness/hermes-agent.d.ts +9 -0
  11. package/dist/adapters/harness/hermes-agent.d.ts.map +1 -0
  12. package/dist/adapters/harness/hermes-agent.js +13 -0
  13. package/dist/adapters/harness/hermes-agent.js.map +1 -0
  14. package/dist/adapters/types.d.ts +39 -18
  15. package/dist/adapters/types.d.ts.map +1 -1
  16. package/dist/adapters/types.js +3 -3
  17. package/dist/adapters/types.js.map +1 -1
  18. package/dist/commands/adapters-generate.d.ts +4 -2
  19. package/dist/commands/adapters-generate.d.ts.map +1 -1
  20. package/dist/commands/adapters-generate.js +14 -6
  21. package/dist/commands/adapters-generate.js.map +1 -1
  22. package/dist/commands/archive.d.ts +4 -2
  23. package/dist/commands/archive.d.ts.map +1 -1
  24. package/dist/commands/archive.js +5 -3
  25. package/dist/commands/archive.js.map +1 -1
  26. package/dist/commands/check.d.ts.map +1 -1
  27. package/dist/commands/check.js +1 -6
  28. package/dist/commands/check.js.map +1 -1
  29. package/dist/commands/init.d.ts +2 -0
  30. package/dist/commands/init.d.ts.map +1 -1
  31. package/dist/commands/init.js +132 -18
  32. package/dist/commands/init.js.map +1 -1
  33. package/dist/commands/publish-check.d.ts +23 -0
  34. package/dist/commands/publish-check.d.ts.map +1 -0
  35. package/dist/commands/publish-check.js +116 -0
  36. package/dist/commands/publish-check.js.map +1 -0
  37. package/dist/commands/publish-gather.d.ts +37 -0
  38. package/dist/commands/publish-gather.d.ts.map +1 -0
  39. package/dist/commands/publish-gather.js +92 -0
  40. package/dist/commands/publish-gather.js.map +1 -0
  41. package/dist/commands/publish-new.d.ts +18 -0
  42. package/dist/commands/publish-new.d.ts.map +1 -0
  43. package/dist/commands/publish-new.js +86 -0
  44. package/dist/commands/publish-new.js.map +1 -0
  45. package/dist/commands/rollup-write.d.ts.map +1 -1
  46. package/dist/commands/rollup-write.js +8 -0
  47. package/dist/commands/rollup-write.js.map +1 -1
  48. package/dist/commands/serve.d.ts +32 -0
  49. package/dist/commands/serve.d.ts.map +1 -0
  50. package/dist/commands/serve.js +170 -0
  51. package/dist/commands/serve.js.map +1 -0
  52. package/dist/commands/update.js +3 -3
  53. package/dist/commands/update.js.map +1 -1
  54. package/dist/commands/verify.d.ts +9 -2
  55. package/dist/commands/verify.d.ts.map +1 -1
  56. package/dist/commands/verify.js +46 -23
  57. package/dist/commands/verify.js.map +1 -1
  58. package/dist/config/defaults.d.ts +53 -15
  59. package/dist/config/defaults.d.ts.map +1 -1
  60. package/dist/config/defaults.js +54 -19
  61. package/dist/config/defaults.js.map +1 -1
  62. package/dist/config/schema.d.ts +49 -12
  63. package/dist/config/schema.d.ts.map +1 -1
  64. package/dist/config/schema.js +115 -23
  65. package/dist/config/schema.js.map +1 -1
  66. package/dist/core/agents-doc.d.ts +63 -12
  67. package/dist/core/agents-doc.d.ts.map +1 -1
  68. package/dist/core/agents-doc.js +191 -41
  69. package/dist/core/agents-doc.js.map +1 -1
  70. package/dist/core/browse/link-resolver.d.ts +12 -0
  71. package/dist/core/browse/link-resolver.d.ts.map +1 -0
  72. package/dist/core/browse/link-resolver.js +12 -0
  73. package/dist/core/browse/link-resolver.js.map +1 -0
  74. package/dist/core/browse/render.d.ts +5 -0
  75. package/dist/core/browse/render.d.ts.map +1 -0
  76. package/dist/core/browse/render.js +66 -0
  77. package/dist/core/browse/render.js.map +1 -0
  78. package/dist/core/browse/routes.d.ts +31 -0
  79. package/dist/core/browse/routes.d.ts.map +1 -0
  80. package/dist/core/browse/routes.js +56 -0
  81. package/dist/core/browse/routes.js.map +1 -0
  82. package/dist/core/browse/templates.d.ts +4 -0
  83. package/dist/core/browse/templates.d.ts.map +1 -0
  84. package/dist/core/browse/templates.js +26 -0
  85. package/dist/core/browse/templates.js.map +1 -0
  86. package/dist/core/checks/harness-portability-checks.d.ts +12 -0
  87. package/dist/core/checks/harness-portability-checks.d.ts.map +1 -0
  88. package/dist/core/checks/harness-portability-checks.js +39 -0
  89. package/dist/core/checks/harness-portability-checks.js.map +1 -0
  90. package/dist/core/checks/integrity-checks.d.ts +43 -3
  91. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  92. package/dist/core/checks/integrity-checks.js +191 -13
  93. package/dist/core/checks/integrity-checks.js.map +1 -1
  94. package/dist/core/checks/manifest.d.ts.map +1 -1
  95. package/dist/core/checks/manifest.js +2 -0
  96. package/dist/core/checks/manifest.js.map +1 -1
  97. package/dist/core/checks/organize-checks.d.ts +21 -1
  98. package/dist/core/checks/organize-checks.d.ts.map +1 -1
  99. package/dist/core/checks/organize-checks.js +64 -4
  100. package/dist/core/checks/organize-checks.js.map +1 -1
  101. package/dist/core/convention-doc.d.ts +32 -0
  102. package/dist/core/convention-doc.d.ts.map +1 -0
  103. package/dist/core/convention-doc.js +137 -0
  104. package/dist/core/convention-doc.js.map +1 -0
  105. package/dist/core/conventions.d.ts +25 -5
  106. package/dist/core/conventions.d.ts.map +1 -1
  107. package/dist/core/conventions.js +65 -3
  108. package/dist/core/conventions.js.map +1 -1
  109. package/dist/core/disclosure/model.d.ts +11 -0
  110. package/dist/core/disclosure/model.d.ts.map +1 -1
  111. package/dist/core/disclosure/model.js +24 -0
  112. package/dist/core/disclosure/model.js.map +1 -1
  113. package/dist/core/errors.d.ts +27 -41
  114. package/dist/core/errors.d.ts.map +1 -1
  115. package/dist/core/errors.js +76 -119
  116. package/dist/core/errors.js.map +1 -1
  117. package/dist/core/fs/fenced-region.d.ts +38 -0
  118. package/dist/core/fs/fenced-region.d.ts.map +1 -1
  119. package/dist/core/fs/fenced-region.js +88 -2
  120. package/dist/core/fs/fenced-region.js.map +1 -1
  121. package/dist/core/git/repo.d.ts +0 -6
  122. package/dist/core/git/repo.d.ts.map +1 -1
  123. package/dist/core/git/repo.js +0 -13
  124. package/dist/core/git/repo.js.map +1 -1
  125. package/dist/core/git/worktree.d.ts +4 -7
  126. package/dist/core/git/worktree.d.ts.map +1 -1
  127. package/dist/core/git/worktree.js +4 -10
  128. package/dist/core/git/worktree.js.map +1 -1
  129. package/dist/core/graph/model.d.ts +14 -0
  130. package/dist/core/graph/model.d.ts.map +1 -1
  131. package/dist/core/graph/model.js +30 -14
  132. package/dist/core/graph/model.js.map +1 -1
  133. package/dist/core/harness/bridge.d.ts +30 -0
  134. package/dist/core/harness/bridge.d.ts.map +1 -0
  135. package/dist/core/harness/bridge.js +178 -0
  136. package/dist/core/harness/bridge.js.map +1 -0
  137. package/dist/core/json-config-merge.d.ts.map +1 -1
  138. package/dist/core/json-config-merge.js +30 -7
  139. package/dist/core/json-config-merge.js.map +1 -1
  140. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts +35 -0
  141. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts.map +1 -0
  142. package/dist/core/migrations/archive-destination-from-taxonomy.js +109 -0
  143. package/dist/core/migrations/archive-destination-from-taxonomy.js.map +1 -0
  144. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts +19 -0
  145. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts.map +1 -0
  146. package/dist/core/migrations/drop-forge-and-workspaces-external.js +49 -0
  147. package/dist/core/migrations/drop-forge-and-workspaces-external.js.map +1 -0
  148. package/dist/core/migrations/registry.d.ts.map +1 -1
  149. package/dist/core/migrations/registry.js +10 -1
  150. package/dist/core/migrations/registry.js.map +1 -1
  151. package/dist/core/migrations/rename-conventions-path.d.ts +26 -0
  152. package/dist/core/migrations/rename-conventions-path.d.ts.map +1 -0
  153. package/dist/core/migrations/rename-conventions-path.js +86 -0
  154. package/dist/core/migrations/rename-conventions-path.js.map +1 -0
  155. package/dist/core/notes/list.d.ts.map +1 -1
  156. package/dist/core/notes/list.js +7 -3
  157. package/dist/core/notes/list.js.map +1 -1
  158. package/dist/core/publish/script-check.d.ts +12 -0
  159. package/dist/core/publish/script-check.d.ts.map +1 -0
  160. package/dist/core/publish/script-check.js +39 -0
  161. package/dist/core/publish/script-check.js.map +1 -0
  162. package/dist/core/reconcile.d.ts +3 -0
  163. package/dist/core/reconcile.d.ts.map +1 -1
  164. package/dist/core/reconcile.js +43 -6
  165. package/dist/core/reconcile.js.map +1 -1
  166. package/dist/core/rollup.d.ts +2 -2
  167. package/dist/core/rollup.d.ts.map +1 -1
  168. package/dist/core/rollup.js +24 -3
  169. package/dist/core/rollup.js.map +1 -1
  170. package/dist/core/session.d.ts +9 -9
  171. package/dist/core/session.js +9 -9
  172. package/dist/core/skills.d.ts +36 -0
  173. package/dist/core/skills.d.ts.map +1 -1
  174. package/dist/core/skills.js +154 -29
  175. package/dist/core/skills.js.map +1 -1
  176. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  177. package/dist/core/write-lifecycle/path-gate.js +5 -3
  178. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  179. package/dist/prompt/inquirer-prompter.d.ts.map +1 -1
  180. package/dist/prompt/inquirer-prompter.js +11 -1
  181. package/dist/prompt/inquirer-prompter.js.map +1 -1
  182. package/dist/prompt/prompter.d.ts +16 -0
  183. package/dist/prompt/prompter.d.ts.map +1 -1
  184. package/dist/run.d.ts.map +1 -1
  185. package/dist/run.js +61 -55
  186. package/dist/run.js.map +1 -1
  187. package/dist/taxonomy/profiles.d.ts +11 -0
  188. package/dist/taxonomy/profiles.d.ts.map +1 -1
  189. package/dist/taxonomy/profiles.js +1 -0
  190. package/dist/taxonomy/profiles.js.map +1 -1
  191. package/dist/version.d.ts +1 -1
  192. package/dist/version.js +1 -1
  193. package/package.json +3 -1
  194. package/templates/agents/canonical.md +2 -8
  195. package/templates/agents/{store-conventions.md → conventions.md} +2 -4
  196. package/templates/agents/mission.md +5 -0
  197. package/templates/conventions/baseline-conventions.md +60 -0
  198. package/templates/conventions/house-conventions-seed.md +34 -0
  199. package/templates/hooks/pre-push.sh +1 -1
  200. package/templates/serve/shell.html +15 -0
  201. package/templates/serve/style.css +88 -0
  202. package/templates/skills/ctxr-land.md +32 -18
  203. package/templates/skills/ctxr-organize-audit.md +1 -1
  204. package/templates/skills/ctxr-publish.md +79 -0
  205. package/templates/skills/ctxr-session-capture.md +44 -1
  206. package/templates/skills/ctxr-session-lifecycle.md +20 -1
  207. package/templates/skills/ctxr-submit.md +15 -11
  208. package/templates/vendor/frontend-design/LICENSE.txt +177 -0
  209. package/templates/vendor/frontend-design/SKILL.md +55 -0
  210. package/templates/vendor/frontend-design/provenance.json +7 -0
  211. package/dist/adapters/forge/github.d.ts +0 -12
  212. package/dist/adapters/forge/github.d.ts.map +0 -1
  213. package/dist/adapters/forge/github.js +0 -76
  214. package/dist/adapters/forge/github.js.map +0 -1
  215. package/dist/adapters/forge/types.d.ts +0 -46
  216. package/dist/adapters/forge/types.d.ts.map +0 -1
  217. package/dist/adapters/forge/types.js +0 -2
  218. package/dist/adapters/forge/types.js.map +0 -1
  219. package/dist/commands/session-abandon.d.ts +0 -13
  220. package/dist/commands/session-abandon.d.ts.map +0 -1
  221. package/dist/commands/session-abandon.js +0 -22
  222. package/dist/commands/session-abandon.js.map +0 -1
  223. package/dist/commands/session-land.d.ts +0 -45
  224. package/dist/commands/session-land.d.ts.map +0 -1
  225. package/dist/commands/session-land.js +0 -171
  226. package/dist/commands/session-land.js.map +0 -1
  227. package/dist/commands/session-reap.d.ts +0 -22
  228. package/dist/commands/session-reap.d.ts.map +0 -1
  229. package/dist/commands/session-reap.js +0 -52
  230. package/dist/commands/session-reap.js.map +0 -1
  231. package/dist/commands/session-submit.d.ts +0 -29
  232. package/dist/commands/session-submit.d.ts.map +0 -1
  233. package/dist/commands/session-submit.js +0 -72
  234. package/dist/commands/session-submit.js.map +0 -1
  235. package/templates/agents/store-conventions-empty.md +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../../src/core/git/worktree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../../src/core/git/worktree.ts"],"names":[],"mappings":"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"}
@@ -72,6 +72,20 @@ export declare function extractLinkTargets(body: string): string[];
72
72
  * link, consistent with "two same-named notes are a valid, expected state"
73
73
  * (the node-identity requirement's own scenario).
74
74
  */
75
+ /**
76
+ * The filename-stem -> path(s) index every wikilink resolution in the
77
+ * system reads (the graph build here, and local-browsing-surface's
78
+ * link-resolver) — factored out so both consult exactly one index and can't
79
+ * silently diverge on what a stem resolves to.
80
+ */
81
+ export declare function buildStemIndex(notes: readonly Note[]): Map<string, string[]>;
82
+ export type StemResolution = {
83
+ path: string;
84
+ } | {
85
+ reason: DanglingReason;
86
+ };
87
+ /** Classifies a wikilink target against a stem index — exactly one match resolves, zero or many don't. */
88
+ export declare function resolveStem(stemIndex: ReadonlyMap<string, string[]>, target: string): StemResolution;
75
89
  export declare function buildGraphFromNotes(notes: readonly Note[], options?: GraphBuildOptions): GraphBuildResult;
76
90
  /** The build options a store's configuration implies — the one place config is translated for the graph. */
77
91
  export declare function graphBuildOptions(config: {
@@ -1 +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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;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,kGAAkG;AAClG,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,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;AAED,MAAM,WAAW,iBAAiB;IAChC,8HAA8H;IAC9H,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,mEAAmE;AACnE,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAA8B,GAAG,MAAM,CAIzF;AAKD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,cAAc,EAAE,CAuB9F;AAYD,uIAAuI;AACvI,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAmC7G;AAED,4GAA4G;AAC5G,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAAG,iBAAiB,CAE9I"}
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;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;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,kGAAkG;AAClG,eAAO,MAAM,cAAc,SAAS,CAAC;AAErC,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;AAED,MAAM,WAAW,iBAAiB;IAChC,8HAA8H;IAC9H,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,mEAAmE;AACnE,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,GAAE,MAA8B,GAAG,MAAM,CAIzF;AAKD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAMD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,cAAc,EAAE,CAuB9F;AAYD,uIAAuI;AACvI,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEzD;AAED;;;;;;;;;;;;GAYG;AACH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAS5E;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC;AAE3E,0GAA0G;AAC1G,wBAAgB,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAKpG;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CA2B7G;AAED,4GAA4G;AAC5G,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IAAE,SAAS,EAAE;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE;YAAE,aAAa,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAAG,iBAAiB,CAE9I"}
@@ -77,6 +77,31 @@ export function extractLinkTargets(body) {
77
77
  * link, consistent with "two same-named notes are a valid, expected state"
78
78
  * (the node-identity requirement's own scenario).
79
79
  */
80
+ /**
81
+ * The filename-stem -> path(s) index every wikilink resolution in the
82
+ * system reads (the graph build here, and local-browsing-surface's
83
+ * link-resolver) — factored out so both consult exactly one index and can't
84
+ * silently diverge on what a stem resolves to.
85
+ */
86
+ export function buildStemIndex(notes) {
87
+ const stemIndex = new Map();
88
+ for (const note of notes) {
89
+ const stem = path.basename(note.path, '.md');
90
+ const list = stemIndex.get(stem) ?? [];
91
+ list.push(note.path);
92
+ stemIndex.set(stem, list);
93
+ }
94
+ return stemIndex;
95
+ }
96
+ /** Classifies a wikilink target against a stem index — exactly one match resolves, zero or many don't. */
97
+ export function resolveStem(stemIndex, target) {
98
+ const resolved = stemIndex.get(target);
99
+ if (!resolved)
100
+ return { reason: 'not_found' };
101
+ if (resolved.length > 1)
102
+ return { reason: 'ambiguous' };
103
+ return { path: resolved[0] };
104
+ }
80
105
  export function buildGraphFromNotes(notes, options = {}) {
81
106
  const idCounts = new Map();
82
107
  for (const note of notes)
@@ -85,28 +110,19 @@ export function buildGraphFromNotes(notes, options = {}) {
85
110
  if (collisions.length > 0) {
86
111
  throw new GraphIdentityCollisionError(collisions);
87
112
  }
88
- const stemIndex = new Map();
89
- for (const note of notes) {
90
- const stem = path.basename(note.path, '.md');
91
- const list = stemIndex.get(stem) ?? [];
92
- list.push(note.path);
93
- stemIndex.set(stem, list);
94
- }
113
+ const stemIndex = buildStemIndex(notes);
95
114
  const depth = options.clusterDepth ?? DEFAULT_CLUSTER_DEPTH;
96
115
  const nodes = notes.map((n) => ({ id: n.path, path: n.path, cluster: clusterOf(n.path, depth) }));
97
116
  const edges = [];
98
117
  const dangling = [];
99
118
  for (const note of notes) {
100
119
  for (const { target, type } of extractLinks(note.body, options.relations ?? [])) {
101
- const resolved = stemIndex.get(target);
102
- if (!resolved) {
103
- dangling.push({ from: note.path, target, reason: 'not_found' });
104
- }
105
- else if (resolved.length > 1) {
106
- dangling.push({ from: note.path, target, reason: 'ambiguous' });
120
+ const resolution = resolveStem(stemIndex, target);
121
+ if ('reason' in resolution) {
122
+ dangling.push({ from: note.path, target, reason: resolution.reason });
107
123
  }
108
124
  else {
109
- edges.push({ src: note.path, dst: resolved[0], type });
125
+ edges.push({ src: note.path, dst: resolution.path, type });
110
126
  }
111
127
  }
112
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/graph/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/core/graph/model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { StoreConfig } from '../../config/schema.js';
2
+ export interface HarnessBridgeResult {
3
+ /** The harness-generation adapter id this bridge is for. */
4
+ harness: string;
5
+ /** Store-relative harness skills directory that was bridged. */
6
+ path: string;
7
+ mode: 'symlink' | 'copy';
8
+ }
9
+ /**
10
+ * The effective skills directory for a configured harness-generation
11
+ * adapter: a store's own override (`adapters[].skills_dir`) takes
12
+ * precedence over the adapter's declared default.
13
+ */
14
+ export declare function effectiveSkillsDir(config: StoreConfig, adapterId: string, adapterDefault: string): string;
15
+ /**
16
+ * Bridges every declared harness-generation adapter's skills directory to
17
+ * the store's configured (canonical) skills path — never derived by
18
+ * inspecting the host machine, always from configuration. An adapter whose
19
+ * effective directory already equals the canonical path needs no bridge and
20
+ * is silently skipped. Returns only the harnesses that actually changed.
21
+ */
22
+ export declare function bridgeHarnessSkills(root: string, config: StoreConfig): Promise<HarnessBridgeResult[]>;
23
+ /**
24
+ * Read-only counterpart for `ctxr doctor`: true when a declared harness's
25
+ * skills directory is broken — materialized as something other than a
26
+ * bridge to canonical — without writing anything. Mirrors `ensureBridge`'s
27
+ * detection exactly; only the repair action differs.
28
+ */
29
+ export declare function isBridgeBroken(root: string, canonicalPath: string, harnessDir: string): Promise<boolean>;
30
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../../src/core/harness/bridge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;CAC1B;AA+HD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAGzG;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAmB3G;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM9G"}
@@ -0,0 +1,178 @@
1
+ import { cp, lstat, mkdir, readFile, readdir, realpath, rm, symlink } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { configuredAdapters } from '../../adapters/registry.js';
4
+ /** Resolves a path to its real path, or itself (as an absolute path) if it does not exist. */
5
+ async function realOrSelf(p) {
6
+ try {
7
+ return await realpath(p);
8
+ }
9
+ catch {
10
+ return path.resolve(p);
11
+ }
12
+ }
13
+ /**
14
+ * Resolves a path's PARENT through symlinks, keeping the final path
15
+ * component literal. Handles the case where a parent directory (e.g. the
16
+ * store root itself) is reached through a link, so two paths that are
17
+ * physically the same location but written with different parent spellings
18
+ * still compare equal.
19
+ */
20
+ async function realParentPlusBase(p) {
21
+ const resolved = path.resolve(p);
22
+ const dir = path.dirname(resolved);
23
+ const base = path.basename(resolved);
24
+ try {
25
+ const realDir = await realpath(dir);
26
+ return path.join(realDir, base);
27
+ }
28
+ catch {
29
+ return resolved;
30
+ }
31
+ }
32
+ /**
33
+ * True when `harnessAbs` already resolves to the same real location as
34
+ * `canonicalAbs` — directly, or through a symlinked parent directory.
35
+ * Checked both ways so neither a symlinked store root nor a symlinked
36
+ * canonical directory causes a bridge that is already correct to be
37
+ * rewritten, or — worse — the canonical directory to be deleted out from
38
+ * under itself.
39
+ */
40
+ async function alreadyBridged(canonicalAbs, harnessAbs) {
41
+ const [realCanonical, realHarness] = await Promise.all([realOrSelf(canonicalAbs), realOrSelf(harnessAbs)]);
42
+ if (realCanonical === realHarness)
43
+ return true;
44
+ const [canonicalViaParent, harnessViaParent] = await Promise.all([realParentPlusBase(canonicalAbs), realParentPlusBase(harnessAbs)]);
45
+ return canonicalViaParent === harnessViaParent;
46
+ }
47
+ /** True only for a real directory — false for a symlink (even one pointing at a directory), so a misdirected link is always repaired rather than judged by its target's contents. */
48
+ async function isPlainDirectory(p) {
49
+ try {
50
+ return (await lstat(p)).isDirectory();
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ async function readDirTree(root, sub = '') {
57
+ const result = new Map();
58
+ let entries;
59
+ try {
60
+ entries = await readdir(path.join(root, sub), { withFileTypes: true });
61
+ }
62
+ catch {
63
+ return result;
64
+ }
65
+ for (const entry of entries) {
66
+ const rel = sub ? `${sub}/${entry.name}` : entry.name;
67
+ if (entry.isDirectory()) {
68
+ for (const [k, v] of await readDirTree(root, rel))
69
+ result.set(k, v);
70
+ }
71
+ else if (entry.isFile()) {
72
+ result.set(rel, await readFile(path.join(root, rel), 'utf8'));
73
+ }
74
+ }
75
+ return result;
76
+ }
77
+ /** Whole-tree byte comparison — cheap at skill-directory scale, and simpler than tracking per-file mtimes. */
78
+ async function directoriesMatch(a, b) {
79
+ const [treeA, treeB] = await Promise.all([readDirTree(a), readDirTree(b)]);
80
+ if (treeA.size !== treeB.size)
81
+ return false;
82
+ for (const [rel, content] of treeA) {
83
+ if (treeB.get(rel) !== content)
84
+ return false;
85
+ }
86
+ return true;
87
+ }
88
+ async function createDirSymlink(canonicalAbs, harnessAbs) {
89
+ await mkdir(path.dirname(harnessAbs), { recursive: true });
90
+ // A relative target keeps the link correct across a clone at a different absolute path.
91
+ const relativeTarget = path.relative(path.dirname(harnessAbs), canonicalAbs);
92
+ try {
93
+ await symlink(relativeTarget, harnessAbs, 'dir');
94
+ return true;
95
+ }
96
+ catch {
97
+ return false;
98
+ }
99
+ }
100
+ async function copySkillsInto(canonicalAbs, harnessAbs) {
101
+ await mkdir(harnessAbs, { recursive: true });
102
+ await cp(canonicalAbs, harnessAbs, { recursive: true });
103
+ }
104
+ /**
105
+ * harness-portability spec (vendored-craft-skills): makes `harnessAbs`
106
+ * resolve to `canonicalAbs`, preferring a directory symlink and falling
107
+ * back to a recursive copy when one cannot be created. Idempotent: a
108
+ * directory that already resolves to canonical (directly, through a
109
+ * symlinked parent, or as a copy whose content still matches) is left
110
+ * untouched and reported as unchanged. A symlink that does not resolve to
111
+ * canonical is always replaced regardless of what it currently points at —
112
+ * never judged "close enough" by its target's contents — which is what
113
+ * makes a misdirected or materialized-as-a-file bridge repairable rather
114
+ * than silently tolerated.
115
+ */
116
+ async function ensureBridge(canonicalAbs, harnessAbs) {
117
+ if (await alreadyBridged(canonicalAbs, harnessAbs))
118
+ return 'unchanged';
119
+ if ((await isPlainDirectory(harnessAbs)) && (await directoriesMatch(canonicalAbs, harnessAbs))) {
120
+ return 'unchanged';
121
+ }
122
+ await rm(harnessAbs, { recursive: true, force: true });
123
+ if (await createDirSymlink(canonicalAbs, harnessAbs))
124
+ return 'symlink';
125
+ await copySkillsInto(canonicalAbs, harnessAbs);
126
+ return 'copy';
127
+ }
128
+ /**
129
+ * The effective skills directory for a configured harness-generation
130
+ * adapter: a store's own override (`adapters[].skills_dir`) takes
131
+ * precedence over the adapter's declared default.
132
+ */
133
+ export function effectiveSkillsDir(config, adapterId, adapterDefault) {
134
+ const declaration = config.adapters.find((d) => d.kind === 'harness-generation' && d.id === adapterId);
135
+ return declaration?.skills_dir ?? adapterDefault;
136
+ }
137
+ /**
138
+ * Bridges every declared harness-generation adapter's skills directory to
139
+ * the store's configured (canonical) skills path — never derived by
140
+ * inspecting the host machine, always from configuration. An adapter whose
141
+ * effective directory already equals the canonical path needs no bridge and
142
+ * is silently skipped. Returns only the harnesses that actually changed.
143
+ */
144
+ export async function bridgeHarnessSkills(root, config) {
145
+ const canonical = config.harness.skills_path;
146
+ // path.resolve, not path.join: these configured paths conventionally end
147
+ // in "/", and fs.symlink's destination argument treats a trailing slash
148
+ // as "this must already be a directory" — failing with ENOENT on the
149
+ // (correct) case where it doesn't exist yet because we're creating it.
150
+ const canonicalAbs = path.resolve(root, canonical);
151
+ const results = [];
152
+ for (const adapter of configuredAdapters(config, 'harness-generation')) {
153
+ const harnessDir = effectiveSkillsDir(config, adapter.id, adapter.skillsDir);
154
+ if (harnessDir === canonical)
155
+ continue;
156
+ const harnessAbs = path.resolve(root, harnessDir);
157
+ const mode = await ensureBridge(canonicalAbs, harnessAbs);
158
+ if (mode !== 'unchanged')
159
+ results.push({ harness: adapter.id, path: harnessDir, mode });
160
+ }
161
+ return results;
162
+ }
163
+ /**
164
+ * Read-only counterpart for `ctxr doctor`: true when a declared harness's
165
+ * skills directory is broken — materialized as something other than a
166
+ * bridge to canonical — without writing anything. Mirrors `ensureBridge`'s
167
+ * detection exactly; only the repair action differs.
168
+ */
169
+ export async function isBridgeBroken(root, canonicalPath, harnessDir) {
170
+ const canonicalAbs = path.resolve(root, canonicalPath);
171
+ const harnessAbs = path.resolve(root, harnessDir);
172
+ if (await alreadyBridged(canonicalAbs, harnessAbs))
173
+ return false;
174
+ if ((await isPlainDirectory(harnessAbs)) && (await directoriesMatch(canonicalAbs, harnessAbs)))
175
+ return false;
176
+ return true;
177
+ }
178
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../src/core/harness/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAWhE,8FAA8F;AAC9F,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,kBAAkB,CAAC,CAAS;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,cAAc,CAAC,YAAoB,EAAE,UAAkB;IACpE,MAAM,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC3G,IAAI,aAAa,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACrI,OAAO,kBAAkB,KAAK,gBAAgB,CAAC;AACjD,CAAC;AAED,qLAAqL;AACrL,KAAK,UAAU,gBAAgB,CAAC,CAAS;IACvC,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,GAAG,GAAG,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QACtD,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8GAA8G;AAC9G,KAAK,UAAU,gBAAgB,CAAC,CAAS,EAAE,CAAS;IAClD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,YAAoB,EAAE,UAAkB;IACtE,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,wFAAwF;IACxF,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,cAAc,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,YAAoB,EAAE,UAAkB;IACpE,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,YAAY,CAAC,YAAoB,EAAE,UAAkB;IAClE,IAAI,MAAM,cAAc,CAAC,YAAY,EAAE,UAAU,CAAC;QAAE,OAAO,WAAW,CAAC;IAEvE,IAAI,CAAC,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QAC/F,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvD,IAAI,MAAM,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IAEvE,MAAM,cAAc,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAmB,EAAE,SAAiB,EAAE,cAAsB;IAC/F,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IACvG,OAAO,WAAW,EAAE,UAAU,IAAI,cAAc,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,MAAmB;IACzE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAC7C,yEAAyE;IACzE,wEAAwE;IACxE,qEAAqE;IACrE,uEAAuE;IACvE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,OAAO,GAA0B,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACvE,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS;QAEvC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,aAAqB,EAAE,UAAkB;IAC1F,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClD,IAAI,MAAM,cAAc,CAAC,YAAY,EAAE,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,CAAC,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7G,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"json-config-merge.d.ts","sourceRoot":"","sources":["../../src/core/json-config-merge.ts"],"names":[],"mappings":"AAKA,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,EAAE,CAAC;IAC5E,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,gBAAgB,EAAE,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5F,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAuBhG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA4D/B"}
1
+ {"version":3,"file":"json-config-merge.d.ts","sourceRoot":"","sources":["../../src/core/json-config-merge.ts"],"names":[],"mappings":"AAKA,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,EAAE,CAAC;IAC5E,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,gBAAgB,EAAE,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5F,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AA6ChG;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA4D/B"}
@@ -5,19 +5,42 @@ import { writeFileAtomic } from './fs/atomic.js';
5
5
  function isHookEntryList(value) {
6
6
  return value.length > 0 && typeof value[0] === 'object' && value[0] !== null;
7
7
  }
8
+ /** The filename a hook entry's command invokes, independent of the absolute path it's rooted at. */
9
+ function hookCommandBasename(entry) {
10
+ const command = entry.hooks[0]?.command;
11
+ return command ? path.basename(command) : '';
12
+ }
8
13
  /**
9
14
  * Upserts each incoming hook-matcher entry into the existing list, matched
10
- * by its own `hooks[0].command` (the path to contexture's generated
11
- * script): replaced in place when found, so regeneration is idempotent,
12
- * appended otherwise. Any entry with a different command — an operator's
13
- * own hook — is left untouched.
15
+ * by `(matcher, hookCommandBasename)` rather than the full command string —
16
+ * deliberately blind to the absolute path prefix, since that prefix is
17
+ * whichever checkout most recently generated it (typically a session
18
+ * worktree) and so is not stable across runs even for the SAME logical
19
+ * rule (stabilize-write-gate-hook-path). The first matching existing entry
20
+ * is replaced in place (preserving its position, so an unrelated
21
+ * hand-added entry elsewhere in the array is never reordered); any further
22
+ * entries that also match are dropped, so a list that has already
23
+ * accumulated more than one stale copy of contexture's own entry (e.g. one
24
+ * per session worktree that ever regenerated it) converges to exactly one
25
+ * on this run, not just on a version bump. An entry with a different
26
+ * matcher or a different script basename — an operator's own hook — is
27
+ * always left untouched.
14
28
  */
15
29
  function mergeHookEntries(existing, incoming) {
16
30
  let result = [...existing];
17
31
  for (const entry of incoming) {
18
- const command = entry.hooks[0]?.command;
19
- const index = result.findIndex((candidate) => candidate.hooks?.[0]?.command === command);
20
- result = index === -1 ? [...result, entry] : result.map((candidate, i) => (i === index ? entry : candidate));
32
+ const isSameHook = (candidate) => candidate.matcher === entry.matcher && hookCommandBasename(candidate) === hookCommandBasename(entry);
33
+ let inserted = false;
34
+ result = result.flatMap((candidate) => {
35
+ if (!isSameHook(candidate))
36
+ return [candidate];
37
+ if (inserted)
38
+ return []; // a further stale duplicate of the same rule — drop it
39
+ inserted = true;
40
+ return [entry]; // replace the first match in place
41
+ });
42
+ if (!inserted)
43
+ result = [...result, entry];
21
44
  }
22
45
  return result;
23
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"json-config-merge.js","sourceRoot":"","sources":["../../src/core/json-config-merge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"json-config-merge.js","sourceRoot":"","sources":["../../src/core/json-config-merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { Migration } from './types.js';
2
+ /**
3
+ * archive-destination-from-taxonomy: `ctxr init` wrote a fixed
4
+ * `DEFAULT_ARCHIVE_PATH` regardless of the taxonomy it had just resolved, so
5
+ * every PARA store was born with `archive/` while its own taxonomy declared
6
+ * `archives/` — a config key pointing at a directory the store does not have.
7
+ * Init now asks the profile; this migration does the same for stores already
8
+ * on disk.
9
+ *
10
+ * Two independent halves, and the second is conditional:
11
+ *
12
+ * 1. The key rename is unconditional — every schema-5 store gets
13
+ * `archive_destination`. `OrganizeSchema`'s fallback transform has already
14
+ * resolved the old spelling by the time `readConfig` returns, so writing
15
+ * the parsed config back is what drops `archive_path` from disk.
16
+ * 2. The value only changes when the store never customized it AND its
17
+ * profile declares a destination of its own. An operator who deliberately
18
+ * set some other path keeps it; a Zettelkasten or Diataxis store, whose
19
+ * profile declares none, keeps `archive/` — for them this is a pure key
20
+ * rename. A custom taxonomy resolves to no shipped profile and is left
21
+ * alone for the same reason.
22
+ *
23
+ * Like 0004, the directory move is a plain filesystem rename (migrations see
24
+ * only `Store` — `root` + `config`, no `GitRunner`), and it is skipped when
25
+ * the old directory was never created. History survives either way: whatever
26
+ * commits this output stages a coherent delete-old/add-new diff, which
27
+ * `git log --follow`'s rename detection reads identically to a `git mv`.
28
+ *
29
+ * Pending-ness is `schema_version < 6`, not key presence — the rule 0002,
30
+ * 0004, and 0005 established, for the same reason: the fallback transform
31
+ * populates `archive_destination` on an unmigrated store too, so its presence
32
+ * cannot distinguish migrated from not.
33
+ */
34
+ export declare const archiveDestinationFromTaxonomyMigration: Migration;
35
+ //# sourceMappingURL=archive-destination-from-taxonomy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-destination-from-taxonomy.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/archive-destination-from-taxonomy.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAc5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,uCAAuC,EAAE,SA4CrD,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { rename } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { readConfig } from '../../config/load.js';
5
+ import { DEFAULT_ARCHIVE_DESTINATION } from '../../config/defaults.js';
6
+ import { renderStoreConfig } from '../../config/render.js';
7
+ import { profileById } from '../../taxonomy/profiles.js';
8
+ import { writeFileAtomic } from '../fs/atomic.js';
9
+ const CONFIG_DELTA = {
10
+ path: 'contexture.yaml',
11
+ description: 'rename organize.archive_path to organize.archive_destination and set schema_version to 6',
12
+ };
13
+ function destinationDelta(from, to) {
14
+ return {
15
+ path: to,
16
+ description: `adopt the taxonomy's own archive destination, moving the default-valued archive directory from ${from} to ${to}`,
17
+ };
18
+ }
19
+ /**
20
+ * archive-destination-from-taxonomy: `ctxr init` wrote a fixed
21
+ * `DEFAULT_ARCHIVE_PATH` regardless of the taxonomy it had just resolved, so
22
+ * every PARA store was born with `archive/` while its own taxonomy declared
23
+ * `archives/` — a config key pointing at a directory the store does not have.
24
+ * Init now asks the profile; this migration does the same for stores already
25
+ * on disk.
26
+ *
27
+ * Two independent halves, and the second is conditional:
28
+ *
29
+ * 1. The key rename is unconditional — every schema-5 store gets
30
+ * `archive_destination`. `OrganizeSchema`'s fallback transform has already
31
+ * resolved the old spelling by the time `readConfig` returns, so writing
32
+ * the parsed config back is what drops `archive_path` from disk.
33
+ * 2. The value only changes when the store never customized it AND its
34
+ * profile declares a destination of its own. An operator who deliberately
35
+ * set some other path keeps it; a Zettelkasten or Diataxis store, whose
36
+ * profile declares none, keeps `archive/` — for them this is a pure key
37
+ * rename. A custom taxonomy resolves to no shipped profile and is left
38
+ * alone for the same reason.
39
+ *
40
+ * Like 0004, the directory move is a plain filesystem rename (migrations see
41
+ * only `Store` — `root` + `config`, no `GitRunner`), and it is skipped when
42
+ * the old directory was never created. History survives either way: whatever
43
+ * commits this output stages a coherent delete-old/add-new diff, which
44
+ * `git log --follow`'s rename detection reads identically to a `git mv`.
45
+ *
46
+ * Pending-ness is `schema_version < 6`, not key presence — the rule 0002,
47
+ * 0004, and 0005 established, for the same reason: the fallback transform
48
+ * populates `archive_destination` on an unmigrated store too, so its presence
49
+ * cannot distinguish migrated from not.
50
+ */
51
+ export const archiveDestinationFromTaxonomyMigration = {
52
+ id: '0006-archive-destination-from-taxonomy',
53
+ fromVersion: 5,
54
+ toVersion: 6,
55
+ description: "Rename the organize.archive_path config key to organize.archive_destination, adopt the taxonomy profile's own archive destination when the value still sat at the shipped default, and bump schema_version to 6.",
56
+ async plan(store) {
57
+ if (store.config.schema_version >= 6)
58
+ return [];
59
+ const deltas = [CONFIG_DELTA];
60
+ const target = taxonomyDestination(store.config.taxonomy.profile, store.config.organize.archive_destination);
61
+ if (target)
62
+ deltas.push(destinationDelta(DEFAULT_ARCHIVE_DESTINATION, target));
63
+ return deltas;
64
+ },
65
+ async apply(store) {
66
+ if (store.config.schema_version >= 6)
67
+ return [];
68
+ const configPath = path.join(store.root, 'contexture.yaml');
69
+ const currentConfig = await readConfig(store.root);
70
+ const appliedDeltas = [CONFIG_DELTA];
71
+ let destination = currentConfig.organize.archive_destination;
72
+ const target = taxonomyDestination(currentConfig.taxonomy.profile, destination);
73
+ if (target) {
74
+ const oldDir = path.join(store.root, DEFAULT_ARCHIVE_DESTINATION);
75
+ const newDir = path.join(store.root, target);
76
+ // Absent whenever nothing was ever archived — only the config changes.
77
+ if (existsSync(oldDir) && !existsSync(newDir)) {
78
+ await rename(oldDir, newDir);
79
+ }
80
+ destination = target;
81
+ appliedDeltas.push(destinationDelta(DEFAULT_ARCHIVE_DESTINATION, target));
82
+ }
83
+ const nextConfig = {
84
+ ...currentConfig,
85
+ schema_version: 6,
86
+ organize: { ...currentConfig.organize, archive_destination: destination },
87
+ };
88
+ await writeFileAtomic(configPath, renderStoreConfig(nextConfig));
89
+ return appliedDeltas;
90
+ },
91
+ };
92
+ /**
93
+ * The profile's own destination, but only when adopting it is safe: the
94
+ * store must still be sitting on the shipped default (otherwise the value is
95
+ * the operator's, not ours to rewrite), the profile must be a shipped one
96
+ * that declares a destination, and it must actually differ from what's
97
+ * already configured.
98
+ */
99
+ function taxonomyDestination(profileId, current) {
100
+ if (current !== DEFAULT_ARCHIVE_DESTINATION)
101
+ return undefined;
102
+ if (profileId === null)
103
+ return undefined;
104
+ const declared = profileById(profileId)?.archiveDestination;
105
+ if (declared === undefined || declared === current)
106
+ return undefined;
107
+ return declared;
108
+ }
109
+ //# sourceMappingURL=archive-destination-from-taxonomy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive-destination-from-taxonomy.js","sourceRoot":"","sources":["../../../src/core/migrations/archive-destination-from-taxonomy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Migration } from './types.js';
2
+ /**
3
+ * session-keeps-only-what-git-cannot-do (design D2): `ctxr session
4
+ * submit`/`land`/`abandon`/`reap` and the `forge` adapter kind are removed;
5
+ * `session.workspaces_external` goes with them, its skill-rendering half
6
+ * never having worked as shipped. Both legacy shapes are ALREADY stripped
7
+ * by the time `readConfig` returns — the adapters field's lenient schema
8
+ * transform drops a `kind: forge` entry (session-keeps-only-what-git-cannot-do
9
+ * D2), and `SessionSchema`'s default strip-unknown-keys behavior drops
10
+ * `workspaces_external` — so this migration's only real work is bumping
11
+ * `schema_version` and writing the already-clean config back to disk.
12
+ *
13
+ * Pending-ness is `schema_version < 5`, not key presence — the same rule
14
+ * 0002 and 0004 established, for the same reason: an unmigrated store
15
+ * already parses as though the legacy shape were gone, so its presence in
16
+ * the parsed config can't distinguish migrated from not.
17
+ */
18
+ export declare const dropForgeAndWorkspacesExternalMigration: Migration;
19
+ //# sourceMappingURL=drop-forge-and-workspaces-external.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-forge-and-workspaces-external.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/drop-forge-and-workspaces-external.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAO5D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uCAAuC,EAAE,SA0BrD,CAAC"}