Sync generated provider output

This commit is contained in:
github-actions[bot]
2026-08-05 22:27:35 +00:00
parent e46e0da885
commit e76b3424d2
30 changed files with 375 additions and 390 deletions
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }
@@ -22,7 +22,7 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process'; import { execFileSync } from 'node:child_process';
import { loadContext, extractPlatform } from './context.mjs'; import { loadContext, extractPlatform } from './context.mjs';
import { getCritiqueDir } from './lib/impeccable-paths.mjs'; import { readLatestSnapshotAcrossTargets } from './critique-storage.mjs';
/** Is there code here at all, or just context files / an empty repo? */ /** Is there code here at all, or just context files / an empty repo? */
function hasCode(cwd) { function hasCode(cwd) {
@@ -34,23 +34,13 @@ function hasCode(cwd) {
} }
/** /**
* The most recent critique snapshot across all targets. Filenames are * Summarize the most recent critique snapshot across all targets.
* timestamp-prefixed (`<iso>__<slug>.md`), so a lexical sort is chronological.
* Parses the small frontmatter for score + P0/P1 counts.
*/ */
function latestCritique(cwd) { function latestCritique(cwd) {
try { try {
const dir = getCritiqueDir(cwd); const latest = readLatestSnapshotAcrossTargets({ cwd });
if (!fs.existsSync(dir)) return null; if (!latest) return null;
const files = fs.readdirSync(dir).filter((f) => f.endsWith('.md')).sort(); const get = (key) => latest.meta[key] ?? null;
if (!files.length) return null;
const newest = files[files.length - 1];
const text = fs.readFileSync(path.join(dir, newest), 'utf-8');
const front = text.split('---')[1] || '';
const get = (k) => {
const m = front.match(new RegExp(`^${k}:\\s*(.+)$`, 'm'));
return m ? m[1].trim() : null;
};
const num = (v) => { const num = (v) => {
const n = Number(v); const n = Number(v);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
@@ -61,7 +51,7 @@ function latestCritique(cwd) {
p0: num(get('p0')), p0: num(get('p0')),
p1: num(get('p1')), p1: num(get('p1')),
timestamp: get('timestamp'), timestamp: get('timestamp'),
file: path.relative(cwd, path.join(dir, newest)), file: path.relative(cwd, latest.path),
}; };
} catch { } catch {
return null; return null;
@@ -105,28 +105,37 @@ function parseFrontmatter(text) {
} }
/** /**
* Return all snapshot files for `slug`, sorted oldest → newest. * Return snapshot files matching `suffix`, sorted oldest → newest.
*/ */
function listSnapshotsForSlug(slug, cwd) { const SNAPSHOT_FILENAME = /^\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z__.+\.md$/;
function listSnapshots(suffix, cwd) {
const dir = getCritiqueDir(cwd); const dir = getCritiqueDir(cwd);
if (!fs.existsSync(dir)) return []; if (!fs.existsSync(dir)) return [];
const suffix = `__${slug}.md`;
return fs.readdirSync(dir) return fs.readdirSync(dir)
.filter((f) => f.endsWith(suffix)) .filter((f) => SNAPSHOT_FILENAME.test(f) && f.endsWith(suffix))
.sort() .sort()
.map((f) => path.join(dir, f)); .map((f) => path.join(dir, f));
} }
function readLatestSnapshotMatching(suffix, cwd) {
const filePath = listSnapshots(suffix, cwd).at(-1);
if (!filePath) return null;
const body = fs.readFileSync(filePath, 'utf-8');
return { path: filePath, body, meta: parseFrontmatter(body) };
}
/** /**
* Return the most recent snapshot for `slug`, or null. Polish reads this * Return the most recent snapshot for `slug`, or null. Polish reads this
* to find its fix backlog when the slug matches. * to find its fix backlog when the slug matches.
*/ */
export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) { export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); return readLatestSnapshotMatching(`__${slug}.md`, cwd);
if (!all.length) return null; }
const latest = all[all.length - 1];
const body = fs.readFileSync(latest, 'utf-8'); /** Return the most recent snapshot across all targets, or null. */
return { path: latest, body, meta: parseFrontmatter(body) }; export function readLatestSnapshotAcrossTargets({ cwd = process.cwd() } = {}) {
return readLatestSnapshotMatching('.md', cwd);
} }
/** /**
@@ -134,7 +143,7 @@ export function readLatestSnapshot(slug, { cwd = process.cwd() } = {}) {
* Critique appends a one-line trend to its output using this. * Critique appends a one-line trend to its output using this.
*/ */
export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) { export function readTrend(slug, { limit = 5, cwd = process.cwd() } = {}) {
const all = listSnapshotsForSlug(slug, cwd); const all = listSnapshots(`__${slug}.md`, cwd);
const slice = all.slice(-limit); const slice = all.slice(-limit);
return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8'))); return slice.map((file) => parseFrontmatter(fs.readFileSync(file, 'utf-8')));
} }