@kevin0181/memoc 1.1.11 → 1.2.1
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.
- package/README.md +1 -1
- package/bin/cli.js +69 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -144,7 +144,7 @@ Run it from the project root. It preserves existing project memory, including:
|
|
|
144
144
|
- `.memoc/systems/`
|
|
145
145
|
- `.memoc/wiki/`
|
|
146
146
|
|
|
147
|
-
It refreshes the managed blocks, project-local wrappers, runtime copy, PATH helpers, and memoc-owned protocol templates. User-owned memory files such as `session-summary.md`, `03-decisions.md`, `04-handoff.md`, `06-project-rules.md`, and wiki topic/source pages are preserved. If `memoc` is not on PATH after upgrading, keep using:
|
|
147
|
+
It refreshes the managed blocks, project-local wrappers, runtime copy, PATH helpers, and memoc-owned protocol templates. User-owned memory files such as `session-summary.md`, `03-decisions.md`, `04-handoff.md`, `06-project-rules.md`, and wiki topic/source pages are preserved. Upgrade also runs the `trim-summary` compaction pass so startup memory stays small. If `memoc` is not on PATH after upgrading, keep using:
|
|
148
148
|
|
|
149
149
|
```bash
|
|
150
150
|
# Windows
|
package/bin/cli.js
CHANGED
|
@@ -246,6 +246,47 @@ function archiveLegacyLog(dir, mark) {
|
|
|
246
246
|
mark('move', `${path.relative(dir, logPath)} -> ${path.relative(dir, archivePath)}`);
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
function summarySectionBulletCounts(src) {
|
|
250
|
+
const counts = {};
|
|
251
|
+
let current = '';
|
|
252
|
+
for (const line of String(src || '').split(/\r?\n/)) {
|
|
253
|
+
const heading = line.match(/^##\s+(.+?)\s*$/);
|
|
254
|
+
if (heading) {
|
|
255
|
+
current = heading[1].trim();
|
|
256
|
+
counts[current] = counts[current] || 0;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (current && /^-\s+/.test(line)) counts[current] = (counts[current] || 0) + 1;
|
|
260
|
+
}
|
|
261
|
+
return counts;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function trimSummaryFile(dir) {
|
|
265
|
+
const summaryPath = path.join(dir, '.memoc', 'session-summary.md');
|
|
266
|
+
const archivePath = path.join(dir, '.memoc', 'session-summary-archive.md');
|
|
267
|
+
if (!fs.existsSync(summaryPath)) {
|
|
268
|
+
write(summaryPath, tplSessionSummary());
|
|
269
|
+
return { action: 'add' };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const src = fs.readFileSync(summaryPath, 'utf8');
|
|
273
|
+
const beforeBytes = Buffer.byteLength(src, 'utf8');
|
|
274
|
+
const counts = summarySectionBulletCounts(src);
|
|
275
|
+
const tooManyBullets = Object.values(counts).some(count => count > 3);
|
|
276
|
+
if (beforeBytes <= 800 && !tooManyBullets) {
|
|
277
|
+
return { action: 'skip', beforeBytes };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const compact = compactSessionSummary(src);
|
|
281
|
+
const afterBytes = Buffer.byteLength(compact, 'utf8');
|
|
282
|
+
const archiveHeader = fs.existsSync(archivePath)
|
|
283
|
+
? ''
|
|
284
|
+
: '# Session Summary Archive\n\nOlder oversized startup summaries moved by `memoc trim-summary`.\n';
|
|
285
|
+
fs.appendFileSync(archivePath, `${archiveHeader}\n## [${nowISO()}] archived summary (${beforeBytes}B)\n\n${src.trimEnd()}\n`, 'utf8');
|
|
286
|
+
write(summaryPath, compact);
|
|
287
|
+
return { action: 'trim', beforeBytes, afterBytes };
|
|
288
|
+
}
|
|
289
|
+
|
|
249
290
|
function migrateLegacyLogReferences(filePath) {
|
|
250
291
|
if (!fs.existsSync(filePath)) return false;
|
|
251
292
|
const before = fs.readFileSync(filePath, 'utf8');
|
|
@@ -940,7 +981,9 @@ function collectMemocMarkdownFiles(dir) {
|
|
|
940
981
|
}
|
|
941
982
|
walk(path.join(dir, '.memoc'));
|
|
942
983
|
walk(path.join(dir, 'skills', 'project-memory-maintainer'));
|
|
943
|
-
return files
|
|
984
|
+
return files
|
|
985
|
+
.filter(fp => !/session-summary-archive(?:-\d+)?\.md$/.test(path.basename(fp)))
|
|
986
|
+
.sort();
|
|
944
987
|
}
|
|
945
988
|
|
|
946
989
|
function ensureMemocFrontmatter(filePath, dir) {
|
|
@@ -2392,6 +2435,16 @@ function run(dir, forceUpdate, action = 'update') {
|
|
|
2392
2435
|
|
|
2393
2436
|
archiveLegacyLog(dir, mark);
|
|
2394
2437
|
|
|
2438
|
+
const trim = trimSummaryFile(dir);
|
|
2439
|
+
if (trim.action === 'trim') {
|
|
2440
|
+
mark('update', `.memoc/session-summary.md (trimmed ${trim.beforeBytes}B -> ${trim.afterBytes}B)`);
|
|
2441
|
+
mark('update', '.memoc/session-summary-archive.md');
|
|
2442
|
+
} else if (trim.action === 'add') {
|
|
2443
|
+
mark('add', '.memoc/session-summary.md');
|
|
2444
|
+
} else {
|
|
2445
|
+
mark('skip', `.memoc/session-summary.md (compact ${trim.beforeBytes || 0}B)`);
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2395
2448
|
// Obsidian graph filters — add/merge memoc tags for existing installs too
|
|
2396
2449
|
ensureObsidianFrontmatter(dir, mark);
|
|
2397
2450
|
}
|
|
@@ -3392,37 +3445,24 @@ function runCompress(dir) {
|
|
|
3392
3445
|
// ═══════════════════════════════════════════════════════════════════
|
|
3393
3446
|
|
|
3394
3447
|
function runTrimSummary(dir) {
|
|
3395
|
-
const
|
|
3396
|
-
|
|
3397
|
-
if (!fs.existsSync(summaryPath)) {
|
|
3398
|
-
write(summaryPath, tplSessionSummary());
|
|
3448
|
+
const result = trimSummaryFile(dir);
|
|
3449
|
+
if (result.action === 'add') {
|
|
3399
3450
|
console.log('\n memoc trim-summary\n');
|
|
3400
3451
|
console.log(' Added .memoc/session-summary.md');
|
|
3401
3452
|
console.log('\n Done.\n');
|
|
3402
3453
|
return;
|
|
3403
3454
|
}
|
|
3404
3455
|
|
|
3405
|
-
|
|
3406
|
-
const beforeBytes = Buffer.byteLength(src, 'utf8');
|
|
3407
|
-
const compact = compactSessionSummary(src);
|
|
3408
|
-
const afterBytes = Buffer.byteLength(compact, 'utf8');
|
|
3409
|
-
|
|
3410
|
-
if (src === compact && beforeBytes <= 800) {
|
|
3456
|
+
if (result.action === 'skip') {
|
|
3411
3457
|
console.log('\n memoc trim-summary\n');
|
|
3412
|
-
console.log(` session-summary.md is already compact (${beforeBytes}B).`);
|
|
3458
|
+
console.log(` session-summary.md is already compact (${result.beforeBytes}B).`);
|
|
3413
3459
|
console.log('\n Done.\n');
|
|
3414
3460
|
return;
|
|
3415
3461
|
}
|
|
3416
3462
|
|
|
3417
|
-
const archiveHeader = fs.existsSync(archivePath)
|
|
3418
|
-
? ''
|
|
3419
|
-
: '# Session Summary Archive\n\nOlder oversized startup summaries moved by `memoc trim-summary`.\n';
|
|
3420
|
-
fs.appendFileSync(archivePath, `${archiveHeader}\n## [${nowISO()}] archived summary (${beforeBytes}B)\n\n${src.trimEnd()}\n`, 'utf8');
|
|
3421
|
-
write(summaryPath, compact);
|
|
3422
|
-
|
|
3423
3463
|
console.log('\n memoc trim-summary\n');
|
|
3424
3464
|
console.log(` Archived .memoc/session-summary-archive.md`);
|
|
3425
|
-
console.log(` Rewrote .memoc/session-summary.md (${beforeBytes}B → ${afterBytes}B)`);
|
|
3465
|
+
console.log(` Rewrote .memoc/session-summary.md (${result.beforeBytes}B → ${result.afterBytes}B)`);
|
|
3426
3466
|
console.log(' Reminder Completed history belongs in worklog; resume details belong in 04-handoff.md.');
|
|
3427
3467
|
console.log('\n Done.\n');
|
|
3428
3468
|
}
|
|
@@ -3432,8 +3472,8 @@ function compactSessionSummary(src) {
|
|
|
3432
3472
|
const lines = [
|
|
3433
3473
|
'# Session Summary',
|
|
3434
3474
|
`Last: ${nowISO()}`,
|
|
3435
|
-
'Replace
|
|
3436
|
-
'
|
|
3475
|
+
'Replace, do not append. Keep <800B.',
|
|
3476
|
+
'History: worklog. Resume risks: 04-handoff.md.',
|
|
3437
3477
|
'',
|
|
3438
3478
|
];
|
|
3439
3479
|
|
|
@@ -3455,6 +3495,7 @@ function sectionText(src, heading) {
|
|
|
3455
3495
|
}
|
|
3456
3496
|
|
|
3457
3497
|
function compactSummaryBullets(text) {
|
|
3498
|
+
const maxLine = 72;
|
|
3458
3499
|
return String(text || '')
|
|
3459
3500
|
.split(/\r?\n/)
|
|
3460
3501
|
.map(line => line.trim())
|
|
@@ -3462,7 +3503,13 @@ function compactSummaryBullets(text) {
|
|
|
3462
3503
|
.map(line => line.replace(/^[-*]\s+/, '').replace(/^\d+[.)]\s+/, '').trim())
|
|
3463
3504
|
.filter(Boolean)
|
|
3464
3505
|
.slice(0, 3)
|
|
3465
|
-
.map(line =>
|
|
3506
|
+
.map(line => {
|
|
3507
|
+
const compact = line
|
|
3508
|
+
.replace(/`/g, '')
|
|
3509
|
+
.replace(/\s+/g, ' ')
|
|
3510
|
+
.trim();
|
|
3511
|
+
return `- ${compact.length > maxLine ? `${compact.slice(0, maxLine - 3)}...` : compact}`;
|
|
3512
|
+
});
|
|
3466
3513
|
}
|
|
3467
3514
|
|
|
3468
3515
|
function summaryPlaceholder(heading) {
|