@isaacriehm/cairn-core 0.4.3 → 0.6.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 +162 -0
- package/dist/align-undo/log.js.map +1 -0
- package/dist/align-undo/undo.d.ts +65 -0
- package/dist/align-undo/undo.js +397 -0
- package/dist/align-undo/undo.js.map +1 -0
- package/dist/attention/bulk-accept.js +9 -22
- package/dist/attention/bulk-accept.js.map +1 -1
- package/dist/attention/dedup.js +1 -47
- package/dist/attention/dedup.js.map +1 -1
- package/dist/attention/serve/api.js +3 -17
- package/dist/attention/serve/api.js.map +1 -1
- package/dist/attention/serve/index.js +3 -3
- package/dist/attention/serve/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 +7 -0
- package/dist/fix-align/index.js +6 -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/fix-align/sentinel.d.ts +59 -0
- package/dist/fix-align/sentinel.js +149 -0
- package/dist/fix-align/sentinel.js.map +1 -0
- package/dist/fs.d.ts +5 -0
- package/dist/fs.js +11 -0
- package/dist/fs.js.map +1 -0
- package/dist/gc/apply.js +4 -4
- package/dist/gc/apply.js.map +1 -1
- 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 +56 -0
- package/dist/ground/anchor-map.js.map +1 -0
- package/dist/ground/frontmatter.d.ts +12 -0
- package/dist/ground/frontmatter.js +28 -0
- package/dist/ground/frontmatter.js.map +1 -1
- package/dist/ground/index.d.ts +10 -3
- package/dist/ground/index.js +9 -3
- 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 +135 -10
- package/dist/ground/schemas.js.map +1 -1
- package/dist/ground/scope-index.js +4 -4
- 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 +79 -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 +62 -0
- package/dist/ground/sot-cache.js.map +1 -0
- package/dist/ground/topic-index.d.ts +27 -0
- package/dist/ground/topic-index.js +82 -0
- package/dist/ground/topic-index.js.map +1 -0
- 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/sot-align.d.ts +166 -0
- package/dist/hooks/post-tool-use/sot-align.js +1306 -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 -410
- 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.js +6 -6
- package/dist/init/mapper.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 -162
- 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 +214 -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 -361
- 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/schemas.d.ts +45 -8
- package/dist/mcp/schemas.js +43 -7
- 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/index.d.ts +1 -1
- package/dist/mcp/tools/index.js +3 -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 +5 -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 +781 -5
- 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
|
@@ -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): Promise<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[]): Promise<void>;
|
|
@@ -0,0 +1,162 @@
|
|
|
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 { withWriteLock } from "../lock.js";
|
|
25
|
+
import { logger } from "../logger.js";
|
|
26
|
+
const log = logger("align-undo.log");
|
|
27
|
+
/**
|
|
28
|
+
* Drop entries older than this on the next append + GC sweep. Operators
|
|
29
|
+
* who never run `cairn attention undo` would otherwise accumulate one
|
|
30
|
+
* line per Layer A auto-resolution forever.
|
|
31
|
+
*/
|
|
32
|
+
const MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
33
|
+
/**
|
|
34
|
+
* Skip the read-rewrite GC pass when the log is below this line count
|
|
35
|
+
* — steady-state operators don't pay for the read on every append.
|
|
36
|
+
*/
|
|
37
|
+
const GC_THRESHOLD_LINES = 256;
|
|
38
|
+
export const AlignUndoEntry = z.object({
|
|
39
|
+
ts: z.string(),
|
|
40
|
+
session_id: z.string().nullish(),
|
|
41
|
+
kind: z.enum(["tier1-cite", "tier2-cite", "tier3-creation", "augments"]),
|
|
42
|
+
file: z.string(),
|
|
43
|
+
start_offset: z.number(),
|
|
44
|
+
end_offset: z.number(),
|
|
45
|
+
/** Original prose block raw (incl. comment delimiters) before strip-replace. */
|
|
46
|
+
original_raw: z.string(),
|
|
47
|
+
/** Replacement that was inserted (e.g. `// §DEC-1234567`). */
|
|
48
|
+
replacement: z.string(),
|
|
49
|
+
/** DEC/INV id cited (tier1/tier2 cite) or freshly emitted (tier3 / augments). */
|
|
50
|
+
primary_id: z.string(),
|
|
51
|
+
/** For tier3-creation: was the freshly-emitted entity a DEC or INV? */
|
|
52
|
+
primary_kind: z.enum(["DEC", "INV"]).optional(),
|
|
53
|
+
/** For augments: the existing entity id that was augmented (its cite stays). */
|
|
54
|
+
augments_existing_id: z.string().optional(),
|
|
55
|
+
});
|
|
56
|
+
export function alignUndoLogPath(repoRoot) {
|
|
57
|
+
return join(repoRoot, ".cairn", "state", "align-undo-log.jsonl");
|
|
58
|
+
}
|
|
59
|
+
export async function appendAlignUndoEntry(repoRoot, entry) {
|
|
60
|
+
const validated = AlignUndoEntry.parse(entry);
|
|
61
|
+
const path = alignUndoLogPath(repoRoot);
|
|
62
|
+
// Wrap the read-trim-append cycle in the project write lock so two
|
|
63
|
+
// concurrent Layer A invocations (or a session running `cairn
|
|
64
|
+
// attention undo` in another shell) can't interleave a partial
|
|
65
|
+
// append against a rewrite.
|
|
66
|
+
await withWriteLock(repoRoot, () => {
|
|
67
|
+
try {
|
|
68
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
69
|
+
const remaining = sweepStale(path);
|
|
70
|
+
if (remaining === null) {
|
|
71
|
+
appendFileSync(path, `${JSON.stringify(validated)}\n`, "utf8");
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
remaining.push(validated);
|
|
75
|
+
writeFileSync(path, `${remaining.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log append failed");
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Read the current log and drop entries older than `MAX_AGE_MS`.
|
|
84
|
+
* Returns the surviving entries when a GC pass actually ran, or `null`
|
|
85
|
+
* when the log is small enough to skip the rewrite (cheap append path).
|
|
86
|
+
*/
|
|
87
|
+
function sweepStale(path) {
|
|
88
|
+
if (!existsSync(path))
|
|
89
|
+
return null;
|
|
90
|
+
let text;
|
|
91
|
+
try {
|
|
92
|
+
text = readFileSync(path, "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
if (text.trim().length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
const lines = text.split("\n").filter((line) => line.trim().length > 0);
|
|
100
|
+
if (lines.length < GC_THRESHOLD_LINES)
|
|
101
|
+
return null;
|
|
102
|
+
const cutoff = Date.now() - MAX_AGE_MS;
|
|
103
|
+
const surviving = [];
|
|
104
|
+
for (const line of lines) {
|
|
105
|
+
try {
|
|
106
|
+
const parsed = AlignUndoEntry.parse(JSON.parse(line));
|
|
107
|
+
const ts = Date.parse(parsed.ts);
|
|
108
|
+
if (Number.isFinite(ts) && ts >= cutoff)
|
|
109
|
+
surviving.push(parsed);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Drop malformed entries on this GC pass.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return surviving;
|
|
116
|
+
}
|
|
117
|
+
export function readAlignUndoLog(repoRoot) {
|
|
118
|
+
const path = alignUndoLogPath(repoRoot);
|
|
119
|
+
if (!existsSync(path))
|
|
120
|
+
return [];
|
|
121
|
+
const text = readFileSync(path, "utf8");
|
|
122
|
+
if (text.trim().length === 0)
|
|
123
|
+
return [];
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const line of text.split("\n")) {
|
|
126
|
+
const trimmed = line.trim();
|
|
127
|
+
if (trimmed.length === 0)
|
|
128
|
+
continue;
|
|
129
|
+
try {
|
|
130
|
+
out.push(AlignUndoEntry.parse(JSON.parse(trimmed)));
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "skipping malformed align-undo entry");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Rewrite the undo log keeping only the entries NOT in `undone`.
|
|
140
|
+
* Idempotency: running `cairn attention undo --since <window>` twice
|
|
141
|
+
* on the same window does nothing the second time because the entries
|
|
142
|
+
* inside the window have already been removed.
|
|
143
|
+
*/
|
|
144
|
+
export async function pruneAlignUndoLog(repoRoot, remaining) {
|
|
145
|
+
const path = alignUndoLogPath(repoRoot);
|
|
146
|
+
// Lock so a concurrent `appendAlignUndoEntry` from a parallel Layer A
|
|
147
|
+
// hook can't slip a write between our read and rewrite.
|
|
148
|
+
await withWriteLock(repoRoot, () => {
|
|
149
|
+
try {
|
|
150
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
151
|
+
if (remaining.length === 0) {
|
|
152
|
+
writeFileSync(path, "", "utf8");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
writeFileSync(path, `${remaining.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
log.warn({ err: err instanceof Error ? err.message : String(err) }, "align-undo log prune failed");
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//# 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,65 @@
|
|
|
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
|
+
* 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
|
+
* - `tier3-creation` — delete the freshly-emitted DEC/INV file, drop
|
|
16
|
+
* its sot-bindings / sot-cache entries, clear the topic-index
|
|
17
|
+
* reference, refresh the affected ledger, and restore the source
|
|
18
|
+
* prose at the recorded offsets. All mutations run under
|
|
19
|
+
* `withWriteLock` so a parallel Layer A hook can't slip in
|
|
20
|
+
* mid-rollback.
|
|
21
|
+
*
|
|
22
|
+
* - `augments` — delete the sibling DEC/INV (steps mirror
|
|
23
|
+
* tier3-creation), then trim the double-cite line in source down to
|
|
24
|
+
* the existing-id cite (the augmented entity stays referenced).
|
|
25
|
+
*
|
|
26
|
+
* Idempotent: the runner truncates undone entries from the log so a
|
|
27
|
+
* second invocation against the same window is a no-op.
|
|
28
|
+
*/
|
|
29
|
+
import { type AlignUndoEntry } from "./log.js";
|
|
30
|
+
export interface UndoArgs {
|
|
31
|
+
repoRoot: string;
|
|
32
|
+
/**
|
|
33
|
+
* Wall-clock window. Entries with `ts` newer than `now - sinceMs`
|
|
34
|
+
* are undone. Default 1h.
|
|
35
|
+
*/
|
|
36
|
+
sinceMs?: number;
|
|
37
|
+
/** Dry-run: classify entries but do not modify source / log. */
|
|
38
|
+
dryRun?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface UndoEntryOutcome {
|
|
41
|
+
entry: AlignUndoEntry;
|
|
42
|
+
/**
|
|
43
|
+
* - `reverted` — source was rewritten back to the original prose.
|
|
44
|
+
* - `already-reverted`— the cite token is no longer in source (operator beat us).
|
|
45
|
+
* - `not-supported` — kind requires manual surgery (tier3-creation, augments).
|
|
46
|
+
* - `source-missing` — source file no longer exists.
|
|
47
|
+
* - `error` — write failed (logged + reported).
|
|
48
|
+
*/
|
|
49
|
+
status: "reverted" | "already-reverted" | "not-supported" | "source-missing" | "error";
|
|
50
|
+
detail?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface UndoResult {
|
|
53
|
+
/** Total entries inside the undo window. */
|
|
54
|
+
windowEntries: number;
|
|
55
|
+
/** Entries left in the log because they were outside the window. */
|
|
56
|
+
outsideWindow: number;
|
|
57
|
+
/** Per-entry outcomes for everything inside the window. */
|
|
58
|
+
outcomes: UndoEntryOutcome[];
|
|
59
|
+
reverted: number;
|
|
60
|
+
alreadyReverted: number;
|
|
61
|
+
notSupported: number;
|
|
62
|
+
sourceMissing: number;
|
|
63
|
+
errors: number;
|
|
64
|
+
}
|
|
65
|
+
export declare function runAttentionUndo(args: UndoArgs): Promise<UndoResult>;
|