@cleocode/core 2026.6.7 → 2026.6.9

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 (67) hide show
  1. package/dist/db/index.d.ts +5 -1
  2. package/dist/db/index.d.ts.map +1 -1
  3. package/dist/db/index.js +5 -1
  4. package/dist/db/index.js.map +1 -1
  5. package/dist/docs/build-provenance-graph.d.ts +12 -0
  6. package/dist/docs/build-provenance-graph.d.ts.map +1 -1
  7. package/dist/docs/build-provenance-graph.js +52 -0
  8. package/dist/docs/build-provenance-graph.js.map +1 -1
  9. package/dist/docs/display-alias.d.ts +97 -0
  10. package/dist/docs/display-alias.d.ts.map +1 -0
  11. package/dist/docs/display-alias.js +136 -0
  12. package/dist/docs/display-alias.js.map +1 -0
  13. package/dist/docs/docs-read-model.d.ts +47 -0
  14. package/dist/docs/docs-read-model.d.ts.map +1 -1
  15. package/dist/docs/docs-read-model.js +40 -2
  16. package/dist/docs/docs-read-model.js.map +1 -1
  17. package/dist/docs/export-document.js +929 -732
  18. package/dist/docs/export-document.js.map +3 -3
  19. package/dist/docs/index.d.ts +6 -0
  20. package/dist/docs/index.d.ts.map +1 -1
  21. package/dist/docs/index.js +3 -0
  22. package/dist/docs/index.js.map +1 -1
  23. package/dist/docs/numbering.d.ts +29 -0
  24. package/dist/docs/numbering.d.ts.map +1 -1
  25. package/dist/docs/numbering.js +41 -0
  26. package/dist/docs/numbering.js.map +1 -1
  27. package/dist/docs/read-doc.d.ts +60 -0
  28. package/dist/docs/read-doc.d.ts.map +1 -0
  29. package/dist/docs/read-doc.js +188 -0
  30. package/dist/docs/read-doc.js.map +1 -0
  31. package/dist/docs/wikilinks.d.ts +119 -0
  32. package/dist/docs/wikilinks.d.ts.map +1 -0
  33. package/dist/docs/wikilinks.js +217 -0
  34. package/dist/docs/wikilinks.js.map +1 -0
  35. package/dist/internal.d.ts +3 -1
  36. package/dist/internal.d.ts.map +1 -1
  37. package/dist/internal.js +2 -1
  38. package/dist/internal.js.map +1 -1
  39. package/dist/llm/plugin-facade.js +973 -778
  40. package/dist/llm/plugin-facade.js.map +3 -3
  41. package/dist/store/attachment-store.d.ts +5 -0
  42. package/dist/store/attachment-store.d.ts.map +1 -1
  43. package/dist/store/attachment-store.js +7 -1
  44. package/dist/store/attachment-store.js.map +1 -1
  45. package/dist/store/dual-scope-db.d.ts +83 -0
  46. package/dist/store/dual-scope-db.d.ts.map +1 -1
  47. package/dist/store/dual-scope-db.js +135 -6
  48. package/dist/store/dual-scope-db.js.map +1 -1
  49. package/dist/store/exodus/abort-events.d.ts +116 -0
  50. package/dist/store/exodus/abort-events.d.ts.map +1 -0
  51. package/dist/store/exodus/abort-events.js +130 -0
  52. package/dist/store/exodus/abort-events.js.map +1 -0
  53. package/dist/store/exodus/index.d.ts +1 -0
  54. package/dist/store/exodus/index.d.ts.map +1 -1
  55. package/dist/store/exodus/index.js +1 -0
  56. package/dist/store/exodus/index.js.map +1 -1
  57. package/dist/store/repair-malformed-dbs.d.ts +87 -0
  58. package/dist/store/repair-malformed-dbs.d.ts.map +1 -0
  59. package/dist/store/repair-malformed-dbs.js +188 -0
  60. package/dist/store/repair-malformed-dbs.js.map +1 -0
  61. package/dist/store/schema/attachments.d.ts +149 -0
  62. package/dist/store/schema/attachments.d.ts.map +1 -1
  63. package/dist/store/schema/attachments.js +93 -0
  64. package/dist/store/schema/attachments.js.map +1 -1
  65. package/migrations/drizzle-tasks/20260605000001_t11826-docs-wikilinks/migration.sql +110 -0
  66. package/migrations/drizzle-tasks/20260606000001_t11875-attachments-display-alias/migration.sql +46 -0
  67. package/package.json +12 -12
@@ -295,6 +295,22 @@ export declare const attachments: import("drizzle-orm/sqlite-core").SQLiteTableW
295
295
  identity: undefined;
296
296
  generated: undefined;
297
297
  }, {}>;
298
+ displayAlias: import("drizzle-orm/sqlite-core").SQLiteColumn<{
299
+ name: string;
300
+ tableName: "attachments";
301
+ dataType: "number int53";
302
+ data: number;
303
+ driverParam: number;
304
+ notNull: false;
305
+ hasDefault: false;
306
+ isPrimaryKey: false;
307
+ isAutoincrement: false;
308
+ hasRuntimeDefault: false;
309
+ enumValues: undefined;
310
+ baseColumn: never;
311
+ identity: undefined;
312
+ generated: undefined;
313
+ }, {}>;
298
314
  };
299
315
  dialect: "sqlite";
300
316
  }>;
@@ -391,8 +407,141 @@ export declare const attachmentRefs: import("drizzle-orm/sqlite-core").SQLiteTab
391
407
  };
392
408
  dialect: "sqlite";
393
409
  }>;
410
+ /**
411
+ * Allowed relations for a `docs_wikilinks` edge.
412
+ *
413
+ * A wikilink is a DERIVED, slug-addressed edge between two docs (or a doc and a
414
+ * task) reconstructed from the authoritative provenance columns on
415
+ * `attachments` — there is no hand-authored edge here. The relation enumerates
416
+ * which source column produced the edge:
417
+ *
418
+ * - `supersedes` — `attachments.supersedes` (newer → older)
419
+ * - `superseded-by` — `attachments.superseded_by` (older → newer)
420
+ * - `related-task` — `attachments.related_tasks` JSON membership (doc → T####)
421
+ * - `topic` — `attachments.topics` JSON co-membership (doc ↔ doc sharing a topic)
422
+ *
423
+ * Kept slug-primary so the edge table is Obsidian-grade (vault links are
424
+ * slug-addressed) and survives attachment-id churn across versions.
425
+ *
426
+ * @task T11826 (Epic T11781 / Saga T11778)
427
+ */
428
+ export declare const DOCS_WIKILINK_RELATIONS: readonly ["supersedes", "superseded-by", "related-task", "topic"];
429
+ /** Discriminated union of `docs_wikilinks.relation` values. */
430
+ export type DocsWikilinkRelation = (typeof DOCS_WIKILINK_RELATIONS)[number];
431
+ /**
432
+ * `docs_wikilinks` — DERIVED, slug-addressed edge table for the docs graph.
433
+ *
434
+ * Per the ratified Docs-SSoT model (saga T11778): `cleo.db` is the SOLE doc
435
+ * authority, and `docs_wikilinks` is a *minimal edge table derived from*
436
+ * `supersedes` + `relatedTasks` + `topics` on `attachments`. It is NOT an
437
+ * authoritative input surface — it is rebuilt idempotently from the provenance
438
+ * columns by {@link import('../../docs/wikilinks.js').rebuildDocsWikilinks}.
439
+ *
440
+ * The table makes the bidirectional backlink graph queryable in O(edges)
441
+ * without recomputing the BFS, which is what the Obsidian plugin (T11827)
442
+ * renders. `cleo docs graph` (T10164) continues to compute the provenance BFS
443
+ * but hydrates persisted backlinks from this table when present.
444
+ *
445
+ * Edges are slug-primary; `to_slug` carries a doc slug for `topic` /
446
+ * `supersedes` / `superseded-by` edges and a `T####` task id for `related-task`
447
+ * edges (`to_is_task = 1`). No markdown body `[[link]]` parsing is performed
448
+ * (AC4) — the edges derive purely from structured provenance columns.
449
+ *
450
+ * @task T11826 (Epic T11781 / Saga T11778)
451
+ */
452
+ export declare const docsWikilinks: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
453
+ name: "docs_wikilinks";
454
+ schema: undefined;
455
+ columns: {
456
+ fromSlug: import("drizzle-orm/sqlite-core").SQLiteColumn<{
457
+ name: string;
458
+ tableName: "docs_wikilinks";
459
+ dataType: "string";
460
+ data: string;
461
+ driverParam: string;
462
+ notNull: true;
463
+ hasDefault: false;
464
+ isPrimaryKey: false;
465
+ isAutoincrement: false;
466
+ hasRuntimeDefault: false;
467
+ enumValues: [string, ...string[]];
468
+ baseColumn: never;
469
+ identity: undefined;
470
+ generated: undefined;
471
+ }, {}>;
472
+ toSlug: import("drizzle-orm/sqlite-core").SQLiteColumn<{
473
+ name: string;
474
+ tableName: "docs_wikilinks";
475
+ dataType: "string";
476
+ data: string;
477
+ driverParam: string;
478
+ notNull: true;
479
+ hasDefault: false;
480
+ isPrimaryKey: false;
481
+ isAutoincrement: false;
482
+ hasRuntimeDefault: false;
483
+ enumValues: [string, ...string[]];
484
+ baseColumn: never;
485
+ identity: undefined;
486
+ generated: undefined;
487
+ }, {}>;
488
+ relation: import("drizzle-orm/sqlite-core").SQLiteColumn<{
489
+ name: string;
490
+ tableName: "docs_wikilinks";
491
+ dataType: "string enum";
492
+ data: "topic" | "supersedes" | "superseded-by" | "related-task";
493
+ driverParam: string;
494
+ notNull: true;
495
+ hasDefault: false;
496
+ isPrimaryKey: false;
497
+ isAutoincrement: false;
498
+ hasRuntimeDefault: false;
499
+ enumValues: ["supersedes", "superseded-by", "related-task", "topic"];
500
+ baseColumn: never;
501
+ identity: undefined;
502
+ generated: undefined;
503
+ }, {}>;
504
+ toIsTask: import("drizzle-orm/sqlite-core").SQLiteColumn<{
505
+ name: string;
506
+ tableName: "docs_wikilinks";
507
+ dataType: "boolean";
508
+ data: boolean;
509
+ driverParam: number;
510
+ notNull: true;
511
+ hasDefault: true;
512
+ isPrimaryKey: false;
513
+ isAutoincrement: false;
514
+ hasRuntimeDefault: false;
515
+ enumValues: undefined;
516
+ baseColumn: never;
517
+ identity: undefined;
518
+ generated: undefined;
519
+ }, {}>;
520
+ derivedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
521
+ name: string;
522
+ tableName: "docs_wikilinks";
523
+ dataType: "string";
524
+ data: string;
525
+ driverParam: string;
526
+ notNull: true;
527
+ hasDefault: true;
528
+ isPrimaryKey: false;
529
+ isAutoincrement: false;
530
+ hasRuntimeDefault: false;
531
+ enumValues: [string, ...string[]];
532
+ baseColumn: never;
533
+ identity: undefined;
534
+ generated: undefined;
535
+ }, {}>;
536
+ };
537
+ dialect: "sqlite";
538
+ }>;
394
539
  export type AttachmentRow = typeof attachments.$inferSelect;
395
540
  export type NewAttachmentRow = typeof attachments.$inferInsert;
396
541
  export type AttachmentRefRow = typeof attachmentRefs.$inferSelect;
397
542
  export type NewAttachmentRefRow = typeof attachmentRefs.$inferInsert;
543
+ /** Row type for `docs_wikilinks` SELECT queries. */
544
+ export type DocsWikilinkRow = typeof docsWikilinks.$inferSelect;
545
+ /** Row type for `docs_wikilinks` INSERT operations. */
546
+ export type NewDocsWikilinkRow = typeof docsWikilinks.$inferInsert;
398
547
  //# sourceMappingURL=attachments.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../../src/store/schema/attachments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gFAOzB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,oFAOhC,CAAC;AAEX,0DAA0D;AAC1D,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+HvB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB1B,CAAC;AAIF,MAAM,MAAM,aAAa,GAAG,OAAO,WAAW,CAAC,YAAY,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,OAAO,WAAW,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC"}
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../../src/store/schema/attachments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gFAOzB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,6BAA6B,oFAOhC,CAAC;AAEX,0DAA0D;AAC1D,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6JvB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB1B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,mEAK1B,CAAC;AAEX,+DAA+D;AAC/D,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBzB,CAAC;AAIF,MAAM,MAAM,aAAa,GAAG,OAAO,WAAW,CAAC,YAAY,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,OAAO,WAAW,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,gBAAgB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AACrE,oDAAoD;AACpD,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AAChE,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC"}
@@ -4,6 +4,7 @@
4
4
  * @epic T760
5
5
  * @task T796
6
6
  */
7
+ import { sql } from 'drizzle-orm';
7
8
  import { index, integer, primaryKey, sqliteTable, text, } from 'drizzle-orm/sqlite-core';
8
9
  /**
9
10
  * Allowed owner-entity types for `attachment_refs.owner_type`.
@@ -167,10 +168,40 @@ export const attachments = sqliteTable('attachments', {
167
168
  * @task T11181 (Epic T10518 / Saga T10516)
168
169
  */
169
170
  docVersion: integer('doc_version').notNull().default(1),
171
+ /**
172
+ * Optional explicit display-alias NUMBER for the doc, DECOUPLED from the
173
+ * slug string.
174
+ *
175
+ * Background (T11875 · ADR reconcile T11676): under the ratified
176
+ * slug-primary model the kebab `slug` is the canonical handle and the
177
+ * displayed number (e.g. ADR "051") is a DISPLAY ALIAS only. Previously
178
+ * that number was DERIVED by parsing the digits out of the slug
179
+ * (`adr-051-*` → 051), so three distinct ADRs that all slug as `adr-051-*`
180
+ * collided on the rendered number with no way to disambiguate.
181
+ *
182
+ * When non-null, this column is the authoritative display number and is
183
+ * PREFERRED over the slug-derived number by
184
+ * {@link import('../../docs/numbering.js').resolveDisplayNumber}. When null,
185
+ * rendering falls back to the slug-derived number unchanged — so docs that
186
+ * never had an alias assigned keep their historical behaviour.
187
+ *
188
+ * Uniqueness among `type='adr'` docs is enforced at the dispatch layer (not
189
+ * via a SQL UNIQUE constraint) by
190
+ * {@link import('../../docs/display-alias.js').setDisplayAlias}, mirroring
191
+ * the dispatch-validated discipline used for `lifecycle_status` /
192
+ * `relation` so future taxonomy changes never require a schema migration.
193
+ *
194
+ * @task T11875 (Epic T11781 / Saga T11778)
195
+ */
196
+ displayAlias: integer('display_alias'),
170
197
  }, (table) => [
171
198
  index('idx_attachments_sha256').on(table.sha256),
172
199
  index('idx_attachments_lifecycle_status').on(table.lifecycleStatus),
173
200
  index('idx_attachments_supersedes').on(table.supersedes),
201
+ // Speeds the per-type uniqueness scan in `setDisplayAlias` (T11875). Not a
202
+ // UNIQUE index — uniqueness is scoped to `type='adr'` and enforced at the
203
+ // dispatch layer so non-adr kinds may reuse numbers freely.
204
+ index('idx_attachments_display_alias').on(table.displayAlias),
174
205
  ]);
175
206
  /**
176
207
  * Ref-counted junction table linking attachments to owner entities.
@@ -196,4 +227,66 @@ export const attachmentRefs = sqliteTable('attachment_refs', {
196
227
  index('idx_attachment_refs_attachment_id').on(table.attachmentId),
197
228
  index('idx_attachment_refs_owner').on(table.ownerType, table.ownerId),
198
229
  ]);
230
+ /**
231
+ * Allowed relations for a `docs_wikilinks` edge.
232
+ *
233
+ * A wikilink is a DERIVED, slug-addressed edge between two docs (or a doc and a
234
+ * task) reconstructed from the authoritative provenance columns on
235
+ * `attachments` — there is no hand-authored edge here. The relation enumerates
236
+ * which source column produced the edge:
237
+ *
238
+ * - `supersedes` — `attachments.supersedes` (newer → older)
239
+ * - `superseded-by` — `attachments.superseded_by` (older → newer)
240
+ * - `related-task` — `attachments.related_tasks` JSON membership (doc → T####)
241
+ * - `topic` — `attachments.topics` JSON co-membership (doc ↔ doc sharing a topic)
242
+ *
243
+ * Kept slug-primary so the edge table is Obsidian-grade (vault links are
244
+ * slug-addressed) and survives attachment-id churn across versions.
245
+ *
246
+ * @task T11826 (Epic T11781 / Saga T11778)
247
+ */
248
+ export const DOCS_WIKILINK_RELATIONS = [
249
+ 'supersedes',
250
+ 'superseded-by',
251
+ 'related-task',
252
+ 'topic',
253
+ ];
254
+ /**
255
+ * `docs_wikilinks` — DERIVED, slug-addressed edge table for the docs graph.
256
+ *
257
+ * Per the ratified Docs-SSoT model (saga T11778): `cleo.db` is the SOLE doc
258
+ * authority, and `docs_wikilinks` is a *minimal edge table derived from*
259
+ * `supersedes` + `relatedTasks` + `topics` on `attachments`. It is NOT an
260
+ * authoritative input surface — it is rebuilt idempotently from the provenance
261
+ * columns by {@link import('../../docs/wikilinks.js').rebuildDocsWikilinks}.
262
+ *
263
+ * The table makes the bidirectional backlink graph queryable in O(edges)
264
+ * without recomputing the BFS, which is what the Obsidian plugin (T11827)
265
+ * renders. `cleo docs graph` (T10164) continues to compute the provenance BFS
266
+ * but hydrates persisted backlinks from this table when present.
267
+ *
268
+ * Edges are slug-primary; `to_slug` carries a doc slug for `topic` /
269
+ * `supersedes` / `superseded-by` edges and a `T####` task id for `related-task`
270
+ * edges (`to_is_task = 1`). No markdown body `[[link]]` parsing is performed
271
+ * (AC4) — the edges derive purely from structured provenance columns.
272
+ *
273
+ * @task T11826 (Epic T11781 / Saga T11778)
274
+ */
275
+ export const docsWikilinks = sqliteTable('docs_wikilinks', {
276
+ /** Source doc slug (→ `attachments.slug`). Always a doc. */
277
+ fromSlug: text('from_slug').notNull(),
278
+ /** Target slug — a doc slug, or a `T####` task id when `toIsTask = 1`. */
279
+ toSlug: text('to_slug').notNull(),
280
+ /** Which provenance column produced this edge — dispatch-validated, no SQL CHECK. */
281
+ relation: text('relation', { enum: DOCS_WIKILINK_RELATIONS }).notNull(),
282
+ /** 1 when `to_slug` is a task id (`related-task` edges); 0 for doc→doc edges. */
283
+ toIsTask: integer('to_is_task', { mode: 'boolean' }).notNull().default(false),
284
+ /** ISO-8601 UTC instant this edge was last (re)derived. */
285
+ derivedAt: text('derived_at').notNull().default(sql `(datetime('now'))`),
286
+ }, (table) => [
287
+ primaryKey({ columns: [table.fromSlug, table.toSlug, table.relation] }),
288
+ index('idx_docs_wikilinks_from').on(table.fromSlug),
289
+ index('idx_docs_wikilinks_to').on(table.toSlug),
290
+ index('idx_docs_wikilinks_relation').on(table.relation),
291
+ ]);
199
292
  //# sourceMappingURL=attachments.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/store/schema/attachments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../../src/store/schema/attachments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAEL,KAAK,EACL,OAAO,EACP,UAAU,EACV,WAAW,EACX,IAAI,GACL,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,MAAM;IACN,aAAa;IACb,SAAS;IACT,UAAU;IACV,UAAU;IACV,SAAS;CACD,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,OAAO;IACP,UAAU;IACV,UAAU;IACV,YAAY;IACZ,UAAU;IACV,YAAY;CACJ,CAAC;AAKX;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CACpC,aAAa,EACb;IACE,8CAA8C;IAC9C,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC3B,kFAAkF;IAClF,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE;IACzC,8EAA8E;IAC9E,cAAc,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,EAAE;IACjD,oEAAoE;IACpE,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE;IACvC;;;;;OAKG;IACH,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD;;;;OAIG;IACH,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,eAAe,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC;SAC/E,OAAO,EAAE;SACT,OAAO,CAAC,OAAO,CAAC;IACnB;;;;;;;;;OASG;IACH,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,UAAU,CAAC,GAAoB,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IAChF;;;;;;;;OAQG;IACH,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,UAAU,CAAC,GAAoB,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IACrF;;;;;;OAMG;IACH,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;IACxB;;;;;;;;OAQG;IACH,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC;IAC1B;;;;;;OAMG;IACH,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;IACtB;;;;;;;;OAQG;IACH,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC;IACnC;;;;;;;OAOG;IACH,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC;IACnC;;;;;;;OAOG;IACH,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC;CACvC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC;IACT,KAAK,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;IAChD,KAAK,CAAC,kCAAkC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC;IACnE,KAAK,CAAC,4BAA4B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC;IACxD,2EAA2E;IAC3E,0EAA0E;IAC1E,4DAA4D;IAC5D,KAAK,CAAC,+BAA+B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;CAC9D,CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CACvC,iBAAiB,EACjB;IACE,iDAAiD;IACjD,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE;IAC7C;;OAEG;IACH,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC,OAAO,EAAE;IACzE,mCAAmC;IACnC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE;IACnC,oDAAoD;IACpD,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE;IACzC,2DAA2D;IAC3D,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC;CAChC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7E,KAAK,CAAC,mCAAmC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;IACjE,KAAK,CAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;CACtE,CACF,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,YAAY;IACZ,eAAe;IACf,cAAc;IACd,OAAO;CACC,CAAC;AAKX;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CACtC,gBAAgB,EAChB;IACE,4DAA4D;IAC5D,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE;IACrC,0EAA0E;IAC1E,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;IACjC,qFAAqF;IACrF,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC,OAAO,EAAE;IACvE,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC7E,2DAA2D;IAC3D,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA,mBAAmB,CAAC;CACxE,EACD,CAAC,KAAK,EAAE,EAAE,CAAC;IACT,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvE,KAAK,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;IACnD,KAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;IAC/C,KAAK,CAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;CACxD,CACF,CAAC"}
@@ -0,0 +1,110 @@
1
+ -- T11826 — `docs_wikilinks`: a DERIVED, slug-addressed edge table for the docs
2
+ -- provenance graph (ratified Docs-SSoT model, saga T11778).
3
+ --
4
+ -- Background:
5
+ -- `cleo.db` is the SOLE doc authority. `docs_wikilinks` is NOT an
6
+ -- authoritative input surface — it is a minimal edge table DERIVED from the
7
+ -- three provenance columns already on `attachments`:
8
+ -- - `supersedes` → newer→older edges (+ reverse `superseded-by`)
9
+ -- - `related_tasks` → doc→T#### edges (JSON array, exploded via json_each)
10
+ -- - `topics` → doc↔doc co-membership edges (shared topic slug)
11
+ -- It makes the bidirectional backlink graph queryable in O(edges) for the
12
+ -- Obsidian plugin (T11827) without recomputing the BFS. The derivation is
13
+ -- rebuilt idempotently by `rebuildDocsWikilinks` (docs/wikilinks.ts); this
14
+ -- migration creates the table and seeds the initial backfill.
15
+ --
16
+ -- Edges are slug-primary (vault links are slug-addressed and survive
17
+ -- attachment-id churn across doc versions). `to_is_task = 1` marks a
18
+ -- `related-task` edge whose `to_slug` is a `T####` id rather than a doc slug.
19
+ -- No markdown body `[[link]]` parsing is performed (AC4) — edges derive purely
20
+ -- from structured provenance columns.
21
+ --
22
+ -- Changes (idempotent — safe to re-run):
23
+ -- 1. CREATE TABLE docs_wikilinks(from_slug, to_slug, relation, to_is_task,
24
+ -- derived_at) with a composite PK + supporting indices.
25
+ -- 2. Backfill `supersedes` + `superseded-by` doc→doc edges by joining
26
+ -- `attachments` to itself on the supersedes/superseded_by FK and resolving
27
+ -- both endpoints to their slugs.
28
+ -- 3. Backfill `related-task` doc→T#### edges by exploding `related_tasks`
29
+ -- JSON arrays via json_each.
30
+ -- 4. Backfill `topic` doc↔doc edges: any two distinct slugged docs that share
31
+ -- a topic slug (json_each over `topics`) get a symmetric pair of edges.
32
+ -- INSERT OR IGNORE coalesces re-runs against the composite primary key.
33
+ --
34
+ -- DEPENDS ON: 20260524000000_t10158-docs-provenance-columns (adds supersedes /
35
+ -- superseded_by / topics / related_tasks to `attachments`)
36
+ -- SAFE FOR: SQLite 3.35+ (CREATE TABLE IF NOT EXISTS + INSERT OR IGNORE)
37
+ --
38
+ -- @task T11826
39
+ -- @epic T11781 (E3-OBSIDIAN-INTEGRATION)
40
+ -- @saga T11778 (SG-DOCS-SSOT-VAULT)
41
+
42
+ CREATE TABLE IF NOT EXISTS `docs_wikilinks` (
43
+ `from_slug` text NOT NULL,
44
+ `to_slug` text NOT NULL,
45
+ `relation` text NOT NULL,
46
+ `to_is_task` integer NOT NULL DEFAULT 0,
47
+ `derived_at` text NOT NULL DEFAULT (datetime('now')),
48
+ CONSTRAINT `docs_wikilinks_pk` PRIMARY KEY(`from_slug`, `to_slug`, `relation`)
49
+ );
50
+ --> statement-breakpoint
51
+
52
+ CREATE INDEX IF NOT EXISTS `idx_docs_wikilinks_from` ON `docs_wikilinks` (`from_slug`);
53
+ --> statement-breakpoint
54
+ CREATE INDEX IF NOT EXISTS `idx_docs_wikilinks_to` ON `docs_wikilinks` (`to_slug`);
55
+ --> statement-breakpoint
56
+ CREATE INDEX IF NOT EXISTS `idx_docs_wikilinks_relation` ON `docs_wikilinks` (`relation`);
57
+ --> statement-breakpoint
58
+
59
+ -- (2) supersedes: newer (a) → older (a.supersedes) doc→doc edge.
60
+ INSERT OR IGNORE INTO `docs_wikilinks` (`from_slug`, `to_slug`, `relation`, `to_is_task`)
61
+ SELECT a.`slug`, b.`slug`, 'supersedes', 0
62
+ FROM `attachments` AS a
63
+ JOIN `attachments` AS b ON b.`id` = a.`supersedes`
64
+ WHERE a.`slug` IS NOT NULL
65
+ AND b.`slug` IS NOT NULL
66
+ AND a.`supersedes` IS NOT NULL;
67
+ --> statement-breakpoint
68
+
69
+ -- (2b) superseded-by: older (a) → newer (a.superseded_by) doc→doc reverse edge.
70
+ INSERT OR IGNORE INTO `docs_wikilinks` (`from_slug`, `to_slug`, `relation`, `to_is_task`)
71
+ SELECT a.`slug`, b.`slug`, 'superseded-by', 0
72
+ FROM `attachments` AS a
73
+ JOIN `attachments` AS b ON b.`id` = a.`superseded_by`
74
+ WHERE a.`slug` IS NOT NULL
75
+ AND b.`slug` IS NOT NULL
76
+ AND a.`superseded_by` IS NOT NULL;
77
+ --> statement-breakpoint
78
+
79
+ -- (3) related-task: doc → T#### edge from the related_tasks JSON array.
80
+ INSERT OR IGNORE INTO `docs_wikilinks` (`from_slug`, `to_slug`, `relation`, `to_is_task`)
81
+ SELECT a.`slug`, je.`value`, 'related-task', 1
82
+ FROM `attachments` AS a,
83
+ json_each(a.`related_tasks`) AS je
84
+ WHERE a.`slug` IS NOT NULL
85
+ AND a.`related_tasks` IS NOT NULL
86
+ AND json_valid(a.`related_tasks`)
87
+ AND json_type(a.`related_tasks`) = 'array'
88
+ AND je.`value` IS NOT NULL;
89
+ --> statement-breakpoint
90
+
91
+ -- (4) topic: symmetric doc↔doc edge for any two distinct slugged docs sharing a
92
+ -- topic slug. The self-join over json_each(topics) produces both directions
93
+ -- because (a,b) and (b,a) are both yielded when a.slug <> b.slug.
94
+ INSERT OR IGNORE INTO `docs_wikilinks` (`from_slug`, `to_slug`, `relation`, `to_is_task`)
95
+ SELECT a.`slug`, b.`slug`, 'topic', 0
96
+ FROM `attachments` AS a,
97
+ json_each(a.`topics`) AS ta,
98
+ `attachments` AS b,
99
+ json_each(b.`topics`) AS tb
100
+ WHERE a.`slug` IS NOT NULL
101
+ AND b.`slug` IS NOT NULL
102
+ AND a.`slug` <> b.`slug`
103
+ AND a.`topics` IS NOT NULL
104
+ AND b.`topics` IS NOT NULL
105
+ AND json_valid(a.`topics`)
106
+ AND json_valid(b.`topics`)
107
+ AND json_type(a.`topics`) = 'array'
108
+ AND json_type(b.`topics`) = 'array'
109
+ AND ta.`value` = tb.`value`
110
+ AND ta.`value` IS NOT NULL;
@@ -0,0 +1,46 @@
1
+ -- T11875 — give ADR display-aliases real storage DECOUPLED from the slug.
2
+ --
3
+ -- Background (ADR reconcile T11676 · ratified slug-primary model, saga T11778):
4
+ -- Under the slug-primary model the kebab `slug` is the canonical handle and
5
+ -- the displayed number (e.g. ADR "051") is a DISPLAY ALIAS only. Until now
6
+ -- that number was DERIVED by parsing the digits out of the slug string
7
+ -- (`adr-051-*` → 051), so three DISTINCT ADRs that all slug as `adr-051-*`
8
+ -- (override-patterns ≠ programmatic-gate-integrity ≠ worktree-extension)
9
+ -- rendered the same "051" with no way to disambiguate. The collision cannot
10
+ -- be resolved by renumbering a slug (that would break the canonical handle).
11
+ --
12
+ -- This migration adds a real, nullable `display_alias` INTEGER column to
13
+ -- `attachments` so a doc can carry an explicit display number independent of
14
+ -- its slug. `numbering.ts::resolveDisplayNumber` PREFERS the stored alias
15
+ -- when present and falls back to the slug-derived number when null — so docs
16
+ -- that never get an alias keep their historical rendering byte-for-byte.
17
+ --
18
+ -- Uniqueness among `type='adr'` docs is enforced at the DISPATCH layer
19
+ -- (`display-alias.ts::setDisplayAlias`), NOT via a SQL UNIQUE constraint:
20
+ -- the constraint is scoped to one kind, and dispatch-validation matches the
21
+ -- discipline already used for `lifecycle_status` / `docs_wikilinks.relation`
22
+ -- so future taxonomy changes never require another schema migration.
23
+ --
24
+ -- Additive + forward-only: the new column is nullable, so SQLite ALTER TABLE
25
+ -- ADD COLUMN does NOT rewrite the table and existing rows pass through with
26
+ -- NULL (i.e. "no alias — derive from slug"). No data migration of legacy rows
27
+ -- is required; the `cleo docs set-alias` verb populates aliases going forward.
28
+ --
29
+ -- Changes (idempotent — safe to re-run):
30
+ -- 1. ALTER TABLE attachments ADD COLUMN display_alias integer (nullable).
31
+ -- 2. CREATE INDEX idx_attachments_display_alias — speeds the per-type
32
+ -- uniqueness scan performed by setDisplayAlias.
33
+ --
34
+ -- DEPENDS ON: 20260416000000_t796-attachments (creates `attachments`)
35
+ -- SAFE FOR: SQLite 3.35+ (ALTER TABLE ADD COLUMN nullable is atomic)
36
+ --
37
+ -- @task T11875
38
+ -- @epic T11781 (E3-OBSIDIAN-INTEGRATION)
39
+ -- @saga T11778 (SG-DOCS-SSOT-VAULT)
40
+ -- @closes (display-alias half of) T11676 ADR reconcile plan
41
+
42
+ ALTER TABLE `attachments` ADD COLUMN `display_alias` integer;
43
+ --> statement-breakpoint
44
+
45
+ CREATE INDEX IF NOT EXISTS `idx_attachments_display_alias`
46
+ ON `attachments` (`display_alias`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/core",
3
- "version": "2026.6.7",
3
+ "version": "2026.6.9",
4
4
  "description": "CLEO core business logic kernel — tasks, sessions, memory, orchestration, lifecycle, with bundled SQLite store",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -429,16 +429,16 @@
429
429
  "write-file-atomic": "^7.0.1",
430
430
  "yaml": "^2.8.3",
431
431
  "zod": "^4.3.6",
432
- "@cleocode/adapters": "2026.6.7",
433
- "@cleocode/caamp": "2026.6.7",
434
- "@cleocode/agents": "2026.6.7",
435
- "@cleocode/contracts": "2026.6.7",
436
- "@cleocode/git-shim": "2026.6.7",
437
- "@cleocode/lafs": "2026.6.7",
438
- "@cleocode/nexus": "2026.6.7",
439
- "@cleocode/paths": "2026.6.7",
440
- "@cleocode/skills": "2026.6.7",
441
- "@cleocode/worktree": "2026.6.7"
432
+ "@cleocode/adapters": "2026.6.9",
433
+ "@cleocode/agents": "2026.6.9",
434
+ "@cleocode/caamp": "2026.6.9",
435
+ "@cleocode/contracts": "2026.6.9",
436
+ "@cleocode/git-shim": "2026.6.9",
437
+ "@cleocode/lafs": "2026.6.9",
438
+ "@cleocode/paths": "2026.6.9",
439
+ "@cleocode/nexus": "2026.6.9",
440
+ "@cleocode/skills": "2026.6.9",
441
+ "@cleocode/worktree": "2026.6.9"
442
442
  },
443
443
  "engines": {
444
444
  "node": ">=24.16.0"
@@ -472,7 +472,7 @@
472
472
  },
473
473
  "optionalDependencies": {
474
474
  "llmtxt": "^2026.5.15",
475
- "@cleocode/studio": "^2026.6.7"
475
+ "@cleocode/studio": "^2026.6.9"
476
476
  },
477
477
  "scripts": {
478
478
  "build": "tsc",