@isaacriehm/cairn-core 0.4.2 → 0.5.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/dist/.tsbuildinfo +1 -1
- package/dist/align-undo/index.d.ts +6 -0
- package/dist/align-undo/index.js +6 -0
- package/dist/align-undo/index.js.map +1 -0
- package/dist/align-undo/log.d.ts +53 -0
- package/dist/align-undo/log.js +99 -0
- package/dist/align-undo/log.js.map +1 -0
- package/dist/align-undo/undo.d.ts +66 -0
- package/dist/align-undo/undo.js +187 -0
- package/dist/align-undo/undo.js.map +1 -0
- package/dist/attention/bulk-accept.js +1 -1
- package/dist/attention/bulk-accept.js.map +1 -1
- package/dist/attention/dedup.d.ts +2 -2
- package/dist/attention/dedup.js +16 -51
- package/dist/attention/dedup.js.map +1 -1
- package/dist/attention/index.d.ts +1 -0
- package/dist/attention/index.js +1 -0
- package/dist/attention/index.js.map +1 -1
- package/dist/attention/restore.js +1 -1
- package/dist/attention/restore.js.map +1 -1
- package/dist/attention/serve/api.d.ts +23 -0
- package/dist/attention/serve/api.js +344 -0
- package/dist/attention/serve/api.js.map +1 -0
- package/dist/attention/serve/index.d.ts +62 -0
- package/dist/attention/serve/index.js +205 -0
- package/dist/attention/serve/index.js.map +1 -0
- package/dist/decision-capture/id.d.ts +62 -25
- package/dist/decision-capture/id.js +78 -57
- package/dist/decision-capture/id.js.map +1 -1
- package/dist/decision-capture/index.d.ts +3 -3
- package/dist/decision-capture/index.js +3 -3
- package/dist/decision-capture/index.js.map +1 -1
- package/dist/drain/drain.d.ts +77 -0
- package/dist/drain/drain.js +464 -0
- package/dist/drain/drain.js.map +1 -0
- package/dist/drain/index.d.ts +5 -0
- package/dist/drain/index.js +5 -0
- package/dist/drain/index.js.map +1 -0
- package/dist/fix-align/index.d.ts +5 -0
- package/dist/fix-align/index.js +5 -0
- package/dist/fix-align/index.js.map +1 -0
- package/dist/fix-align/run.d.ts +99 -0
- package/dist/fix-align/run.js +258 -0
- package/dist/fix-align/run.js.map +1 -0
- package/dist/ground/alignment-pending.d.ts +28 -0
- package/dist/ground/alignment-pending.js +83 -0
- package/dist/ground/alignment-pending.js.map +1 -0
- package/dist/ground/anchor-map.d.ts +14 -0
- package/dist/ground/anchor-map.js +57 -0
- package/dist/ground/anchor-map.js.map +1 -0
- package/dist/ground/index.d.ts +9 -2
- package/dist/ground/index.js +8 -2
- package/dist/ground/index.js.map +1 -1
- package/dist/ground/paths.d.ts +21 -0
- package/dist/ground/paths.js +43 -0
- package/dist/ground/paths.js.map +1 -1
- package/dist/ground/schemas.d.ts +201 -0
- package/dist/ground/schemas.js +128 -3
- package/dist/ground/schemas.js.map +1 -1
- package/dist/ground/scope-index.js +2 -2
- package/dist/ground/scope-index.js.map +1 -1
- package/dist/ground/slug.d.ts +60 -0
- package/dist/ground/slug.js +103 -0
- package/dist/ground/slug.js.map +1 -0
- package/dist/ground/sot-bindings.d.ts +14 -0
- package/dist/ground/sot-bindings.js +80 -0
- package/dist/ground/sot-bindings.js.map +1 -0
- package/dist/ground/sot-cache.d.ts +18 -0
- package/dist/ground/sot-cache.js +63 -0
- package/dist/ground/sot-cache.js.map +1 -0
- package/dist/ground/topic-index.d.ts +20 -0
- package/dist/ground/topic-index.js +60 -0
- package/dist/ground/topic-index.js.map +1 -0
- package/dist/hooks/post-tool-use/citation-scanner.d.ts +1 -1
- package/dist/hooks/post-tool-use/citation-scanner.js +3 -3
- package/dist/hooks/post-tool-use/citation-scanner.js.map +1 -1
- package/dist/hooks/post-tool-use/copy-scanner.js +1 -1
- package/dist/hooks/post-tool-use/copy-scanner.js.map +1 -1
- package/dist/hooks/post-tool-use/index.d.ts +2 -0
- package/dist/hooks/post-tool-use/index.js +1 -0
- package/dist/hooks/post-tool-use/index.js.map +1 -1
- package/dist/hooks/post-tool-use/legend-builder.d.ts +1 -1
- package/dist/hooks/post-tool-use/legend-builder.js +2 -2
- package/dist/hooks/post-tool-use/legend-builder.js.map +1 -1
- package/dist/hooks/post-tool-use/sot-align.d.ts +166 -0
- package/dist/hooks/post-tool-use/sot-align.js +1311 -0
- package/dist/hooks/post-tool-use/sot-align.js.map +1 -0
- package/dist/hooks/pre-commit/index.d.ts +8 -0
- package/dist/hooks/pre-commit/index.js +8 -0
- package/dist/hooks/pre-commit/index.js.map +1 -0
- package/dist/hooks/pre-commit/sot-align-precommit.d.ts +60 -0
- package/dist/hooks/pre-commit/sot-align-precommit.js +221 -0
- package/dist/hooks/pre-commit/sot-align-precommit.js.map +1 -0
- package/dist/hooks/runners/session-start.js +41 -0
- package/dist/hooks/runners/session-start.js.map +1 -1
- package/dist/hooks/sot-align-common.d.ts +39 -0
- package/dist/hooks/sot-align-common.js +152 -0
- package/dist/hooks/sot-align-common.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/init/index.d.ts +4 -2
- package/dist/init/index.js +2 -1
- package/dist/init/index.js.map +1 -1
- package/dist/init/ingest-docs.d.ts +30 -47
- package/dist/init/ingest-docs.js +113 -406
- package/dist/init/ingest-docs.js.map +1 -1
- package/dist/init/init.d.ts +8 -0
- package/dist/init/init.js +58 -29
- package/dist/init/init.js.map +1 -1
- package/dist/init/mapper-parallel.js +1 -1
- package/dist/init/mapper-parallel.js.map +1 -1
- package/dist/init/phases/5-brand.js +1 -1
- package/dist/init/phases/5-brand.js.map +1 -1
- package/dist/init/phases/5b-topic-index.d.ts +30 -0
- package/dist/init/phases/5b-topic-index.js +62 -0
- package/dist/init/phases/5b-topic-index.js.map +1 -0
- package/dist/init/phases/6-docs-ingest.d.ts +4 -5
- package/dist/init/phases/6-docs-ingest.js +5 -6
- package/dist/init/phases/6-docs-ingest.js.map +1 -1
- package/dist/init/phases/index.d.ts +2 -0
- package/dist/init/phases/index.js +1 -0
- package/dist/init/phases/index.js.map +1 -1
- package/dist/init/phases/parallel-678.d.ts +14 -17
- package/dist/init/phases/parallel-678.js +77 -98
- package/dist/init/phases/parallel-678.js.map +1 -1
- package/dist/init/phases/source-comments-output-io.d.ts +16 -10
- package/dist/init/phases/source-comments-output-io.js +7 -10
- package/dist/init/phases/source-comments-output-io.js.map +1 -1
- package/dist/init/phases/types.d.ts +1 -1
- package/dist/init/phases/types.js +1 -0
- package/dist/init/phases/types.js.map +1 -1
- package/dist/init/rules-merge/discover.d.ts +8 -3
- package/dist/init/rules-merge/discover.js +7 -3
- package/dist/init/rules-merge/discover.js.map +1 -1
- package/dist/init/rules-merge/ingest.d.ts +81 -28
- package/dist/init/rules-merge/ingest.js +456 -155
- package/dist/init/rules-merge/ingest.js.map +1 -1
- package/dist/init/sot-emit.d.ts +84 -0
- package/dist/init/sot-emit.js +218 -0
- package/dist/init/sot-emit.js.map +1 -0
- package/dist/init/source-comments/classify.d.ts +12 -10
- package/dist/init/source-comments/classify.js +13 -25
- package/dist/init/source-comments/classify.js.map +1 -1
- package/dist/init/source-comments/index.d.ts +1 -1
- package/dist/init/source-comments/index.js +1 -1
- package/dist/init/source-comments/index.js.map +1 -1
- package/dist/init/source-comments/ingest.d.ts +91 -67
- package/dist/init/source-comments/ingest.js +392 -349
- package/dist/init/source-comments/ingest.js.map +1 -1
- package/dist/init/topic-index/index.d.ts +36 -0
- package/dist/init/topic-index/index.js +46 -0
- package/dist/init/topic-index/index.js.map +1 -0
- package/dist/init/topic-index/judge.d.ts +20 -0
- package/dist/init/topic-index/judge.js +65 -0
- package/dist/init/topic-index/judge.js.map +1 -0
- package/dist/init/topic-index/resolve.d.ts +50 -0
- package/dist/init/topic-index/resolve.js +196 -0
- package/dist/init/topic-index/resolve.js.map +1 -0
- package/dist/init/topic-index/walk.d.ts +43 -0
- package/dist/init/topic-index/walk.js +293 -0
- package/dist/init/topic-index/walk.js.map +1 -0
- package/dist/mcp/history/summarizer.js +1 -1
- package/dist/mcp/history/summarizer.js.map +1 -1
- package/dist/mcp/schemas.d.ts +46 -9
- package/dist/mcp/schemas.js +48 -12
- package/dist/mcp/schemas.js.map +1 -1
- package/dist/mcp/tools/align-drain.d.ts +7 -0
- package/dist/mcp/tools/align-drain.js +26 -0
- package/dist/mcp/tools/align-drain.js.map +1 -0
- package/dist/mcp/tools/archive.js +1 -1
- package/dist/mcp/tools/archive.js.map +1 -1
- package/dist/mcp/tools/attention-restore.js +1 -1
- package/dist/mcp/tools/attention-restore.js.map +1 -1
- package/dist/mcp/tools/attention-serve.d.ts +23 -0
- package/dist/mcp/tools/attention-serve.js +78 -0
- package/dist/mcp/tools/attention-serve.js.map +1 -0
- package/dist/mcp/tools/attention-wait.d.ts +18 -0
- package/dist/mcp/tools/attention-wait.js +74 -0
- package/dist/mcp/tools/attention-wait.js.map +1 -0
- package/dist/mcp/tools/index.js +7 -0
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/init-phases.js +4 -1
- package/dist/mcp/tools/init-phases.js.map +1 -1
- package/dist/mcp/tools/record-decision.js +14 -2
- package/dist/mcp/tools/record-decision.js.map +1 -1
- package/dist/mcp/tools/resolve-attention.d.ts +2 -2
- package/dist/mcp/tools/resolve-attention.js +830 -7
- package/dist/mcp/tools/resolve-attention.js.map +1 -1
- package/dist/status-line/event-queue.d.ts +40 -0
- package/dist/status-line/event-queue.js +195 -0
- package/dist/status-line/event-queue.js.map +1 -0
- package/dist/status-line/format.d.ts +1 -1
- package/dist/status-line/format.js +49 -6
- package/dist/status-line/format.js.map +1 -1
- package/dist/status-line/index.d.ts +41 -0
- package/dist/status-line/index.js +14 -0
- package/dist/status-line/index.js.map +1 -1
- package/dist/status-line/reader.js +23 -18
- package/dist/status-line/reader.js.map +1 -1
- package/dist/status-line/writer.d.ts +1 -1
- package/dist/status-line/writer.js +5 -0
- package/dist/status-line/writer.js.map +1 -1
- package/dist/text/jaccard.d.ts +19 -0
- package/dist/text/jaccard.js +68 -0
- package/dist/text/jaccard.js.map +1 -0
- package/package.json +1 -1
- package/templates/.cairn/git-hooks/pre-commit +16 -3
- package/templates/attention-ui/app.css +406 -0
- package/templates/attention-ui/app.js +384 -0
- package/templates/attention-ui/index.html +56 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer A undo log + `cairn attention undo` runner. Plan §11.7.
|
|
3
|
+
*/
|
|
4
|
+
export { AlignUndoEntry, alignUndoLogPath, appendAlignUndoEntry, pruneAlignUndoLog, readAlignUndoLog, } from "./log.js";
|
|
5
|
+
export { runAttentionUndo } from "./undo.js";
|
|
6
|
+
export type { UndoArgs, UndoEntryOutcome, UndoResult } from "./undo.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer A undo log + `cairn attention undo` runner. Plan §11.7.
|
|
3
|
+
*/
|
|
4
|
+
export { AlignUndoEntry, alignUndoLogPath, appendAlignUndoEntry, pruneAlignUndoLog, readAlignUndoLog, } from "./log.js";
|
|
5
|
+
export { runAttentionUndo } from "./undo.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/align-undo/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer A audit log for `cairn attention undo` (plan §11.7).
|
|
3
|
+
*
|
|
4
|
+
* Every Layer A auto-resolution (Tier 1 cite, Tier 2 same cite, Tier 3
|
|
5
|
+
* fresh DEC creation, augments-DEC/INV emission) appends one line to
|
|
6
|
+
* `.cairn/state/align-undo-log.jsonl`. The CLI command
|
|
7
|
+
* `cairn attention undo [--since <duration>]` reads recent entries and
|
|
8
|
+
* reverses them.
|
|
9
|
+
*
|
|
10
|
+
* The deviation from plan §11.7's literal "reads invalidation events
|
|
11
|
+
* from `.cairn/events/`" — invalidation events are designed for
|
|
12
|
+
* cross-session broadcast (kind, refs, source), not for carrying the
|
|
13
|
+
* (file, offset, original_raw) metadata that undo needs. Keeping the
|
|
14
|
+
* undo log separate avoids polluting the broadcast surface and lets
|
|
15
|
+
* the GC retention policy stay independent.
|
|
16
|
+
*
|
|
17
|
+
* Truncation policy: `cairn attention undo` rewrites the log keeping
|
|
18
|
+
* only entries OUTSIDE the undo window so re-running `undo` against
|
|
19
|
+
* the same window is idempotent.
|
|
20
|
+
*/
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
export declare const AlignUndoEntry: z.ZodObject<{
|
|
23
|
+
ts: z.ZodString;
|
|
24
|
+
session_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
25
|
+
kind: z.ZodEnum<{
|
|
26
|
+
"tier1-cite": "tier1-cite";
|
|
27
|
+
"tier2-cite": "tier2-cite";
|
|
28
|
+
"tier3-creation": "tier3-creation";
|
|
29
|
+
augments: "augments";
|
|
30
|
+
}>;
|
|
31
|
+
file: z.ZodString;
|
|
32
|
+
start_offset: z.ZodNumber;
|
|
33
|
+
end_offset: z.ZodNumber;
|
|
34
|
+
original_raw: z.ZodString;
|
|
35
|
+
replacement: z.ZodString;
|
|
36
|
+
primary_id: z.ZodString;
|
|
37
|
+
primary_kind: z.ZodOptional<z.ZodEnum<{
|
|
38
|
+
DEC: "DEC";
|
|
39
|
+
INV: "INV";
|
|
40
|
+
}>>;
|
|
41
|
+
augments_existing_id: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
export type AlignUndoEntry = z.infer<typeof AlignUndoEntry>;
|
|
44
|
+
export declare function alignUndoLogPath(repoRoot: string): string;
|
|
45
|
+
export declare function appendAlignUndoEntry(repoRoot: string, entry: AlignUndoEntry): void;
|
|
46
|
+
export declare function readAlignUndoLog(repoRoot: string): AlignUndoEntry[];
|
|
47
|
+
/**
|
|
48
|
+
* Rewrite the undo log keeping only the entries NOT in `undone`.
|
|
49
|
+
* Idempotency: running `cairn attention undo --since <window>` twice
|
|
50
|
+
* on the same window does nothing the second time because the entries
|
|
51
|
+
* inside the window have already been removed.
|
|
52
|
+
*/
|
|
53
|
+
export declare function pruneAlignUndoLog(repoRoot: string, remaining: AlignUndoEntry[]): void;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer A audit log for `cairn attention undo` (plan §11.7).
|
|
3
|
+
*
|
|
4
|
+
* Every Layer A auto-resolution (Tier 1 cite, Tier 2 same cite, Tier 3
|
|
5
|
+
* fresh DEC creation, augments-DEC/INV emission) appends one line to
|
|
6
|
+
* `.cairn/state/align-undo-log.jsonl`. The CLI command
|
|
7
|
+
* `cairn attention undo [--since <duration>]` reads recent entries and
|
|
8
|
+
* reverses them.
|
|
9
|
+
*
|
|
10
|
+
* The deviation from plan §11.7's literal "reads invalidation events
|
|
11
|
+
* from `.cairn/events/`" — invalidation events are designed for
|
|
12
|
+
* cross-session broadcast (kind, refs, source), not for carrying the
|
|
13
|
+
* (file, offset, original_raw) metadata that undo needs. Keeping the
|
|
14
|
+
* undo log separate avoids polluting the broadcast surface and lets
|
|
15
|
+
* the GC retention policy stay independent.
|
|
16
|
+
*
|
|
17
|
+
* Truncation policy: `cairn attention undo` rewrites the log keeping
|
|
18
|
+
* only entries OUTSIDE the undo window so re-running `undo` against
|
|
19
|
+
* the same window is idempotent.
|
|
20
|
+
*/
|
|
21
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22
|
+
import { dirname, join } from "node:path";
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
import { logger } from "../logger.js";
|
|
25
|
+
const log = logger("align-undo.log");
|
|
26
|
+
export const AlignUndoEntry = z.object({
|
|
27
|
+
ts: z.string(),
|
|
28
|
+
session_id: z.string().nullable().optional(),
|
|
29
|
+
kind: z.enum(["tier1-cite", "tier2-cite", "tier3-creation", "augments"]),
|
|
30
|
+
file: z.string(),
|
|
31
|
+
start_offset: z.number(),
|
|
32
|
+
end_offset: z.number(),
|
|
33
|
+
/** Original prose block raw (incl. comment delimiters) before strip-replace. */
|
|
34
|
+
original_raw: z.string(),
|
|
35
|
+
/** Replacement that was inserted (e.g. `// §DEC-1234567`). */
|
|
36
|
+
replacement: z.string(),
|
|
37
|
+
/** DEC/INV id cited (tier1/tier2 cite) or freshly emitted (tier3 / augments). */
|
|
38
|
+
primary_id: z.string(),
|
|
39
|
+
/** For tier3-creation: was the freshly-emitted entity a DEC or INV? */
|
|
40
|
+
primary_kind: z.enum(["DEC", "INV"]).optional(),
|
|
41
|
+
/** For augments: the existing entity id that was augmented (its cite stays). */
|
|
42
|
+
augments_existing_id: z.string().optional(),
|
|
43
|
+
});
|
|
44
|
+
export function alignUndoLogPath(repoRoot) {
|
|
45
|
+
return join(repoRoot, ".cairn", "state", "align-undo-log.jsonl");
|
|
46
|
+
}
|
|
47
|
+
export function appendAlignUndoEntry(repoRoot, entry) {
|
|
48
|
+
const validated = AlignUndoEntry.parse(entry);
|
|
49
|
+
const path = alignUndoLogPath(repoRoot);
|
|
50
|
+
try {
|
|
51
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
52
|
+
appendFileSync(path, `${JSON.stringify(validated)}\n`, "utf8");
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log append failed");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function readAlignUndoLog(repoRoot) {
|
|
59
|
+
const path = alignUndoLogPath(repoRoot);
|
|
60
|
+
if (!existsSync(path))
|
|
61
|
+
return [];
|
|
62
|
+
const text = readFileSync(path, "utf8");
|
|
63
|
+
if (text.trim().length === 0)
|
|
64
|
+
return [];
|
|
65
|
+
const out = [];
|
|
66
|
+
for (const line of text.split("\n")) {
|
|
67
|
+
const trimmed = line.trim();
|
|
68
|
+
if (trimmed.length === 0)
|
|
69
|
+
continue;
|
|
70
|
+
try {
|
|
71
|
+
out.push(AlignUndoEntry.parse(JSON.parse(trimmed)));
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "skipping malformed align-undo entry");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Rewrite the undo log keeping only the entries NOT in `undone`.
|
|
81
|
+
* Idempotency: running `cairn attention undo --since <window>` twice
|
|
82
|
+
* on the same window does nothing the second time because the entries
|
|
83
|
+
* inside the window have already been removed.
|
|
84
|
+
*/
|
|
85
|
+
export function pruneAlignUndoLog(repoRoot, remaining) {
|
|
86
|
+
const path = alignUndoLogPath(repoRoot);
|
|
87
|
+
try {
|
|
88
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
89
|
+
if (remaining.length === 0) {
|
|
90
|
+
writeFileSync(path, "", "utf8");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
writeFileSync(path, `${remaining.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log prune failed");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/align-undo/log.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cairn attention undo` runner (plan §11.7).
|
|
3
|
+
*
|
|
4
|
+
* Reverses Layer A auto-resolutions logged at
|
|
5
|
+
* `.cairn/state/align-undo-log.jsonl`. The CLI passes `--since
|
|
6
|
+
* <duration>` (default 1h); only entries within the window are
|
|
7
|
+
* undone, the rest stay in the log.
|
|
8
|
+
*
|
|
9
|
+
* Currently reverses:
|
|
10
|
+
*
|
|
11
|
+
* - `tier1-cite` / `tier2-cite` — find the cite line in the current
|
|
12
|
+
* source, swap it back for the original prose block. Idempotent
|
|
13
|
+
* when the source has been hand-edited away from the cite already.
|
|
14
|
+
*
|
|
15
|
+
* Out of scope for v0.5.0 (deferred to v0.6 — these need targeted
|
|
16
|
+
* ledger surgery + sotBindings/sotCache rollback):
|
|
17
|
+
*
|
|
18
|
+
* - `tier3-creation` — would need to delete the DEC/INV file, drop
|
|
19
|
+
* its sotBindings / sotCache / topic-index entries, refresh the
|
|
20
|
+
* ledger, and restore the source. Reported in the undo summary
|
|
21
|
+
* so the operator can hand-resolve.
|
|
22
|
+
*
|
|
23
|
+
* - `augments` — would need to delete the sibling DEC/INV and
|
|
24
|
+
* remove its cite from the double-cite while keeping the
|
|
25
|
+
* existing-id cite in place.
|
|
26
|
+
*
|
|
27
|
+
* Idempotent: the runner truncates undone entries from the log so a
|
|
28
|
+
* second invocation against the same window is a no-op.
|
|
29
|
+
*/
|
|
30
|
+
import { type AlignUndoEntry } from "./log.js";
|
|
31
|
+
export interface UndoArgs {
|
|
32
|
+
repoRoot: string;
|
|
33
|
+
/**
|
|
34
|
+
* Wall-clock window. Entries with `ts` newer than `now - sinceMs`
|
|
35
|
+
* are undone. Default 1h.
|
|
36
|
+
*/
|
|
37
|
+
sinceMs?: number;
|
|
38
|
+
/** Dry-run: classify entries but do not modify source / log. */
|
|
39
|
+
dryRun?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface UndoEntryOutcome {
|
|
42
|
+
entry: AlignUndoEntry;
|
|
43
|
+
/**
|
|
44
|
+
* - `reverted` — source was rewritten back to the original prose.
|
|
45
|
+
* - `already-reverted`— the cite token is no longer in source (operator beat us).
|
|
46
|
+
* - `not-supported` — kind requires manual surgery (tier3-creation, augments).
|
|
47
|
+
* - `source-missing` — source file no longer exists.
|
|
48
|
+
* - `error` — write failed (logged + reported).
|
|
49
|
+
*/
|
|
50
|
+
status: "reverted" | "already-reverted" | "not-supported" | "source-missing" | "error";
|
|
51
|
+
detail?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface UndoResult {
|
|
54
|
+
/** Total entries inside the undo window. */
|
|
55
|
+
windowEntries: number;
|
|
56
|
+
/** Entries left in the log because they were outside the window. */
|
|
57
|
+
outsideWindow: number;
|
|
58
|
+
/** Per-entry outcomes for everything inside the window. */
|
|
59
|
+
outcomes: UndoEntryOutcome[];
|
|
60
|
+
reverted: number;
|
|
61
|
+
alreadyReverted: number;
|
|
62
|
+
notSupported: number;
|
|
63
|
+
sourceMissing: number;
|
|
64
|
+
errors: number;
|
|
65
|
+
}
|
|
66
|
+
export declare function runAttentionUndo(args: UndoArgs): Promise<UndoResult>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cairn attention undo` runner (plan §11.7).
|
|
3
|
+
*
|
|
4
|
+
* Reverses Layer A auto-resolutions logged at
|
|
5
|
+
* `.cairn/state/align-undo-log.jsonl`. The CLI passes `--since
|
|
6
|
+
* <duration>` (default 1h); only entries within the window are
|
|
7
|
+
* undone, the rest stay in the log.
|
|
8
|
+
*
|
|
9
|
+
* Currently reverses:
|
|
10
|
+
*
|
|
11
|
+
* - `tier1-cite` / `tier2-cite` — find the cite line in the current
|
|
12
|
+
* source, swap it back for the original prose block. Idempotent
|
|
13
|
+
* when the source has been hand-edited away from the cite already.
|
|
14
|
+
*
|
|
15
|
+
* Out of scope for v0.5.0 (deferred to v0.6 — these need targeted
|
|
16
|
+
* ledger surgery + sotBindings/sotCache rollback):
|
|
17
|
+
*
|
|
18
|
+
* - `tier3-creation` — would need to delete the DEC/INV file, drop
|
|
19
|
+
* its sotBindings / sotCache / topic-index entries, refresh the
|
|
20
|
+
* ledger, and restore the source. Reported in the undo summary
|
|
21
|
+
* so the operator can hand-resolve.
|
|
22
|
+
*
|
|
23
|
+
* - `augments` — would need to delete the sibling DEC/INV and
|
|
24
|
+
* remove its cite from the double-cite while keeping the
|
|
25
|
+
* existing-id cite in place.
|
|
26
|
+
*
|
|
27
|
+
* Idempotent: the runner truncates undone entries from the log so a
|
|
28
|
+
* second invocation against the same window is a no-op.
|
|
29
|
+
*/
|
|
30
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
31
|
+
import { join } from "node:path";
|
|
32
|
+
import { logger } from "../logger.js";
|
|
33
|
+
import { pruneAlignUndoLog, readAlignUndoLog, } from "./log.js";
|
|
34
|
+
const log = logger("align-undo.runner");
|
|
35
|
+
const DEFAULT_SINCE_MS = 60 * 60 * 1_000;
|
|
36
|
+
/* -------------------------------------------------------------------------- */
|
|
37
|
+
/* Run */
|
|
38
|
+
/* -------------------------------------------------------------------------- */
|
|
39
|
+
export async function runAttentionUndo(args) {
|
|
40
|
+
const { repoRoot } = args;
|
|
41
|
+
const sinceMs = args.sinceMs ?? DEFAULT_SINCE_MS;
|
|
42
|
+
const dryRun = args.dryRun === true;
|
|
43
|
+
const cutoff = Date.now() - sinceMs;
|
|
44
|
+
const all = readAlignUndoLog(repoRoot);
|
|
45
|
+
const inside = [];
|
|
46
|
+
const outside = [];
|
|
47
|
+
for (const e of all) {
|
|
48
|
+
const tsMs = Date.parse(e.ts);
|
|
49
|
+
if (Number.isFinite(tsMs) && tsMs >= cutoff) {
|
|
50
|
+
inside.push(e);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
outside.push(e);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const outcomes = [];
|
|
57
|
+
// Process newest first — undoing in reverse order matches typical
|
|
58
|
+
// operator intent ("undo my last 5 minutes of cites").
|
|
59
|
+
inside.sort((a, b) => Date.parse(b.ts) - Date.parse(a.ts));
|
|
60
|
+
for (const entry of inside) {
|
|
61
|
+
outcomes.push(reverseEntry(repoRoot, entry, dryRun));
|
|
62
|
+
}
|
|
63
|
+
const result = {
|
|
64
|
+
windowEntries: inside.length,
|
|
65
|
+
outsideWindow: outside.length,
|
|
66
|
+
outcomes,
|
|
67
|
+
reverted: outcomes.filter((o) => o.status === "reverted").length,
|
|
68
|
+
alreadyReverted: outcomes.filter((o) => o.status === "already-reverted").length,
|
|
69
|
+
notSupported: outcomes.filter((o) => o.status === "not-supported").length,
|
|
70
|
+
sourceMissing: outcomes.filter((o) => o.status === "source-missing").length,
|
|
71
|
+
errors: outcomes.filter((o) => o.status === "error").length,
|
|
72
|
+
};
|
|
73
|
+
if (!dryRun) {
|
|
74
|
+
// Keep entries that we couldn't undo (not-supported / errors) so
|
|
75
|
+
// the operator can re-attempt or hand-resolve. Entries we
|
|
76
|
+
// reverted (or that were already reverted) are removed.
|
|
77
|
+
const keep = [
|
|
78
|
+
...outside,
|
|
79
|
+
...outcomes
|
|
80
|
+
.filter((o) => o.status === "not-supported" || o.status === "error")
|
|
81
|
+
.map((o) => o.entry),
|
|
82
|
+
];
|
|
83
|
+
pruneAlignUndoLog(repoRoot, keep);
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
87
|
+
/* -------------------------------------------------------------------------- */
|
|
88
|
+
/* Per-entry reversal */
|
|
89
|
+
/* -------------------------------------------------------------------------- */
|
|
90
|
+
function reverseEntry(repoRoot, entry, dryRun) {
|
|
91
|
+
if (entry.kind === "tier3-creation" || entry.kind === "augments") {
|
|
92
|
+
return {
|
|
93
|
+
entry,
|
|
94
|
+
status: "not-supported",
|
|
95
|
+
detail: entry.kind === "tier3-creation"
|
|
96
|
+
? "fresh DEC/INV creation undo deferred to v0.6 — manually delete the entity file and restore the source block"
|
|
97
|
+
: "augments-sibling undo deferred to v0.6 — manually delete the sibling and trim the double-cite",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const abs = join(repoRoot, entry.file);
|
|
101
|
+
if (!existsSync(abs)) {
|
|
102
|
+
return { entry, status: "source-missing", detail: `${entry.file} no longer exists` };
|
|
103
|
+
}
|
|
104
|
+
let source;
|
|
105
|
+
try {
|
|
106
|
+
source = readFileSync(abs, "utf8");
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
entry,
|
|
111
|
+
status: "error",
|
|
112
|
+
detail: `cannot read ${entry.file}: ${err instanceof Error ? err.message : String(err)}`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
// Locate the cite line in the current source. The exact byte offsets
|
|
116
|
+
// recorded at log-time are stale (the strip-replace re-flowed the
|
|
117
|
+
// file), so we search for the literal replacement string instead.
|
|
118
|
+
const replacement = entry.replacement.trimEnd();
|
|
119
|
+
const idx = source.indexOf(replacement);
|
|
120
|
+
if (idx === -1) {
|
|
121
|
+
// Already hand-edited away — operator removed the cite themselves.
|
|
122
|
+
return {
|
|
123
|
+
entry,
|
|
124
|
+
status: "already-reverted",
|
|
125
|
+
detail: `cite "${replacement.trim()}" not found in ${entry.file}`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
// Swap the replacement (matched + any trailing whitespace until newline) for the original raw.
|
|
129
|
+
// Replacement is typically a one-liner like "// §DEC-aaaaaaa"; we
|
|
130
|
+
// want to preserve indentation if the original raw had any.
|
|
131
|
+
const lineStart = source.lastIndexOf("\n", idx) + 1;
|
|
132
|
+
const lineEnd = source.indexOf("\n", idx + replacement.length);
|
|
133
|
+
const cutEnd = lineEnd === -1 ? source.length : lineEnd;
|
|
134
|
+
const before = source.slice(0, lineStart);
|
|
135
|
+
const after = source.slice(cutEnd);
|
|
136
|
+
// Match the indentation that strip-replace prepended on the cite —
|
|
137
|
+
// leading whitespace from `lineStart` up to the `idx`.
|
|
138
|
+
const indent = source.slice(lineStart, idx);
|
|
139
|
+
const reflowedOriginal = reapplyIndent(entry.original_raw, indent);
|
|
140
|
+
const next = `${before}${reflowedOriginal}${after}`;
|
|
141
|
+
if (!dryRun) {
|
|
142
|
+
try {
|
|
143
|
+
writeFileSync(abs, next, "utf8");
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
log.warn({ file: entry.file, err: err instanceof Error ? err.message : String(err) }, "align-undo write failed");
|
|
147
|
+
return {
|
|
148
|
+
entry,
|
|
149
|
+
status: "error",
|
|
150
|
+
detail: `cannot write ${entry.file}: ${err instanceof Error ? err.message : String(err)}`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { entry, status: "reverted", detail: `${entry.file}` };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Re-apply the leading indent that the cite line carried so the
|
|
158
|
+
* restored original block lines up at the right column. Most blocks'
|
|
159
|
+
* raw already includes the full indentation — we only prepend `indent`
|
|
160
|
+
* to lines that start without it, which handles JSDoc / line-comment
|
|
161
|
+
* blocks captured at column 0.
|
|
162
|
+
*/
|
|
163
|
+
function reapplyIndent(raw, indent) {
|
|
164
|
+
if (indent.length === 0)
|
|
165
|
+
return raw;
|
|
166
|
+
const lines = raw.split("\n");
|
|
167
|
+
const out = [];
|
|
168
|
+
let isFirst = true;
|
|
169
|
+
for (const line of lines) {
|
|
170
|
+
if (isFirst) {
|
|
171
|
+
out.push(line);
|
|
172
|
+
isFirst = false;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (line.length === 0) {
|
|
176
|
+
out.push(line);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (line.startsWith(indent) || /^\s/.test(line)) {
|
|
180
|
+
out.push(line);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
out.push(`${indent}${line}`);
|
|
184
|
+
}
|
|
185
|
+
return out.join("\n");
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=undo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo.js","sourceRoot":"","sources":["../../src/align-undo/undo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAEL,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,UAAU,CAAC;AAElB,MAAM,GAAG,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAiDxC,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAEzC,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAc;IACnD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IAEpC,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,kEAAkE;IAClE,uDAAuD;IACvD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAe;QACzB,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,aAAa,EAAE,OAAO,CAAC,MAAM;QAC7B,QAAQ;QACR,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM;QAChE,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,kBAAkB,CAAC,CAAC,MAAM;QAC/E,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,MAAM;QACzE,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,MAAM;QAC3E,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM;KAC5D,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,iEAAiE;QACjE,0DAA0D;QAC1D,wDAAwD;QACxD,MAAM,IAAI,GAAqB;YAC7B,GAAG,OAAO;YACV,GAAG,QAAQ;iBACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC;iBACnE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;SACvB,CAAC;QACF,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF,SAAS,YAAY,CACnB,QAAgB,EAChB,KAAqB,EACrB,MAAe;IAEf,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACjE,OAAO;YACL,KAAK;YACL,MAAM,EAAE,eAAe;YACvB,MAAM,EACJ,KAAK,CAAC,IAAI,KAAK,gBAAgB;gBAC7B,CAAC,CAAC,6GAA6G;gBAC/G,CAAC,CAAC,+FAA+F;SACtG,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,mBAAmB,EAAE,CAAC;IACvF,CAAC;IACD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,KAAK;YACL,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,eAAe,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACzF,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,kEAAkE;IAClE,kEAAkE;IAClE,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,mEAAmE;QACnE,OAAO;YACL,KAAK;YACL,MAAM,EAAE,kBAAkB;YAC1B,MAAM,EAAE,SAAS,WAAW,CAAC,IAAI,EAAE,kBAAkB,KAAK,CAAC,IAAI,EAAE;SAClE,CAAC;IACJ,CAAC;IAED,+FAA+F;IAC/F,kEAAkE;IAClE,4DAA4D;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,mEAAmE;IACnE,uDAAuD;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,aAAa,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,GAAG,MAAM,GAAG,gBAAgB,GAAG,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CACN,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC3E,yBAAyB,CAC1B,CAAC;YACF,OAAO;gBACL,KAAK;gBACL,MAAM,EAAE,OAAO;gBACf,MAAM,EAAE,gBAAgB,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,GAAW,EAAE,MAAc;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,EAAE,CAAC;YACZ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -181,7 +181,7 @@ export async function bulkAcceptObvious(args) {
|
|
|
181
181
|
};
|
|
182
182
|
if (existsSync(invDir)) {
|
|
183
183
|
const invEntries = readdirSync(invDir, { withFileTypes: true });
|
|
184
|
-
const invFiles = invEntries.filter((e) => e.isFile() && /^INV
|
|
184
|
+
const invFiles = invEntries.filter((e) => e.isFile() && /^INV-[0-9a-f]{7,}\.md$/.test(e.name));
|
|
185
185
|
invResult.invariantsScanned = invFiles.length;
|
|
186
186
|
if (invFiles.length > 0 && !dry) {
|
|
187
187
|
await withWriteLock(args.repoRoot, () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-accept.js","sourceRoot":"","sources":["../../src/attention/bulk-accept.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bulk-accept.js","sourceRoot":"","sources":["../../src/attention/bulk-accept.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* CLI subcommand wraps `findDuplicateClusters` for `--dry-run` previews.
|
|
19
19
|
*/
|
|
20
20
|
export interface DraftRef {
|
|
21
|
-
/** DEC id (e.g. `DEC-
|
|
21
|
+
/** DEC id (e.g. `DEC-a3f7b2c`). */
|
|
22
22
|
id: string;
|
|
23
23
|
/** Repo-relative path to the draft file in `_inbox/`. */
|
|
24
24
|
path: string;
|
|
@@ -36,7 +36,7 @@ export interface DuplicateCluster {
|
|
|
36
36
|
tier: "definite" | "potential";
|
|
37
37
|
/** Average pairwise Jaccard within the cluster. */
|
|
38
38
|
averageSimilarity: number;
|
|
39
|
-
/** Cluster members; first-listed is a stable suggested survivor (
|
|
39
|
+
/** Cluster members; first-listed is a stable suggested survivor (oldest mtime, then lex id). */
|
|
40
40
|
drafts: DraftRef[];
|
|
41
41
|
}
|
|
42
42
|
export interface DedupResult {
|
package/dist/attention/dedup.js
CHANGED
|
@@ -17,58 +17,12 @@
|
|
|
17
17
|
* Output is deliberately a pure data structure — the skill renders. The
|
|
18
18
|
* CLI subcommand wraps `findDuplicateClusters` for `--dry-run` previews.
|
|
19
19
|
*/
|
|
20
|
-
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
20
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { decisionsDir } from "../ground/paths.js";
|
|
23
|
-
|
|
24
|
-
/* Tokenization */
|
|
25
|
-
/* -------------------------------------------------------------------------- */
|
|
26
|
-
/**
|
|
27
|
-
* Stopwords. Hard-coded English set plus a handful of cairn-domain
|
|
28
|
-
* terms that appear in nearly every draft and would otherwise dominate
|
|
29
|
-
* Jaccard scores ("rationale", "decision").
|
|
30
|
-
*/
|
|
31
|
-
const STOPWORDS = new Set([
|
|
32
|
-
"the", "a", "an", "and", "or", "of", "in", "on", "to", "for", "with",
|
|
33
|
-
"by", "from", "is", "are", "was", "were", "be", "been", "being", "has",
|
|
34
|
-
"have", "had", "do", "does", "did", "this", "that", "these", "those",
|
|
35
|
-
"it", "its", "as", "at", "but", "if", "than", "so", "use", "used",
|
|
36
|
-
"using", "via", "out", "off", "up", "our", "their", "one", "two",
|
|
37
|
-
"when", "where", "what", "how", "why", "who", "which", "can", "should",
|
|
38
|
-
"must", "will", "shall", "may", "not", "no", "any", "all", "some",
|
|
39
|
-
"few", "more", "most", "only", "also",
|
|
40
|
-
]);
|
|
23
|
+
import { jaccard, tokenize } from "../text/jaccard.js";
|
|
41
24
|
/** Default char window of body to fold into the token bag. */
|
|
42
25
|
const BODY_CHAR_WINDOW = 500;
|
|
43
|
-
function stem(w) {
|
|
44
|
-
if (w.length <= 4)
|
|
45
|
-
return w;
|
|
46
|
-
if (w.endsWith("ing"))
|
|
47
|
-
return w.slice(0, -3);
|
|
48
|
-
if (w.endsWith("ed"))
|
|
49
|
-
return w.slice(0, -2);
|
|
50
|
-
if (w.endsWith("s") && !w.endsWith("ss"))
|
|
51
|
-
return w.slice(0, -1);
|
|
52
|
-
return w;
|
|
53
|
-
}
|
|
54
|
-
function tokenize(text) {
|
|
55
|
-
return new Set(text
|
|
56
|
-
.toLowerCase()
|
|
57
|
-
.replace(/[^a-z0-9\s]/g, " ")
|
|
58
|
-
.split(/\s+/)
|
|
59
|
-
.map(stem)
|
|
60
|
-
.filter((w) => w.length >= 3 && !STOPWORDS.has(w)));
|
|
61
|
-
}
|
|
62
|
-
function jaccard(a, b) {
|
|
63
|
-
if (a.size === 0 && b.size === 0)
|
|
64
|
-
return 0;
|
|
65
|
-
let inter = 0;
|
|
66
|
-
for (const x of a)
|
|
67
|
-
if (b.has(x))
|
|
68
|
-
inter += 1;
|
|
69
|
-
const union = a.size + b.size - inter;
|
|
70
|
-
return union === 0 ? 0 : inter / union;
|
|
71
|
-
}
|
|
72
26
|
function parseMinimalFrontmatter(raw) {
|
|
73
27
|
const m = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
74
28
|
if (m === null || m[1] === undefined || m[2] === undefined) {
|
|
@@ -112,9 +66,12 @@ export function findDuplicateClusters(args) {
|
|
|
112
66
|
const files = readdirSync(inbox, { encoding: "utf8" }).filter((f) => f.endsWith(".draft.md"));
|
|
113
67
|
const docs = [];
|
|
114
68
|
for (const f of files) {
|
|
69
|
+
const abs = join(inbox, f);
|
|
115
70
|
let raw;
|
|
71
|
+
let mtimeMs;
|
|
116
72
|
try {
|
|
117
|
-
raw = readFileSync(
|
|
73
|
+
raw = readFileSync(abs, "utf8");
|
|
74
|
+
mtimeMs = statSync(abs).mtimeMs;
|
|
118
75
|
}
|
|
119
76
|
catch {
|
|
120
77
|
continue;
|
|
@@ -131,6 +88,7 @@ export function findDuplicateClusters(args) {
|
|
|
131
88
|
source: fm.capture_source ?? "",
|
|
132
89
|
confidence: fm.capture_confidence ?? null,
|
|
133
90
|
tokens: tokenize(text),
|
|
91
|
+
mtimeMs,
|
|
134
92
|
});
|
|
135
93
|
}
|
|
136
94
|
const n = docs.length;
|
|
@@ -206,11 +164,18 @@ export function findDuplicateClusters(args) {
|
|
|
206
164
|
}
|
|
207
165
|
const avg = count === 0 ? 0 : total / count;
|
|
208
166
|
const tier = avg >= thresholdDefinite ? "definite" : "potential";
|
|
209
|
-
// Stable survivor pick:
|
|
167
|
+
// Stable survivor pick: oldest mtime first (so the earliest-captured
|
|
168
|
+
// draft becomes the canonical one), then lex id as a deterministic
|
|
169
|
+
// tiebreaker. Content-addressed ids lex-sort to a random order, so
|
|
170
|
+
// mtime is the meaningful signal under hash-based ids.
|
|
210
171
|
const ordered = idxs
|
|
211
172
|
.map((i) => docs[i])
|
|
212
173
|
.filter((d) => d !== undefined);
|
|
213
|
-
ordered.sort((a, b) =>
|
|
174
|
+
ordered.sort((a, b) => {
|
|
175
|
+
if (a.mtimeMs !== b.mtimeMs)
|
|
176
|
+
return a.mtimeMs - b.mtimeMs;
|
|
177
|
+
return a.id.localeCompare(b.id);
|
|
178
|
+
});
|
|
214
179
|
clusters.push({
|
|
215
180
|
tier,
|
|
216
181
|
averageSimilarity: Number(avg.toFixed(3)),
|