@sledorze/cairn 0.1.0 → 0.3.0
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 +69 -18
- package/dist/cli.js +69378 -70958
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -10
- package/dist/config.js.map +1 -1
- package/dist/core/Config.d.ts +22 -22
- package/dist/core/Config.d.ts.map +1 -1
- package/dist/core/Config.js +33 -33
- package/dist/core/Config.js.map +1 -1
- package/dist/core/glob.bench.js +1 -1
- package/dist/core/glob.d.ts.map +1 -1
- package/dist/core/hashing.d.ts +3 -0
- package/dist/core/hashing.d.ts.map +1 -0
- package/dist/core/hashing.js +16 -0
- package/dist/core/hashing.js.map +1 -0
- package/dist/core/links/Anchors.d.ts +30 -0
- package/dist/core/links/Anchors.d.ts.map +1 -0
- package/dist/core/links/Anchors.js +119 -0
- package/dist/core/links/Anchors.js.map +1 -0
- package/dist/core/links/MarkdownLinks.bench.d.ts.map +1 -0
- package/dist/core/{MarkdownLinks.bench.js → links/MarkdownLinks.bench.js} +1 -1
- package/dist/core/links/MarkdownLinks.bench.js.map +1 -0
- package/dist/core/links/MarkdownLinks.d.ts +121 -0
- package/dist/core/links/MarkdownLinks.d.ts.map +1 -0
- package/dist/core/links/MarkdownLinks.js +228 -0
- package/dist/core/links/MarkdownLinks.js.map +1 -0
- package/dist/core/links/RefStore.d.ts +32 -0
- package/dist/core/links/RefStore.d.ts.map +1 -0
- package/dist/core/links/RefStore.js +60 -0
- package/dist/core/links/RefStore.js.map +1 -0
- package/dist/core/links/markdownFences.d.ts +10 -0
- package/dist/core/links/markdownFences.d.ts.map +1 -0
- package/dist/core/links/markdownFences.js +51 -0
- package/dist/core/links/markdownFences.js.map +1 -0
- package/dist/core/paths.d.ts +8 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +13 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/sidecar.d.ts +45 -0
- package/dist/core/sidecar.d.ts.map +1 -0
- package/dist/core/sidecar.js +83 -0
- package/dist/core/sidecar.js.map +1 -0
- package/dist/core/{DocSummaries.d.ts → summaries/DocSummaries.d.ts} +13 -3
- package/dist/core/summaries/DocSummaries.d.ts.map +1 -0
- package/dist/core/{DocSummaries.js → summaries/DocSummaries.js} +31 -11
- package/dist/core/summaries/DocSummaries.js.map +1 -0
- package/dist/core/summaries/StampStore.d.ts +19 -0
- package/dist/core/summaries/StampStore.d.ts.map +1 -0
- package/dist/core/summaries/StampStore.js +34 -0
- package/dist/core/summaries/StampStore.js.map +1 -0
- package/dist/core/summaries/SummaryTree.bench.d.ts.map +1 -0
- package/dist/core/{SummaryTree.bench.js → summaries/SummaryTree.bench.js} +24 -14
- package/dist/core/summaries/SummaryTree.bench.js.map +1 -0
- package/dist/core/{SummaryTree.d.ts → summaries/SummaryTree.d.ts} +10 -1
- package/dist/core/summaries/SummaryTree.d.ts.map +1 -0
- package/dist/core/{SummaryTree.js → summaries/SummaryTree.js} +35 -9
- package/dist/core/summaries/SummaryTree.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/init/content.d.ts +2 -2
- package/dist/init/content.d.ts.map +1 -1
- package/dist/init/content.js +45 -15
- package/dist/init/content.js.map +1 -1
- package/dist/init/generate.d.ts +1 -1
- package/dist/init/generate.d.ts.map +1 -1
- package/dist/init/generate.js +1 -1
- package/dist/io/DocsFs.d.ts +2 -3
- package/dist/io/DocsFs.d.ts.map +1 -1
- package/dist/io/DocsFs.js +15 -5
- package/dist/io/DocsFs.js.map +1 -1
- package/dist/program/JsonReport.d.ts +2 -2
- package/dist/program/JsonReport.d.ts.map +1 -1
- package/dist/program/JsonReport.js +2 -2
- package/dist/program/JsonReport.js.map +1 -1
- package/dist/program/{CheckLinks.d.ts → links/CheckLinks.d.ts} +9 -4
- package/dist/program/links/CheckLinks.d.ts.map +1 -0
- package/dist/program/links/CheckLinks.js +243 -0
- package/dist/program/links/CheckLinks.js.map +1 -0
- package/dist/program/links/CheckRefs.d.ts +47 -0
- package/dist/program/links/CheckRefs.d.ts.map +1 -0
- package/dist/program/links/CheckRefs.js +151 -0
- package/dist/program/links/CheckRefs.js.map +1 -0
- package/dist/program/locale.d.ts.map +1 -1
- package/dist/program/summaries/CheckSummaries.bench.d.ts +2 -0
- package/dist/program/summaries/CheckSummaries.bench.d.ts.map +1 -0
- package/dist/program/summaries/CheckSummaries.bench.js +94 -0
- package/dist/program/summaries/CheckSummaries.bench.js.map +1 -0
- package/dist/program/summaries/CheckSummaries.d.ts +58 -0
- package/dist/program/summaries/CheckSummaries.d.ts.map +1 -0
- package/dist/program/summaries/CheckSummaries.js +302 -0
- package/dist/program/summaries/CheckSummaries.js.map +1 -0
- package/package.json +7 -8
- package/schema/cairn.schema.json +35 -38
- package/dist/core/DocSummaries.d.ts.map +0 -1
- package/dist/core/DocSummaries.js.map +0 -1
- package/dist/core/MarkdownLinks.bench.d.ts.map +0 -1
- package/dist/core/MarkdownLinks.bench.js.map +0 -1
- package/dist/core/MarkdownLinks.d.ts +0 -51
- package/dist/core/MarkdownLinks.d.ts.map +0 -1
- package/dist/core/MarkdownLinks.js +0 -115
- package/dist/core/MarkdownLinks.js.map +0 -1
- package/dist/core/SummaryTree.bench.d.ts.map +0 -1
- package/dist/core/SummaryTree.bench.js.map +0 -1
- package/dist/core/SummaryTree.d.ts.map +0 -1
- package/dist/core/SummaryTree.js.map +0 -1
- package/dist/program/CheckLinks.d.ts.map +0 -1
- package/dist/program/CheckLinks.js +0 -122
- package/dist/program/CheckLinks.js.map +0 -1
- package/dist/program/CheckSummaries.d.ts +0 -38
- package/dist/program/CheckSummaries.d.ts.map +0 -1
- package/dist/program/CheckSummaries.js +0 -198
- package/dist/program/CheckSummaries.js.map +0 -1
- /package/dist/core/{MarkdownLinks.bench.d.ts → links/MarkdownLinks.bench.d.ts} +0 -0
- /package/dist/core/{SummaryTree.bench.d.ts → summaries/SummaryTree.bench.d.ts} +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
/** The hidden directory name every metadata tree lives under, relative to `base`. */
|
|
3
|
+
export declare const META_DIR = ".cairn";
|
|
4
|
+
export interface MetaLayout {
|
|
5
|
+
/** The project root every node path and every sidecar is resolved under. */
|
|
6
|
+
readonly base: string;
|
|
7
|
+
/** `join(base, META_DIR)` — passed explicitly (not recomputed) so callers who
|
|
8
|
+
* already have it (e.g. after listing `.cairn/**`) don't rederive it. */
|
|
9
|
+
readonly metaRoot: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const metaRootFor: (base: string) => string;
|
|
12
|
+
/** True for any path inside the hidden metadata tree — used to keep `.cairn/**`
|
|
13
|
+
* out of the set of markdown source files a plan considers. */
|
|
14
|
+
export declare const isSidecarPath: (candidate: string, metaRoot: string) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* `<base>/docs/a.summary.md` -> `<metaRoot>/docs/a.summary.md.json`, or, with
|
|
17
|
+
* a `namespace` (e.g. `'refs'`), `<metaRoot>/refs/docs/a.summary.md.json` —
|
|
18
|
+
* the mechanism that keeps two DIFFERENT sidecar kinds for the SAME doc path
|
|
19
|
+
* from colliding (a doc's own freshness stamp vs its reference hashes; see
|
|
20
|
+
* `links/RefStore.ts`'s header for the real collision this closes). Throws
|
|
21
|
+
* if `nodeAtPath` isn't under `base`: every real node path is (roots are
|
|
22
|
+
* always resolved under the project root before a plan ever runs), so this
|
|
23
|
+
* signals a caller bug, not a runtime data condition to recover from.
|
|
24
|
+
*/
|
|
25
|
+
export declare const sidecarPathFor: (nodeAtPath: string, layout: MetaLayout, namespace?: string) => string;
|
|
26
|
+
/**
|
|
27
|
+
* The inverse of `sidecarPathFor` (namespace-free form): given a sidecar's
|
|
28
|
+
* own path (e.g. found by listing `.cairn/**`), recover the node path it
|
|
29
|
+
* mirrors. Returns `null` for a path that isn't a well-formed sidecar under
|
|
30
|
+
* `metaRoot` (not `.json`, or outside the tree) rather than throwing —
|
|
31
|
+
* unlike `sidecarPathFor`, this reads data that could plausibly be malformed
|
|
32
|
+
* (a stray non-JSON file dropped into `.cairn/` by hand), so `null` is the
|
|
33
|
+
* right "not a sidecar" signal, not a crash.
|
|
34
|
+
*/
|
|
35
|
+
export declare const nodePathForSidecar: (sidecarPath: string, layout: MetaLayout) => string | null;
|
|
36
|
+
export interface SidecarCodec<A> {
|
|
37
|
+
/** Read a sidecar's record back, or `null` if missing/corrupt/malformed —
|
|
38
|
+
* NEVER throws (see module header). */
|
|
39
|
+
readonly parse: (content: string) => A | null;
|
|
40
|
+
/** The sidecar's on-disk JSON form. Trailing newline for a clean git diff. */
|
|
41
|
+
readonly serialize: (record: A) => string;
|
|
42
|
+
}
|
|
43
|
+
/** Build a lenient JSON codec for one sidecar record shape from its `Schema`. */
|
|
44
|
+
export declare const makeSidecarCodec: <S extends Parameters<typeof Schema.decodeUnknownResult>[0]>(schema: S) => SidecarCodec<S['Type']>;
|
|
45
|
+
//# sourceMappingURL=sidecar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../../src/core/sidecar.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AAKvC,qFAAqF;AACrF,eAAO,MAAM,QAAQ,WAAW,CAAA;AAEhC,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;6EACyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,MAAmC,CAAA;AAE9E;+DAC+D;AAC/D,eAAO,MAAM,aAAa,cAAe,MAAM,YAAY,MAAM,KAAG,OACJ,CAAA;AAEhE;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,eAAgB,MAAM,UAAU,UAAU,cAAc,MAAM,KAAG,MAO3F,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,gBAAiB,MAAM,UAAU,UAAU,KAAG,MAAM,GAAG,IASrF,CAAA;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B;2CACuC;IACvC,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,GAAG,IAAI,CAAA;IAC7C,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAA;CAC1C;AAED,iFAAiF;AACjF,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,UAAU,CAAC,OAAO,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,UACjF,CAAC,KACR,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAexB,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// The shared low-level primitive under every hidden `.cairn/**` metadata
|
|
2
|
+
// sidecar: path mapping (a node's real path -> its sidecar's path, and back)
|
|
3
|
+
// and a lenient JSON codec factory. Used by BOTH `summaries/StampStore.ts`
|
|
4
|
+
// (doc-freshness records) and `links/RefStore.ts` (reference content-hash
|
|
5
|
+
// records) — genuinely shared mechanics, kept deliberately separate from
|
|
6
|
+
// either domain's own record shape (`StampRecord` vs `RefsRecord`), which
|
|
7
|
+
// stay domain-owned: forcing one schema to serve two different sidecar
|
|
8
|
+
// kinds would leave one half always meaningless for any given sidecar.
|
|
9
|
+
//
|
|
10
|
+
// Two invariants this module enforces:
|
|
11
|
+
// - every node path handed to `sidecarPathFor` must live under `base` (real
|
|
12
|
+
// usage: `base` is the project root, every root/node resolved under it) —
|
|
13
|
+
// violating this is a programming error, not a data error, so it throws;
|
|
14
|
+
// - a codec's `parse` decodes LENIENTLY: unknown keys are ignored rather
|
|
15
|
+
// than rejected (forward-compatible), and a corrupt/hand-edited/merge-
|
|
16
|
+
// conflicted sidecar reads as `null` — exactly equivalent to no record at
|
|
17
|
+
// all, never a crash.
|
|
18
|
+
import * as nodePath from 'node:path';
|
|
19
|
+
import { Result, Schema } from 'effect';
|
|
20
|
+
// POSIX path semantics so sidecar paths are identical on every OS.
|
|
21
|
+
const path = nodePath.posix;
|
|
22
|
+
/** The hidden directory name every metadata tree lives under, relative to `base`. */
|
|
23
|
+
export const META_DIR = '.cairn';
|
|
24
|
+
export const metaRootFor = (base) => path.join(base, META_DIR);
|
|
25
|
+
/** True for any path inside the hidden metadata tree — used to keep `.cairn/**`
|
|
26
|
+
* out of the set of markdown source files a plan considers. */
|
|
27
|
+
export const isSidecarPath = (candidate, metaRoot) => candidate === metaRoot || candidate.startsWith(`${metaRoot}/`);
|
|
28
|
+
/**
|
|
29
|
+
* `<base>/docs/a.summary.md` -> `<metaRoot>/docs/a.summary.md.json`, or, with
|
|
30
|
+
* a `namespace` (e.g. `'refs'`), `<metaRoot>/refs/docs/a.summary.md.json` —
|
|
31
|
+
* the mechanism that keeps two DIFFERENT sidecar kinds for the SAME doc path
|
|
32
|
+
* from colliding (a doc's own freshness stamp vs its reference hashes; see
|
|
33
|
+
* `links/RefStore.ts`'s header for the real collision this closes). Throws
|
|
34
|
+
* if `nodeAtPath` isn't under `base`: every real node path is (roots are
|
|
35
|
+
* always resolved under the project root before a plan ever runs), so this
|
|
36
|
+
* signals a caller bug, not a runtime data condition to recover from.
|
|
37
|
+
*/
|
|
38
|
+
export const sidecarPathFor = (nodeAtPath, layout, namespace) => {
|
|
39
|
+
const rel = path.relative(layout.base, nodeAtPath);
|
|
40
|
+
if (rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
41
|
+
throw new Error(`sidecarPathFor: "${nodeAtPath}" is not under base "${layout.base}"`);
|
|
42
|
+
}
|
|
43
|
+
const root = namespace === undefined ? layout.metaRoot : path.join(layout.metaRoot, namespace);
|
|
44
|
+
return `${path.join(root, rel)}.json`;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The inverse of `sidecarPathFor` (namespace-free form): given a sidecar's
|
|
48
|
+
* own path (e.g. found by listing `.cairn/**`), recover the node path it
|
|
49
|
+
* mirrors. Returns `null` for a path that isn't a well-formed sidecar under
|
|
50
|
+
* `metaRoot` (not `.json`, or outside the tree) rather than throwing —
|
|
51
|
+
* unlike `sidecarPathFor`, this reads data that could plausibly be malformed
|
|
52
|
+
* (a stray non-JSON file dropped into `.cairn/` by hand), so `null` is the
|
|
53
|
+
* right "not a sidecar" signal, not a crash.
|
|
54
|
+
*/
|
|
55
|
+
export const nodePathForSidecar = (sidecarPath, layout) => {
|
|
56
|
+
if (!isSidecarPath(sidecarPath, layout.metaRoot) || !sidecarPath.endsWith('.json')) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const rel = path.relative(layout.metaRoot, sidecarPath);
|
|
60
|
+
if (rel.startsWith('..')) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
return path.join(layout.base, rel.slice(0, -'.json'.length));
|
|
64
|
+
};
|
|
65
|
+
/** Build a lenient JSON codec for one sidecar record shape from its `Schema`. */
|
|
66
|
+
export const makeSidecarCodec = (schema) => {
|
|
67
|
+
const decode = Schema.decodeUnknownResult(schema);
|
|
68
|
+
return {
|
|
69
|
+
parse: (content) => {
|
|
70
|
+
let json;
|
|
71
|
+
try {
|
|
72
|
+
json = JSON.parse(content);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const decoded = decode(json);
|
|
78
|
+
return Result.isSuccess(decoded) ? decoded.success : null;
|
|
79
|
+
},
|
|
80
|
+
serialize: (record) => `${JSON.stringify(record, null, 2)}\n`,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=sidecar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/core/sidecar.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,14 +29,24 @@ export declare const isSummaryFile: (path: string, naming?: Naming) => boolean;
|
|
|
29
29
|
export declare const summaryPathFor: (path: string, naming?: Naming) => string;
|
|
30
30
|
/** A non-summary Markdown file longer than the threshold must have a summary. */
|
|
31
31
|
export declare const needsSummary: ({ lineCount, naming, path, thresholdLines, }: NeedsSummaryArgs) => boolean;
|
|
32
|
-
/** Deterministic content hash used to stamp and verify summaries. */
|
|
33
|
-
export declare const hashContent: (content: string) => string;
|
|
34
32
|
/** The HTML-comment stamp a summary must carry to declare which source it reflects. */
|
|
35
33
|
export declare const sourceHashTag: (hash: string) => string;
|
|
36
34
|
/** Read back the source hash recorded in a summary, or null if absent. */
|
|
37
35
|
export declare const extractSourceHash: (summaryContent: string) => string | null;
|
|
38
|
-
/** Return the summary content stamped with `hash` (replacing any existing stamp).
|
|
36
|
+
/** Return the summary content stamped with `hash` (replacing any existing stamp).
|
|
37
|
+
* Retained only for the one-off `--migrate-stamps` path (`CheckSummaries.ts`),
|
|
38
|
+
* which needs to recognise the OLD in-content form while migrating a repo off
|
|
39
|
+
* it — the ongoing stamp mechanism now lives in a `.cairn/**` sidecar
|
|
40
|
+
* (`StampStore.ts`), never in a summary's own content. */
|
|
39
41
|
export declare const withSourceHash: (summaryContent: string, hash: string) => string;
|
|
42
|
+
/**
|
|
43
|
+
* Remove a legacy in-content stamp (and the blank line `withSourceHash` used to
|
|
44
|
+
* insert after it), leaving pure authored prose. The one-time migration step:
|
|
45
|
+
* `--migrate-stamps` calls this on every summary that still carries the old
|
|
46
|
+
* comment, before writing the hash to its `.cairn/**` sidecar instead. A no-op
|
|
47
|
+
* (returns `summaryContent` unchanged) when no stamp is present.
|
|
48
|
+
*/
|
|
49
|
+
export declare const stripSourceHash: (summaryContent: string) => string;
|
|
40
50
|
/** Classify a summary: missing, stale (hash absent or mismatched) or ok. */
|
|
41
51
|
export declare const classifySummary: ({ recordedHash, sourceHash, summaryExists }: ClassifyArgs) => SummaryStatus;
|
|
42
52
|
//# sourceMappingURL=DocSummaries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocSummaries.d.ts","sourceRoot":"","sources":["../../../src/core/summaries/DocSummaries.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAA;AAEtD,qDAAqD;AACrD,MAAM,WAAW,MAAM;IACrB,yDAAyD;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;CACnC;AAED,4DAA4D;AAC5D,eAAO,MAAM,cAAc,EAAE,MAG5B,CAAA;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAChC;AAED,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAIzC,uDAAuD;AACvD,eAAO,MAAM,UAAU,YAAa,MAAM,KAAG,MAM5C,CAAA;AAED,uDAAuD;AACvD,eAAO,MAAM,aAAa,SAAU,MAAM,WAAU,MAAM,KAAoB,OACrC,CAAA;AAEzC,wEAAwE;AACxE,eAAO,MAAM,cAAc,SAAU,MAAM,WAAU,MAAM,KAAoB,MAC9B,CAAA;AAEjD,iFAAiF;AACjF,eAAO,MAAM,YAAY,iDAKtB,gBAAgB,KAAG,OAQrB,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,aAAa,SAAU,MAAM,KAAG,MAA2C,CAAA;AAExF,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,mBAAoB,MAAM,KAAG,MAAM,GAAG,IAAiD,CAAA;AAErH;;;;0DAI0D;AAC1D,eAAO,MAAM,cAAc,mBAAoB,MAAM,QAAQ,MAAM,KAAG,MAMrE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,mBAAoB,MAAM,KAAG,MAKxD,CAAA;AAED,4EAA4E;AAC5E,eAAO,MAAM,eAAe,gDAAiD,YAAY,KAAG,aAQ3F,CAAA"}
|
|
@@ -6,13 +6,22 @@
|
|
|
6
6
|
// Freshness is enforced by a content hash, NOT by filesystem mtime: git does not
|
|
7
7
|
// preserve mtimes, so after a clone/checkout (e.g. in CI) every file shares the
|
|
8
8
|
// same timestamp and a time-based check silently passes on stale summaries.
|
|
9
|
-
//
|
|
10
|
-
//
|
|
9
|
+
// The recorded hash lives in a hidden `.cairn/**` sidecar (StampStore.ts), never
|
|
10
|
+
// inside the summary's own content — the checker recomputes the source hash and
|
|
11
|
+
// flags any mismatch against whatever the sidecar last recorded. Deterministic
|
|
12
|
+
// and clone-independent. `extractSourceHash`/`withSourceHash`/`HASH_RE` below
|
|
13
|
+
// recognise the OLD in-content `<!-- source-sha256: ... -->` form; they're kept
|
|
14
|
+
// only for `stripSourceHash` and the one-off `--migrate-stamps` path that moves
|
|
15
|
+
// an existing repo off it.
|
|
11
16
|
//
|
|
12
17
|
// Naming (directory-summary filename, file-summary suffix) is configurable; the
|
|
13
18
|
// defaults below reproduce the original behaviour. Unit-tested in
|
|
14
|
-
// DocSummaries.unit.test.ts; the Effect program is in
|
|
15
|
-
|
|
19
|
+
// DocSummaries.unit.test.ts; the Effect program is in ../../program/summaries/CheckSummaries.ts.
|
|
20
|
+
//
|
|
21
|
+
// `hashContent` itself lives in `../hashing.ts`, not here — it's genuinely
|
|
22
|
+
// shared (links/CheckRefs.ts hashes REFERENCED targets with the exact same
|
|
23
|
+
// function), not summary-specific; found via an import-graph audit that
|
|
24
|
+
// this file was the one summaries/ module a links/ program also depended on.
|
|
16
25
|
/** Defaults matching the original hard-coded convention. */
|
|
17
26
|
export const DEFAULT_NAMING = {
|
|
18
27
|
dirSummary: '_SUMMARY.md',
|
|
@@ -43,17 +52,15 @@ export const needsSummary = ({ lineCount, naming = DEFAULT_NAMING, path, thresho
|
|
|
43
52
|
}
|
|
44
53
|
return lineCount > thresholdLines;
|
|
45
54
|
};
|
|
46
|
-
// One-shot `crypto.hash` (Node >=20.12) skips the streaming Hash object's
|
|
47
|
-
// internal state entirely — faster than `createHash().update().digest()` for
|
|
48
|
-
// the KB-sized markdown content this hashes, at the scale this runs at (once
|
|
49
|
-
// per file/manifest per plan).
|
|
50
|
-
/** Deterministic content hash used to stamp and verify summaries. */
|
|
51
|
-
export const hashContent = (content) => hashHex('sha256', content, 'hex');
|
|
52
55
|
/** The HTML-comment stamp a summary must carry to declare which source it reflects. */
|
|
53
56
|
export const sourceHashTag = (hash) => `<!-- source-sha256: ${hash} -->`;
|
|
54
57
|
/** Read back the source hash recorded in a summary, or null if absent. */
|
|
55
58
|
export const extractSourceHash = (summaryContent) => HASH_RE.exec(summaryContent)?.[1] ?? null;
|
|
56
|
-
/** Return the summary content stamped with `hash` (replacing any existing stamp).
|
|
59
|
+
/** Return the summary content stamped with `hash` (replacing any existing stamp).
|
|
60
|
+
* Retained only for the one-off `--migrate-stamps` path (`CheckSummaries.ts`),
|
|
61
|
+
* which needs to recognise the OLD in-content form while migrating a repo off
|
|
62
|
+
* it — the ongoing stamp mechanism now lives in a `.cairn/**` sidecar
|
|
63
|
+
* (`StampStore.ts`), never in a summary's own content. */
|
|
57
64
|
export const withSourceHash = (summaryContent, hash) => {
|
|
58
65
|
const tag = sourceHashTag(hash);
|
|
59
66
|
if (HASH_RE.test(summaryContent)) {
|
|
@@ -61,6 +68,19 @@ export const withSourceHash = (summaryContent, hash) => {
|
|
|
61
68
|
}
|
|
62
69
|
return `${tag}\n\n${summaryContent}`;
|
|
63
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Remove a legacy in-content stamp (and the blank line `withSourceHash` used to
|
|
73
|
+
* insert after it), leaving pure authored prose. The one-time migration step:
|
|
74
|
+
* `--migrate-stamps` calls this on every summary that still carries the old
|
|
75
|
+
* comment, before writing the hash to its `.cairn/**` sidecar instead. A no-op
|
|
76
|
+
* (returns `summaryContent` unchanged) when no stamp is present.
|
|
77
|
+
*/
|
|
78
|
+
export const stripSourceHash = (summaryContent) => {
|
|
79
|
+
if (!HASH_RE.test(summaryContent)) {
|
|
80
|
+
return summaryContent;
|
|
81
|
+
}
|
|
82
|
+
return summaryContent.replace(HASH_RE, '').replace(/^\n+/, '');
|
|
83
|
+
};
|
|
64
84
|
/** Classify a summary: missing, stale (hash absent or mismatched) or ok. */
|
|
65
85
|
export const classifySummary = ({ recordedHash, sourceHash, summaryExists }) => {
|
|
66
86
|
if (!summaryExists) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocSummaries.js","sourceRoot":"","sources":["../../../src/core/summaries/DocSummaries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface StampRecord {
|
|
2
|
+
readonly sha256: string;
|
|
3
|
+
readonly version: number;
|
|
4
|
+
}
|
|
5
|
+
/** Bumped only if the sidecar's own shape changes incompatibly (never for adding
|
|
6
|
+
* an optional field — the codec already tolerates unknown keys, forward-compatible
|
|
7
|
+
* with a future, richer sidecar). */
|
|
8
|
+
export declare const STAMP_VERSION = 1;
|
|
9
|
+
/** The sidecar's on-disk JSON form. Trailing newline for a clean git diff. */
|
|
10
|
+
export declare const serializeStamp: (record: StampRecord) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Read a sidecar's `StampRecord` back, or `null` if it's missing/corrupt/
|
|
13
|
+
* malformed/hand-edited/merge-conflicted — this must NEVER throw. A stamp that
|
|
14
|
+
* can't be trusted is exactly equivalent to no stamp: the node it covers reads
|
|
15
|
+
* as stale, not as a crash (see AGENTS.md's note on treating an unparsable
|
|
16
|
+
* stamp the same as a missing one).
|
|
17
|
+
*/
|
|
18
|
+
export declare const parseStamp: (content: string) => StampRecord | null;
|
|
19
|
+
//# sourceMappingURL=StampStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StampStore.d.ts","sourceRoot":"","sources":["../../../src/core/summaries/StampStore.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;qCAEqC;AACrC,eAAO,MAAM,aAAa,IAAI,CAAA;AAS9B,8EAA8E;AAC9E,eAAO,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,MAA6B,CAAA;AAEnF;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,IAAuB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// The hidden, hierarchy-mirroring metadata tree that replaces the in-content
|
|
2
|
+
// `<!-- source-sha256: H -->` stamp (see AGENTS.md / issue #35). Every
|
|
3
|
+
// summarizable node keeps its authored prose stamp-free; instead, a sidecar
|
|
4
|
+
// JSON file under `<base>/.cairn/` mirrors the node's path 1:1 and carries the
|
|
5
|
+
// freshness hash. This module is pure (no IO): the `StampRecord` shape only.
|
|
6
|
+
// `../../program/summaries/CheckSummaries.ts` is the impure edge that reads/
|
|
7
|
+
// writes sidecars via `DocsFs`.
|
|
8
|
+
//
|
|
9
|
+
// Path mapping and the lenient-decode codec mechanics live in `../sidecar.ts`
|
|
10
|
+
// — genuinely shared with `../links/RefStore.ts` (both are `.cairn/**`
|
|
11
|
+
// sidecars), kept out of this file so it stays about ONE thing: what a
|
|
12
|
+
// summary-freshness record actually contains.
|
|
13
|
+
import { Schema } from 'effect';
|
|
14
|
+
import { makeSidecarCodec } from '../sidecar.js';
|
|
15
|
+
/** Bumped only if the sidecar's own shape changes incompatibly (never for adding
|
|
16
|
+
* an optional field — the codec already tolerates unknown keys, forward-compatible
|
|
17
|
+
* with a future, richer sidecar). */
|
|
18
|
+
export const STAMP_VERSION = 1;
|
|
19
|
+
const StampRecordSchema = Schema.Struct({
|
|
20
|
+
sha256: Schema.String,
|
|
21
|
+
version: Schema.Number,
|
|
22
|
+
});
|
|
23
|
+
const stampCodec = makeSidecarCodec(StampRecordSchema);
|
|
24
|
+
/** The sidecar's on-disk JSON form. Trailing newline for a clean git diff. */
|
|
25
|
+
export const serializeStamp = stampCodec.serialize;
|
|
26
|
+
/**
|
|
27
|
+
* Read a sidecar's `StampRecord` back, or `null` if it's missing/corrupt/
|
|
28
|
+
* malformed/hand-edited/merge-conflicted — this must NEVER throw. A stamp that
|
|
29
|
+
* can't be trusted is exactly equivalent to no stamp: the node it covers reads
|
|
30
|
+
* as stale, not as a crash (see AGENTS.md's note on treating an unparsable
|
|
31
|
+
* stamp the same as a missing one).
|
|
32
|
+
*/
|
|
33
|
+
export const parseStamp = stampCodec.parse;
|
|
34
|
+
//# sourceMappingURL=StampStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StampStore.js","sourceRoot":"","sources":["../../../src/core/summaries/StampStore.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,uEAAuE;AACvE,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,gCAAgC;AAChC,EAAE;AACF,8EAA8E;AAC9E,uEAAuE;AACvE,uEAAuE;AACvE,8CAA8C;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAOhD;;qCAEqC;AACrC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAA;AAE9B,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,gBAAgB,CAAC,iBAAiB,CAAC,CAAA;AAEtD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAoC,UAAU,CAAC,SAAS,CAAA;AAEnF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAA4C,UAAU,CAAC,KAAK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryTree.bench.d.ts","sourceRoot":"","sources":["../../../src/core/summaries/SummaryTree.bench.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import * as nodePath from 'node:path';
|
|
2
2
|
import { bench, describe } from 'vitest';
|
|
3
|
-
import { hashContent
|
|
4
|
-
import {
|
|
3
|
+
import { hashContent } from '../hashing.js';
|
|
4
|
+
import { isSummaryFile, summaryPathFor } from './DocSummaries.js';
|
|
5
|
+
import { DIR_SUMMARY, isDirSummary, planSummaries } from './SummaryTree.js';
|
|
5
6
|
const path = nodePath.posix;
|
|
6
7
|
const bigContent = (seed) => Array.from({ length: 40 }, (_, i) => `${seed} body line ${i} with some representative prose content`).join('\n');
|
|
7
8
|
const smallContent = (seed) => `${seed} short note`;
|
|
8
|
-
/** A fully
|
|
9
|
-
|
|
9
|
+
/** A fully link-complete tree (no stamps embedded — freshness lives in a
|
|
10
|
+
* separate `stamps` map now, see `StampStore.ts` / `SummaryTree.ts`'s
|
|
11
|
+
* `PlanArgs.stamps`), plus the stamps map a real `.cairn/**` sidecar store
|
|
12
|
+
* would hold for it. `planSummaries({files, stamps, ...})` on the pair reports
|
|
13
|
+
* every node `ok` — this is `buildFreshTree`'s "steady state" fixture. */
|
|
14
|
+
const buildFreshTree = ({ depth, dirsPerLevel, filesPerDir, root, }) => {
|
|
10
15
|
const files = new Map();
|
|
16
|
+
const stamps = new Map();
|
|
11
17
|
const visit = (dir, level) => {
|
|
12
18
|
const docTargets = [];
|
|
13
19
|
const inputs = [];
|
|
@@ -19,7 +25,9 @@ const buildFreshTree = ({ depth, dirsPerLevel, filesPerDir, root }) => {
|
|
|
19
25
|
docTargets.push(docPath);
|
|
20
26
|
if (big) {
|
|
21
27
|
const sp = summaryPathFor(docPath);
|
|
22
|
-
|
|
28
|
+
const summaryContent = `# summary\n\nSee [source](./${path.basename(docPath)}).`;
|
|
29
|
+
files.set(sp, summaryContent);
|
|
30
|
+
stamps.set(sp, hashContent(content));
|
|
23
31
|
inputs.push(sp);
|
|
24
32
|
}
|
|
25
33
|
else {
|
|
@@ -40,31 +48,33 @@ const buildFreshTree = ({ depth, dirsPerLevel, filesPerDir, root }) => {
|
|
|
40
48
|
.toSorted()
|
|
41
49
|
.join('\n');
|
|
42
50
|
const links = [...docTargets, ...dirTargets].map((t) => `- [link](${path.relative(dir, t)})`).join('\n');
|
|
43
|
-
files.set(`${dir}/${DIR_SUMMARY}`,
|
|
51
|
+
files.set(`${dir}/${DIR_SUMMARY}`, links);
|
|
52
|
+
stamps.set(`${dir}/${DIR_SUMMARY}`, hashContent(manifest));
|
|
44
53
|
};
|
|
45
54
|
visit(root, 0);
|
|
46
|
-
return files;
|
|
55
|
+
return { files, stamps };
|
|
47
56
|
};
|
|
48
|
-
/** Same source docs, no summaries anywhere yet — the "first run" worst case
|
|
57
|
+
/** Same source docs, no summaries anywhere yet — the "first run" worst case
|
|
58
|
+
* (no stamps either, matching an empty/not-yet-populated `.cairn/**`). */
|
|
49
59
|
const sourceOnly = (files) => new Map([...files].filter(([p]) => !isSummaryFile(p) && !isDirSummary(p)));
|
|
50
60
|
const SMALL = { depth: 1, dirsPerLevel: 9, filesPerDir: 10, root: '/repo/docs' };
|
|
51
61
|
const LARGE = { depth: 4, dirsPerLevel: 3, filesPerDir: 16, root: '/repo/docs' };
|
|
52
62
|
const smallFresh = buildFreshTree(SMALL);
|
|
53
|
-
const smallRaw = sourceOnly(smallFresh);
|
|
63
|
+
const smallRaw = sourceOnly(smallFresh.files);
|
|
54
64
|
const largeFresh = buildFreshTree(LARGE);
|
|
55
|
-
const largeRaw = sourceOnly(largeFresh);
|
|
65
|
+
const largeRaw = sourceOnly(largeFresh.files);
|
|
56
66
|
describe('planSummaries()', () => {
|
|
57
|
-
bench('~100 files, flat/shallow, first run (no summaries)', () => {
|
|
67
|
+
bench('~100 files, flat/shallow, first run (no summaries, no stamps)', () => {
|
|
58
68
|
planSummaries({ files: smallRaw, roots: [SMALL.root] });
|
|
59
69
|
});
|
|
60
70
|
bench('~100 files, flat/shallow, steady state (fully stamped)', () => {
|
|
61
|
-
planSummaries({ files: smallFresh, roots: [SMALL.root] });
|
|
71
|
+
planSummaries({ files: smallFresh.files, roots: [SMALL.root], stamps: smallFresh.stamps });
|
|
62
72
|
});
|
|
63
|
-
bench('~2000 files, deep/nested, first run (no summaries)', () => {
|
|
73
|
+
bench('~2000 files, deep/nested, first run (no summaries, no stamps)', () => {
|
|
64
74
|
planSummaries({ files: largeRaw, roots: [LARGE.root] });
|
|
65
75
|
});
|
|
66
76
|
bench('~2000 files, deep/nested, steady state (fully stamped)', () => {
|
|
67
|
-
planSummaries({ files: largeFresh, roots: [LARGE.root] });
|
|
77
|
+
planSummaries({ files: largeFresh.files, roots: [LARGE.root], stamps: largeFresh.stamps });
|
|
68
78
|
});
|
|
69
79
|
});
|
|
70
80
|
//# sourceMappingURL=SummaryTree.bench.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryTree.bench.js","sourceRoot":"","sources":["../../../src/core/summaries/SummaryTree.bench.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;AAErC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAExC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAE3E,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAA;AAS3B,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,cAAc,CAAC,yCAAyC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAElH,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,GAAG,IAAI,aAAa,CAAA;AAEnE;;;;0EAI0E;AAC1E,MAAM,cAAc,GAAG,CAAC,EACtB,KAAK,EACL,YAAY,EACZ,WAAW,EACX,IAAI,GACM,EAAiF,EAAE;IAC7F,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAA;IACvC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IAExC,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,KAAa,EAAQ,EAAE;QACjD,MAAM,UAAU,GAAa,EAAE,CAAA;QAC/B,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAA;YACpC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACvB,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAA;YACjE,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC3B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACxB,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;gBAClC,MAAM,cAAc,GAAG,+BAA+B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAA;gBAChF,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC,CAAA;gBAC7B,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;gBACpC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACjB,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAa,EAAE,CAAA;QAC/B,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;YAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,GAAG,GAAG,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAA;gBAC7B,KAAK,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;gBACrB,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACpB,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM;aACpB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;aACrF,QAAQ,EAAE;aACV,IAAI,CAAC,IAAI,CAAC,CAAA;QACb,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACxG,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,WAAW,EAAE,EAAE,KAAK,CAAC,CAAA;QACzC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,WAAW,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAA;IAED,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IACd,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC,CAAA;AAED;0EAC0E;AAC1E,MAAM,UAAU,GAAG,CAAC,KAAkC,EAAuB,EAAE,CAC7E,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAE5E,MAAM,KAAK,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;AAC3F,MAAM,KAAK,GAAc,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;AAE3F,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;AACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAC7C,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;AACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AAE7C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,KAAK,CAAC,+DAA+D,EAAE,GAAG,EAAE;QAC1E,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACnE,aAAa,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,+DAA+D,EAAE,GAAG,EAAE;QAC1E,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,KAAK,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACnE,aAAa,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -16,11 +16,20 @@ export interface PlanArgs {
|
|
|
16
16
|
readonly naming?: Naming;
|
|
17
17
|
readonly requireDirSummaries?: boolean;
|
|
18
18
|
readonly roots: readonly string[];
|
|
19
|
+
/** Node path -> recorded hash, loaded from `.cairn/**` sidecars. Optional and
|
|
20
|
+
* defaults to empty — an absent/not-yet-populated stamp store degrades every
|
|
21
|
+
* node to `stale`/`missing`, the correct first-run behaviour, never a crash. */
|
|
22
|
+
readonly stamps?: ReadonlyMap<string, string>;
|
|
19
23
|
readonly thresholdLines?: number;
|
|
20
24
|
}
|
|
21
25
|
export interface SummaryPlan {
|
|
22
26
|
readonly nodes: readonly PlanNode[];
|
|
23
27
|
readonly orphans: readonly string[];
|
|
28
|
+
/** A `.cairn/**` sidecar whose node no longer exists — its source doc (and
|
|
29
|
+
* possibly its summary file too) was deleted, renamed, or dropped below the
|
|
30
|
+
* size threshold. See `findDeletedStamps` for why this is distinct from
|
|
31
|
+
* `orphans`. */
|
|
32
|
+
readonly orphanStamps: readonly string[];
|
|
24
33
|
readonly todo: readonly PlanNode[];
|
|
25
34
|
}
|
|
26
35
|
/** True when `p` is a directory summary under the configured naming. */
|
|
@@ -41,5 +50,5 @@ export interface NodeHashArgs {
|
|
|
41
50
|
*/
|
|
42
51
|
export declare const nodeExpectedHash: ({ files, inputs, kind, path: nodeAtPath }: NodeHashArgs) => string;
|
|
43
52
|
/** Compute the full hierarchical summary plan from the current file contents. */
|
|
44
|
-
export declare const planSummaries: ({ files, ignore, naming, requireDirSummaries, roots, thresholdLines, }: PlanArgs) => SummaryPlan;
|
|
53
|
+
export declare const planSummaries: ({ files, ignore, naming, requireDirSummaries, roots, stamps, thresholdLines, }: PlanArgs) => SummaryPlan;
|
|
45
54
|
//# sourceMappingURL=SummaryTree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryTree.d.ts","sourceRoot":"","sources":["../../../src/core/summaries/SummaryTree.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAO9D,6CAA6C;AAC7C,eAAO,MAAM,WAAW,QAA4B,CAAA;AAEpD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;oFAEgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC;;;oBAGgB;IAChB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,EAAE,CAAA;CACnC;AAMD,wEAAwE;AACxE,eAAO,MAAM,YAAY,MAAO,MAAM,WAAU,MAAM,KAAoB,OACV,CAAA;AA2BhE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,8CAA+C,YAAY,KAAG,MAU1F,CAAA;AAED,iFAAiF;AACjF,eAAO,MAAM,aAAa,mFAQvB,QAAQ,KAAG,WA2Hb,CAAA"}
|
|
@@ -6,10 +6,15 @@
|
|
|
6
6
|
// direct docs (or their summary when the doc is big) AND the `_SUMMARY.md`
|
|
7
7
|
// of its direct sub-directories.
|
|
8
8
|
//
|
|
9
|
-
// Freshness is content-hash based (clone/CI-proof, unlike mtime). Each summary
|
|
10
|
-
//
|
|
9
|
+
// Freshness is content-hash based (clone/CI-proof, unlike mtime). Each summary's
|
|
10
|
+
// hash H is recorded in a hidden sidecar under `.cairn/` (see StampStore.ts),
|
|
11
|
+
// never inside the summary's own content:
|
|
11
12
|
// - file summary -> H = hash(source doc content)
|
|
12
13
|
// - dir summary -> H = hash(manifest of its inputs' relative-path:content-hash)
|
|
14
|
+
// `planSummaries` never reads or writes a sidecar itself — it's handed the
|
|
15
|
+
// already-loaded `stamps` map (node path -> recorded hash) as a plain value, so
|
|
16
|
+
// this whole module stays pure and storage-agnostic; `program/CheckSummaries.ts`
|
|
17
|
+
// is the impure edge that loads `stamps` from `.cairn/**` via `DocsFs`.
|
|
13
18
|
//
|
|
14
19
|
// `planSummaries` returns every expected summary with its status and, crucially,
|
|
15
20
|
// the bottom-up order in which to (re)generate them so a single pass converges:
|
|
@@ -19,14 +24,16 @@
|
|
|
19
24
|
// Filenames (`naming`), the line threshold, ignored globs and whether directory
|
|
20
25
|
// summaries are required are all configurable; defaults reproduce the original.
|
|
21
26
|
import * as nodePath from 'node:path';
|
|
22
|
-
import {
|
|
23
|
-
import { matchesAny } from
|
|
24
|
-
import {
|
|
27
|
+
import { extractLinks, isCheckableTarget, stripAnchor, stripCode } from '../links/MarkdownLinks.js';
|
|
28
|
+
import { matchesAny } from '../glob.js';
|
|
29
|
+
import { hashContent } from '../hashing.js';
|
|
30
|
+
import { countLines, DEFAULT_NAMING, isSummaryFile, summaryPathFor } from './DocSummaries.js';
|
|
25
31
|
// POSIX path semantics so the plan is identical on every OS (inputs normalised
|
|
26
32
|
// to `/` at the IO boundary).
|
|
27
33
|
const path = nodePath.posix;
|
|
28
34
|
/** Default per-directory digest filename. */
|
|
29
35
|
export const DIR_SUMMARY = DEFAULT_NAMING.dirSummary;
|
|
36
|
+
const EMPTY_STAMPS = new Map();
|
|
30
37
|
const DEFAULT_THRESHOLD_LINES = 30;
|
|
31
38
|
/** True when `p` is a directory summary under the configured naming. */
|
|
32
39
|
export const isDirSummary = (p, naming = DEFAULT_NAMING) => p === naming.dirSummary || p.endsWith(`/${naming.dirSummary}`);
|
|
@@ -73,9 +80,9 @@ export const nodeExpectedHash = ({ files, inputs, kind, path: nodeAtPath }) => {
|
|
|
73
80
|
return hashContent(manifest);
|
|
74
81
|
};
|
|
75
82
|
/** Compute the full hierarchical summary plan from the current file contents. */
|
|
76
|
-
export const planSummaries = ({ files, ignore = [], naming = DEFAULT_NAMING, requireDirSummaries = true, roots, thresholdLines = DEFAULT_THRESHOLD_LINES, }) => {
|
|
83
|
+
export const planSummaries = ({ files, ignore = [], naming = DEFAULT_NAMING, requireDirSummaries = true, roots, stamps = EMPTY_STAMPS, thresholdLines = DEFAULT_THRESHOLD_LINES, }) => {
|
|
77
84
|
const allPaths = [...files.keys()];
|
|
78
|
-
const recorded = (p) =>
|
|
85
|
+
const recorded = (p) => stamps.get(p) ?? null;
|
|
79
86
|
const sourceDocs = allPaths.filter((p) => p.endsWith('.md') && !isSummaryFile(p, naming) && !isDirSummary(p, naming) && !matchesAny(p, ignore));
|
|
80
87
|
// Computed once per doc up front (a Set lookup below) rather than via a
|
|
81
88
|
// countLines() call at each of the two sites that ask "is this doc big" — the
|
|
@@ -103,7 +110,12 @@ export const planSummaries = ({ files, ignore = [], naming = DEFAULT_NAMING, req
|
|
|
103
110
|
}
|
|
104
111
|
if (!requireDirSummaries) {
|
|
105
112
|
const orphans = findOrphans({ files, ignore, naming, nodes: fileNodes, requireDirSummaries });
|
|
106
|
-
|
|
113
|
+
const orphanStamps = findDeletedStamps({
|
|
114
|
+
expectedNodePaths: new Set(fileNodes.map((n) => n.path)),
|
|
115
|
+
ignore,
|
|
116
|
+
stampNodePaths: stamps.keys(),
|
|
117
|
+
});
|
|
118
|
+
return { nodes: fileNodes, orphanStamps, orphans, todo: fileNodes.filter((n) => n.status !== 'ok') };
|
|
107
119
|
}
|
|
108
120
|
// --- directories in scope ---
|
|
109
121
|
const inScope = (d) => roots.some((r) => d === r || d.startsWith(`${r}/`));
|
|
@@ -177,8 +189,22 @@ export const planSummaries = ({ files, ignore = [], naming = DEFAULT_NAMING, req
|
|
|
177
189
|
dirNodes.sort((a, b) => depth(b.path) - depth(a.path) || a.path.localeCompare(b.path));
|
|
178
190
|
const nodes = [...fileNodes, ...dirNodes];
|
|
179
191
|
const orphans = findOrphans({ files, ignore, naming, nodes, requireDirSummaries });
|
|
180
|
-
|
|
192
|
+
const orphanStamps = findDeletedStamps({
|
|
193
|
+
expectedNodePaths: new Set(nodes.map((n) => n.path)),
|
|
194
|
+
ignore,
|
|
195
|
+
stampNodePaths: stamps.keys(),
|
|
196
|
+
});
|
|
197
|
+
return { nodes, orphanStamps, orphans, todo: nodes.filter((n) => n.status !== 'ok') };
|
|
181
198
|
};
|
|
199
|
+
/**
|
|
200
|
+
* A `.cairn/**` sidecar (see StampStore.ts) whose node no longer corresponds to
|
|
201
|
+
* any expected node. Unlike `findOrphans` (which only sees a leftover summary
|
|
202
|
+
* FILE still on disk), a sidecar is written exclusively by the tool and never
|
|
203
|
+
* touched by hand — so it remains as evidence even when the summary file
|
|
204
|
+
* itself was deleted alongside its source, catching a deletion `findOrphans`
|
|
205
|
+
* alone would miss entirely.
|
|
206
|
+
*/
|
|
207
|
+
const findDeletedStamps = ({ expectedNodePaths, ignore, stampNodePaths }) => [...stampNodePaths].filter((p) => !expectedNodePaths.has(p) && !matchesAny(p, ignore)).toSorted();
|
|
182
208
|
/**
|
|
183
209
|
* A `.summary.md`/`_SUMMARY.md` on disk that no longer corresponds to any
|
|
184
210
|
* expected node — its source doc was deleted, renamed, or (for file summaries)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SummaryTree.js","sourceRoot":"","sources":["../../../src/core/summaries/SummaryTree.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from './core/DocSummaries.ts';
|
|
1
|
+
export * from './core/summaries/DocSummaries.ts';
|
|
2
2
|
export * from './core/glob.ts';
|
|
3
|
-
export * from './core/MarkdownLinks.ts';
|
|
4
|
-
export * from './core/SummaryTree.ts';
|
|
3
|
+
export * from './core/links/MarkdownLinks.ts';
|
|
4
|
+
export * from './core/summaries/SummaryTree.ts';
|
|
5
5
|
export * from './io/DocsFs.ts';
|
|
6
|
-
export * from './program/CheckLinks.ts';
|
|
7
|
-
export * from './program/CheckSummaries.ts';
|
|
6
|
+
export * from './program/links/CheckLinks.ts';
|
|
7
|
+
export * from './program/summaries/CheckSummaries.ts';
|
|
8
8
|
export * from './program/locale.ts';
|
|
9
9
|
export * from './config.ts';
|
|
10
10
|
export type { AgentTarget, InitArgs, InitResult } from './init/generate.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// Public API surface. The CLI (`cairn`) is the primary entrypoint, but the pure
|
|
2
2
|
// planners and Effect programs are exported for programmatic use and testing.
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export { runInit } from
|
|
3
|
+
export * from './core/summaries/DocSummaries.js';
|
|
4
|
+
export * from './core/glob.js';
|
|
5
|
+
export * from './core/links/MarkdownLinks.js';
|
|
6
|
+
export * from './core/summaries/SummaryTree.js';
|
|
7
|
+
export * from './io/DocsFs.js';
|
|
8
|
+
export * from './program/links/CheckLinks.js';
|
|
9
|
+
export * from './program/summaries/CheckSummaries.js';
|
|
10
|
+
export * from './program/locale.js';
|
|
11
|
+
export * from './config.js';
|
|
12
|
+
export { runInit } from './init/generate.js';
|
|
13
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,8EAA8E;AAE9E,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,8EAA8E;AAE9E,cAAc,kCAAkC,CAAA;AAChD,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAE3B,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA"}
|