mirror of
https://github.com/vectorize-io/hindsight.git
synced 2026-09-14 19:31:49 +08:00
1b74e3efa8
The skill and the README documented the same configuration in two hand- maintained files, and they drifted in both directions. The skill never named `bankIdTemplate`, `dynamicBankId`, `optInOnly`, `optInPaths`, `retainTags`, `retainMetadata`, `resolveWorktrees`, `maxParallelRetains` or any daemon setting, and it stated outright that the package reads "no environment variables" — there are 35 (core/config.ts ENV_KEYS). That is the half #3735 reported. The README had lost the other half: `autoReflect` and `surveyRefreshCommits` were documented only in the skill, and neither file mentioned that `HINDSIGHT_CONFIG` relocates the config file, that the layering chain ends at `banks.<resolvedBankId>`, or that `optInPaths` takes a comma-separated env value like its sibling `retainTags`. The README is now the single source. scripts/build-skill.mjs copies the regions it marks with `skill:begin` / `skill:end` into skill/SKILL.md, normalising heading levels per region; only the agent-facing half — which tools to call, crediting memory, correcting a stale memory — stays separate, in skill-src/preamble.md. The docs page was already generated from the README; its generator now strips the markers, which MDX cannot parse. The skill's operative debugging knowledge (sync-status readiness, resetting a bank, the survey-baseline/gitlog marker documents, the session_start/deepen_started triage rule) moved into the README, so it reaches users and the docs site too. src/docs-freshness.test.ts fails when the skill is stale, when a field of `RawConfig` is readable from a config file but named nowhere in the README — the check that makes this class of drift impossible to reintroduce — and when a documented claim about the env layer stops holding (every key really is `HINDSIGHT_<FIELD_IN_CAPS>`; the four map-valued settings really are file-only). It also unit-tests the marker parser. prepublishOnly regenerates the skill so a publish cannot ship a stale copy.
96 lines
4.5 KiB
JavaScript
96 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Generate docs-integrations/coding-agents.md from the integration's README.
|
|
*
|
|
* The two pages said the same things in different words and drifted — the docs page kept install
|
|
* instructions that no longer worked and a harness table that had fallen behind. The README is the
|
|
* single source now; this rewrites the doc page from it so "keep them in sync" is mechanical
|
|
* instead of a habit.
|
|
*
|
|
* Two adjustments are applied, both because the audience differs:
|
|
* - Docusaurus frontmatter replaces the README's H1 (the title comes from frontmatter).
|
|
* - Repo-relative links (`src/…`, `../other-integration`) are dropped to plain text: they resolve
|
|
* on GitHub but 404 on the docs site.
|
|
* - Absolute asset URLs on our own domain become site-relative. The README must use absolute URLs
|
|
* so images render on npm and GitHub, but on the docs site those same URLs pin every image to
|
|
* PRODUCTION — so a new asset shows as broken locally and in previews until it is deployed,
|
|
* which is exactly when you are trying to look at it.
|
|
* - The `skill:begin` / `skill:end` markers are dropped. They tell the integration's
|
|
* scripts/build-skill.mjs which regions the companion skill copies; MDX has no HTML comments,
|
|
* so leaving them in would fail the docs build outright.
|
|
*
|
|
* Run: node hindsight-docs/scripts/sync-coding-agents-doc.mjs [--check]
|
|
* `--check` fails when the doc page is out of date instead of writing it (for CI).
|
|
*/
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const readme = join(here, '..', '..', 'hindsight-integrations', 'coding-agents', 'README.md');
|
|
const page = join(here, '..', 'docs-integrations', 'coding-agents.md');
|
|
|
|
// Kept in the doc page's frontmatter rather than derived, so title/description stay tuned for
|
|
// search without touching the README's own heading.
|
|
const FRONTMATTER = `---
|
|
sidebar_position: 6
|
|
title: "Coding Agents"
|
|
description: "One Hindsight memory plugin for coding agents — per-repo memory banks built automatically from git history and past sessions, injected into the agent as it works."
|
|
---
|
|
|
|
{/* GENERATED from hindsight-integrations/coding-agents/README.md — edit that file, then run
|
|
node hindsight-docs/scripts/sync-coding-agents-doc.mjs */}
|
|
`;
|
|
|
|
/** Sections that only make sense inside the repo (contributor-facing), dropped from the doc page. */
|
|
const DROP_SECTIONS = ['Layout', 'Ingestion internals (no CLI)', 'Companion skill (generated)'];
|
|
|
|
function build() {
|
|
const src = readFileSync(readme, 'utf8');
|
|
const lines = src.split('\n');
|
|
const out = [];
|
|
let dropping = false;
|
|
for (const line of lines) {
|
|
const heading = /^(#{1,6})\s+(.*)$/.exec(line);
|
|
if (heading) {
|
|
const [, hashes, text] = heading;
|
|
if (hashes.length === 1) continue; // the H1 becomes frontmatter `title`
|
|
dropping = hashes.length === 2 && DROP_SECTIONS.includes(text.trim());
|
|
if (dropping) continue;
|
|
}
|
|
if (!dropping) out.push(line);
|
|
}
|
|
const body = out
|
|
.join('\n')
|
|
// Region markers for the companion-skill generator — invalid syntax in MDX, and meaningless
|
|
// to a reader of the docs site either way.
|
|
.replace(/^<!--\s*skill:(?:begin|end)[^>]*-->\n?/gm, '')
|
|
// Repo-relative links 404 on the docs site; keep the label, drop the link.
|
|
.replace(/\[([^\]]+)\]\((?!https?:|\/)[^)]+\)/g, '$1')
|
|
// Our own absolute URLs -> site-relative. Assets so the page uses THIS build's static
|
|
// files rather than whatever is live in production; doc links so they resolve within the
|
|
// site (and so the docs-skill generator can turn them into file-relative paths, which it
|
|
// cannot do with an absolute URL). The README keeps them absolute because it also renders
|
|
// on GitHub, where site-relative would 404.
|
|
.replace(/https:\/\/hindsight\.vectorize\.io\/([^\s"')]+)/g, '/$1')
|
|
.replace(/\n{3,}/g, '\n\n')
|
|
.trim();
|
|
return `${FRONTMATTER}\n${body}\n`;
|
|
}
|
|
|
|
const generated = build();
|
|
if (process.argv.includes('--check')) {
|
|
const current = readFileSync(page, 'utf8');
|
|
if (current !== generated) {
|
|
console.error(
|
|
'[coding-agents] ❌ docs page is out of date with the README.\n' +
|
|
' Run: node hindsight-docs/scripts/sync-coding-agents-doc.mjs',
|
|
);
|
|
process.exit(1);
|
|
}
|
|
console.log('[coding-agents] ✅ docs page matches the README.');
|
|
} else {
|
|
writeFileSync(page, generated);
|
|
console.log(`[coding-agents] wrote ${page} from the README.`);
|
|
}
|