hub-bulk-metadata.mjs
56 lines 2.2 KB
Raw
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor ⚠ breaking 2 days ago
1 /**
2 * Hub bulk operations by metadata (project slug). Self-hosted Node Hub only; see docs/HUB-METADATA-BULK-OPS.md.
3 */
4
5 import { runListNotes } from './list-notes.mjs';
6 import { deleteNote, writeNote } from './write.mjs';
7 import { readNote, normalizeSlug } from './vault.mjs';
8
9 /**
10 * @param {string} vaultPath
11 * @param {string} projectRaw
12 * @param {{ ignore?: string[] }} [options]
13 * @returns {{ deleted: number, paths: string[] }}
14 */
15 export function deleteNotesByProjectSlug(vaultPath, projectRaw, options = {}) {
16 const slug = normalizeSlug(String(projectRaw ?? '').trim());
17 if (!slug) throw new Error('project slug required');
18 const vc = { vault_path: vaultPath, ignore: options.ignore || [] };
19 const out = runListNotes(vc, { project: slug, limit: 100000, offset: 0, fields: 'path' });
20 const paths = (out.notes || []).map((n) => n.path).filter(Boolean);
21 const deletedPaths = [];
22 for (const rel of paths) {
23 try {
24 deleteNote(vaultPath, rel);
25 deletedPaths.push(String(rel).replace(/\\/g, '/'));
26 } catch (e) {
27 if (e.message && e.message.includes('not found')) continue;
28 throw e;
29 }
30 }
31 return { deleted: deletedPaths.length, paths: deletedPaths };
32 }
33
34 /**
35 * @param {string} vaultPath
36 * @param {string} fromRaw
37 * @param {string} toRaw
38 * @param {{ ignore?: string[] }} [options]
39 * @returns {{ updated: number, paths: string[] }}
40 */
41 export function renameProjectSlugInVault(vaultPath, fromRaw, toRaw, options = {}) {
42 const from = normalizeSlug(String(fromRaw ?? '').trim());
43 const to = normalizeSlug(String(toRaw ?? '').trim());
44 if (!from || !to) throw new Error('from and to project slugs required');
45 if (from === to) return { updated: 0, paths: [] };
46 const vc = { vault_path: vaultPath, ignore: options.ignore || [] };
47 const out = runListNotes(vc, { project: from, limit: 100000, offset: 0, fields: 'path' });
48 const paths = (out.notes || []).map((n) => n.path).filter(Boolean);
49 const updatedPaths = [];
50 for (const rel of paths) {
51 const note = readNote(vaultPath, rel);
52 writeNote(vaultPath, rel, { body: note.body, frontmatter: { project: to } });
53 updatedPaths.push(String(rel).replace(/\\/g, '/'));
54 }
55 return { updated: updatedPaths.length, paths: updatedPaths };
56 }
File History 2 commits
sha256:65ccb454656ea5acdea0a10e559b78bcde1eb6ff753ecc2911bc99d1c3d7cadd feat(calendar): enforce agent context tiers in retrieval AP… Human minor 2 days ago
sha256:9103f98c89257ed2b01c237cea895dabb3e85ea337dccb1161c175e4422355b6 docs: accept Calendar Events v0 spec with Phase 0 security … Human 2 days ago