context-vault 3.1.7 → 3.1.8

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 (123) hide show
  1. package/bin/cli.js +11 -11
  2. package/dist/archive.d.ts +23 -0
  3. package/dist/archive.d.ts.map +1 -0
  4. package/dist/archive.js +197 -0
  5. package/dist/archive.js.map +1 -0
  6. package/dist/consolidation.d.ts +14 -0
  7. package/dist/consolidation.d.ts.map +1 -0
  8. package/dist/consolidation.js +59 -0
  9. package/dist/consolidation.js.map +1 -0
  10. package/dist/error-log.d.ts +4 -0
  11. package/dist/error-log.d.ts.map +1 -0
  12. package/dist/error-log.js +33 -0
  13. package/dist/error-log.js.map +1 -0
  14. package/dist/helpers.d.ts +10 -0
  15. package/dist/helpers.d.ts.map +1 -0
  16. package/dist/helpers.js +42 -0
  17. package/dist/helpers.js.map +1 -0
  18. package/dist/linking.d.ts +13 -0
  19. package/dist/linking.d.ts.map +1 -0
  20. package/dist/linking.js +86 -0
  21. package/dist/linking.js.map +1 -0
  22. package/dist/migrate-dirs.d.ts +16 -0
  23. package/dist/migrate-dirs.d.ts.map +1 -0
  24. package/dist/migrate-dirs.js +127 -0
  25. package/dist/migrate-dirs.js.map +1 -0
  26. package/dist/register-tools.d.ts +3 -0
  27. package/dist/register-tools.d.ts.map +1 -0
  28. package/dist/register-tools.js +161 -0
  29. package/dist/register-tools.js.map +1 -0
  30. package/dist/server.d.ts +3 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +241 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/status.d.ts +18 -0
  35. package/dist/status.d.ts.map +1 -0
  36. package/dist/status.js +265 -0
  37. package/dist/status.js.map +1 -0
  38. package/dist/telemetry.d.ts +6 -0
  39. package/dist/telemetry.d.ts.map +1 -0
  40. package/dist/telemetry.js +74 -0
  41. package/dist/telemetry.js.map +1 -0
  42. package/dist/temporal.d.ts +9 -0
  43. package/dist/temporal.d.ts.map +1 -0
  44. package/dist/temporal.js +76 -0
  45. package/dist/temporal.js.map +1 -0
  46. package/dist/tools/clear-context.d.ts +11 -0
  47. package/dist/tools/clear-context.d.ts.map +1 -0
  48. package/dist/tools/clear-context.js +28 -0
  49. package/dist/tools/clear-context.js.map +1 -0
  50. package/dist/tools/context-status.d.ts +6 -0
  51. package/dist/tools/context-status.d.ts.map +1 -0
  52. package/dist/tools/context-status.js +160 -0
  53. package/dist/tools/context-status.js.map +1 -0
  54. package/dist/tools/create-snapshot.d.ts +13 -0
  55. package/dist/tools/create-snapshot.d.ts.map +1 -0
  56. package/dist/tools/create-snapshot.js +161 -0
  57. package/dist/tools/create-snapshot.js.map +1 -0
  58. package/dist/tools/delete-context.d.ts +9 -0
  59. package/dist/tools/delete-context.d.ts.map +1 -0
  60. package/dist/tools/delete-context.js +45 -0
  61. package/dist/tools/delete-context.js.map +1 -0
  62. package/dist/tools/get-context.d.ts +85 -0
  63. package/dist/tools/get-context.d.ts.map +1 -0
  64. package/dist/tools/get-context.js +576 -0
  65. package/dist/tools/get-context.js.map +1 -0
  66. package/dist/tools/ingest-project.d.ts +11 -0
  67. package/dist/tools/ingest-project.d.ts.map +1 -0
  68. package/dist/tools/ingest-project.js +226 -0
  69. package/dist/tools/ingest-project.js.map +1 -0
  70. package/dist/tools/ingest-url.d.ts +11 -0
  71. package/dist/tools/ingest-url.d.ts.map +1 -0
  72. package/dist/tools/ingest-url.js +62 -0
  73. package/dist/tools/ingest-url.js.map +1 -0
  74. package/dist/tools/list-buckets.d.ts +9 -0
  75. package/dist/tools/list-buckets.d.ts.map +1 -0
  76. package/dist/tools/list-buckets.js +76 -0
  77. package/dist/tools/list-buckets.js.map +1 -0
  78. package/dist/tools/list-context.d.ts +19 -0
  79. package/dist/tools/list-context.d.ts.map +1 -0
  80. package/dist/tools/list-context.js +110 -0
  81. package/dist/tools/list-context.js.map +1 -0
  82. package/dist/tools/save-context.d.ts +36 -0
  83. package/dist/tools/save-context.d.ts.map +1 -0
  84. package/dist/tools/save-context.js +458 -0
  85. package/dist/tools/save-context.js.map +1 -0
  86. package/dist/tools/session-start.d.ts +11 -0
  87. package/dist/tools/session-start.d.ts.map +1 -0
  88. package/dist/tools/session-start.js +224 -0
  89. package/dist/tools/session-start.js.map +1 -0
  90. package/dist/types.d.ts +37 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +2 -0
  93. package/dist/types.js.map +1 -0
  94. package/node_modules/@context-vault/core/dist/constants.d.ts +1 -1
  95. package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -1
  96. package/node_modules/@context-vault/core/dist/constants.js +1 -1
  97. package/node_modules/@context-vault/core/dist/constants.js.map +1 -1
  98. package/node_modules/@context-vault/core/package.json +1 -1
  99. package/node_modules/@context-vault/core/src/constants.ts +1 -1
  100. package/package.json +10 -4
  101. package/src/{archive.js → archive.ts} +63 -30
  102. package/src/consolidation.ts +78 -0
  103. package/src/{error-log.js → error-log.ts} +3 -3
  104. package/src/{helpers.js → helpers.ts} +11 -5
  105. package/src/{linking.js → linking.ts} +14 -9
  106. package/src/{migrate-dirs.js → migrate-dirs.ts} +21 -8
  107. package/src/{register-tools.js → register-tools.ts} +21 -11
  108. package/src/{server.js → server.ts} +26 -20
  109. package/src/{status.js → status.ts} +60 -38
  110. package/src/{telemetry.js → telemetry.ts} +8 -4
  111. package/src/{temporal.js → temporal.ts} +10 -3
  112. package/src/tools/{clear-context.js → clear-context.ts} +2 -5
  113. package/src/tools/{context-status.js → context-status.ts} +6 -9
  114. package/src/tools/{create-snapshot.js → create-snapshot.ts} +11 -10
  115. package/src/tools/{delete-context.js → delete-context.ts} +9 -9
  116. package/src/tools/{get-context.js → get-context.ts} +39 -54
  117. package/src/tools/{ingest-project.js → ingest-project.ts} +19 -11
  118. package/src/tools/{ingest-url.js → ingest-url.ts} +11 -8
  119. package/src/tools/{list-buckets.js → list-buckets.ts} +11 -15
  120. package/src/tools/{list-context.js → list-context.ts} +13 -15
  121. package/src/tools/{save-context.js → save-context.ts} +42 -42
  122. package/src/tools/{session-start.js → session-start.ts} +29 -20
  123. package/src/types.ts +29 -0
package/bin/cli.js CHANGED
@@ -34,7 +34,7 @@ const HOME = homedir();
34
34
 
35
35
  const pkg = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf-8'));
36
36
  const VERSION = pkg.version;
37
- const SERVER_PATH = resolve(ROOT, 'src', 'server.js');
37
+ const SERVER_PATH = resolve(ROOT, 'dist', 'server.js');
38
38
 
39
39
  /** Detect if running as an npm-installed package (global or local) vs local dev clone */
40
40
  function isInstalledPackage() {
@@ -1707,7 +1707,7 @@ async function runMigrateDirs() {
1707
1707
  process.exit(1);
1708
1708
  }
1709
1709
 
1710
- const { planMigration, executeMigration } = await import('../src/migrate-dirs.js');
1710
+ const { planMigration, executeMigration } = await import('../dist/migrate-dirs.js');
1711
1711
 
1712
1712
  const ops = planMigration(vaultDir);
1713
1713
 
@@ -1822,7 +1822,7 @@ async function runArchive() {
1822
1822
  const { resolveConfig } = await import('@context-vault/core/config');
1823
1823
  const { initDatabase, prepareStatements, insertVec, deleteVec } =
1824
1824
  await import('@context-vault/core/db');
1825
- const { findArchiveCandidates, archiveEntries } = await import('../src/archive.js');
1825
+ const { findArchiveCandidates, archiveEntries } = await import('../dist/archive.js');
1826
1826
 
1827
1827
  const config = resolveConfig();
1828
1828
  if (!config.vaultDirExists) {
@@ -1899,7 +1899,7 @@ async function runRestore() {
1899
1899
 
1900
1900
  if (!entryId || entryId.startsWith('--')) {
1901
1901
  const { resolveConfig } = await import('@context-vault/core/config');
1902
- const { listArchivedEntries } = await import('../src/archive.js');
1902
+ const { listArchivedEntries } = await import('../dist/archive.js');
1903
1903
 
1904
1904
  const config = resolveConfig();
1905
1905
 
@@ -1929,7 +1929,7 @@ async function runRestore() {
1929
1929
  const { initDatabase, prepareStatements, insertVec, deleteVec } =
1930
1930
  await import('@context-vault/core/db');
1931
1931
  const { embed } = await import('@context-vault/core/embed');
1932
- const { restoreEntry } = await import('../src/archive.js');
1932
+ const { restoreEntry } = await import('../dist/archive.js');
1933
1933
 
1934
1934
  const config = resolveConfig();
1935
1935
  if (!config.vaultDirExists) {
@@ -1964,8 +1964,8 @@ async function runRestore() {
1964
1964
  async function runStatus() {
1965
1965
  const { resolveConfig } = await import('@context-vault/core/config');
1966
1966
  const { initDatabase } = await import('@context-vault/core/db');
1967
- const { gatherVaultStatus } = await import('../src/status.js');
1968
- const { errorLogPath, errorLogCount } = await import('../src/error-log.js');
1967
+ const { gatherVaultStatus } = await import('../dist/status.js');
1968
+ const { errorLogPath, errorLogCount } = await import('../dist/error-log.js');
1969
1969
 
1970
1970
  const config = resolveConfig();
1971
1971
 
@@ -4357,7 +4357,7 @@ ${bold('Commands:')}
4357
4357
 
4358
4358
  async function runDoctor() {
4359
4359
  const { resolveConfig } = await import('@context-vault/core/config');
4360
- const { errorLogPath, errorLogCount } = await import('../src/error-log.js');
4360
+ const { errorLogPath, errorLogCount } = await import('../dist/error-log.js');
4361
4361
 
4362
4362
  console.log();
4363
4363
  console.log(` ${bold('◇ context-vault doctor')} ${dim(`v${VERSION}`)}`);
@@ -4966,7 +4966,7 @@ async function runConsolidate() {
4966
4966
 
4967
4967
  const { resolveConfig } = await import('@context-vault/core/config');
4968
4968
  const { initDatabase } = await import('@context-vault/core/db');
4969
- const { findHotTags, findColdEntries } = await import('@context-vault/core/consolidation/index');
4969
+ const { findHotTags, findColdEntries } = await import('../dist/consolidation.js');
4970
4970
 
4971
4971
  const config = resolveConfig();
4972
4972
 
@@ -5070,7 +5070,7 @@ async function runConsolidate() {
5070
5070
 
5071
5071
  async function runDebug() {
5072
5072
  const { resolveConfig } = await import('@context-vault/core/config');
5073
- const { errorLogPath, errorLogCount } = await import('../src/error-log.js');
5073
+ const { errorLogPath, errorLogCount } = await import('../dist/error-log.js');
5074
5074
 
5075
5075
  let config;
5076
5076
  try {
@@ -5146,7 +5146,7 @@ async function runDebug() {
5146
5146
  }
5147
5147
 
5148
5148
  async function runServe() {
5149
- await import('../src/server.js');
5149
+ await import('../dist/server.js');
5150
5150
  }
5151
5151
 
5152
5152
  async function main() {
@@ -0,0 +1,23 @@
1
+ import type { LocalCtx } from './types.js';
2
+ export declare function findArchiveCandidates(ctx: LocalCtx): unknown[];
3
+ export declare function archiveEntries(ctx: LocalCtx): Promise<{
4
+ archived: unknown[];
5
+ count: number;
6
+ }>;
7
+ export declare function restoreEntry(ctx: LocalCtx, entryId: string): Promise<{
8
+ restored: boolean;
9
+ reason?: string;
10
+ filePath?: string;
11
+ kind?: string;
12
+ id?: string;
13
+ }>;
14
+ export declare function countArchivedEntries(vaultDir: string): number;
15
+ export declare function listArchivedEntries(vaultDir: string): Array<{
16
+ id: string | null;
17
+ kind: string;
18
+ title: string;
19
+ tags: unknown[];
20
+ created: string | null;
21
+ filePath: string;
22
+ }>;
23
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,EAAE,CAmC9D;AAYD,wBAAsB,cAAc,CAClC,GAAG,EAAE,QAAQ,GACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA0CjD;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA2EhG;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IAC3D,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAgCD"}
@@ -0,0 +1,197 @@
1
+ import { existsSync, mkdirSync, renameSync, readFileSync } from 'node:fs';
2
+ import { join, dirname, relative } from 'node:path';
3
+ import { categoryFor, defaultTierFor } from '@context-vault/core/categories';
4
+ import { parseFrontmatter, parseEntryFromMarkdown } from '@context-vault/core/frontmatter';
5
+ import { DEFAULT_LIFECYCLE } from '@context-vault/core/constants';
6
+ import { walkDir } from '@context-vault/core/files';
7
+ import { indexEntry } from '@context-vault/core/index';
8
+ const VALID_TIERS = new Set(['ephemeral', 'working', 'durable']);
9
+ const VALID_CATEGORIES = new Set(['knowledge', 'entity', 'event']);
10
+ function resolveLifecycle(config) {
11
+ return config?.lifecycle ?? structuredClone(DEFAULT_LIFECYCLE);
12
+ }
13
+ function archiveDir(vaultDir) {
14
+ return join(vaultDir, '_archive');
15
+ }
16
+ export function findArchiveCandidates(ctx) {
17
+ const lifecycle = resolveLifecycle(ctx.config);
18
+ const now = new Date();
19
+ const candidates = [];
20
+ const seen = new Set();
21
+ for (const [key, rules] of Object.entries(lifecycle)) {
22
+ if (!rules?.archiveAfterDays)
23
+ continue;
24
+ const cutoff = new Date(now.getTime() - rules.archiveAfterDays * 86400000).toISOString();
25
+ const isTier = VALID_TIERS.has(key);
26
+ const isCategory = VALID_CATEGORIES.has(key);
27
+ if (!isTier && !isCategory)
28
+ continue;
29
+ const column = isTier ? 'tier' : 'category';
30
+ const rows = ctx.db
31
+ .prepare(`SELECT id, kind, category, title, tier, file_path, created_at, updated_at
32
+ FROM vault
33
+ WHERE ${column} = ? AND COALESCE(updated_at, created_at) <= ?
34
+ ORDER BY COALESCE(updated_at, created_at) ASC`)
35
+ .all(key, cutoff);
36
+ for (const row of rows) {
37
+ if (seen.has(row.id))
38
+ continue;
39
+ seen.add(row.id);
40
+ candidates.push({
41
+ ...row,
42
+ reason: `${column}=${key}, archiveAfterDays=${rules.archiveAfterDays}`,
43
+ });
44
+ }
45
+ }
46
+ return candidates;
47
+ }
48
+ function removeFromIndex(ctx, id) {
49
+ const rowidRow = ctx.stmts.getRowid.get(id);
50
+ if (rowidRow?.rowid) {
51
+ try {
52
+ ctx.deleteVec(Number(rowidRow.rowid));
53
+ }
54
+ catch { }
55
+ }
56
+ ctx.stmts.deleteEntry.run(id);
57
+ }
58
+ export async function archiveEntries(ctx) {
59
+ const candidates = findArchiveCandidates(ctx);
60
+ if (candidates.length === 0)
61
+ return { archived: candidates, count: 0 };
62
+ const vaultDir = ctx.config.vaultDir;
63
+ const archRoot = archiveDir(vaultDir);
64
+ let count = 0;
65
+ for (const entry of candidates) {
66
+ const filePath = entry.file_path;
67
+ if (!filePath) {
68
+ removeFromIndex(ctx, entry.id);
69
+ count++;
70
+ continue;
71
+ }
72
+ const rel = relative(vaultDir, filePath);
73
+ if (rel.startsWith('..') || rel.startsWith('_archive'))
74
+ continue;
75
+ const destPath = join(archRoot, rel);
76
+ const destDir = dirname(destPath);
77
+ try {
78
+ mkdirSync(destDir, { recursive: true });
79
+ renameSync(filePath, destPath);
80
+ }
81
+ catch (e) {
82
+ if (e.code === 'ENOENT' && !existsSync(filePath)) {
83
+ // File already gone — just remove from index
84
+ }
85
+ else {
86
+ throw e;
87
+ }
88
+ }
89
+ removeFromIndex(ctx, entry.id);
90
+ count++;
91
+ }
92
+ return { archived: candidates, count };
93
+ }
94
+ export async function restoreEntry(ctx, entryId) {
95
+ const vaultDir = ctx.config.vaultDir;
96
+ const archRoot = archiveDir(vaultDir);
97
+ if (!existsSync(archRoot)) {
98
+ return { restored: false, reason: 'no _archive directory' };
99
+ }
100
+ const mdFiles = walkDir(archRoot);
101
+ let targetFile = null;
102
+ for (const { filePath } of mdFiles) {
103
+ try {
104
+ const raw = readFileSync(filePath, 'utf-8');
105
+ const { meta } = parseFrontmatter(raw);
106
+ if (meta.id === entryId) {
107
+ targetFile = filePath;
108
+ break;
109
+ }
110
+ }
111
+ catch {
112
+ continue;
113
+ }
114
+ }
115
+ if (!targetFile) {
116
+ return { restored: false, reason: `entry ${entryId} not found in _archive` };
117
+ }
118
+ const rel = relative(archRoot, targetFile);
119
+ const destPath = join(vaultDir, rel);
120
+ const destDir = dirname(destPath);
121
+ if (existsSync(destPath)) {
122
+ return { restored: false, reason: `destination already exists: ${destPath}` };
123
+ }
124
+ mkdirSync(destDir, { recursive: true });
125
+ renameSync(targetFile, destPath);
126
+ const raw = readFileSync(destPath, 'utf-8');
127
+ const { meta, body: rawBody } = parseFrontmatter(raw);
128
+ const relFromVault = relative(vaultDir, destPath);
129
+ const kindDir = relFromVault.split('/').filter(Boolean);
130
+ let kind = meta.kind ||
131
+ (kindDir.length >= 2 ? kindDir[kindDir.length - 2] : kindDir[0]) ||
132
+ 'note';
133
+ const parsed = parseEntryFromMarkdown(kind, rawBody, meta);
134
+ const category = categoryFor(kind);
135
+ await indexEntry(ctx, {
136
+ id: meta.id || entryId,
137
+ kind,
138
+ category,
139
+ title: parsed.title,
140
+ body: parsed.body,
141
+ meta: parsed.meta ?? undefined,
142
+ tags: Array.isArray(meta.tags) ? meta.tags : null,
143
+ source: meta.source || 'archive-restore',
144
+ filePath: destPath,
145
+ createdAt: meta.created || new Date().toISOString(),
146
+ identity_key: meta.identity_key || null,
147
+ expires_at: meta.expires_at || null,
148
+ tier: meta.tier || defaultTierFor(kind),
149
+ source_files: null,
150
+ });
151
+ return {
152
+ restored: true,
153
+ filePath: destPath,
154
+ kind,
155
+ id: meta.id || entryId,
156
+ };
157
+ }
158
+ export function countArchivedEntries(vaultDir) {
159
+ const archRoot = archiveDir(vaultDir);
160
+ if (!existsSync(archRoot))
161
+ return 0;
162
+ try {
163
+ return walkDir(archRoot).length;
164
+ }
165
+ catch {
166
+ return 0;
167
+ }
168
+ }
169
+ export function listArchivedEntries(vaultDir) {
170
+ const archRoot = archiveDir(vaultDir);
171
+ if (!existsSync(archRoot))
172
+ return [];
173
+ const entries = [];
174
+ try {
175
+ const mdFiles = walkDir(archRoot);
176
+ for (const { filePath, relDir } of mdFiles) {
177
+ try {
178
+ const raw = readFileSync(filePath, 'utf-8');
179
+ const { meta, body } = parseFrontmatter(raw);
180
+ entries.push({
181
+ id: meta.id || null,
182
+ kind: relDir?.split('/').pop() || 'unknown',
183
+ title: meta.title || body.slice(0, 80),
184
+ tags: Array.isArray(meta.tags) ? meta.tags : [],
185
+ created: meta.created || null,
186
+ filePath,
187
+ });
188
+ }
189
+ catch {
190
+ continue;
191
+ }
192
+ }
193
+ }
194
+ catch { }
195
+ return entries;
196
+ }
197
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare function findHotTags(db: DatabaseSync, opts?: {
3
+ tagThreshold?: number;
4
+ maxSnapshotAgeDays?: number;
5
+ }): Array<{
6
+ tag: string;
7
+ entryCount: number;
8
+ lastSnapshotAge: number | null;
9
+ }>;
10
+ export declare function findColdEntries(db: DatabaseSync, opts?: {
11
+ maxAgeDays?: number;
12
+ maxHitCount?: number;
13
+ }): string[];
14
+ //# sourceMappingURL=consolidation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidation.d.ts","sourceRoot":"","sources":["../src/consolidation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,WAAW,CACzB,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAO,GAChE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAmD5E;AAED,wBAAgB,eAAe,CAC7B,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACvD,MAAM,EAAE,CAgBV"}
@@ -0,0 +1,59 @@
1
+ export function findHotTags(db, opts = {}) {
2
+ const tagThreshold = opts.tagThreshold ?? 10;
3
+ const maxSnapshotAgeDays = opts.maxSnapshotAgeDays ?? 7;
4
+ const cutoff = new Date(Date.now() - maxSnapshotAgeDays * 86400000).toISOString();
5
+ const rows = db
6
+ .prepare(`SELECT tags FROM vault
7
+ WHERE kind != 'brief'
8
+ AND superseded_by IS NULL
9
+ AND (expires_at IS NULL OR expires_at > datetime('now'))`)
10
+ .all();
11
+ const tagCounts = new Map();
12
+ for (const row of rows) {
13
+ if (!row.tags)
14
+ continue;
15
+ try {
16
+ const tags = JSON.parse(row.tags);
17
+ for (const tag of tags) {
18
+ tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
19
+ }
20
+ }
21
+ catch {
22
+ continue;
23
+ }
24
+ }
25
+ const results = [];
26
+ for (const [tag, count] of tagCounts) {
27
+ if (count < tagThreshold)
28
+ continue;
29
+ const recentBrief = db
30
+ .prepare(`SELECT created_at FROM vault
31
+ WHERE kind = 'brief'
32
+ AND tags LIKE ?
33
+ ORDER BY created_at DESC LIMIT 1`)
34
+ .get(`%"${tag}"%`);
35
+ let lastSnapshotAge = null;
36
+ if (recentBrief) {
37
+ const brief = recentBrief;
38
+ lastSnapshotAge = Math.round((Date.now() - new Date(brief.created_at).getTime()) / 86400000);
39
+ if (brief.created_at >= cutoff)
40
+ continue;
41
+ }
42
+ results.push({ tag, entryCount: count, lastSnapshotAge });
43
+ }
44
+ return results.sort((a, b) => b.entryCount - a.entryCount);
45
+ }
46
+ export function findColdEntries(db, opts = {}) {
47
+ const maxAgeDays = opts.maxAgeDays ?? 90;
48
+ const maxHitCount = opts.maxHitCount ?? 0;
49
+ const cutoff = new Date(Date.now() - maxAgeDays * 86400000).toISOString();
50
+ const rows = db
51
+ .prepare(`SELECT id FROM vault
52
+ WHERE created_at < ?
53
+ AND superseded_by IS NULL
54
+ AND COALESCE(hit_count, 0) <= ?
55
+ AND (expires_at IS NULL OR expires_at > datetime('now'))`)
56
+ .all(cutoff, maxHitCount);
57
+ return rows.map((r) => r.id);
58
+ }
59
+ //# sourceMappingURL=consolidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../src/consolidation.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CACzB,EAAgB,EAChB,OAA+D,EAAE;IAEjE,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IAC7C,MAAM,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,kBAAkB,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAElF,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;kEAG4D,CAC7D;SACA,GAAG,EAAE,CAAC;IAET,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,KAAK,MAAM,GAAG,IAAI,IAAsC,EAAE,CAAC;QACzD,IAAI,CAAC,GAAG,CAAC,IAAI;YAAE,SAAS;QACxB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QACrC,IAAI,KAAK,GAAG,YAAY;YAAE,SAAS;QAEnC,MAAM,WAAW,GAAG,EAAE;aACnB,OAAO,CACN;;;0CAGkC,CACnC;aACA,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QAErB,IAAI,eAAe,GAAkB,IAAI,CAAC;QAC1C,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,WAAqC,CAAC;YACpD,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC7F,IAAI,KAAK,CAAC,UAAU,IAAI,MAAM;gBAAE,SAAS;QAC3C,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,EAAgB,EAChB,OAAsD,EAAE;IAExD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAE1E,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;;kEAI4D,CAC7D;SACA,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAE5B,OAAQ,IAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function errorLogPath(dataDir: string): string;
2
+ export declare function appendErrorLog(dataDir: string, entry: Record<string, unknown>): void;
3
+ export declare function errorLogCount(dataDir: string): number;
4
+ //# sourceMappingURL=error-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-log.d.ts","sourceRoot":"","sources":["../src/error-log.ts"],"names":[],"mappings":"AAYA,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWpF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUrD"}
@@ -0,0 +1,33 @@
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync, } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const MAX_LOG_SIZE = 1024 * 1024;
4
+ export function errorLogPath(dataDir) {
5
+ return join(dataDir, 'error.log');
6
+ }
7
+ export function appendErrorLog(dataDir, entry) {
8
+ try {
9
+ mkdirSync(dataDir, { recursive: true });
10
+ const logPath = errorLogPath(dataDir);
11
+ if (existsSync(logPath) && statSync(logPath).size >= MAX_LOG_SIZE) {
12
+ writeFileSync(logPath, '');
13
+ }
14
+ appendFileSync(logPath, JSON.stringify(entry) + '\n');
15
+ }
16
+ catch {
17
+ // intentionally swallowed
18
+ }
19
+ }
20
+ export function errorLogCount(dataDir) {
21
+ try {
22
+ const logPath = errorLogPath(dataDir);
23
+ if (!existsSync(logPath))
24
+ return 0;
25
+ return readFileSync(logPath, 'utf-8')
26
+ .split('\n')
27
+ .filter((l) => l.trim()).length;
28
+ }
29
+ catch {
30
+ return 0;
31
+ }
32
+ }
33
+ //# sourceMappingURL=error-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-log.js","sourceRoot":"","sources":["../src/error-log.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,UAAU,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC;AAEjC,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,KAA8B;IAC5E,IAAI,CAAC;QACH,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC;YAClE,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,CAAC;QACnC,OAAO,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC;aAClC,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { VaultConfig } from '@context-vault/core/types';
2
+ import type { ToolResult } from './types.js';
3
+ declare const pkg: any;
4
+ export declare function ok(text: string): ToolResult;
5
+ export declare function err(text: string, code?: string, meta?: Record<string, unknown>): ToolResult;
6
+ export declare function errWithHint(text: string, code: string, hint?: string): ToolResult;
7
+ export declare function ensureVaultExists(config: VaultConfig): ToolResult | null;
8
+ export declare function ensureValidKind(kind: string): ToolResult | null;
9
+ export { pkg };
10
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,QAAA,MAAM,GAAG,KAA2E,CAAC;AAErF,wBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAE3C;AAED,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,SAAY,EAChB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,UAAU,CAaZ;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAKjF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CASxE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQ/D;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
6
+ export function ok(text) {
7
+ return { content: [{ type: 'text', text }] };
8
+ }
9
+ export function err(text, code = 'UNKNOWN', meta = {}) {
10
+ return {
11
+ content: [{ type: 'text', text }],
12
+ isError: true,
13
+ code,
14
+ _meta: {
15
+ cv_version: pkg.version,
16
+ node_version: process.version,
17
+ platform: process.platform,
18
+ arch: process.arch,
19
+ ...meta,
20
+ },
21
+ };
22
+ }
23
+ export function errWithHint(text, code, hint) {
24
+ const prompt = hint
25
+ ? `\n\n**Debug with AI:** Paste this into Claude Code or your AI assistant:\n> "${hint}"`
26
+ : '';
27
+ return err(text + prompt, code);
28
+ }
29
+ export function ensureVaultExists(config) {
30
+ if (!config.vaultDirExists) {
31
+ return errWithHint(`Vault directory not found: ${config.vaultDir}. Run context-status for diagnostics.`, 'VAULT_NOT_FOUND', "My context-vault can't find the vault directory. Run `context-vault doctor` and help me fix it.");
32
+ }
33
+ return null;
34
+ }
35
+ export function ensureValidKind(kind) {
36
+ if (!/^[a-z][a-z0-9_-]*$/.test(kind)) {
37
+ return err("Required: kind (lowercase alphanumeric, e.g. 'insight', 'reference')", 'INVALID_KIND');
38
+ }
39
+ return null;
40
+ }
41
+ export { pkg };
42
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAIzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAErF,MAAM,UAAU,EAAE,CAAC,IAAY;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,GAAG,CACjB,IAAY,EACZ,IAAI,GAAG,SAAS,EAChB,OAAgC,EAAE;IAElC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI;QACb,IAAI;QACJ,KAAK,EAAE;YACL,UAAU,EAAE,GAAG,CAAC,OAAO;YACvB,YAAY,EAAE,OAAO,CAAC,OAAO;YAC7B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,IAAI;SACR;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,IAAY,EAAE,IAAa;IACnE,MAAM,MAAM,GAAG,IAAI;QACjB,CAAC,CAAC,gFAAgF,IAAI,GAAG;QACzF,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,GAAG,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,WAAW,CAChB,8BAA8B,MAAM,CAAC,QAAQ,uCAAuC,EACpF,iBAAiB,EACjB,iGAAiG,CAClG,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,CACR,sEAAsE,EACtE,cAAc,CACf,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,OAAO,EAAE,GAAG,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { DatabaseSync } from 'node:sqlite';
2
+ export declare function parseRelatedTo(raw: unknown): string[];
3
+ export declare function resolveLinks(db: DatabaseSync, ids: string[]): any[];
4
+ export declare function resolveBacklinks(db: DatabaseSync, entryId: string): any[];
5
+ export declare function collectLinkedEntries(db: DatabaseSync, primaryEntries: Array<{
6
+ id: string;
7
+ related_to?: string | null;
8
+ }>): {
9
+ forward: any[];
10
+ backward: any[];
11
+ };
12
+ export declare function validateRelatedTo(relatedTo: unknown): string | null;
13
+ //# sourceMappingURL=linking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CASrD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,CAgBnE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,EAAE,CAezE;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,YAAY,EAChB,cAAc,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GAChE;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,QAAQ,EAAE,GAAG,EAAE,CAAA;CAAE,CAyBrC;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYnE"}
@@ -0,0 +1,86 @@
1
+ export function parseRelatedTo(raw) {
2
+ if (!raw)
3
+ return [];
4
+ try {
5
+ const parsed = JSON.parse(raw);
6
+ if (!Array.isArray(parsed))
7
+ return [];
8
+ return parsed.filter((id) => typeof id === 'string' && id.trim());
9
+ }
10
+ catch {
11
+ return [];
12
+ }
13
+ }
14
+ export function resolveLinks(db, ids) {
15
+ if (!ids.length)
16
+ return [];
17
+ const unique = [...new Set(ids)];
18
+ const placeholders = unique.map(() => '?').join(',');
19
+ try {
20
+ return db
21
+ .prepare(`SELECT * FROM vault
22
+ WHERE id IN (${placeholders})
23
+ AND (expires_at IS NULL OR expires_at > datetime('now'))
24
+ AND superseded_by IS NULL`)
25
+ .all(...unique);
26
+ }
27
+ catch {
28
+ return [];
29
+ }
30
+ }
31
+ export function resolveBacklinks(db, entryId) {
32
+ if (!entryId)
33
+ return [];
34
+ const likePattern = `%"${entryId}"%`;
35
+ try {
36
+ return db
37
+ .prepare(`SELECT * FROM vault
38
+ WHERE related_to LIKE ?
39
+ AND (expires_at IS NULL OR expires_at > datetime('now'))
40
+ AND superseded_by IS NULL`)
41
+ .all(likePattern);
42
+ }
43
+ catch {
44
+ return [];
45
+ }
46
+ }
47
+ export function collectLinkedEntries(db, primaryEntries) {
48
+ const primaryIds = new Set(primaryEntries.map((e) => e.id));
49
+ const forwardIds = [];
50
+ for (const entry of primaryEntries) {
51
+ const ids = parseRelatedTo(entry.related_to);
52
+ for (const id of ids) {
53
+ if (!primaryIds.has(id))
54
+ forwardIds.push(id);
55
+ }
56
+ }
57
+ const forwardEntries = resolveLinks(db, forwardIds).filter((e) => !primaryIds.has(e.id));
58
+ const backwardSeen = new Set();
59
+ const backwardEntries = [];
60
+ for (const entry of primaryEntries) {
61
+ const backlinks = resolveBacklinks(db, entry.id);
62
+ for (const bl of backlinks) {
63
+ if (!primaryIds.has(bl.id) && !backwardSeen.has(bl.id)) {
64
+ backwardSeen.add(bl.id);
65
+ backwardEntries.push(bl);
66
+ }
67
+ }
68
+ }
69
+ return { forward: forwardEntries, backward: backwardEntries };
70
+ }
71
+ export function validateRelatedTo(relatedTo) {
72
+ if (relatedTo === undefined || relatedTo === null)
73
+ return null;
74
+ if (!Array.isArray(relatedTo))
75
+ return 'related_to must be an array of entry IDs';
76
+ for (const id of relatedTo) {
77
+ if (typeof id !== 'string' || !id.trim()) {
78
+ return 'each related_to entry must be a non-empty string ID';
79
+ }
80
+ if (id.length > 32) {
81
+ return `related_to ID too long (max 32 chars): "${id.slice(0, 32)}..."`;
82
+ }
83
+ }
84
+ return null;
85
+ }
86
+ //# sourceMappingURL=linking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linking.js","sourceRoot":"","sources":["../src/linking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export declare const PLURAL_TO_SINGULAR: Record<string, string>;
2
+ export interface MigrationOp {
3
+ action: 'rename' | 'merge';
4
+ pluralDir: string;
5
+ singularDir: string;
6
+ pluralName: string;
7
+ singularName: string;
8
+ fileCount: number;
9
+ }
10
+ export declare function planMigration(vaultDir: string): MigrationOp[];
11
+ export declare function executeMigration(ops: MigrationOp[]): {
12
+ renamed: number;
13
+ merged: number;
14
+ errors: string[];
15
+ };
16
+ //# sourceMappingURL=migrate-dirs.d.ts.map