397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
2.0 KiB
JavaScript
52 lines
2.0 KiB
JavaScript
#!/usr/bin/env node
|
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
|
|
const COUNTER_PATH = 'docs/observer/.read-counter.json';
|
|
const SELF_PRUNE_WEEKS = 54;
|
|
|
|
export function weeksSince(isoTimestamp, now = new Date()) {
|
|
const past = new Date(isoTimestamp);
|
|
const ms = now - past;
|
|
return Math.floor(ms / (1000 * 60 * 60 * 24 * 7));
|
|
}
|
|
|
|
export function isStale(counter, thresholdWeeks = SELF_PRUNE_WEEKS, now = new Date()) {
|
|
if (!counter || !counter.last_read_at) return true;
|
|
return weeksSince(counter.last_read_at, now) >= thresholdWeeks;
|
|
}
|
|
|
|
export function recordRead(counterPath = COUNTER_PATH, now = new Date()) {
|
|
let counter = { last_read_at: now.toISOString(), read_count_last_period: 0, period_start: now.toISOString() };
|
|
if (existsSync(counterPath)) {
|
|
try {
|
|
counter = JSON.parse(readFileSync(counterPath, 'utf-8'));
|
|
} catch {}
|
|
}
|
|
counter.last_read_at = now.toISOString();
|
|
counter.read_count_last_period = (counter.read_count_last_period || 0) + 1;
|
|
writeFileSync(counterPath, JSON.stringify(counter, null, 2) + '\n');
|
|
return counter;
|
|
}
|
|
|
|
if (process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('/observer-of-observer.mjs')) {
|
|
const mode = process.argv[2] || 'check';
|
|
if (mode === 'record') {
|
|
recordRead();
|
|
console.log(`[observer-of-observer] recorded read`);
|
|
process.exit(0);
|
|
}
|
|
if (!existsSync(COUNTER_PATH)) {
|
|
console.warn(`[observer-of-observer] WARN — counter file missing: ${COUNTER_PATH}`);
|
|
process.exit(0);
|
|
}
|
|
const counter = JSON.parse(readFileSync(COUNTER_PATH, 'utf-8'));
|
|
if (isStale(counter)) {
|
|
console.warn(`[observer-of-observer] WARN — observer infrastructure not read for ≥${SELF_PRUNE_WEEKS} weeks.`);
|
|
console.warn(` last_read_at: ${counter.last_read_at}`);
|
|
console.warn(` Consider self-pruning: archive docs/observer/ and remove Stop-hook.`);
|
|
process.exit(0);
|
|
}
|
|
console.log(`[observer-of-observer] OK — last read ${weeksSince(counter.last_read_at)} week(s) ago`);
|
|
process.exit(0);
|
|
}
|