@kevin0181/memoc 1.4.1 → 1.4.2

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 (2) hide show
  1. package/bin/cli.js +50 -0
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -263,6 +263,23 @@ function archiveLegacySystems(dir, mark) {
263
263
  mark('move', `${path.relative(dir, systemsPath)} -> ${path.relative(dir, archivePath)}`);
264
264
  }
265
265
 
266
+ function isDefaultLegacyWikiDirectory(dirPath) {
267
+ let entries = [];
268
+ try {
269
+ entries = fs.readdirSync(dirPath).filter(name => !name.startsWith('.'));
270
+ } catch {
271
+ return false;
272
+ }
273
+ if (entries.length !== 1 || entries[0] !== 'README.md') return false;
274
+
275
+ const src = safeRead(path.join(dirPath, 'README.md'));
276
+ const name = path.basename(dirPath);
277
+ if (name === 'sources') return src.includes('# Sources') && src.includes('Provenance records');
278
+ if (name === 'topics') return src.includes('# Topics') && src.includes('Synthesized topic pages');
279
+ if (name === 'global') return src.includes('# Global') && src.includes('Project-wide principles');
280
+ return false;
281
+ }
282
+
266
283
  function migrateKnowledgeWiki(dir, mark) {
267
284
  const wikiDir = path.join(dir, '.memoc', 'wiki');
268
285
  const knowledgeDir = path.join(wikiDir, 'knowledge');
@@ -283,6 +300,16 @@ function migrateKnowledgeWiki(dir, mark) {
283
300
  try {
284
301
  const st = fs.statSync(dest);
285
302
  if (st.isFile() && isDefaultKnowledgeScaffold(dest)) fs.unlinkSync(dest);
303
+ else if (st.isDirectory() && fs.statSync(src).isDirectory()) {
304
+ if (isDefaultLegacyWikiDirectory(src)) {
305
+ fs.rmSync(src, { recursive: true, force: true });
306
+ mark('remove', `${path.relative(dir, src)} (legacy wiki scaffold)`);
307
+ } else {
308
+ const archived = movePathUnique(src, path.join(dir, '.memoc', 'raw', 'legacy-wiki-root', from));
309
+ mark('move', `${path.relative(dir, src)} -> ${path.relative(dir, archived)} (legacy wiki dir)`);
310
+ }
311
+ continue;
312
+ }
286
313
  else continue;
287
314
  } catch {
288
315
  continue;
@@ -319,6 +346,18 @@ function migrateKnowledgeLayerLinks(filePath) {
319
346
  return true;
320
347
  }
321
348
 
349
+ function migrateRawKnowledgeLinks(filePath) {
350
+ if (!fs.existsSync(filePath)) return false;
351
+ const before = safeRead(filePath);
352
+ if (!before) return false;
353
+ const after = before
354
+ .replace(/\]\(\.\.\/wiki\/sources\/README\.md\)/g, '](../wiki/knowledge/sources/README.md)')
355
+ .replace(/\]\(\.\.\/\.\.\/wiki\/sources\/README\.md\)/g, '](../../wiki/knowledge/sources/README.md)');
356
+ if (after === before) return false;
357
+ write(filePath, after);
358
+ return true;
359
+ }
360
+
322
361
  function isDefaultKnowledgeScaffold(filePath) {
323
362
  const src = safeRead(filePath);
324
363
  const name = path.basename(filePath);
@@ -2576,6 +2615,17 @@ function run(dir, forceUpdate, action = 'update') {
2576
2615
  if (migrateKnowledgeLayerLinks(fp)) mark('update', `${path.relative(dir, fp)} (wiki links)`);
2577
2616
  }
2578
2617
 
2618
+ const rawLinkFiles = [
2619
+ path.join(memDir, 'raw/README.md'),
2620
+ path.join(memDir, 'raw/files/README.md'),
2621
+ path.join(memDir, 'raw/urls/README.md'),
2622
+ path.join(memDir, 'raw/conversations/README.md'),
2623
+ path.join(memDir, 'raw/docs/README.md'),
2624
+ ];
2625
+ for (const fp of rawLinkFiles) {
2626
+ if (migrateRawKnowledgeLinks(fp)) mark('update', `${path.relative(dir, fp)} (raw links)`);
2627
+ }
2628
+
2579
2629
  const legacyReferenceFiles = [
2580
2630
  path.join(memDir, '02-current-project-state.md'),
2581
2631
  path.join(memDir, '04-handoff.md'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevin0181/memoc",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Give AI agents a memory. Scaffolds session-to-session context for Claude Code, Codex, Cursor, and more.",
5
5
  "keywords": [
6
6
  "ai",