lockstep-cli 0.0.7 → 0.1.1
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 +29 -0
- package/dist/adapters/claude.js +23 -7
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/install.test.js +53 -2
- package/dist/adapters/install.test.js.map +1 -1
- package/dist/adapters/merge.d.ts +9 -0
- package/dist/adapters/merge.js +32 -0
- package/dist/adapters/merge.js.map +1 -1
- package/dist/adapters/templates.d.ts +3 -2
- package/dist/adapters/templates.js +92 -3
- package/dist/adapters/templates.js.map +1 -1
- package/dist/capture/classify-edge.test.js +9 -7
- package/dist/capture/classify-edge.test.js.map +1 -1
- package/dist/capture/classify.d.ts +6 -4
- package/dist/capture/classify.js +9 -8
- package/dist/capture/classify.js.map +1 -1
- package/dist/capture/classify.test.js +7 -2
- package/dist/capture/classify.test.js.map +1 -1
- package/dist/capture/diff.d.ts +2 -0
- package/dist/capture/diff.js +15 -0
- package/dist/capture/diff.js.map +1 -1
- package/dist/capture/extract.d.ts +5 -0
- package/dist/capture/extract.js +17 -0
- package/dist/capture/extract.js.map +1 -0
- package/dist/capture/feature-context.d.ts +3 -0
- package/dist/capture/feature-context.js +43 -0
- package/dist/capture/feature-context.js.map +1 -0
- package/dist/capture/feature-context.test.d.ts +1 -0
- package/dist/capture/feature-context.test.js +45 -0
- package/dist/capture/feature-context.test.js.map +1 -0
- package/dist/capture/index.d.ts +59 -0
- package/dist/capture/index.js +92 -36
- package/dist/capture/index.js.map +1 -1
- package/dist/capture/manifest.d.ts +26 -0
- package/dist/capture/manifest.js +98 -0
- package/dist/capture/manifest.js.map +1 -0
- package/dist/capture/manifest.test.d.ts +1 -0
- package/dist/capture/manifest.test.js +40 -0
- package/dist/capture/manifest.test.js.map +1 -0
- package/dist/capture/outbound.d.ts +10 -0
- package/dist/capture/outbound.js +139 -0
- package/dist/capture/outbound.js.map +1 -0
- package/dist/capture/outbound.test.d.ts +1 -0
- package/dist/capture/outbound.test.js +89 -0
- package/dist/capture/outbound.test.js.map +1 -0
- package/dist/capture/python.d.ts +5 -0
- package/dist/capture/python.js +127 -0
- package/dist/capture/python.js.map +1 -0
- package/dist/capture/python.test.d.ts +1 -0
- package/dist/capture/python.test.js +99 -0
- package/dist/capture/python.test.js.map +1 -0
- package/dist/capture/replay.test.d.ts +1 -0
- package/dist/capture/replay.test.js +101 -0
- package/dist/capture/replay.test.js.map +1 -0
- package/dist/capture/surface.d.ts +23 -0
- package/dist/capture/surface.js +83 -0
- package/dist/capture/surface.js.map +1 -0
- package/dist/capture/surface.test.d.ts +1 -0
- package/dist/capture/surface.test.js +37 -0
- package/dist/capture/surface.test.js.map +1 -0
- package/dist/connect.d.ts +1 -1
- package/dist/connect.js +23 -12
- package/dist/connect.js.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/init.js +3 -1
- package/dist/init.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +26 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/scan.d.ts +64 -0
- package/dist/scan.js +176 -0
- package/dist/scan.js.map +1 -0
- package/dist/scan.test.d.ts +1 -0
- package/dist/scan.test.js +258 -0
- package/dist/scan.test.js.map +1 -0
- package/package.json +8 -4
package/dist/capture/diff.js
CHANGED
|
@@ -16,4 +16,19 @@ export function changedFiles(cwd) {
|
|
|
16
16
|
return [];
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
/** Every tracked file in the repo (+ untracked, minus gitignored), read-only. The full-repo walk `lockstep scan` runs over. */
|
|
20
|
+
export function trackedFiles(cwd) {
|
|
21
|
+
try {
|
|
22
|
+
const tracked = execFileSync("git", ["-C", cwd, "ls-files"], { encoding: "utf8" }).split("\n").filter(Boolean);
|
|
23
|
+
const untracked = execFileSync("git", ["-C", cwd, "ls-files", "--others", "--exclude-standard"], {
|
|
24
|
+
encoding: "utf8",
|
|
25
|
+
})
|
|
26
|
+
.split("\n")
|
|
27
|
+
.filter(Boolean);
|
|
28
|
+
return [...new Set([...tracked, ...untracked])];
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
19
34
|
//# sourceMappingURL=diff.js.map
|
package/dist/capture/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/capture/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,+FAA+F;AAC/F,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;aAClG,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE;YAC/F,QAAQ,EAAE,MAAM;SACjB,CAAC;aACC,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/capture/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,+FAA+F;AAC/F,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;aAClG,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE;YAC/F,QAAQ,EAAE,MAAM;SACjB,CAAC;aACC,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,+HAA+H;AAC/H,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/G,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,CAAC,EAAE;YAC/F,QAAQ,EAAE,MAAM;SACjB,CAAC;aACC,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type OutboundRef } from "./outbound.js";
|
|
2
|
+
/** Every canonical surface ID a file defines (produces), across all supported languages. */
|
|
3
|
+
export declare function extractAllSurfaces(path: string, content?: string): string[];
|
|
4
|
+
/** Every outbound-call candidate a file makes (consumes), across all supported languages. */
|
|
5
|
+
export declare function extractAllOutbound(path: string, content?: string): OutboundRef[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language-composed extraction — the single entry point scan/capture use. Each language module
|
|
3
|
+
* stays pure and self-gated by extension; this file just unions their results. `surface.ts` is
|
|
4
|
+
* deliberately untouched (it is vendored to the GitHub Action's `surface.mjs`).
|
|
5
|
+
*/
|
|
6
|
+
import { extractSurfaces } from "./surface.js";
|
|
7
|
+
import { extractOutbound } from "./outbound.js";
|
|
8
|
+
import { extractPythonOutbound, extractPythonSurfaces } from "./python.js";
|
|
9
|
+
/** Every canonical surface ID a file defines (produces), across all supported languages. */
|
|
10
|
+
export function extractAllSurfaces(path, content) {
|
|
11
|
+
return [...new Set([...extractSurfaces(path, content), ...extractPythonSurfaces(path, content)])];
|
|
12
|
+
}
|
|
13
|
+
/** Every outbound-call candidate a file makes (consumes), across all supported languages. */
|
|
14
|
+
export function extractAllOutbound(path, content) {
|
|
15
|
+
return [...extractOutbound(path, content), ...extractPythonOutbound(path, content)];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/capture/extract.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAoB,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAE3E,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,OAAgB;IAC/D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,OAAgB;IAC/D,OAAO,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,GAAG,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
/**
|
|
6
|
+
* Session feature-context cache — mirrors statusline.ts's tmpdir cache, but keyed by git remote.
|
|
7
|
+
* `set_feature_context` writes here so the (separate-process) capture hook can attach the
|
|
8
|
+
* capabilityRef to change events. Accepted limitation (B-DB2): concurrent sessions on one
|
|
9
|
+
* checkout share one context, same as the statusline cache.
|
|
10
|
+
*/
|
|
11
|
+
const TTL_MS = 8 * 3600_000; // 8 hours
|
|
12
|
+
function pathFor(remote) {
|
|
13
|
+
const key = createHash("sha1").update(remote).digest("hex").slice(0, 12);
|
|
14
|
+
return join(tmpdir(), `lockstep-feature-${key}.json`);
|
|
15
|
+
}
|
|
16
|
+
export function writeFeatureContext(remote, ref) {
|
|
17
|
+
try {
|
|
18
|
+
writeFileSync(pathFor(remote), JSON.stringify({ ref, ts: Date.now() }));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
/* ignore */
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function readFeatureContext(remote) {
|
|
25
|
+
try {
|
|
26
|
+
const c = JSON.parse(readFileSync(pathFor(remote), "utf8"));
|
|
27
|
+
if (Date.now() - c.ts < TTL_MS)
|
|
28
|
+
return c.ref;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* no context */
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
export function clearFeatureContext(remote) {
|
|
36
|
+
try {
|
|
37
|
+
unlinkSync(pathFor(remote));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* ignore */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=feature-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-context.js","sourceRoot":"","sources":["../../src/capture/feature-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,UAAU;AAOvC,SAAS,OAAO,CAAC,MAAc;IAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,GAAG,OAAO,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,GAAW;IAC7D,IAAI,CAAC;QACH,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAgB,CAAC,CAAC,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAQ,CAAC;QACnE,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,IAAI,CAAC;QACH,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { test } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { writeFeatureContext, readFeatureContext, clearFeatureContext } from "./feature-context.js";
|
|
8
|
+
// Unique remote per run so parallel/repeat runs don't collide on the tmpdir file.
|
|
9
|
+
const remote = `github.com/lockstep-test/feature-ctx-${process.pid}-${Date.now()}`;
|
|
10
|
+
const pathFor = (r) => join(tmpdir(), `lockstep-feature-${createHash("sha1").update(r).digest("hex").slice(0, 12)}.json`);
|
|
11
|
+
test("write → read round-trips the capabilityRef", () => {
|
|
12
|
+
clearFeatureContext(remote);
|
|
13
|
+
writeFeatureContext(remote, "feature:guest-checkout");
|
|
14
|
+
assert.equal(readFeatureContext(remote), "feature:guest-checkout");
|
|
15
|
+
clearFeatureContext(remote);
|
|
16
|
+
});
|
|
17
|
+
test("missing context → null", () => {
|
|
18
|
+
clearFeatureContext(remote);
|
|
19
|
+
assert.equal(readFeatureContext(remote), null);
|
|
20
|
+
});
|
|
21
|
+
test("stale ts (older than TTL) → null", () => {
|
|
22
|
+
// Hand-write a context with a timestamp well beyond the 8h TTL.
|
|
23
|
+
const stale = { ref: "feature:old", ts: Date.now() - 9 * 3600_000 };
|
|
24
|
+
writeFileSync(pathFor(remote), JSON.stringify(stale));
|
|
25
|
+
assert.equal(readFeatureContext(remote), null);
|
|
26
|
+
clearFeatureContext(remote);
|
|
27
|
+
});
|
|
28
|
+
test("distinct remotes get distinct files", () => {
|
|
29
|
+
const a = `${remote}-a`;
|
|
30
|
+
const b = `${remote}-b`;
|
|
31
|
+
writeFeatureContext(a, "feature:a");
|
|
32
|
+
writeFeatureContext(b, "feature:b");
|
|
33
|
+
assert.equal(readFeatureContext(a), "feature:a");
|
|
34
|
+
assert.equal(readFeatureContext(b), "feature:b");
|
|
35
|
+
clearFeatureContext(a);
|
|
36
|
+
clearFeatureContext(b);
|
|
37
|
+
});
|
|
38
|
+
test("clear removes the file (read → null after)", () => {
|
|
39
|
+
writeFeatureContext(remote, "feature:x");
|
|
40
|
+
const p = pathFor(remote);
|
|
41
|
+
assert.equal(JSON.parse(readFileSync(p, "utf8")).ref, "feature:x");
|
|
42
|
+
clearFeatureContext(remote);
|
|
43
|
+
assert.equal(readFeatureContext(remote), null);
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=feature-context.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-context.test.js","sourceRoot":"","sources":["../../src/capture/feature-context.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEpG,kFAAkF;AAClF,MAAM,MAAM,GAAG,wCAAwC,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;AACnF,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAC5B,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;AAErG,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACtD,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,mBAAmB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAC,CAAC;IACnE,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;IAClC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAC5C,gEAAgE;IAChE,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;IACpE,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAC/C,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE;IAC/C,MAAM,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,GAAG,MAAM,IAAI,CAAC;IACxB,mBAAmB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACpC,mBAAmB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACjD,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACvB,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACtD,mBAAmB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,CAAC,KAAK,CAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACxF,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC"}
|
package/dist/capture/index.d.ts
CHANGED
|
@@ -1,6 +1,65 @@
|
|
|
1
|
+
interface InboxResp {
|
|
2
|
+
unread?: number;
|
|
3
|
+
changes?: Array<{
|
|
4
|
+
summary: string;
|
|
5
|
+
surface: string | null;
|
|
6
|
+
impact?: number;
|
|
7
|
+
}>;
|
|
8
|
+
questions?: Array<{
|
|
9
|
+
id: string;
|
|
10
|
+
body: string;
|
|
11
|
+
scopeRef: string | null;
|
|
12
|
+
urgent: boolean;
|
|
13
|
+
status: string;
|
|
14
|
+
}>;
|
|
15
|
+
tasks?: Array<{
|
|
16
|
+
id: string;
|
|
17
|
+
title: string;
|
|
18
|
+
runState: string;
|
|
19
|
+
status: string;
|
|
20
|
+
}>;
|
|
21
|
+
decisions?: Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
scopeRef: string;
|
|
24
|
+
ruleText: string;
|
|
25
|
+
status: string;
|
|
26
|
+
impact?: number;
|
|
27
|
+
}>;
|
|
28
|
+
conflicts?: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
surface: string;
|
|
31
|
+
constraintRuleText: string;
|
|
32
|
+
engRuleText: string;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
interface DecisionsResp {
|
|
36
|
+
decisions?: Array<{
|
|
37
|
+
scopeRef: string;
|
|
38
|
+
status: string;
|
|
39
|
+
ruleText: string;
|
|
40
|
+
impact?: number;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
/** Product-layer briefing: ranked, budget-capped constraints (origin=document, binding) in scope. */
|
|
44
|
+
export interface BriefingResp {
|
|
45
|
+
constraints: Array<{
|
|
46
|
+
line: string;
|
|
47
|
+
impact: number;
|
|
48
|
+
conflictOpen: boolean;
|
|
49
|
+
}>;
|
|
50
|
+
overflow: number;
|
|
51
|
+
/** Phase P: binding decisionType=principle decisions — the team's standing decision criteria. */
|
|
52
|
+
principles?: Array<{
|
|
53
|
+
line: string;
|
|
54
|
+
impact: number;
|
|
55
|
+
}>;
|
|
56
|
+
principlesOverflow?: number;
|
|
57
|
+
}
|
|
58
|
+
export declare function formatReplay(inbox: InboxResp | null, decisions: DecisionsResp | null, briefing?: BriefingResp | null): string;
|
|
1
59
|
/**
|
|
2
60
|
* Hook entrypoint. Resilient by design — never break the agent: on any error it exits 0.
|
|
3
61
|
* SessionStart → replay inbox + binding decisions as additionalContext.
|
|
4
62
|
* PostToolUse/Stop → diff → classify surface → risk-tiered publish via notify.
|
|
5
63
|
*/
|
|
6
64
|
export declare function runCapture(event: string): Promise<void>;
|
|
65
|
+
export {};
|
package/dist/capture/index.js
CHANGED
|
@@ -3,15 +3,29 @@ import { join } from "node:path";
|
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { registerSession } from "../mcp/session.js";
|
|
5
5
|
import { call } from "../mcp/api.js";
|
|
6
|
+
import { gitRemote } from "../mcp/git.js";
|
|
7
|
+
import { readFeatureContext } from "./feature-context.js";
|
|
6
8
|
import { changedFiles } from "./diff.js";
|
|
7
9
|
import { isContractSurface, riskTierFor } from "./classify.js";
|
|
8
|
-
|
|
10
|
+
import { extractAllSurfaces } from "./extract.js";
|
|
11
|
+
import { readManifest } from "./manifest.js";
|
|
12
|
+
/** Sync this repo's declared dependencies (lockstep.yaml `consumes:`) into the usage graph. Idempotent. */
|
|
13
|
+
async function syncManifestDeps(cwd, sessionId) {
|
|
14
|
+
const { consumes } = readManifest(cwd);
|
|
15
|
+
for (const producedSurface of consumes) {
|
|
16
|
+
await call("POST", "/dependencies", sessionId, { producedSurface, source: "manifest" }).catch(() => { });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** Highest-blast-radius first, so the session-start briefing leads with what matters most. */
|
|
20
|
+
const byImpact = (a, b) => (b.impact ?? 0) - (a.impact ?? 0);
|
|
21
|
+
const tag = (impact) => ((impact ?? 0) > 0 ? `[impact ${impact}] ` : "");
|
|
22
|
+
export function formatReplay(inbox, decisions, briefing) {
|
|
9
23
|
const lines = [];
|
|
10
|
-
const changes = inbox?.changes ?? [];
|
|
24
|
+
const changes = [...(inbox?.changes ?? [])].sort(byImpact);
|
|
11
25
|
if (changes.length) {
|
|
12
26
|
lines.push(`📥 ${changes.length} change(s) since you were last here:`);
|
|
13
27
|
for (const c of changes.slice(0, 8))
|
|
14
|
-
lines.push(` • ${c.summary}${c.surface ? ` (${c.surface})` : ""}`);
|
|
28
|
+
lines.push(` • ${tag(c.impact)}${c.summary}${c.surface ? ` (${c.surface})` : ""}`);
|
|
15
29
|
}
|
|
16
30
|
const qs = (inbox?.questions ?? []).filter((q) => q.status === "open");
|
|
17
31
|
if (qs.length) {
|
|
@@ -31,11 +45,37 @@ function formatReplay(inbox, decisions) {
|
|
|
31
45
|
for (const d of pendingDecisions.slice(0, 8))
|
|
32
46
|
lines.push(` • [${d.scopeRef}] ${d.ruleText}`);
|
|
33
47
|
}
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
lines.push(
|
|
37
|
-
for (const
|
|
38
|
-
lines.push(` • [${
|
|
48
|
+
const conflicts = inbox?.conflicts ?? [];
|
|
49
|
+
if (conflicts.length) {
|
|
50
|
+
lines.push(`⚔️ ${conflicts.length} drift conflict(s) — your work may conflict with a ratified product constraint:`);
|
|
51
|
+
for (const c of conflicts.slice(0, 8))
|
|
52
|
+
lines.push(` • [${c.surface}] your "${c.engRuleText}" vs constraint "${c.constraintRuleText}" — review both`);
|
|
53
|
+
}
|
|
54
|
+
// Principles lead — they're the criteria the agent should judge everything else by (TOMASP "M").
|
|
55
|
+
const principles = briefing?.principles ?? [];
|
|
56
|
+
if (principles.length) {
|
|
57
|
+
lines.push(`◆ ${principles.length} project principle(s) — the team's standing decision criteria:`);
|
|
58
|
+
for (const p of principles)
|
|
59
|
+
lines.push(` • ${p.line}`);
|
|
60
|
+
if ((briefing?.principlesOverflow ?? 0) > 0)
|
|
61
|
+
lines.push(` • (+${briefing?.principlesOverflow} more — query the ledger)`);
|
|
62
|
+
}
|
|
63
|
+
const binding = (decisions?.decisions ?? []).filter((d) => d.status === "binding").sort(byImpact);
|
|
64
|
+
const constraints = briefing?.constraints ?? [];
|
|
65
|
+
if (binding.length || constraints.length) {
|
|
66
|
+
const rows = [
|
|
67
|
+
...binding.map((d) => ({
|
|
68
|
+
impact: d.impact ?? 0,
|
|
69
|
+
isConstraint: false,
|
|
70
|
+
line: ` • ${tag(d.impact)}[${d.scopeRef}] ${d.ruleText}`,
|
|
71
|
+
})),
|
|
72
|
+
...constraints.map((c) => ({ impact: c.impact, isConstraint: true, line: ` • ${c.line}` })),
|
|
73
|
+
].sort((a, b) => b.impact - a.impact || Number(b.isConstraint) - Number(a.isConstraint));
|
|
74
|
+
lines.push(`📌 ${rows.length} binding decision(s) in effect:`);
|
|
75
|
+
for (const r of rows.slice(0, 8))
|
|
76
|
+
lines.push(r.line);
|
|
77
|
+
if ((briefing?.overflow ?? 0) > 0)
|
|
78
|
+
lines.push(` • (+${briefing?.overflow} product constraints in scope — get_product_context)`);
|
|
39
79
|
}
|
|
40
80
|
return lines.length ? `Lockstep:\n${lines.join("\n")}` : "Lockstep: nothing new.";
|
|
41
81
|
}
|
|
@@ -71,11 +111,15 @@ export async function runCapture(event) {
|
|
|
71
111
|
catch {
|
|
72
112
|
process.exit(0); // not a connected repo / not logged in → silent no-op
|
|
73
113
|
}
|
|
114
|
+
const remote = gitRemote(cwd);
|
|
115
|
+
const capabilityRef = remote ? readFeatureContext(remote) : null;
|
|
74
116
|
try {
|
|
75
117
|
if (event === "SessionStart") {
|
|
118
|
+
await syncManifestDeps(cwd, session.sessionId); // keep the usage graph current from lockstep.yaml
|
|
76
119
|
const inbox = await call("GET", "/inbox", session.sessionId).catch(() => null);
|
|
77
120
|
const decisions = await call("GET", "/decisions", session.sessionId).catch(() => null);
|
|
78
|
-
const
|
|
121
|
+
const briefing = await call("GET", "/briefing", session.sessionId).catch(() => null);
|
|
122
|
+
const replay = formatReplay(inbox, decisions, briefing);
|
|
79
123
|
process.stdout.write(JSON.stringify({
|
|
80
124
|
hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: replay },
|
|
81
125
|
}));
|
|
@@ -89,7 +133,9 @@ export async function runCapture(event) {
|
|
|
89
133
|
const files = changedFiles(cwd);
|
|
90
134
|
if (files.length === 0)
|
|
91
135
|
return;
|
|
92
|
-
|
|
136
|
+
// Extract CANONICAL surface IDs (e.g. "http:POST /auth/session") — the shared vocabulary that
|
|
137
|
+
// lets a consumer's declared dependency match a producer's change. File paths never matched.
|
|
138
|
+
const surfaceIds = new Set();
|
|
93
139
|
let anyContractSurface = false;
|
|
94
140
|
for (const f of files) {
|
|
95
141
|
let content = "";
|
|
@@ -99,40 +145,50 @@ export async function runCapture(event) {
|
|
|
99
145
|
catch {
|
|
100
146
|
/* deleted/binary — skip content */
|
|
101
147
|
}
|
|
102
|
-
|
|
148
|
+
const ids = extractAllSurfaces(f, content);
|
|
149
|
+
if (ids.length > 0) {
|
|
103
150
|
anyContractSurface = true;
|
|
104
|
-
|
|
151
|
+
ids.forEach((s) => surfaceIds.add(s));
|
|
152
|
+
}
|
|
153
|
+
else if (isContractSurface(f, content)) {
|
|
154
|
+
anyContractSurface = true; // contract-ish file we couldn't parse into an exact surface
|
|
105
155
|
}
|
|
106
156
|
}
|
|
107
157
|
// v1: contract surface ⇒ shared (the safety-critical bias). Ownership-based refinement later.
|
|
108
158
|
const riskTier = riskTierFor({ anyContractSurface, allOwnedByMe: true });
|
|
109
159
|
const summary = `${event}: changed ${files.length} file(s): ${files.slice(0, 5).join(", ")}${files.length > 5 ? "…" : ""}`;
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
surface
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
160
|
+
const baseHash = createHash("sha256").update(files.sort().join("|")).digest("hex").slice(0, 16);
|
|
161
|
+
const ids = [...surfaceIds].slice(0, 10);
|
|
162
|
+
if (ids.length === 0) {
|
|
163
|
+
// No contract surface touched — record a single owned activity entry (routes to no one).
|
|
164
|
+
await call("POST", "/changes", session.sessionId, {
|
|
165
|
+
summary,
|
|
166
|
+
riskTier,
|
|
167
|
+
verified: true,
|
|
168
|
+
verifiedAgainst: "git-diff",
|
|
169
|
+
diffHash: baseHash,
|
|
170
|
+
capabilityRef: capabilityRef ?? undefined,
|
|
171
|
+
}).catch(() => { });
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
// One change per changed surface, so each routes to that surface's consumers.
|
|
175
|
+
for (const surface of ids) {
|
|
176
|
+
await call("POST", "/changes", session.sessionId, {
|
|
177
|
+
summary,
|
|
178
|
+
surface,
|
|
179
|
+
riskTier,
|
|
180
|
+
verified: true, // mechanical delta is derived from real local code (displayed as "extracted", not "verified")
|
|
181
|
+
verifiedAgainst: "git-diff",
|
|
182
|
+
diffHash: `${baseHash}:${surface}`,
|
|
183
|
+
capabilityRef: capabilityRef ?? undefined,
|
|
184
|
+
}).catch(() => { });
|
|
133
185
|
}
|
|
134
|
-
process.stderr.write(`[lockstep] proposed decision for ${surfaces.length} contract surface(s)\n`);
|
|
135
186
|
}
|
|
187
|
+
process.stderr.write(`[lockstep] published change (${riskTier}, ${ids.length} surface(s))\n`);
|
|
188
|
+
// NOTE: capture publishes a CHANGE event only. A change is NOT a decision — decisions are
|
|
189
|
+
// durable rules/architectural choices, logged deliberately by the agent via propose_decision
|
|
190
|
+
// (see the lockstep skill). Auto-minting a decision per save was a category error that flooded
|
|
191
|
+
// the ledger; routing/impact for changes is handled by recordChange on the server.
|
|
136
192
|
// Peek at inbox (without marking as read) — notify the agent if there are unread items
|
|
137
193
|
const peek = await call("GET", "/inbox/peek", session.sessionId).catch(() => null);
|
|
138
194
|
const badge = formatPeek(peek);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/capture/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface Manifest {
|
|
2
|
+
produces: string[];
|
|
3
|
+
consumes: string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Read `lockstep.yaml` from the repo root. This is the deterministic source of truth for the usage
|
|
7
|
+
* graph: `consumes:` declares the canonical surface IDs this repo depends on (so it gets warned when
|
|
8
|
+
* they change), `produces:` optionally declares/overrides what it exposes. We parse a minimal YAML
|
|
9
|
+
* subset (two top-level keys, each a `- item` list) to stay dependency-free and predictable.
|
|
10
|
+
*
|
|
11
|
+
* Example:
|
|
12
|
+
* produces:
|
|
13
|
+
* - http:POST /auth/session
|
|
14
|
+
* consumes:
|
|
15
|
+
* - http:GET /orders/:id
|
|
16
|
+
*/
|
|
17
|
+
export declare function readManifest(cwd: string): Manifest;
|
|
18
|
+
/**
|
|
19
|
+
* Write `lockstep.yaml`, MERGE-preserving what's already there — existing human entries are unioned
|
|
20
|
+
* with the proposed ones (never dropped), and the file's leading comment block is kept. Atomic write
|
|
21
|
+
* with a one-time `.lockstep.bak` and idempotent no-op, via the shared `applyFile`. This is the single
|
|
22
|
+
* sanctioned writer of the manifest — the capture hook never touches it (see IMPROVEMENTS #11).
|
|
23
|
+
*/
|
|
24
|
+
export declare function writeManifest(cwd: string, manifest: Manifest, opts?: {
|
|
25
|
+
dryRun?: boolean;
|
|
26
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { applyFile } from "../adapters/fsutil.js";
|
|
4
|
+
/**
|
|
5
|
+
* Read `lockstep.yaml` from the repo root. This is the deterministic source of truth for the usage
|
|
6
|
+
* graph: `consumes:` declares the canonical surface IDs this repo depends on (so it gets warned when
|
|
7
|
+
* they change), `produces:` optionally declares/overrides what it exposes. We parse a minimal YAML
|
|
8
|
+
* subset (two top-level keys, each a `- item` list) to stay dependency-free and predictable.
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
* produces:
|
|
12
|
+
* - http:POST /auth/session
|
|
13
|
+
* consumes:
|
|
14
|
+
* - http:GET /orders/:id
|
|
15
|
+
*/
|
|
16
|
+
export function readManifest(cwd) {
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = readFileSync(join(cwd, "lockstep.yaml"), "utf8");
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return { produces: [], consumes: [] };
|
|
23
|
+
}
|
|
24
|
+
const out = { produces: [], consumes: [] };
|
|
25
|
+
let key = null;
|
|
26
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
27
|
+
if (/^\s*#/.test(line) || line.trim() === "")
|
|
28
|
+
continue;
|
|
29
|
+
const top = line.match(/^(produces|consumes)\s*:\s*$/);
|
|
30
|
+
if (top) {
|
|
31
|
+
key = top[1];
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const item = line.match(/^\s*-\s*(.+?)\s*$/);
|
|
35
|
+
if (item && key) {
|
|
36
|
+
out[key].push(item[1].replace(/^["']|["']$/g, ""));
|
|
37
|
+
}
|
|
38
|
+
else if (/^\S/.test(line)) {
|
|
39
|
+
key = null; // a new unindented non-list key ends the current list
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
const DEFAULT_HEADER = `# Lockstep manifest — the deterministic source of truth for the usage graph.
|
|
45
|
+
# Managed by the \`/lockstep-setup\` skill (the only sanctioned writer; the capture hook is read-only).
|
|
46
|
+
# Surface IDs are canonical: http:METHOD /path · proto:pkg.Service/Rpc · gql:Root.field
|
|
47
|
+
`;
|
|
48
|
+
/** Preserve the file's existing top-of-file comment block (so human notes survive a rewrite). */
|
|
49
|
+
function leadingComment(raw) {
|
|
50
|
+
if (!raw)
|
|
51
|
+
return null;
|
|
52
|
+
const head = [];
|
|
53
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
54
|
+
if (/^\s*#/.test(line) || line.trim() === "")
|
|
55
|
+
head.push(line);
|
|
56
|
+
else
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
const block = head.join("\n").trimEnd();
|
|
60
|
+
return block ? block + "\n" : null;
|
|
61
|
+
}
|
|
62
|
+
const union = (a, b) => {
|
|
63
|
+
const out = [];
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
for (const x of [...a, ...b])
|
|
66
|
+
if (x && !seen.has(x))
|
|
67
|
+
(seen.add(x), out.push(x));
|
|
68
|
+
return out;
|
|
69
|
+
};
|
|
70
|
+
function serialize(m, header) {
|
|
71
|
+
const list = (items) => items.map((i) => ` - ${i}`).join("\n");
|
|
72
|
+
const block = (key, items) => (items.length ? `${key}:\n${list(items)}\n` : `${key}:\n`);
|
|
73
|
+
return `${header}\n${block("produces", m.produces)}\n${block("consumes", m.consumes)}`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Write `lockstep.yaml`, MERGE-preserving what's already there — existing human entries are unioned
|
|
77
|
+
* with the proposed ones (never dropped), and the file's leading comment block is kept. Atomic write
|
|
78
|
+
* with a one-time `.lockstep.bak` and idempotent no-op, via the shared `applyFile`. This is the single
|
|
79
|
+
* sanctioned writer of the manifest — the capture hook never touches it (see IMPROVEMENTS #11).
|
|
80
|
+
*/
|
|
81
|
+
export async function writeManifest(cwd, manifest, opts = {}) {
|
|
82
|
+
const path = join(cwd, "lockstep.yaml");
|
|
83
|
+
let raw;
|
|
84
|
+
try {
|
|
85
|
+
raw = readFileSync(path, "utf8");
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
raw = null;
|
|
89
|
+
}
|
|
90
|
+
const existing = readManifest(cwd);
|
|
91
|
+
const merged = {
|
|
92
|
+
produces: union(existing.produces, manifest.produces),
|
|
93
|
+
consumes: union(existing.consumes, manifest.consumes),
|
|
94
|
+
};
|
|
95
|
+
const header = leadingComment(raw) ?? DEFAULT_HEADER;
|
|
96
|
+
return applyFile(path, () => serialize(merged, header), opts.dryRun ?? false);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/capture/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|