ctxr-cli 0.5.0 → 0.7.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 (289) 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 +38 -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 +6 -4
  23. package/dist/commands/archive.d.ts.map +1 -1
  24. package/dist/commands/archive.js +7 -5
  25. package/dist/commands/archive.js.map +1 -1
  26. package/dist/commands/catalog-show.d.ts +0 -1
  27. package/dist/commands/catalog-show.d.ts.map +1 -1
  28. package/dist/commands/catalog-show.js +1 -1
  29. package/dist/commands/catalog-show.js.map +1 -1
  30. package/dist/commands/graph-query.d.ts +2 -11
  31. package/dist/commands/graph-query.d.ts.map +1 -1
  32. package/dist/commands/graph-query.js +11 -14
  33. package/dist/commands/graph-query.js.map +1 -1
  34. package/dist/commands/init.d.ts +2 -0
  35. package/dist/commands/init.d.ts.map +1 -1
  36. package/dist/commands/init.js +82 -21
  37. package/dist/commands/init.js.map +1 -1
  38. package/dist/commands/publish-check.d.ts +23 -0
  39. package/dist/commands/publish-check.d.ts.map +1 -0
  40. package/dist/commands/publish-check.js +112 -0
  41. package/dist/commands/publish-check.js.map +1 -0
  42. package/dist/commands/publish-gather.d.ts +27 -0
  43. package/dist/commands/publish-gather.d.ts.map +1 -0
  44. package/dist/commands/publish-gather.js +73 -0
  45. package/dist/commands/publish-gather.js.map +1 -0
  46. package/dist/commands/publish-new.d.ts +19 -0
  47. package/dist/commands/publish-new.d.ts.map +1 -0
  48. package/dist/commands/publish-new.js +108 -0
  49. package/dist/commands/publish-new.js.map +1 -0
  50. package/dist/commands/serve.d.ts +32 -0
  51. package/dist/commands/serve.d.ts.map +1 -0
  52. package/dist/commands/serve.js +151 -0
  53. package/dist/commands/serve.js.map +1 -0
  54. package/dist/commands/session-capture.d.ts.map +1 -1
  55. package/dist/commands/session-capture.js +0 -2
  56. package/dist/commands/session-capture.js.map +1 -1
  57. package/dist/commands/update.js +3 -3
  58. package/dist/commands/update.js.map +1 -1
  59. package/dist/config/defaults.d.ts +49 -44
  60. package/dist/config/defaults.d.ts.map +1 -1
  61. package/dist/config/defaults.js +49 -47
  62. package/dist/config/defaults.js.map +1 -1
  63. package/dist/config/schema.d.ts +53 -52
  64. package/dist/config/schema.d.ts.map +1 -1
  65. package/dist/config/schema.js +84 -62
  66. package/dist/config/schema.js.map +1 -1
  67. package/dist/core/agents-doc.d.ts +9 -0
  68. package/dist/core/agents-doc.d.ts.map +1 -1
  69. package/dist/core/agents-doc.js +31 -16
  70. package/dist/core/agents-doc.js.map +1 -1
  71. package/dist/core/browse/link-resolver.d.ts +12 -0
  72. package/dist/core/browse/link-resolver.d.ts.map +1 -0
  73. package/dist/core/browse/link-resolver.js +12 -0
  74. package/dist/core/browse/link-resolver.js.map +1 -0
  75. package/dist/core/browse/nav.d.ts +10 -0
  76. package/dist/core/browse/nav.d.ts.map +1 -0
  77. package/dist/core/browse/nav.js +101 -0
  78. package/dist/core/browse/nav.js.map +1 -0
  79. package/dist/core/browse/render.d.ts +5 -0
  80. package/dist/core/browse/render.d.ts.map +1 -0
  81. package/dist/core/browse/render.js +66 -0
  82. package/dist/core/browse/render.js.map +1 -0
  83. package/dist/core/browse/routes.d.ts +40 -0
  84. package/dist/core/browse/routes.d.ts.map +1 -0
  85. package/dist/core/browse/routes.js +68 -0
  86. package/dist/core/browse/routes.js.map +1 -0
  87. package/dist/core/browse/templates.d.ts +13 -0
  88. package/dist/core/browse/templates.d.ts.map +1 -0
  89. package/dist/core/browse/templates.js +39 -0
  90. package/dist/core/browse/templates.js.map +1 -0
  91. package/dist/core/browse/tree.d.ts +33 -0
  92. package/dist/core/browse/tree.d.ts.map +1 -0
  93. package/dist/core/browse/tree.js +53 -0
  94. package/dist/core/browse/tree.js.map +1 -0
  95. package/dist/core/catalog/build.d.ts +1 -1
  96. package/dist/core/catalog/build.d.ts.map +1 -1
  97. package/dist/core/catalog/build.js +1 -2
  98. package/dist/core/catalog/build.js.map +1 -1
  99. package/dist/core/catalog/model.d.ts +2 -0
  100. package/dist/core/catalog/model.d.ts.map +1 -1
  101. package/dist/core/catalog/model.js +2 -1
  102. package/dist/core/catalog/model.js.map +1 -1
  103. package/dist/core/checks/integrity-checks.d.ts +18 -2
  104. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  105. package/dist/core/checks/integrity-checks.js +55 -10
  106. package/dist/core/checks/integrity-checks.js.map +1 -1
  107. package/dist/core/checks/manifest.d.ts.map +1 -1
  108. package/dist/core/checks/manifest.js +0 -5
  109. package/dist/core/checks/manifest.js.map +1 -1
  110. package/dist/core/checks/organize-checks.d.ts +10 -3
  111. package/dist/core/checks/organize-checks.d.ts.map +1 -1
  112. package/dist/core/checks/organize-checks.js +14 -5
  113. package/dist/core/checks/organize-checks.js.map +1 -1
  114. package/dist/core/checks/types.d.ts +1 -1
  115. package/dist/core/convention-doc.d.ts +21 -19
  116. package/dist/core/convention-doc.d.ts.map +1 -1
  117. package/dist/core/convention-doc.js +48 -62
  118. package/dist/core/convention-doc.js.map +1 -1
  119. package/dist/core/conventions.d.ts +2 -2
  120. package/dist/core/conventions.js +2 -2
  121. package/dist/core/errors.d.ts +31 -44
  122. package/dist/core/errors.d.ts.map +1 -1
  123. package/dist/core/errors.js +81 -128
  124. package/dist/core/errors.js.map +1 -1
  125. package/dist/core/exit-codes.d.ts +7 -5
  126. package/dist/core/exit-codes.d.ts.map +1 -1
  127. package/dist/core/exit-codes.js +7 -5
  128. package/dist/core/exit-codes.js.map +1 -1
  129. package/dist/core/git/repo.d.ts +0 -6
  130. package/dist/core/git/repo.d.ts.map +1 -1
  131. package/dist/core/git/repo.js +0 -13
  132. package/dist/core/git/repo.js.map +1 -1
  133. package/dist/core/git/worktree.d.ts +4 -7
  134. package/dist/core/git/worktree.d.ts.map +1 -1
  135. package/dist/core/git/worktree.js +4 -10
  136. package/dist/core/git/worktree.js.map +1 -1
  137. package/dist/core/graph/model.d.ts +14 -0
  138. package/dist/core/graph/model.d.ts.map +1 -1
  139. package/dist/core/graph/model.js +30 -14
  140. package/dist/core/graph/model.js.map +1 -1
  141. package/dist/core/harness/bridge.d.ts +30 -0
  142. package/dist/core/harness/bridge.d.ts.map +1 -0
  143. package/dist/core/harness/bridge.js +178 -0
  144. package/dist/core/harness/bridge.js.map +1 -0
  145. package/dist/core/ingest/identity.d.ts +4 -4
  146. package/dist/core/ingest/identity.js +4 -4
  147. package/dist/core/json-config-merge.d.ts.map +1 -1
  148. package/dist/core/json-config-merge.js +30 -7
  149. package/dist/core/json-config-merge.js.map +1 -1
  150. package/dist/core/migrations/add-explanation-craft-skill.d.ts +26 -0
  151. package/dist/core/migrations/add-explanation-craft-skill.d.ts.map +1 -0
  152. package/dist/core/migrations/add-explanation-craft-skill.js +94 -0
  153. package/dist/core/migrations/add-explanation-craft-skill.js.map +1 -0
  154. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts +35 -0
  155. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts.map +1 -0
  156. package/dist/core/migrations/archive-destination-from-taxonomy.js +109 -0
  157. package/dist/core/migrations/archive-destination-from-taxonomy.js.map +1 -0
  158. package/dist/core/migrations/drop-access-axes.d.ts +24 -0
  159. package/dist/core/migrations/drop-access-axes.d.ts.map +1 -0
  160. package/dist/core/migrations/drop-access-axes.js +54 -0
  161. package/dist/core/migrations/drop-access-axes.js.map +1 -0
  162. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts +19 -0
  163. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts.map +1 -0
  164. package/dist/core/migrations/drop-forge-and-workspaces-external.js +49 -0
  165. package/dist/core/migrations/drop-forge-and-workspaces-external.js.map +1 -0
  166. package/dist/core/migrations/registry.d.ts +11 -1
  167. package/dist/core/migrations/registry.d.ts.map +1 -1
  168. package/dist/core/migrations/registry.js +19 -3
  169. package/dist/core/migrations/registry.js.map +1 -1
  170. package/dist/core/notes/list.d.ts +1 -12
  171. package/dist/core/notes/list.d.ts.map +1 -1
  172. package/dist/core/notes/list.js +5 -1
  173. package/dist/core/notes/list.js.map +1 -1
  174. package/dist/core/publish/script-check.d.ts +12 -0
  175. package/dist/core/publish/script-check.d.ts.map +1 -0
  176. package/dist/core/publish/script-check.js +39 -0
  177. package/dist/core/publish/script-check.js.map +1 -0
  178. package/dist/core/reconcile.d.ts +3 -0
  179. package/dist/core/reconcile.d.ts.map +1 -1
  180. package/dist/core/reconcile.js +15 -5
  181. package/dist/core/reconcile.js.map +1 -1
  182. package/dist/core/records.d.ts +4 -5
  183. package/dist/core/records.d.ts.map +1 -1
  184. package/dist/core/records.js +0 -2
  185. package/dist/core/records.js.map +1 -1
  186. package/dist/core/session.d.ts +9 -9
  187. package/dist/core/session.js +9 -9
  188. package/dist/core/skills.d.ts +42 -0
  189. package/dist/core/skills.d.ts.map +1 -1
  190. package/dist/core/skills.js +159 -31
  191. package/dist/core/skills.js.map +1 -1
  192. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  193. package/dist/core/write-lifecycle/path-gate.js +4 -2
  194. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  195. package/dist/prompt/inquirer-prompter.d.ts.map +1 -1
  196. package/dist/prompt/inquirer-prompter.js +11 -1
  197. package/dist/prompt/inquirer-prompter.js.map +1 -1
  198. package/dist/prompt/prompter.d.ts +16 -0
  199. package/dist/prompt/prompter.d.ts.map +1 -1
  200. package/dist/run.d.ts.map +1 -1
  201. package/dist/run.js +69 -101
  202. package/dist/run.js.map +1 -1
  203. package/dist/taxonomy/profiles.d.ts +11 -0
  204. package/dist/taxonomy/profiles.d.ts.map +1 -1
  205. package/dist/taxonomy/profiles.js +1 -0
  206. package/dist/taxonomy/profiles.js.map +1 -1
  207. package/dist/version.d.ts +1 -1
  208. package/dist/version.js +1 -1
  209. package/package.json +3 -1
  210. package/templates/agents/canonical.md +1 -3
  211. package/templates/conventions/baseline-conventions.md +27 -0
  212. package/templates/conventions/{custom-convention-seed.md → house-conventions-seed.md} +15 -2
  213. package/templates/hooks/pre-push.sh +1 -1
  214. package/templates/serve/shell.html +18 -0
  215. package/templates/serve/style.css +163 -0
  216. package/templates/skills/ctxr-land.md +32 -18
  217. package/templates/skills/ctxr-organize-audit.md +2 -10
  218. package/templates/skills/ctxr-placement.md +6 -24
  219. package/templates/skills/ctxr-publish.md +84 -0
  220. package/templates/skills/ctxr-session-capture.md +43 -3
  221. package/templates/skills/ctxr-session-lifecycle.md +20 -1
  222. package/templates/skills/ctxr-submit.md +15 -11
  223. package/templates/vendor/eli5/LICENSE.txt +21 -0
  224. package/templates/vendor/eli5/SKILL.md +116 -0
  225. package/templates/vendor/eli5/provenance.json +8 -0
  226. package/templates/vendor/frontend-design/LICENSE.txt +177 -0
  227. package/templates/vendor/frontend-design/SKILL.md +55 -0
  228. package/templates/vendor/frontend-design/provenance.json +7 -0
  229. package/dist/adapters/forge/github.d.ts +0 -12
  230. package/dist/adapters/forge/github.d.ts.map +0 -1
  231. package/dist/adapters/forge/github.js +0 -76
  232. package/dist/adapters/forge/github.js.map +0 -1
  233. package/dist/adapters/forge/types.d.ts +0 -46
  234. package/dist/adapters/forge/types.d.ts.map +0 -1
  235. package/dist/adapters/forge/types.js +0 -2
  236. package/dist/adapters/forge/types.js.map +0 -1
  237. package/dist/commands/check.d.ts +0 -30
  238. package/dist/commands/check.d.ts.map +0 -1
  239. package/dist/commands/check.js +0 -70
  240. package/dist/commands/check.js.map +0 -1
  241. package/dist/commands/note-resolve.d.ts +0 -14
  242. package/dist/commands/note-resolve.d.ts.map +0 -1
  243. package/dist/commands/note-resolve.js +0 -24
  244. package/dist/commands/note-resolve.js.map +0 -1
  245. package/dist/commands/session-abandon.d.ts +0 -13
  246. package/dist/commands/session-abandon.d.ts.map +0 -1
  247. package/dist/commands/session-abandon.js +0 -22
  248. package/dist/commands/session-abandon.js.map +0 -1
  249. package/dist/commands/session-land.d.ts +0 -45
  250. package/dist/commands/session-land.d.ts.map +0 -1
  251. package/dist/commands/session-land.js +0 -171
  252. package/dist/commands/session-land.js.map +0 -1
  253. package/dist/commands/session-reap.d.ts +0 -22
  254. package/dist/commands/session-reap.d.ts.map +0 -1
  255. package/dist/commands/session-reap.js +0 -52
  256. package/dist/commands/session-reap.js.map +0 -1
  257. package/dist/commands/session-submit.d.ts +0 -29
  258. package/dist/commands/session-submit.d.ts.map +0 -1
  259. package/dist/commands/session-submit.js +0 -72
  260. package/dist/commands/session-submit.js.map +0 -1
  261. package/dist/core/checks/disclosure-checks.d.ts +0 -4
  262. package/dist/core/checks/disclosure-checks.d.ts.map +0 -1
  263. package/dist/core/checks/disclosure-checks.js +0 -24
  264. package/dist/core/checks/disclosure-checks.js.map +0 -1
  265. package/dist/core/disclosure/leak-scan.d.ts +0 -19
  266. package/dist/core/disclosure/leak-scan.d.ts.map +0 -1
  267. package/dist/core/disclosure/leak-scan.js +0 -31
  268. package/dist/core/disclosure/leak-scan.js.map +0 -1
  269. package/dist/core/disclosure/model.d.ts +0 -18
  270. package/dist/core/disclosure/model.d.ts.map +0 -1
  271. package/dist/core/disclosure/model.js +0 -45
  272. package/dist/core/disclosure/model.js.map +0 -1
  273. package/dist/core/graph/visibility-filter.d.ts +0 -13
  274. package/dist/core/graph/visibility-filter.d.ts.map +0 -1
  275. package/dist/core/graph/visibility-filter.js +0 -26
  276. package/dist/core/graph/visibility-filter.js.map +0 -1
  277. package/dist/core/migrations/rename-visibility-field.d.ts +0 -3
  278. package/dist/core/migrations/rename-visibility-field.d.ts.map +0 -1
  279. package/dist/core/migrations/rename-visibility-field.js +0 -62
  280. package/dist/core/migrations/rename-visibility-field.js.map +0 -1
  281. package/dist/core/notes/checks.d.ts +0 -20
  282. package/dist/core/notes/checks.d.ts.map +0 -1
  283. package/dist/core/notes/checks.js +0 -58
  284. package/dist/core/notes/checks.js.map +0 -1
  285. package/dist/core/notes/visibility.d.ts +0 -26
  286. package/dist/core/notes/visibility.d.ts.map +0 -1
  287. package/dist/core/notes/visibility.js +0 -41
  288. package/dist/core/notes/visibility.js.map +0 -1
  289. package/templates/conventions/baseline-convention.md +0 -60
@@ -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,26 @@
1
+ import type { Migration } from './types.js';
2
+ /**
3
+ * vendor-explanation-craft-skill: the shipped vendored set grew a second craft
4
+ * skill, and `init` writes the RESOLVED list into `contexture.yaml` while
5
+ * `reconcileStore` never rewrites configuration. So a change to the shipped
6
+ * default reaches new stores only; without this migration every store already
7
+ * on disk would keep a one-entry list and silently never receive the skill the
8
+ * publish skill now tells it to load.
9
+ *
10
+ * The uncomfortable part, stated rather than implied: `config/schema.ts` says
11
+ * the schema version bumps "only on a genuinely incompatible change, never on
12
+ * an additive one," and adding a skill is additive. This bumps it anyway, which
13
+ * means every existing store reports as needing `ctxr migrate` because a skill
14
+ * was added. That was the accepted price of guaranteed propagation — the
15
+ * alternatives were leaving the shipped default a lie for every store predating
16
+ * it, or an update-time nag that would never stop firing in a store that
17
+ * deliberately opted out. Do not read this as license to bump the version for
18
+ * the next additive change; weigh that one on its own.
19
+ *
20
+ * Pending-ness is the recorded schema version, never the list's contents — the
21
+ * rule 0002, 0004, 0005, and 0006 all follow, because the config schema fills
22
+ * `skills.vendored` from the shipped default when the key is absent, so an
23
+ * unmigrated store already reads as though it declared the new set.
24
+ */
25
+ export declare const addExplanationCraftSkillMigration: Migration;
26
+ //# sourceMappingURL=add-explanation-craft-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-explanation-craft-skill.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/add-explanation-craft-skill.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AA6C5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iCAAiC,EAAE,SA8B/C,CAAC"}
@@ -0,0 +1,94 @@
1
+ import path from 'node:path';
2
+ import { DEFAULT_VENDORED_SKILLS } from '../../config/defaults.js';
3
+ import { readConfig } from '../../config/load.js';
4
+ import { renderStoreConfig } from '../../config/render.js';
5
+ import { writeFileAtomic } from '../fs/atomic.js';
6
+ /**
7
+ * The shipped set as it stood before this change — a fixed historical literal,
8
+ * never derived from `DEFAULT_VENDORED_SKILLS`. Deriving it would make the
9
+ * "was this list ever customized?" test drift every time the shipped set grows
10
+ * again, silently re-adding to lists a later operator had curated.
11
+ */
12
+ const PREVIOUS_SHIPPED_SET = ['frontend-design'];
13
+ const SCHEMA_VERSION = 7;
14
+ function configDelta(next) {
15
+ return {
16
+ path: 'contexture.yaml',
17
+ description: `set skills.vendored to [${next.join(', ')}] and schema_version to ${SCHEMA_VERSION}`,
18
+ };
19
+ }
20
+ function versionOnlyDelta() {
21
+ return {
22
+ path: 'contexture.yaml',
23
+ description: `set schema_version to ${SCHEMA_VERSION}, leaving this store's own skills.vendored list untouched`,
24
+ };
25
+ }
26
+ /**
27
+ * The list to write, or undefined when this store's is not ours to rewrite.
28
+ *
29
+ * The heuristic 0004 and 0006 both used: a list still sitting exactly on the
30
+ * previous shipped default was never curated, so growing it matches what the
31
+ * operator already accepted. A list that was reordered, added to, or emptied to
32
+ * opt out is a decision, and re-adding to it would overwrite that decision —
33
+ * such a store gets the version bump alone.
34
+ */
35
+ function nextVendoredList(current) {
36
+ const unchanged = current.length === PREVIOUS_SHIPPED_SET.length && current.every((name, i) => name === PREVIOUS_SHIPPED_SET[i]);
37
+ if (!unchanged)
38
+ return undefined;
39
+ const shipped = [...DEFAULT_VENDORED_SKILLS];
40
+ const added = shipped.filter((name) => !current.includes(name));
41
+ return added.length > 0 ? shipped : undefined;
42
+ }
43
+ /**
44
+ * vendor-explanation-craft-skill: the shipped vendored set grew a second craft
45
+ * skill, and `init` writes the RESOLVED list into `contexture.yaml` while
46
+ * `reconcileStore` never rewrites configuration. So a change to the shipped
47
+ * default reaches new stores only; without this migration every store already
48
+ * on disk would keep a one-entry list and silently never receive the skill the
49
+ * publish skill now tells it to load.
50
+ *
51
+ * The uncomfortable part, stated rather than implied: `config/schema.ts` says
52
+ * the schema version bumps "only on a genuinely incompatible change, never on
53
+ * an additive one," and adding a skill is additive. This bumps it anyway, which
54
+ * means every existing store reports as needing `ctxr migrate` because a skill
55
+ * was added. That was the accepted price of guaranteed propagation — the
56
+ * alternatives were leaving the shipped default a lie for every store predating
57
+ * it, or an update-time nag that would never stop firing in a store that
58
+ * deliberately opted out. Do not read this as license to bump the version for
59
+ * the next additive change; weigh that one on its own.
60
+ *
61
+ * Pending-ness is the recorded schema version, never the list's contents — the
62
+ * rule 0002, 0004, 0005, and 0006 all follow, because the config schema fills
63
+ * `skills.vendored` from the shipped default when the key is absent, so an
64
+ * unmigrated store already reads as though it declared the new set.
65
+ */
66
+ export const addExplanationCraftSkillMigration = {
67
+ id: '0007-add-explanation-craft-skill',
68
+ fromVersion: 6,
69
+ toVersion: SCHEMA_VERSION,
70
+ description: `Add the explanation craft skill to a store whose skills.vendored list still sits at the previous shipped default, and bump schema_version to ${SCHEMA_VERSION}.`,
71
+ async plan(store) {
72
+ if (store.config.schema_version >= SCHEMA_VERSION)
73
+ return [];
74
+ const next = nextVendoredList(store.config.skills.vendored);
75
+ return [next ? configDelta(next) : versionOnlyDelta()];
76
+ },
77
+ async apply(store) {
78
+ if (store.config.schema_version >= SCHEMA_VERSION)
79
+ return [];
80
+ // Re-read from disk rather than trusting the store snapshot: an interrupted
81
+ // run may have written the config already, and resumability means deciding
82
+ // from current state.
83
+ const currentConfig = await readConfig(store.root);
84
+ const next = nextVendoredList(currentConfig.skills.vendored);
85
+ const nextConfig = {
86
+ ...currentConfig,
87
+ schema_version: SCHEMA_VERSION,
88
+ skills: { ...currentConfig.skills, vendored: next ?? currentConfig.skills.vendored },
89
+ };
90
+ await writeFileAtomic(path.join(store.root, 'contexture.yaml'), renderStoreConfig(nextConfig));
91
+ return [next ? configDelta(next) : versionOnlyDelta()];
92
+ },
93
+ };
94
+ //# sourceMappingURL=add-explanation-craft-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-explanation-craft-skill.js","sourceRoot":"","sources":["../../../src/core/migrations/add-explanation-craft-skill.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,24 @@
1
+ import type { Migration } from './types.js';
2
+ /**
3
+ * retire-the-access-axes: the visibility and disclosure axes are removed, and
4
+ * with them `fields.visibility` (the configurable name of the visibility
5
+ * frontmatter key).
6
+ *
7
+ * Unlike 0005, this migration cannot lean on `readConfig` having already
8
+ * stripped the legacy shape: all three keys are TOP-LEVEL, and
9
+ * `StoreConfigSchema` is `.passthrough()`, so they survive parsing intact.
10
+ * Deleting them explicitly is the whole job.
11
+ *
12
+ * No note is rewritten (design.md D3). A note's retired visibility-field key
13
+ * stays in its frontmatter, unread — `parseNote` reads frontmatter into a
14
+ * `Record<string, unknown>` and nothing consumes that key any more, so it
15
+ * costs nothing at runtime and keeps the removal cheap to reverse. Stripping
16
+ * it would make re-entry a hand re-labelling pass over every note.
17
+ *
18
+ * Pending-ness is `schema_version < 8`, not key presence — the rule every
19
+ * migration from 0002 onward established. A store could have had its config
20
+ * hand-edited to drop the keys while still sitting at an older version, and
21
+ * it still needs the version bump.
22
+ */
23
+ export declare const dropAccessAxesMigration: Migration;
24
+ //# sourceMappingURL=drop-access-axes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-access-axes.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/drop-access-axes.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AAU5D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAuBrC,CAAC"}
@@ -0,0 +1,54 @@
1
+ import path from 'node:path';
2
+ import { readConfig } from '../../config/load.js';
3
+ import { renderStoreConfig } from '../../config/render.js';
4
+ import { writeFileAtomic } from '../fs/atomic.js';
5
+ const CONFIG_DELTA = {
6
+ path: 'contexture.yaml',
7
+ description: 'remove the visibility:, disclosure:, and fields: blocks, and set schema_version to 8',
8
+ };
9
+ /** The retired top-level keys, named here as fixed historical literals — no constant for them survives. */
10
+ const RETIRED_KEYS = ['visibility', 'disclosure', 'fields'];
11
+ /**
12
+ * retire-the-access-axes: the visibility and disclosure axes are removed, and
13
+ * with them `fields.visibility` (the configurable name of the visibility
14
+ * frontmatter key).
15
+ *
16
+ * Unlike 0005, this migration cannot lean on `readConfig` having already
17
+ * stripped the legacy shape: all three keys are TOP-LEVEL, and
18
+ * `StoreConfigSchema` is `.passthrough()`, so they survive parsing intact.
19
+ * Deleting them explicitly is the whole job.
20
+ *
21
+ * No note is rewritten (design.md D3). A note's retired visibility-field key
22
+ * stays in its frontmatter, unread — `parseNote` reads frontmatter into a
23
+ * `Record<string, unknown>` and nothing consumes that key any more, so it
24
+ * costs nothing at runtime and keeps the removal cheap to reverse. Stripping
25
+ * it would make re-entry a hand re-labelling pass over every note.
26
+ *
27
+ * Pending-ness is `schema_version < 8`, not key presence — the rule every
28
+ * migration from 0002 onward established. A store could have had its config
29
+ * hand-edited to drop the keys while still sitting at an older version, and
30
+ * it still needs the version bump.
31
+ */
32
+ export const dropAccessAxesMigration = {
33
+ id: '0008-drop-access-axes',
34
+ fromVersion: 7,
35
+ toVersion: 8,
36
+ description: 'Remove the visibility:, disclosure:, and fields: blocks from contexture.yaml, and bump schema_version to 8. No note is modified.',
37
+ async plan(store) {
38
+ if (store.config.schema_version >= 8)
39
+ return [];
40
+ return [CONFIG_DELTA];
41
+ },
42
+ async apply(store) {
43
+ if (store.config.schema_version >= 8)
44
+ return [];
45
+ const configPath = path.join(store.root, 'contexture.yaml');
46
+ const currentConfig = await readConfig(store.root);
47
+ const nextConfig = { ...currentConfig, schema_version: 8 };
48
+ for (const key of RETIRED_KEYS)
49
+ delete nextConfig[key];
50
+ await writeFileAtomic(configPath, renderStoreConfig(nextConfig));
51
+ return [CONFIG_DELTA];
52
+ },
53
+ };
54
+ //# sourceMappingURL=drop-access-axes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-access-axes.js","sourceRoot":"","sources":["../../../src/core/migrations/drop-access-axes.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,YAAY,GAAmB;IACnC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,sFAAsF;CACpG,CAAC;AAEF,2GAA2G;AAC3G,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAc;IAChD,EAAE,EAAE,uBAAuB;IAC3B,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,CAAC;IACZ,WAAW,EACT,kIAAkI;IAEpI,KAAK,CAAC,IAAI,CAAC,KAAK;QACd,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAChD,OAAO,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAK;QACf,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC5D,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,UAAU,GAA4B,EAAE,GAAG,aAAa,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QACpF,KAAK,MAAM,GAAG,IAAI,YAAY;YAAE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,eAAe,CAAC,UAAU,EAAE,iBAAiB,CAAC,UAAqD,CAAC,CAAC,CAAC;QAE5G,OAAO,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;CACF,CAAC"}
@@ -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"}
@@ -0,0 +1,49 @@
1
+ import path from 'node:path';
2
+ import { readConfig } from '../../config/load.js';
3
+ import { renderStoreConfig } from '../../config/render.js';
4
+ import { writeFileAtomic } from '../fs/atomic.js';
5
+ const CONFIG_DELTA = {
6
+ path: 'contexture.yaml',
7
+ description: 'strip any legacy kind: forge adapter declarations and the session.workspaces_external key, and set schema_version to 5',
8
+ };
9
+ /**
10
+ * session-keeps-only-what-git-cannot-do (design D2): `ctxr session
11
+ * submit`/`land`/`abandon`/`reap` and the `forge` adapter kind are removed;
12
+ * `session.workspaces_external` goes with them, its skill-rendering half
13
+ * never having worked as shipped. Both legacy shapes are ALREADY stripped
14
+ * by the time `readConfig` returns — the adapters field's lenient schema
15
+ * transform drops a `kind: forge` entry (session-keeps-only-what-git-cannot-do
16
+ * D2), and `SessionSchema`'s default strip-unknown-keys behavior drops
17
+ * `workspaces_external` — so this migration's only real work is bumping
18
+ * `schema_version` and writing the already-clean config back to disk.
19
+ *
20
+ * Pending-ness is `schema_version < 5`, not key presence — the same rule
21
+ * 0002 and 0004 established, for the same reason: an unmigrated store
22
+ * already parses as though the legacy shape were gone, so its presence in
23
+ * the parsed config can't distinguish migrated from not.
24
+ */
25
+ export const dropForgeAndWorkspacesExternalMigration = {
26
+ id: '0005-drop-forge-and-workspaces-external',
27
+ fromVersion: 4,
28
+ toVersion: 5,
29
+ description: 'Strip any legacy kind: forge adapter declarations and the session.workspaces_external key from contexture.yaml, and bump schema_version to 5.',
30
+ async plan(store) {
31
+ if (store.config.schema_version >= 5)
32
+ return [];
33
+ return [CONFIG_DELTA];
34
+ },
35
+ async apply(store) {
36
+ if (store.config.schema_version >= 5)
37
+ return [];
38
+ const configPath = path.join(store.root, 'contexture.yaml');
39
+ // readConfig() already applies the lenient schema — a raw `kind: forge`
40
+ // entry and a raw `session.workspaces_external` key are both gone from
41
+ // this object before this line runs; writing it back is what removes
42
+ // them from disk.
43
+ const currentConfig = await readConfig(store.root);
44
+ const nextConfig = { ...currentConfig, schema_version: 5 };
45
+ await writeFileAtomic(configPath, renderStoreConfig(nextConfig));
46
+ return [CONFIG_DELTA];
47
+ },
48
+ };
49
+ //# sourceMappingURL=drop-forge-and-workspaces-external.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drop-forge-and-workspaces-external.js","sourceRoot":"","sources":["../../../src/core/migrations/drop-forge-and-workspaces-external.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,YAAY,GAAmB;IACnC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,wHAAwH;CACtI,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,uCAAuC,GAAc;IAChE,EAAE,EAAE,yCAAyC;IAC7C,WAAW,EAAE,CAAC;IACd,SAAS,EAAE,CAAC;IACZ,WAAW,EACT,+IAA+I;IAEjJ,KAAK,CAAC,IAAI,CAAC,KAAK;QACd,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAChD,OAAO,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAK;QACf,IAAI,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAEhD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC5D,wEAAwE;QACxE,uEAAuE;QACvE,qEAAqE;QACrE,kBAAkB;QAClB,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,EAAE,GAAG,aAAa,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAC3D,MAAM,eAAe,CAAC,UAAU,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;QAEjE,OAAO,CAAC,YAAY,CAAC,CAAC;IACxB,CAAC;CACF,CAAC"}
@@ -1,5 +1,15 @@
1
1
  import type { Migration } from './types.js';
2
- /** Every migration contexture ships, in ascending fromVersion order. Later phases append here, nothing else. */
2
+ /**
3
+ * Every migration contexture ships, in ascending fromVersion order. Later
4
+ * phases append here, nothing else.
5
+ *
6
+ * The chain is deliberately NOT contiguous: the 1 -> 2 visibility-field
7
+ * rename was retired with the field itself (retire-the-access-axes D7), so a
8
+ * schema-1 store's first pending migration is the 2 -> 3 one, which guards on
9
+ * `schema_version < 3` and carries it straight there. `pendingMigrations`
10
+ * selects on `fromVersion >= current`, never on adjacency, so a gap costs
11
+ * nothing.
12
+ */
3
13
  export declare const MIGRATIONS: readonly Migration[];
4
14
  /** Every migration a store currently at `fromVersion` still needs to reach the CLI's supported version, in order. */
5
15
  export declare function pendingMigrations(fromVersion: number): Migration[];
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,gHAAgH;AAChH,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAI1C,CAAC;AAEF,qHAAqH;AACrH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAElE"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/registry.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAO1C,CAAC;AAEF,qHAAqH;AACrH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,CAElE"}
@@ -1,11 +1,27 @@
1
+ import { addExplanationCraftSkillMigration } from './add-explanation-craft-skill.js';
2
+ import { archiveDestinationFromTaxonomyMigration } from './archive-destination-from-taxonomy.js';
3
+ import { dropAccessAxesMigration } from './drop-access-axes.js';
4
+ import { dropForgeAndWorkspacesExternalMigration } from './drop-forge-and-workspaces-external.js';
1
5
  import { renameConventionsPathMigration } from './rename-conventions-path.js';
2
6
  import { renameProceduresPathMigration } from './rename-procedures-path.js';
3
- import { renameVisibilityFieldMigration } from './rename-visibility-field.js';
4
- /** Every migration contexture ships, in ascending fromVersion order. Later phases append here, nothing else. */
7
+ /**
8
+ * Every migration contexture ships, in ascending fromVersion order. Later
9
+ * phases append here, nothing else.
10
+ *
11
+ * The chain is deliberately NOT contiguous: the 1 -> 2 visibility-field
12
+ * rename was retired with the field itself (retire-the-access-axes D7), so a
13
+ * schema-1 store's first pending migration is the 2 -> 3 one, which guards on
14
+ * `schema_version < 3` and carries it straight there. `pendingMigrations`
15
+ * selects on `fromVersion >= current`, never on adjacency, so a gap costs
16
+ * nothing.
17
+ */
5
18
  export const MIGRATIONS = [
6
- renameVisibilityFieldMigration,
7
19
  renameProceduresPathMigration,
8
20
  renameConventionsPathMigration,
21
+ dropForgeAndWorkspacesExternalMigration,
22
+ archiveDestinationFromTaxonomyMigration,
23
+ addExplanationCraftSkillMigration,
24
+ dropAccessAxesMigration,
9
25
  ];
10
26
  /** Every migration a store currently at `fromVersion` still needs to reach the CLI's supported version, in order. */
11
27
  export function pendingMigrations(fromVersion) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/migrations/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAG9E,gHAAgH;AAChH,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,8BAA8B;IAC9B,6BAA6B;IAC7B,8BAA8B;CAC/B,CAAC;AAEF,qHAAqH;AACrH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;AACtH,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/migrations/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uCAAuC,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAG5E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAyB;IAC9C,6BAA6B;IAC7B,8BAA8B;IAC9B,uCAAuC;IACvC,uCAAuC;IACvC,iCAAiC;IACjC,uBAAuB;CACxB,CAAC;AAEF,qHAAqH;AACrH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;AACtH,CAAC"}
@@ -1,17 +1,6 @@
1
1
  import type { StoreConfig } from '../../config/schema.js';
2
- /**
3
- * The note-enumeration seam every later retrieval leg builds on. `as` is
4
- * accepted (and, until Phase 5, ignored) from Phase 0 — a real finding:
5
- * openspec/config.yaml's own authoring rule says "sequence visibility
6
- * enforcement before retrieval — a pre-filter cannot be safely retrofitted
7
- * from a post-filter," but tasks.md's phase order puts retrieval (Phase 3/4)
8
- * before visibility enforcement (Phase 5). Accepting `as` here from the
9
- * start means Phase 5 wires a real filter into an already-filterable
10
- * signature, instead of auditing every earlier traversal for safety.
11
- */
2
+ /** The note-enumeration seam every retrieval leg builds on. */
12
3
  export interface NoteQuery {
13
- /** The requesting context, for visibility filtering. Wired in Phase 5. */
14
- as?: string;
15
4
  underPrefix?: string;
16
5
  }
17
6
  export interface Note {
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAsCD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAUjE;AAkCD,wGAAwG;AACxG,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAO9G"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/core/notes/list.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAG1D,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AA0CD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAYjE;AAkCD,wGAAwG;AACxG,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,GAAE,SAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAO9G"}