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.
Files changed (77) hide show
  1. package/README.md +29 -0
  2. package/dist/adapters/claude.js +23 -7
  3. package/dist/adapters/claude.js.map +1 -1
  4. package/dist/adapters/install.test.js +53 -2
  5. package/dist/adapters/install.test.js.map +1 -1
  6. package/dist/adapters/merge.d.ts +9 -0
  7. package/dist/adapters/merge.js +32 -0
  8. package/dist/adapters/merge.js.map +1 -1
  9. package/dist/adapters/templates.d.ts +3 -2
  10. package/dist/adapters/templates.js +92 -3
  11. package/dist/adapters/templates.js.map +1 -1
  12. package/dist/capture/classify-edge.test.js +9 -7
  13. package/dist/capture/classify-edge.test.js.map +1 -1
  14. package/dist/capture/classify.d.ts +6 -4
  15. package/dist/capture/classify.js +9 -8
  16. package/dist/capture/classify.js.map +1 -1
  17. package/dist/capture/classify.test.js +7 -2
  18. package/dist/capture/classify.test.js.map +1 -1
  19. package/dist/capture/diff.d.ts +2 -0
  20. package/dist/capture/diff.js +15 -0
  21. package/dist/capture/diff.js.map +1 -1
  22. package/dist/capture/extract.d.ts +5 -0
  23. package/dist/capture/extract.js +17 -0
  24. package/dist/capture/extract.js.map +1 -0
  25. package/dist/capture/feature-context.d.ts +3 -0
  26. package/dist/capture/feature-context.js +43 -0
  27. package/dist/capture/feature-context.js.map +1 -0
  28. package/dist/capture/feature-context.test.d.ts +1 -0
  29. package/dist/capture/feature-context.test.js +45 -0
  30. package/dist/capture/feature-context.test.js.map +1 -0
  31. package/dist/capture/index.d.ts +59 -0
  32. package/dist/capture/index.js +92 -36
  33. package/dist/capture/index.js.map +1 -1
  34. package/dist/capture/manifest.d.ts +26 -0
  35. package/dist/capture/manifest.js +98 -0
  36. package/dist/capture/manifest.js.map +1 -0
  37. package/dist/capture/manifest.test.d.ts +1 -0
  38. package/dist/capture/manifest.test.js +40 -0
  39. package/dist/capture/manifest.test.js.map +1 -0
  40. package/dist/capture/outbound.d.ts +10 -0
  41. package/dist/capture/outbound.js +139 -0
  42. package/dist/capture/outbound.js.map +1 -0
  43. package/dist/capture/outbound.test.d.ts +1 -0
  44. package/dist/capture/outbound.test.js +89 -0
  45. package/dist/capture/outbound.test.js.map +1 -0
  46. package/dist/capture/python.d.ts +5 -0
  47. package/dist/capture/python.js +127 -0
  48. package/dist/capture/python.js.map +1 -0
  49. package/dist/capture/python.test.d.ts +1 -0
  50. package/dist/capture/python.test.js +99 -0
  51. package/dist/capture/python.test.js.map +1 -0
  52. package/dist/capture/replay.test.d.ts +1 -0
  53. package/dist/capture/replay.test.js +101 -0
  54. package/dist/capture/replay.test.js.map +1 -0
  55. package/dist/capture/surface.d.ts +23 -0
  56. package/dist/capture/surface.js +83 -0
  57. package/dist/capture/surface.js.map +1 -0
  58. package/dist/capture/surface.test.d.ts +1 -0
  59. package/dist/capture/surface.test.js +37 -0
  60. package/dist/capture/surface.test.js.map +1 -0
  61. package/dist/connect.d.ts +1 -1
  62. package/dist/connect.js +23 -12
  63. package/dist/connect.js.map +1 -1
  64. package/dist/index.js +20 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/init.js +3 -1
  67. package/dist/init.js.map +1 -1
  68. package/dist/mcp/server.d.ts +1 -1
  69. package/dist/mcp/server.js +26 -3
  70. package/dist/mcp/server.js.map +1 -1
  71. package/dist/scan.d.ts +64 -0
  72. package/dist/scan.js +176 -0
  73. package/dist/scan.js.map +1 -0
  74. package/dist/scan.test.d.ts +1 -0
  75. package/dist/scan.test.js +258 -0
  76. package/dist/scan.test.js.map +1 -0
  77. package/package.json +8 -4
@@ -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
@@ -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,3 @@
1
+ export declare function writeFeatureContext(remote: string, ref: string): void;
2
+ export declare function readFeatureContext(remote: string): string | null;
3
+ export declare function clearFeatureContext(remote: string): void;
@@ -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":"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"}
@@ -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 {};
@@ -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
- function formatReplay(inbox, decisions) {
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 binding = (decisions?.decisions ?? []).filter((d) => d.status === "binding");
35
- if (binding.length) {
36
- lines.push(`📌 ${binding.length} binding decision(s) in effect:`);
37
- for (const d of binding.slice(0, 8))
38
- lines.push(` • [${d.scopeRef}] ${d.ruleText}`);
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 replay = formatReplay(inbox, decisions);
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
- const surfaces = [];
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
- if (isContractSurface(f, content)) {
148
+ const ids = extractAllSurfaces(f, content);
149
+ if (ids.length > 0) {
103
150
  anyContractSurface = true;
104
- surfaces.push(f);
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 diffHash = createHash("sha256").update(files.sort().join("|")).digest("hex").slice(0, 16);
111
- await call("POST", "/changes", session.sessionId, {
112
- summary,
113
- surface: surfaces[0],
114
- riskTier,
115
- verified: true, // mechanical delta is derived from real local code
116
- verifiedAgainst: "git-diff",
117
- diffHash,
118
- }).catch(() => { });
119
- process.stderr.write(`[lockstep] published change (${riskTier})\n`);
120
- // Auto-propose a decision when a contract surface is modified
121
- if (riskTier === "shared" && surfaces.length > 0) {
122
- for (const surface of surfaces.slice(0, 3)) {
123
- const ruleText = `${event}: modified contract surface ${surface} (${files.length} file(s) changed)`;
124
- await call("POST", "/decisions", session.sessionId, {
125
- scopeKind: "surface",
126
- scopeRef: surface,
127
- ruleText,
128
- baseVersion: 0,
129
- provenance: { source: "auto-capture", vendor, diffHash },
130
- }).catch(() => {
131
- // 409 = decision already exists for this scope, which is fine
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":"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"}
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 {};