ctxr-cli 0.5.0 → 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 (200) 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 +84 -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/serve.d.ts +32 -0
  46. package/dist/commands/serve.d.ts.map +1 -0
  47. package/dist/commands/serve.js +170 -0
  48. package/dist/commands/serve.js.map +1 -0
  49. package/dist/commands/update.js +3 -3
  50. package/dist/commands/update.js.map +1 -1
  51. package/dist/config/defaults.d.ts +39 -17
  52. package/dist/config/defaults.d.ts.map +1 -1
  53. package/dist/config/defaults.js +40 -21
  54. package/dist/config/defaults.js.map +1 -1
  55. package/dist/config/schema.d.ts +36 -9
  56. package/dist/config/schema.d.ts.map +1 -1
  57. package/dist/config/schema.js +71 -15
  58. package/dist/config/schema.js.map +1 -1
  59. package/dist/core/browse/link-resolver.d.ts +12 -0
  60. package/dist/core/browse/link-resolver.d.ts.map +1 -0
  61. package/dist/core/browse/link-resolver.js +12 -0
  62. package/dist/core/browse/link-resolver.js.map +1 -0
  63. package/dist/core/browse/render.d.ts +5 -0
  64. package/dist/core/browse/render.d.ts.map +1 -0
  65. package/dist/core/browse/render.js +66 -0
  66. package/dist/core/browse/render.js.map +1 -0
  67. package/dist/core/browse/routes.d.ts +31 -0
  68. package/dist/core/browse/routes.d.ts.map +1 -0
  69. package/dist/core/browse/routes.js +56 -0
  70. package/dist/core/browse/routes.js.map +1 -0
  71. package/dist/core/browse/templates.d.ts +4 -0
  72. package/dist/core/browse/templates.d.ts.map +1 -0
  73. package/dist/core/browse/templates.js +26 -0
  74. package/dist/core/browse/templates.js.map +1 -0
  75. package/dist/core/checks/integrity-checks.d.ts +18 -2
  76. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  77. package/dist/core/checks/integrity-checks.js +55 -10
  78. package/dist/core/checks/integrity-checks.js.map +1 -1
  79. package/dist/core/checks/organize-checks.d.ts +9 -1
  80. package/dist/core/checks/organize-checks.d.ts.map +1 -1
  81. package/dist/core/checks/organize-checks.js +13 -3
  82. package/dist/core/checks/organize-checks.js.map +1 -1
  83. package/dist/core/convention-doc.d.ts +8 -9
  84. package/dist/core/convention-doc.d.ts.map +1 -1
  85. package/dist/core/convention-doc.js +45 -18
  86. package/dist/core/convention-doc.js.map +1 -1
  87. package/dist/core/conventions.d.ts +2 -2
  88. package/dist/core/conventions.js +2 -2
  89. package/dist/core/disclosure/model.d.ts +11 -0
  90. package/dist/core/disclosure/model.d.ts.map +1 -1
  91. package/dist/core/disclosure/model.js +24 -0
  92. package/dist/core/disclosure/model.js.map +1 -1
  93. package/dist/core/errors.d.ts +27 -41
  94. package/dist/core/errors.d.ts.map +1 -1
  95. package/dist/core/errors.js +76 -119
  96. package/dist/core/errors.js.map +1 -1
  97. package/dist/core/git/repo.d.ts +0 -6
  98. package/dist/core/git/repo.d.ts.map +1 -1
  99. package/dist/core/git/repo.js +0 -13
  100. package/dist/core/git/repo.js.map +1 -1
  101. package/dist/core/git/worktree.d.ts +4 -7
  102. package/dist/core/git/worktree.d.ts.map +1 -1
  103. package/dist/core/git/worktree.js +4 -10
  104. package/dist/core/git/worktree.js.map +1 -1
  105. package/dist/core/graph/model.d.ts +14 -0
  106. package/dist/core/graph/model.d.ts.map +1 -1
  107. package/dist/core/graph/model.js +30 -14
  108. package/dist/core/graph/model.js.map +1 -1
  109. package/dist/core/harness/bridge.d.ts +30 -0
  110. package/dist/core/harness/bridge.d.ts.map +1 -0
  111. package/dist/core/harness/bridge.js +178 -0
  112. package/dist/core/harness/bridge.js.map +1 -0
  113. package/dist/core/json-config-merge.d.ts.map +1 -1
  114. package/dist/core/json-config-merge.js +30 -7
  115. package/dist/core/json-config-merge.js.map +1 -1
  116. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts +35 -0
  117. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts.map +1 -0
  118. package/dist/core/migrations/archive-destination-from-taxonomy.js +109 -0
  119. package/dist/core/migrations/archive-destination-from-taxonomy.js.map +1 -0
  120. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts +19 -0
  121. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts.map +1 -0
  122. package/dist/core/migrations/drop-forge-and-workspaces-external.js +49 -0
  123. package/dist/core/migrations/drop-forge-and-workspaces-external.js.map +1 -0
  124. package/dist/core/migrations/registry.d.ts.map +1 -1
  125. package/dist/core/migrations/registry.js +4 -0
  126. package/dist/core/migrations/registry.js.map +1 -1
  127. package/dist/core/notes/list.d.ts.map +1 -1
  128. package/dist/core/notes/list.js +5 -1
  129. package/dist/core/notes/list.js.map +1 -1
  130. package/dist/core/publish/script-check.d.ts +12 -0
  131. package/dist/core/publish/script-check.d.ts.map +1 -0
  132. package/dist/core/publish/script-check.js +39 -0
  133. package/dist/core/publish/script-check.js.map +1 -0
  134. package/dist/core/reconcile.d.ts +3 -0
  135. package/dist/core/reconcile.d.ts.map +1 -1
  136. package/dist/core/reconcile.js +15 -5
  137. package/dist/core/reconcile.js.map +1 -1
  138. package/dist/core/session.d.ts +9 -9
  139. package/dist/core/session.js +9 -9
  140. package/dist/core/skills.d.ts +36 -0
  141. package/dist/core/skills.d.ts.map +1 -1
  142. package/dist/core/skills.js +154 -29
  143. package/dist/core/skills.js.map +1 -1
  144. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  145. package/dist/core/write-lifecycle/path-gate.js +4 -2
  146. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  147. package/dist/prompt/inquirer-prompter.d.ts.map +1 -1
  148. package/dist/prompt/inquirer-prompter.js +11 -1
  149. package/dist/prompt/inquirer-prompter.js.map +1 -1
  150. package/dist/prompt/prompter.d.ts +16 -0
  151. package/dist/prompt/prompter.d.ts.map +1 -1
  152. package/dist/run.d.ts.map +1 -1
  153. package/dist/run.js +61 -55
  154. package/dist/run.js.map +1 -1
  155. package/dist/taxonomy/profiles.d.ts +11 -0
  156. package/dist/taxonomy/profiles.d.ts.map +1 -1
  157. package/dist/taxonomy/profiles.js +1 -0
  158. package/dist/taxonomy/profiles.js.map +1 -1
  159. package/dist/version.d.ts +1 -1
  160. package/dist/version.js +1 -1
  161. package/package.json +3 -1
  162. package/templates/agents/canonical.md +1 -1
  163. package/templates/conventions/{baseline-convention.md → baseline-conventions.md} +4 -4
  164. package/templates/conventions/{custom-convention-seed.md → house-conventions-seed.md} +15 -2
  165. package/templates/hooks/pre-push.sh +1 -1
  166. package/templates/serve/shell.html +15 -0
  167. package/templates/serve/style.css +88 -0
  168. package/templates/skills/ctxr-land.md +32 -18
  169. package/templates/skills/ctxr-organize-audit.md +1 -1
  170. package/templates/skills/ctxr-publish.md +79 -0
  171. package/templates/skills/ctxr-session-capture.md +44 -1
  172. package/templates/skills/ctxr-session-lifecycle.md +20 -1
  173. package/templates/skills/ctxr-submit.md +15 -11
  174. package/templates/vendor/frontend-design/LICENSE.txt +177 -0
  175. package/templates/vendor/frontend-design/SKILL.md +55 -0
  176. package/templates/vendor/frontend-design/provenance.json +7 -0
  177. package/dist/adapters/forge/github.d.ts +0 -12
  178. package/dist/adapters/forge/github.d.ts.map +0 -1
  179. package/dist/adapters/forge/github.js +0 -76
  180. package/dist/adapters/forge/github.js.map +0 -1
  181. package/dist/adapters/forge/types.d.ts +0 -46
  182. package/dist/adapters/forge/types.d.ts.map +0 -1
  183. package/dist/adapters/forge/types.js +0 -2
  184. package/dist/adapters/forge/types.js.map +0 -1
  185. package/dist/commands/session-abandon.d.ts +0 -13
  186. package/dist/commands/session-abandon.d.ts.map +0 -1
  187. package/dist/commands/session-abandon.js +0 -22
  188. package/dist/commands/session-abandon.js.map +0 -1
  189. package/dist/commands/session-land.d.ts +0 -45
  190. package/dist/commands/session-land.d.ts.map +0 -1
  191. package/dist/commands/session-land.js +0 -171
  192. package/dist/commands/session-land.js.map +0 -1
  193. package/dist/commands/session-reap.d.ts +0 -22
  194. package/dist/commands/session-reap.d.ts.map +0 -1
  195. package/dist/commands/session-reap.js +0 -52
  196. package/dist/commands/session-reap.js.map +0 -1
  197. package/dist/commands/session-submit.d.ts +0 -29
  198. package/dist/commands/session-submit.d.ts.map +0 -1
  199. package/dist/commands/session-submit.js +0 -72
  200. package/dist/commands/session-submit.js.map +0 -1
@@ -22,7 +22,7 @@ import { z } from 'zod';
22
22
  * `harness.conventions_path` -> `harness.guidance_path`. HarnessSchema's
23
23
  * transform accepts the old key through this version too, the same way.
24
24
  */
25
- export declare const SUPPORTED_SCHEMA_VERSION = 4;
25
+ export declare const SUPPORTED_SCHEMA_VERSION = 6;
26
26
  export declare const TaxonomyLayerSchema: z.ZodObject<{
27
27
  name: z.ZodString;
28
28
  path: z.ZodString;
@@ -60,10 +60,10 @@ declare const HardWallSchema: z.ZodObject<{
60
60
  declare const AdapterDeclarationSchema: z.ZodObject<{
61
61
  id: z.ZodString;
62
62
  kind: z.ZodEnum<{
63
- forge: "forge";
64
63
  "harness-generation": "harness-generation";
65
64
  }>;
66
65
  module: z.ZodOptional<z.ZodString>;
66
+ skills_dir: z.ZodOptional<z.ZodString>;
67
67
  }, z.core.$strip>;
68
68
  export declare const StoreConfigSchema: z.ZodObject<{
69
69
  schema_version: z.ZodNumber;
@@ -102,7 +102,6 @@ export declare const StoreConfigSchema: z.ZodObject<{
102
102
  session: z.ZodObject<{
103
103
  branch_prefix: z.ZodString;
104
104
  worktrees_path: z.ZodString;
105
- workspaces_external: z.ZodDefault<z.ZodBoolean>;
106
105
  }, z.core.$strip>;
107
106
  write_lifecycle: z.ZodObject<{
108
107
  diff_size_ceiling_lines: z.ZodNumber;
@@ -112,6 +111,12 @@ export declare const StoreConfigSchema: z.ZodObject<{
112
111
  path: z.ZodString;
113
112
  section_max_bytes: z.ZodNumber;
114
113
  }, z.core.$strip>;
114
+ publish: z.ZodDefault<z.ZodObject<{
115
+ path: z.ZodDefault<z.ZodString>;
116
+ }, z.core.$strip>>;
117
+ skills: z.ZodDefault<z.ZodObject<{
118
+ vendored: z.ZodDefault<z.ZodArray<z.ZodString>>;
119
+ }, z.core.$strip>>;
115
120
  disclosure: z.ZodObject<{
116
121
  internal_audiences: z.ZodArray<z.ZodString>;
117
122
  hard_walls: z.ZodArray<z.ZodObject<{
@@ -130,11 +135,21 @@ export declare const StoreConfigSchema: z.ZodObject<{
130
135
  inbox_path: z.ZodString;
131
136
  tracking_params: z.ZodDefault<z.ZodArray<z.ZodString>>;
132
137
  }, z.core.$strip>;
133
- organize: z.ZodObject<{
134
- archive_path: z.ZodString;
138
+ organize: z.ZodPipe<z.ZodObject<{
139
+ archive_destination: z.ZodOptional<z.ZodString>;
140
+ archive_path: z.ZodOptional<z.ZodString>;
135
141
  rollup_stale_days: z.ZodDefault<z.ZodNumber>;
136
142
  mission_path: z.ZodOptional<z.ZodString>;
137
- }, z.core.$strip>;
143
+ }, z.core.$strip>, z.ZodTransform<{
144
+ archive_destination: string;
145
+ rollup_stale_days: number;
146
+ mission_path?: string | undefined;
147
+ }, {
148
+ archive_destination?: string | undefined;
149
+ archive_path?: string | undefined;
150
+ rollup_stale_days: number;
151
+ mission_path?: string | undefined;
152
+ }>>;
138
153
  harness: z.ZodPipe<z.ZodObject<{
139
154
  skills_path: z.ZodOptional<z.ZodString>;
140
155
  procedures_path: z.ZodOptional<z.ZodString>;
@@ -152,14 +167,26 @@ export declare const StoreConfigSchema: z.ZodObject<{
152
167
  conventions_path?: string | undefined;
153
168
  convention_max_bytes?: number | undefined;
154
169
  }>>;
155
- adapters: z.ZodArray<z.ZodObject<{
170
+ adapters: z.ZodPipe<z.ZodPipe<z.ZodArray<z.ZodObject<{
171
+ id: z.ZodString;
172
+ kind: z.ZodString;
173
+ module: z.ZodOptional<z.ZodString>;
174
+ }, z.core.$strip>>, z.ZodTransform<{
175
+ id: string;
176
+ kind: string;
177
+ module?: string | undefined;
178
+ }[], {
179
+ id: string;
180
+ kind: string;
181
+ module?: string | undefined;
182
+ }[]>>, z.ZodArray<z.ZodObject<{
156
183
  id: z.ZodString;
157
184
  kind: z.ZodEnum<{
158
- forge: "forge";
159
185
  "harness-generation": "harness-generation";
160
186
  }>;
161
187
  module: z.ZodOptional<z.ZodString>;
162
- }, z.core.$strip>>;
188
+ skills_dir: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strip>>>;
163
190
  }, z.core.$loose>;
164
191
  export type StoreConfig = z.infer<typeof StoreConfigSchema>;
165
192
  export type TaxonomyLayerConfig = z.infer<typeof TaxonomyLayerSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAqCH;;;;;;GAMG;AACH,QAAA,MAAM,mBAAmB;;;;;iBAKvB,CAAC;AA2CH;;;;;GAKG;AACH,QAAA,MAAM,cAAc;;;;;;;;;iBAQlB,CAAC;AAyGH,QAAA,MAAM,wBAAwB;;;;;;;iBAI5B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBd,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;GAIG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,eAAO,MAAM,mBAAmB;;;;iBAI9B,CAAC;AAqCH;;;;;;GAMG;AACH,QAAA,MAAM,mBAAmB;;;;;iBAKvB,CAAC;AAwDH;;;;;GAKG;AACH,QAAA,MAAM,cAAc;;;;;;;;;iBAQlB,CAAC;AAmIH,QAAA,MAAM,wBAAwB;;;;;;;iBAM5B,CAAC;AAiBH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoBd,CAAC;AAEjB,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { DEFAULT_ARCHIVE_DESTINATION, DEFAULT_PUBLISH_PATH, DEFAULT_VENDORED_SKILLS } from './defaults.js';
2
3
  /**
3
4
  * store-lifecycle spec: schema_version versions STORE STATE (config shape +
4
5
  * note frontmatter conventions) — a monotonic integer independent of the npm
@@ -22,7 +23,7 @@ import { z } from 'zod';
22
23
  * `harness.conventions_path` -> `harness.guidance_path`. HarnessSchema's
23
24
  * transform accepts the old key through this version too, the same way.
24
25
  */
25
- export const SUPPORTED_SCHEMA_VERSION = 4;
26
+ export const SUPPORTED_SCHEMA_VERSION = 6;
26
27
  export const TaxonomyLayerSchema = z.object({
27
28
  name: z.string().min(1),
28
29
  path: z.string().min(1),
@@ -87,17 +88,9 @@ const RetrievalSchema = z.object({
87
88
  const GitSchema = z.object({
88
89
  default_branch: z.string().min(1),
89
90
  });
90
- /**
91
- * write-lifecycle spec: `workspaces_external: true` marks a store whose
92
- * session worktrees are created/removed by a process outside `ctxr` (e.g. an
93
- * external agent-runtime WebUI) — `ctxr session reap` refuses to run rather
94
- * than touch a worktree it does not own. Defaults to `false`, the prior
95
- * behavior, for every store that does not set it.
96
- */
97
91
  const SessionSchema = z.object({
98
92
  branch_prefix: z.string().min(1),
99
93
  worktrees_path: z.string().min(1),
100
- workspaces_external: z.boolean().default(false),
101
94
  });
102
95
  /** session-capture-command spec (D5): declaring any path here turns the sanctioned-location gate on; empty (the default) leaves every in-store path accepted. */
103
96
  const WriteLifecycleSchema = z.object({
@@ -108,6 +101,25 @@ const CatalogSchema = z.object({
108
101
  path: z.string().min(1),
109
102
  section_max_bytes: z.number().int().positive(),
110
103
  });
104
+ /**
105
+ * publish spec (design.md): unlike every other tool-owned path field, this one is
106
+ * schema-optional with a default — a `contexture.yaml` written before this field
107
+ * existed has no `publish:` key at all, and `readConfig`'s strict `safeParse` has
108
+ * no default-merging, so a required field here would break every pre-existing
109
+ * store. `init` still writes it explicitly for a freshly generated config.
110
+ */
111
+ const PublishSchema = z.object({
112
+ path: z.string().min(1).default(DEFAULT_PUBLISH_PATH),
113
+ });
114
+ /**
115
+ * harness-portability spec (vendored-craft-skills): which vendored
116
+ * third-party skills a store wants, defaulting to the shipped set so a
117
+ * `contexture.yaml` predating this key still parses. An empty list opts
118
+ * out entirely — same schema-optional-with-default shape as `publish`.
119
+ */
120
+ const SkillsSchema = z.object({
121
+ vendored: z.array(z.string()).default([...DEFAULT_VENDORED_SKILLS]),
122
+ });
111
123
  /**
112
124
  * disclosure-policy spec: "v1 keeps the disclosure ladder's shape with a
113
125
  * flat, user-defined value list" (design.md) — no registry syntax, just a
@@ -137,9 +149,26 @@ const IngestSchema = z.object({
137
149
  .array(z.string())
138
150
  .default(['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid']),
139
151
  });
140
- /** context-organize spec: archive's destination — independent of taxonomy layers, so it works under any profile. */
141
- const OrganizeSchema = z.object({
142
- archive_path: z.string().min(1),
152
+ /**
153
+ * context-organize spec: archive's destination — independent of taxonomy
154
+ * layers, so it works under any profile.
155
+ *
156
+ * archive-destination-from-taxonomy migration (0006): `archive_destination`
157
+ * is the current key; `archive_path` is its pre-migration name, accepted
158
+ * here so a store on schema 5 still loads. Like `harness.guidance_path` and
159
+ * unlike `harness.skills_path`, this key always had a workable default, so
160
+ * an unmigrated store loads silently onto that default rather than erroring
161
+ * — `ctxr migrate` rewrites the key (and, for a profile that declares a
162
+ * destination, the value) but nothing breaks before it runs.
163
+ *
164
+ * The transform below is the ONLY place the old spelling is read — every
165
+ * other consumer sees `config.organize.archive_destination` and nothing
166
+ * else, so `archive_path` never leaks past config loading.
167
+ */
168
+ const OrganizeSchema = z
169
+ .object({
170
+ archive_destination: z.string().min(1).optional(),
171
+ archive_path: z.string().min(1).optional(),
143
172
  /** store-primitives-from-migration-audit spec (D4): the grace period, in days, before a stale rollup is reported — bounds noise from a backlink edited moments ago. */
144
173
  rollup_stale_days: z.number().int().nonnegative().default(7),
145
174
  /**
@@ -151,7 +180,16 @@ const OrganizeSchema = z.object({
151
180
  * time rather than backlinks (see `checkMissionStaleness`).
152
181
  */
153
182
  mission_path: z.string().min(1).optional(),
154
- });
183
+ })
184
+ .transform((value) => ({
185
+ archive_destination: value.archive_destination ?? value.archive_path ?? DEFAULT_ARCHIVE_DESTINATION,
186
+ rollup_stale_days: value.rollup_stale_days,
187
+ // Spread, not a plain key, so the output type keeps `mission_path`
188
+ // genuinely optional (`key?: string`) rather than always-present-but-
189
+ // possibly-undefined — the latter would force every `StoreConfig`
190
+ // object literal in the codebase to add the key just to compile.
191
+ ...(value.mission_path !== undefined ? { mission_path: value.mission_path } : {}),
192
+ }));
155
193
  /**
156
194
  * harness-portability spec: the portable skill pack and the guidance
157
195
  * documents (a shipped baseline convention file, the operator's own
@@ -220,12 +258,28 @@ const HarnessSchema = z
220
258
  * v1 resolves every entry against the built-in adapter registry by
221
259
  * (kind, id).
222
260
  */
223
- const AdapterKindSchema = z.enum(['harness-generation', 'forge']);
261
+ const AdapterKindSchema = z.enum(['harness-generation']);
224
262
  const AdapterDeclarationSchema = z.object({
225
263
  id: z.string().min(1),
226
264
  kind: AdapterKindSchema,
227
265
  module: z.string().min(1).optional(),
266
+ /** vendored-craft-skills spec: overrides a harness-generation adapter's declared skillsDir for this store; equal to the configured skills path means no bridge is created. */
267
+ skills_dir: z.string().min(1).optional(),
228
268
  });
269
+ /**
270
+ * session-keeps-only-what-git-cannot-do (D2): removing the `forge` kind
271
+ * outright would make a store still declaring `{ kind: forge }` fail to
272
+ * load at all — a shape error, not a migration opportunity — since
273
+ * `readConfig` runs this schema before `ctxr migrate` can act. Mirrors
274
+ * `HarnessSchema`'s fallback-transform precedent: accept the legacy shape
275
+ * loosely, drop it here, and let the schema_version < 5 migration rewrite
276
+ * the YAML on disk. Any OTHER unrecognized kind is a genuine error and
277
+ * still fails loudly against `AdapterDeclarationSchema` below.
278
+ */
279
+ const AdaptersFieldSchema = z
280
+ .array(z.object({ id: z.string().min(1), kind: z.string().min(1), module: z.string().min(1).optional() }))
281
+ .transform((declarations) => declarations.filter((d) => d.kind !== 'forge'))
282
+ .pipe(z.array(AdapterDeclarationSchema));
229
283
  export const StoreConfigSchema = z
230
284
  .object({
231
285
  schema_version: z.number().int().positive(),
@@ -238,11 +292,13 @@ export const StoreConfigSchema = z
238
292
  session: SessionSchema,
239
293
  write_lifecycle: WriteLifecycleSchema,
240
294
  catalog: CatalogSchema,
295
+ publish: PublishSchema.default({ path: DEFAULT_PUBLISH_PATH }),
296
+ skills: SkillsSchema.default({ vendored: [...DEFAULT_VENDORED_SKILLS] }),
241
297
  disclosure: DisclosureSchema,
242
298
  ingest: IngestSchema,
243
299
  organize: OrganizeSchema,
244
300
  harness: HarnessSchema,
245
- adapters: z.array(AdapterDeclarationSchema),
301
+ adapters: AdaptersFieldSchema,
246
302
  })
247
303
  .passthrough();
248
304
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type StemResolution } from '../graph/model.js';
2
+ import type { Note } from '../notes/list.js';
3
+ /** A wikilink target -> a resolved note path, or a reason it didn't resolve to exactly one note. */
4
+ export type LinkResolver = (target: string) => StemResolution;
5
+ /**
6
+ * local-browsing-surface design.md D3: backed by the exact same stem index
7
+ * `ctxr graph build` resolves wikilinks against, so a note that renders
8
+ * cleanly in the browser view is, by construction, a note the graph build
9
+ * also resolves cleanly — never a second, potentially divergent resolver.
10
+ */
11
+ export declare function buildLinkResolver(notes: readonly Note[]): LinkResolver;
12
+ //# sourceMappingURL=link-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-resolver.d.ts","sourceRoot":"","sources":["../../../src/core/browse/link-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,oGAAoG;AACpG,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,CAAC;AAE9D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,YAAY,CAGtE"}
@@ -0,0 +1,12 @@
1
+ import { buildStemIndex, resolveStem } from '../graph/model.js';
2
+ /**
3
+ * local-browsing-surface design.md D3: backed by the exact same stem index
4
+ * `ctxr graph build` resolves wikilinks against, so a note that renders
5
+ * cleanly in the browser view is, by construction, a note the graph build
6
+ * also resolves cleanly — never a second, potentially divergent resolver.
7
+ */
8
+ export function buildLinkResolver(notes) {
9
+ const stemIndex = buildStemIndex(notes);
10
+ return (target) => resolveStem(stemIndex, target);
11
+ }
12
+ //# sourceMappingURL=link-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-resolver.js","sourceRoot":"","sources":["../../../src/core/browse/link-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAuB,MAAM,mBAAmB,CAAC;AAMrF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACtD,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,CAAC,MAAc,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { LinkResolver } from './link-resolver.js';
2
+ export declare function escapeHtml(text: string): string;
3
+ /** Renders a note's markdown body to HTML, with wikilinks resolved via `resolveLink` (design.md D3). */
4
+ export declare function renderNoteBody(body: string, resolveLink: LinkResolver): string;
5
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/core/browse/render.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA+CvD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAuBD,wGAAwG;AACxG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,GAAG,MAAM,CAE9E"}
@@ -0,0 +1,66 @@
1
+ import MarkdownIt from 'markdown-it';
2
+ const OPEN = 0x5b; // '['
3
+ /**
4
+ * local-browsing-surface design.md D3: a resolvable `[[Target]]` becomes a
5
+ * real link to that note's route; an unresolved or ambiguous one becomes
6
+ * visibly-marked, non-clickable markup naming the reason — never a link to
7
+ * an arbitrary or wrong target. Target extraction (up to the first `]`,
8
+ * `|`, or `#`) mirrors `extractLinks`' `WIKILINK_RE` in
9
+ * `src/core/graph/model.ts`, so a link this parses is a link the graph
10
+ * build parses identically.
11
+ */
12
+ function wikilinkRule(state, silent) {
13
+ const start = state.pos;
14
+ const max = state.posMax;
15
+ if (start + 3 >= max)
16
+ return false;
17
+ if (state.src.charCodeAt(start) !== OPEN || state.src.charCodeAt(start + 1) !== OPEN)
18
+ return false;
19
+ const end = state.src.indexOf(']]', start + 2);
20
+ if (end === -1 || end > max)
21
+ return false;
22
+ const rawInner = state.src.slice(start + 2, end);
23
+ const targetMatch = /^([^\]|#]+)/.exec(rawInner);
24
+ const target = targetMatch?.[1]?.trim();
25
+ if (!target)
26
+ return false;
27
+ const pipeIdx = rawInner.indexOf('|');
28
+ const label = (pipeIdx !== -1 ? rawInner.slice(pipeIdx + 1).trim() : '') || target;
29
+ if (!silent) {
30
+ const token = state.push('wikilink', '', 0);
31
+ token.meta = { target, label };
32
+ }
33
+ state.pos = end + 2;
34
+ return true;
35
+ }
36
+ export function escapeHtml(text) {
37
+ return text
38
+ .replace(/&/g, '&amp;')
39
+ .replace(/</g, '&lt;')
40
+ .replace(/>/g, '&gt;')
41
+ .replace(/"/g, '&quot;');
42
+ }
43
+ function renderWikilink(resolveLink) {
44
+ return (tokens, idx) => {
45
+ const { target, label } = tokens[idx].meta;
46
+ const resolution = resolveLink(target);
47
+ const safeLabel = escapeHtml(label);
48
+ if ('path' in resolution) {
49
+ return `<a href="/notes/${encodeURI(resolution.path)}">${safeLabel}</a>`;
50
+ }
51
+ const reasonText = resolution.reason === 'ambiguous' ? 'ambiguous' : 'unresolved';
52
+ const title = `${reasonText} wikilink target: ${target}`;
53
+ return `<span class="ctxr-broken-link" data-reason="${resolution.reason}" title="${escapeHtml(title)}">${safeLabel}</span>`;
54
+ };
55
+ }
56
+ function buildRenderer(resolveLink) {
57
+ const md = new MarkdownIt({ html: false, linkify: true });
58
+ md.inline.ruler.before('link', 'wikilink', wikilinkRule);
59
+ md.renderer.rules.wikilink = renderWikilink(resolveLink);
60
+ return md;
61
+ }
62
+ /** Renders a note's markdown body to HTML, with wikilinks resolved via `resolveLink` (design.md D3). */
63
+ export function renderNoteBody(body, resolveLink) {
64
+ return buildRenderer(resolveLink).render(body);
65
+ }
66
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/core/browse/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type Note } from '../notes/list.js';
2
+ import type { Store } from '../store.js';
3
+ export interface CatalogRoute {
4
+ id: string;
5
+ absolutePath: string;
6
+ }
7
+ export interface PublishFileRoute {
8
+ /** URL-relative path under /publish/, e.g. "my-page/index.html". */
9
+ urlPath: string;
10
+ absolutePath: string;
11
+ }
12
+ export interface RouteTable {
13
+ /** Keyed by store-relative note path (the same string used as the note's URL and its graph node id). */
14
+ notes: ReadonlyMap<string, Note>;
15
+ /** Keyed by catalog section id. */
16
+ catalog: ReadonlyMap<string, CatalogRoute>;
17
+ graphDocumentPath: string;
18
+ /** Keyed by the exact URL-relative path under /publish/ — a lookup miss is the only traversal guard needed (design.md D2). */
19
+ publishFiles: ReadonlyMap<string, PublishFileRoute>;
20
+ }
21
+ /**
22
+ * local-browsing-surface design.md D2: built fresh from the store's own
23
+ * enumeration on every call, never cached — so a path outside every
24
+ * configured location is absent from the table by construction, and a
25
+ * request for it is an ordinary lookup miss rather than a check that could
26
+ * be forgotten on one route and not another.
27
+ */
28
+ export declare function buildRouteTable(store: Store): Promise<RouteTable>;
29
+ /** The distinct top-level page folders under the publish route, for the index page. */
30
+ export declare function publishSlugs(table: RouteTable): string[];
31
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/core/browse/routes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,wGAAwG;IACxG,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjC,mCAAmC;IACnC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8HAA8H;IAC9H,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACrD;AAuBD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAevE;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,CAOxD"}
@@ -0,0 +1,56 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { catalogSectionsFor, sectionFileName } from '../catalog/model.js';
4
+ import { graphDocumentPath } from '../graph/persist.js';
5
+ import { listNotes } from '../notes/list.js';
6
+ async function walkFiles(root, relative = '') {
7
+ let entries;
8
+ try {
9
+ entries = await readdir(path.join(root, relative), { withFileTypes: true });
10
+ }
11
+ catch (err) {
12
+ if (err.code === 'ENOENT')
13
+ return [];
14
+ throw err;
15
+ }
16
+ const files = [];
17
+ for (const entry of entries) {
18
+ const entryRelative = relative ? `${relative}/${entry.name}` : entry.name;
19
+ if (entry.isDirectory()) {
20
+ files.push(...(await walkFiles(root, entryRelative)));
21
+ }
22
+ else if (entry.isFile()) {
23
+ files.push({ urlPath: entryRelative, absolutePath: path.join(root, entryRelative) });
24
+ }
25
+ }
26
+ return files;
27
+ }
28
+ /**
29
+ * local-browsing-surface design.md D2: built fresh from the store's own
30
+ * enumeration on every call, never cached — so a path outside every
31
+ * configured location is absent from the table by construction, and a
32
+ * request for it is an ordinary lookup miss rather than a check that could
33
+ * be forgotten on one route and not another.
34
+ */
35
+ export async function buildRouteTable(store) {
36
+ const noteList = await listNotes(store.root, store.config);
37
+ const notes = new Map(noteList.map((note) => [note.path, note]));
38
+ const catalog = new Map(catalogSectionsFor(store.config).map((section) => [
39
+ section.id,
40
+ { id: section.id, absolutePath: path.join(store.root, store.config.catalog.path, sectionFileName(section)) },
41
+ ]));
42
+ const publishRoot = path.join(store.root, store.config.publish.path);
43
+ const publishFiles = new Map((await walkFiles(publishRoot)).map((file) => [file.urlPath, file]));
44
+ return { notes, catalog, graphDocumentPath: graphDocumentPath(store), publishFiles };
45
+ }
46
+ /** The distinct top-level page folders under the publish route, for the index page. */
47
+ export function publishSlugs(table) {
48
+ const slugs = new Set();
49
+ for (const urlPath of table.publishFiles.keys()) {
50
+ const slug = urlPath.split('/')[0];
51
+ if (slug)
52
+ slugs.add(slug);
53
+ }
54
+ return [...slugs].sort();
55
+ }
56
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/core/browse/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Wraps rendered body HTML in the shared page shell, substituting both slots exactly once each. */
2
+ export declare function renderShell(title: string, bodyHtml: string): Promise<string>;
3
+ export declare function readStylesheet(): Promise<string>;
4
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/core/browse/templates.ts"],"names":[],"mappings":"AAoBA,oGAAoG;AACpG,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlF;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAEtD"}
@@ -0,0 +1,26 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ * local-browsing-surface design.md D7: shell.html/style.css are markup and
6
+ * CSS, not markdown fragments meant for splicing, so they don't fit
7
+ * `packagedTemplate()`'s contract (strips exactly one trailing newline from
8
+ * a `.md` file, for `substituteBlock`'s line-array callers). This mirrors
9
+ * `hooks.ts`'s own small async reader for the same reason: a different file
10
+ * type needs a different loading contract, not a stretched shared one.
11
+ */
12
+ function templatesDir() {
13
+ return fileURLToPath(new URL('../../../templates/serve', import.meta.url));
14
+ }
15
+ async function readServeTemplate(fileName) {
16
+ return readFile(path.join(templatesDir(), fileName), 'utf8');
17
+ }
18
+ /** Wraps rendered body HTML in the shared page shell, substituting both slots exactly once each. */
19
+ export async function renderShell(title, bodyHtml) {
20
+ const shell = await readServeTemplate('shell.html');
21
+ return shell.replace('{{TITLE}}', title).replace('{{BODY}}', bodyHtml);
22
+ }
23
+ export async function readStylesheet() {
24
+ return readServeTemplate('style.css');
25
+ }
26
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/core/browse/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;GAOG;AACH,SAAS,YAAY;IACnB,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,0BAA0B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IAC/C,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,QAAgB;IAC/D,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,OAAO,iBAAiB,CAAC,WAAW,CAAC,CAAC;AACxC,CAAC"}
@@ -8,17 +8,33 @@
8
8
  */
9
9
  export declare const derivedArtifactStalenessCheck: import("./types.js").CheckDefinition;
10
10
  /**
11
- * store-integrity spec: "dangling links... (per context-retrieval)." A
11
+ * store-integrity spec: "ambiguous link resolution... (per context-retrieval)." A
12
12
  * genuine identity collision is NOT re-checked here — buildGraphFromNotes
13
13
  * refuses to persist a graph that has one (core/graph/model.ts), so a
14
14
  * persisted graph.json is proof by construction that none exists; there is
15
15
  * nothing for a doctor check to find after the fact.
16
+ *
17
+ * `graph.dangling` covers two reasons (core/graph/model.ts: DanglingReason).
18
+ * They're split by owner, not shared: a link that resolves to no note at all
19
+ * (`not_found`) can't be told apart from a healthy forward reference, so it's
20
+ * lint's alone (organize-checks.ts:brokenLinksCheck, observation, code
21
+ * organize.broken_link). A link that resolves ambiguously, to more than one
22
+ * note (`ambiguous`), is always a mechanical defect with a fix (alias
23
+ * syntax) — never a legitimate "leave it" case — so it's this check's alone.
16
24
  */
17
- export declare const graphDanglingLinksCheck: import("./types.js").CheckDefinition;
25
+ export declare const graphAmbiguousLinksCheck: import("./types.js").CheckDefinition;
18
26
  /** store-integrity spec: "schema version currency (per store-lifecycle)." */
19
27
  export declare const schemaVersionCurrencyCheck: import("./types.js").CheckDefinition;
20
28
  /** store-integrity spec: "adapter compatibility (per adapters)." */
21
29
  export declare const adapterCompatibilityCheck: import("./types.js").CheckDefinition;
30
+ /**
31
+ * harness-portability spec (vendored-craft-skills): "a broken bridge is
32
+ * detected and repaired" — the read-only half. A harness whose effective
33
+ * directory already equals the configured skills path has no bridge to
34
+ * check (same as `bridgeHarnessSkills` skipping it, per the adapters spec's
35
+ * "no bridge is created" scenario).
36
+ */
37
+ export declare const harnessSkillsBridgeCheck: import("./types.js").CheckDefinition;
22
38
  /**
23
39
  * harness-portability spec: "A harness-specific entry file only imports" —
24
40
  * SHALL contain nothing beyond the adapter's own managed import plus that
@@ -1 +1 @@
1
- {"version":3,"file":"integrity-checks.d.ts","sourceRoot":"","sources":["../../../src/core/checks/integrity-checks.ts"],"names":[],"mappings":"AAiCA;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,sCAkCxC,CAAC;AAEH;;;;;;GAMG;AAGH,eAAO,MAAM,uBAAuB,sCAoBlC,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,sCAsBrC,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,sCAuBpC,CAAC;AAYH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0CAA0C,sCAgDrD,CAAC;AAEH,qEAAqE;AACrE,eAAO,MAAM,6BAA6B,sCAgBxC,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,sCA4B7C,CAAC;AAqBH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wCAAwC,sCAiEnD,CAAC;AAEH,eAAO,MAAM,gBAAgB,wCAS5B,CAAC"}
1
+ {"version":3,"file":"integrity-checks.d.ts","sourceRoot":"","sources":["../../../src/core/checks/integrity-checks.ts"],"names":[],"mappings":"AAkCA;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,sCAkCxC,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,wBAAwB,sCAsBnC,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,sCAsBrC,CAAC;AAEH,oEAAoE;AACpE,eAAO,MAAM,yBAAyB,sCAuBpC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,sCAwBnC,CAAC;AAYH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0CAA0C,sCAiDrD,CAAC;AAEH,qEAAqE;AACrE,eAAO,MAAM,6BAA6B,sCAgBxC,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,sCA4B7C,CAAC;AAqBH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wCAAwC,sCAiEnD,CAAC;AAEH,eAAO,MAAM,gBAAgB,wCAU5B,CAAC"}