lockwire 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +327 -0
  3. package/dist/actions.d.ts +67 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +430 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/actor.d.ts +4 -0
  8. package/dist/actor.d.ts.map +1 -0
  9. package/dist/actor.js +14 -0
  10. package/dist/actor.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +192 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +5 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +27 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/extract.d.ts +16 -0
  20. package/dist/extract.d.ts.map +1 -0
  21. package/dist/extract.js +349 -0
  22. package/dist/extract.js.map +1 -0
  23. package/dist/format.d.ts +5 -0
  24. package/dist/format.d.ts.map +1 -0
  25. package/dist/format.js +65 -0
  26. package/dist/format.js.map +1 -0
  27. package/dist/grammar.d.ts +6 -0
  28. package/dist/grammar.d.ts.map +1 -0
  29. package/dist/grammar.js +45 -0
  30. package/dist/grammar.js.map +1 -0
  31. package/dist/hash.d.ts +12 -0
  32. package/dist/hash.d.ts.map +1 -0
  33. package/dist/hash.js +34 -0
  34. package/dist/hash.js.map +1 -0
  35. package/dist/hook-claude.d.ts +6 -0
  36. package/dist/hook-claude.d.ts.map +1 -0
  37. package/dist/hook-claude.js +50 -0
  38. package/dist/hook-claude.js.map +1 -0
  39. package/dist/hook-codex.d.ts +8 -0
  40. package/dist/hook-codex.d.ts.map +1 -0
  41. package/dist/hook-codex.js +52 -0
  42. package/dist/hook-codex.js.map +1 -0
  43. package/dist/hook-common.d.ts +23 -0
  44. package/dist/hook-common.d.ts.map +1 -0
  45. package/dist/hook-common.js +72 -0
  46. package/dist/hook-common.js.map +1 -0
  47. package/dist/index.d.ts +12 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +12 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/ledger.d.ts +13 -0
  52. package/dist/ledger.d.ts.map +1 -0
  53. package/dist/ledger.js +69 -0
  54. package/dist/ledger.js.map +1 -0
  55. package/dist/lockfile.d.ts +9 -0
  56. package/dist/lockfile.d.ts.map +1 -0
  57. package/dist/lockfile.js +40 -0
  58. package/dist/lockfile.js.map +1 -0
  59. package/dist/markers.d.ts +18 -0
  60. package/dist/markers.d.ts.map +1 -0
  61. package/dist/markers.js +89 -0
  62. package/dist/markers.js.map +1 -0
  63. package/dist/mcp-server.d.ts +2 -0
  64. package/dist/mcp-server.d.ts.map +1 -0
  65. package/dist/mcp-server.js +69 -0
  66. package/dist/mcp-server.js.map +1 -0
  67. package/dist/repo.d.ts +14 -0
  68. package/dist/repo.d.ts.map +1 -0
  69. package/dist/repo.js +75 -0
  70. package/dist/repo.js.map +1 -0
  71. package/dist/types.d.ts +100 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +11 -0
  74. package/dist/types.js.map +1 -0
  75. package/grammars/tree-sitter-javascript.wasm +0 -0
  76. package/grammars/tree-sitter-python.wasm +0 -0
  77. package/grammars/tree-sitter-tsx.wasm +0 -0
  78. package/grammars/tree-sitter-typescript.wasm +0 -0
  79. package/package.json +75 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAoCtD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAkB3E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAcxD"}
package/dist/format.js ADDED
@@ -0,0 +1,65 @@
1
+ const VERSION = "0.1.0";
2
+ export function formatText(result) {
3
+ const lines = [];
4
+ const byDoc = new Map();
5
+ for (const r of result.results) {
6
+ const key = r.anchor.doc ?? "(lockfile-only)";
7
+ const list = byDoc.get(key) ?? [];
8
+ list.push(r);
9
+ byDoc.set(key, list);
10
+ }
11
+ for (const [doc, anchors] of byDoc) {
12
+ const noteworthy = anchors.filter((a) => a.status !== "fresh" && a.status !== "waived" && a.status !== "superseded");
13
+ if (noteworthy.length === 0) {
14
+ lines.push(`${doc}`, " ok", "");
15
+ continue;
16
+ }
17
+ lines.push(doc);
18
+ for (const a of noteworthy) {
19
+ const t = `${a.anchor.target.path}${a.anchor.target.symbol ? `#${a.anchor.target.symbol}` : ""}`;
20
+ const label = a.status.toUpperCase().padEnd(9);
21
+ const tierNote = a.driftedTiers.length ? ` (${a.driftedTiers.join(",")})` : "";
22
+ lines.push(` ${label} ${t}${tierNote}`);
23
+ }
24
+ lines.push("");
25
+ }
26
+ const { summary } = result;
27
+ lines.push(`${summary.anchors} anchor${summary.anchors === 1 ? "" : "s"} · ${summary.fresh} ok · ${summary.drifted} drifted · ${summary.orphaned} orphaned`);
28
+ lines.push(`single-hash would flag ${summary.noise.singleHashWouldFlag} · lockwire flagged ${summary.noise.tieredFlagged} · noise −${summary.noise.reductionPercent}%`);
29
+ return lines.join("\n");
30
+ }
31
+ export function formatJson(result, repo) {
32
+ const payload = {
33
+ schema: "lockwire.check.v1",
34
+ tool: { name: "lockwire", version: VERSION },
35
+ repo,
36
+ checkedAt: new Date().toISOString(),
37
+ summary: result.summary,
38
+ anchors: result.results.map((r) => ({
39
+ id: r.anchor.id,
40
+ doc: r.anchor.doc,
41
+ line: r.anchor.claim?.line ?? null,
42
+ target: `${r.anchor.target.path}${r.anchor.target.symbol ? `#${r.anchor.target.symbol}` : ""}`,
43
+ status: r.status,
44
+ driftedTiers: r.driftedTiers,
45
+ excerpt: r.anchor.claim?.excerpt ?? null,
46
+ })),
47
+ };
48
+ return JSON.stringify(payload, null, 2);
49
+ }
50
+ export function formatGithub(result) {
51
+ const lines = [];
52
+ for (const r of result.results) {
53
+ if (r.status !== "drifted" && r.status !== "orphaned")
54
+ continue;
55
+ const target = `${r.anchor.target.path}${r.anchor.target.symbol ? `#${r.anchor.target.symbol}` : ""}`;
56
+ const file = r.anchor.doc ?? r.anchor.target.path;
57
+ const line = r.anchor.claim?.line ?? 1;
58
+ const message = r.status === "orphaned"
59
+ ? `lockwire: "${target}" no longer exists — this claim is orphaned`
60
+ : `lockwire: "${target}" drifted on ${r.driftedTiers.join(",")} — this claim may be stale`;
61
+ lines.push(`::error file=${file},line=${line}::${message}`);
62
+ }
63
+ return lines.join("\n");
64
+ }
65
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Language, Parser } from "web-tree-sitter";
2
+ export type LangId = "typescript" | "tsx" | "javascript" | "python";
3
+ export declare function langForPath(path: string): LangId | null;
4
+ export declare function loadLanguage(lang: LangId): Promise<Language>;
5
+ export declare function parserFor(lang: LangId): Promise<Parser>;
6
+ //# sourceMappingURL=grammar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,YAAY,GAAG,QAAQ,CAAC;AAYpE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvD;AAKD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAUlE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK7D"}
@@ -0,0 +1,45 @@
1
+ import { dirname, join } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { Language, Parser } from "web-tree-sitter";
4
+ const GRAMMAR_FILE = {
5
+ typescript: "tree-sitter-typescript.wasm",
6
+ tsx: "tree-sitter-tsx.wasm",
7
+ javascript: "tree-sitter-javascript.wasm",
8
+ python: "tree-sitter-python.wasm",
9
+ };
10
+ // dist/grammar.js -> ../grammars (flat src/ -> flat dist/, see package.json "files")
11
+ const GRAMMARS_DIR = join(dirname(fileURLToPath(import.meta.url)), "..", "grammars");
12
+ export function langForPath(path) {
13
+ if (path.endsWith(".tsx"))
14
+ return "tsx";
15
+ if (path.endsWith(".ts") || path.endsWith(".mts") || path.endsWith(".cts"))
16
+ return "typescript";
17
+ if (path.endsWith(".jsx"))
18
+ return "javascript";
19
+ if (path.endsWith(".js") || path.endsWith(".mjs") || path.endsWith(".cjs"))
20
+ return "javascript";
21
+ if (path.endsWith(".py"))
22
+ return "python";
23
+ return null;
24
+ }
25
+ let initialized = false;
26
+ const cache = new Map();
27
+ export async function loadLanguage(lang) {
28
+ if (!initialized) {
29
+ await Parser.init();
30
+ initialized = true;
31
+ }
32
+ const cached = cache.get(lang);
33
+ if (cached)
34
+ return cached;
35
+ const loaded = await Language.load(join(GRAMMARS_DIR, GRAMMAR_FILE[lang]));
36
+ cache.set(lang, loaded);
37
+ return loaded;
38
+ }
39
+ export async function parserFor(lang) {
40
+ const language = await loadLanguage(lang);
41
+ const parser = new Parser();
42
+ parser.setLanguage(language);
43
+ return parser;
44
+ }
45
+ //# sourceMappingURL=grammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grammar.js","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAInD,MAAM,YAAY,GAA2B;IAC3C,UAAU,EAAE,6BAA6B;IACzC,GAAG,EAAE,sBAAsB;IAC3B,UAAU,EAAE,6BAA6B;IACzC,MAAM,EAAE,yBAAyB;CAClC,CAAC;AAEF,qFAAqF;AACrF,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAErF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IAChG,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,YAAY,CAAC;IAChG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3E,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/hash.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * A lockwire fingerprint: `b3:` + 32 lowercase hex chars — the first 16 bytes
3
+ * (128 bits) of a BLAKE3 digest. 128 bits is far past the collision risk that
4
+ * matters here (we're comparing a few thousand anchors, not defending against
5
+ * an adversary who controls the input), and it keeps `lockwire.lock` compact.
6
+ */
7
+ export declare function fingerprint(input: string): string;
8
+ /** Hash a sorted-unique string set as a single fingerprint (used for the `deps` tier and the ledger root). */
9
+ export declare function fingerprintSet(items: readonly string[]): string;
10
+ /** Canonical JSON: sorted keys, no whitespace. Used so ledger event hashes are reproducible across platforms. */
11
+ export declare function canonicalJson(value: unknown): string;
12
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,8GAA8G;AAC9G,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAG/D;AAED,iHAAiH;AACjH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD"}
package/dist/hash.js ADDED
@@ -0,0 +1,34 @@
1
+ import { blake3 } from "@noble/hashes/blake3.js";
2
+ import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
3
+ /**
4
+ * A lockwire fingerprint: `b3:` + 32 lowercase hex chars — the first 16 bytes
5
+ * (128 bits) of a BLAKE3 digest. 128 bits is far past the collision risk that
6
+ * matters here (we're comparing a few thousand anchors, not defending against
7
+ * an adversary who controls the input), and it keeps `lockwire.lock` compact.
8
+ */
9
+ export function fingerprint(input) {
10
+ const full = blake3(utf8ToBytes(input));
11
+ return `b3:${bytesToHex(full.subarray(0, 16))}`;
12
+ }
13
+ /** Hash a sorted-unique string set as a single fingerprint (used for the `deps` tier and the ledger root). */
14
+ export function fingerprintSet(items) {
15
+ const sorted = [...new Set(items)].sort();
16
+ return fingerprint(JSON.stringify(sorted));
17
+ }
18
+ /** Canonical JSON: sorted keys, no whitespace. Used so ledger event hashes are reproducible across platforms. */
19
+ export function canonicalJson(value) {
20
+ return JSON.stringify(sortKeysDeep(value));
21
+ }
22
+ function sortKeysDeep(value) {
23
+ if (Array.isArray(value))
24
+ return value.map(sortKeysDeep);
25
+ if (value !== null && typeof value === "object") {
26
+ const out = {};
27
+ for (const key of Object.keys(value).sort()) {
28
+ out[key] = sortKeysDeep(value[key]);
29
+ }
30
+ return out;
31
+ }
32
+ return value;
33
+ }
34
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACxC,OAAO,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,cAAc,CAAC,KAAwB;IACrD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Claude Code PreToolUse/PostToolUse adapter. Fail-open by contract: any exception here must
3
+ * result in exit 0 with no output, never a broken tool call. See LOCKWIRE-SPEC.md §6.
4
+ */
5
+ export declare function runClaudeHook(adapter: "claude-pre" | "claude-post", repoRoot: string): Promise<void>;
6
+ //# sourceMappingURL=hook-claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-claude.d.ts","sourceRoot":"","sources":["../src/hook-claude.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,YAAY,GAAG,aAAa,EACrC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -0,0 +1,50 @@
1
+ import { readConfig } from "./config.js";
2
+ import { buildAdvisoryText, claimsForPath, logHookError, normalizeTouchedPath, readStdinJson, reportDriftFor, } from "./hook-common.js";
3
+ /**
4
+ * Claude Code PreToolUse/PostToolUse adapter. Fail-open by contract: any exception here must
5
+ * result in exit 0 with no output, never a broken tool call. See LOCKWIRE-SPEC.md §6.
6
+ */
7
+ export async function runClaudeHook(adapter, repoRoot) {
8
+ try {
9
+ const input = await readStdinJson();
10
+ if (!input.tool_name || !["Edit", "Write"].includes(input.tool_name))
11
+ return;
12
+ const filePath = input.tool_input?.file_path;
13
+ if (!filePath)
14
+ return;
15
+ const touched = normalizeTouchedPath(repoRoot, filePath);
16
+ const config = await readConfig(repoRoot);
17
+ if (adapter === "claude-pre") {
18
+ const anchors = await claimsForPath(repoRoot, touched);
19
+ if (anchors.length === 0)
20
+ return;
21
+ const additionalContext = buildAdvisoryText(anchors, config);
22
+ const output = {
23
+ hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext },
24
+ };
25
+ const spec = output.hookSpecificOutput;
26
+ if (config.hook.mode === "ask") {
27
+ spec.permissionDecision = "ask";
28
+ spec.permissionDecisionReason = "lockwire: documented claims cover this code";
29
+ }
30
+ else if (config.hook.mode === "deny") {
31
+ spec.permissionDecision = "deny";
32
+ spec.permissionDecisionReason =
33
+ "lockwire: acknowledge the affected claims first (lockwire_claims_for / lockwire ack)";
34
+ }
35
+ process.stdout.write(JSON.stringify(output));
36
+ }
37
+ else {
38
+ const { text, anyDrift } = await reportDriftFor(repoRoot, touched);
39
+ if (!anyDrift)
40
+ return;
41
+ process.stdout.write(JSON.stringify({
42
+ hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: text },
43
+ }));
44
+ }
45
+ }
46
+ catch (err) {
47
+ await logHookError(repoRoot, adapter, err);
48
+ }
49
+ }
50
+ //# sourceMappingURL=hook-claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-claude.js","sourceRoot":"","sources":["../src/hook-claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAAqC,EACrC,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;YAAE,OAAO;QAC7E,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC;QAC7C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACjC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7D,MAAM,MAAM,GAA4B;gBACtC,kBAAkB,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE;aACvE,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,CAAC,kBAA6C,CAAC;YAClE,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC/B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;gBAChC,IAAI,CAAC,wBAAwB,GAAG,6CAA6C,CAAC;YAChF,CAAC;iBAAM,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACvC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;gBACjC,IAAI,CAAC,wBAAwB;oBAC3B,sFAAsF,CAAC;YAC3F,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnE,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;gBACb,kBAAkB,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE;aAC9E,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Codex PreToolUse/PostToolUse adapter. Codex can deny a tool call but cannot rewrite its input,
3
+ * so `ask` mode degrades to advisory here — see LOCKWIRE-SPEC.md §6 for the verified caveat on
4
+ * apply_patch hook emission (fixed in Codex 0.123.0) vs deny enforcement (still version-dependent,
5
+ * openai/codex#27833). lockwire's advisory default only needs emission, which is solid.
6
+ */
7
+ export declare function runCodexHook(adapter: "codex-pre" | "codex-post", repoRoot: string): Promise<void>;
8
+ //# sourceMappingURL=hook-codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-codex.d.ts","sourceRoot":"","sources":["../src/hook-codex.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,WAAW,GAAG,YAAY,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAwCf"}
@@ -0,0 +1,52 @@
1
+ import { readConfig } from "./config.js";
2
+ import { buildAdvisoryText, claimsForPath, logHookError, normalizeTouchedPath, readStdinJson, reportDriftFor, } from "./hook-common.js";
3
+ /**
4
+ * Codex PreToolUse/PostToolUse adapter. Codex can deny a tool call but cannot rewrite its input,
5
+ * so `ask` mode degrades to advisory here — see LOCKWIRE-SPEC.md §6 for the verified caveat on
6
+ * apply_patch hook emission (fixed in Codex 0.123.0) vs deny enforcement (still version-dependent,
7
+ * openai/codex#27833). lockwire's advisory default only needs emission, which is solid.
8
+ */
9
+ export async function runCodexHook(adapter, repoRoot) {
10
+ try {
11
+ const input = await readStdinJson();
12
+ // Codex file edits arrive as `apply_patch`; the patch body is on tool_input.command per the
13
+ // 2026-04-23 fix. We only need the touched path, so a best-effort regex over the patch header
14
+ // is enough — this hook never needs to understand the patch body itself.
15
+ if (input.tool_name !== "apply_patch")
16
+ return;
17
+ const patch = input.tool_input?.command ?? "";
18
+ const match = /\*\*\*\s*(?:Update|Add|Delete) File:\s*(.+)/.exec(patch);
19
+ const filePath = match?.[1]?.trim();
20
+ if (!filePath)
21
+ return;
22
+ const touched = normalizeTouchedPath(repoRoot, filePath);
23
+ const config = await readConfig(repoRoot);
24
+ if (adapter === "codex-pre") {
25
+ const anchors = await claimsForPath(repoRoot, touched);
26
+ if (anchors.length === 0)
27
+ return;
28
+ const additionalContext = buildAdvisoryText(anchors, config);
29
+ const output = {
30
+ hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext },
31
+ };
32
+ if (config.hook.mode === "deny") {
33
+ output.hookSpecificOutput.permissionDecision = "deny";
34
+ output.hookSpecificOutput.permissionDecisionReason =
35
+ "lockwire: acknowledge the affected claims first";
36
+ }
37
+ process.stdout.write(JSON.stringify(output));
38
+ }
39
+ else {
40
+ const { text, anyDrift } = await reportDriftFor(repoRoot, touched);
41
+ if (!anyDrift)
42
+ return;
43
+ process.stdout.write(JSON.stringify({
44
+ hookSpecificOutput: { hookEventName: "PostToolUse", additionalContext: text },
45
+ }));
46
+ }
47
+ }
48
+ catch (err) {
49
+ await logHookError(repoRoot, adapter, err);
50
+ }
51
+ }
52
+ //# sourceMappingURL=hook-codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-codex.js","sourceRoot":"","sources":["../src/hook-codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,oBAAoB,EACpB,aAAa,EACb,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAmC,EACnC,QAAgB;IAEhB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;QACpC,4FAA4F;QAC5F,8FAA8F;QAC9F,yEAAyE;QACzE,IAAI,KAAK,CAAC,SAAS,KAAK,aAAa;YAAE,OAAO;QAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,6CAA6C,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACjC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC7D,MAAM,MAAM,GAA4B;gBACtC,kBAAkB,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE;aACvE,CAAC;YACF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC/B,MAAM,CAAC,kBAA8C,CAAC,kBAAkB,GAAG,MAAM,CAAC;gBAClF,MAAM,CAAC,kBAA8C,CAAC,wBAAwB;oBAC7E,iDAAiD,CAAC;YACtD,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnE,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,IAAI,CAAC,SAAS,CAAC;gBACb,kBAAkB,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE;aAC9E,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { Anchor, LockwireConfig } from "./types.js";
2
+ export interface HookInput {
3
+ tool_name?: string;
4
+ tool_input?: {
5
+ file_path?: string;
6
+ old_string?: string;
7
+ content?: string;
8
+ command?: string;
9
+ };
10
+ session_id?: string;
11
+ cwd?: string;
12
+ }
13
+ export declare function readStdinJson(): Promise<HookInput>;
14
+ /** Windows delivers `C:\project\src\index.ts`; hooks compare against posix, repo-relative anchor targets. */
15
+ export declare function normalizeTouchedPath(repoRoot: string, filePath: string): string;
16
+ export declare function buildAdvisoryText(anchors: Anchor[], config: LockwireConfig): string;
17
+ export declare function claimsForPath(repoRoot: string, touchedPath: string): Promise<Anchor[]>;
18
+ export declare function reportDriftFor(repoRoot: string, touchedPath: string): Promise<{
19
+ text: string;
20
+ anyDrift: boolean;
21
+ }>;
22
+ export declare function logHookError(repoRoot: string, adapter: string, err: unknown): Promise<void>;
23
+ //# sourceMappingURL=hook-common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-common.d.ts","sourceRoot":"","sources":["../src/hook-common.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,SAAS,CAAC,CAMxD;AAED,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO/E;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAgBnF;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE5F;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAoB9C;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjG"}
@@ -0,0 +1,72 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { check, refs } from "./actions.js";
3
+ import { readConfig } from "./config.js";
4
+ import { toPosix, toRepoRelative } from "./repo.js";
5
+ export async function readStdinJson() {
6
+ const chunks = [];
7
+ for await (const chunk of process.stdin)
8
+ chunks.push(chunk);
9
+ const raw = Buffer.concat(chunks).toString("utf8").trim();
10
+ if (!raw)
11
+ return {};
12
+ return JSON.parse(raw);
13
+ }
14
+ /** Windows delivers `C:\project\src\index.ts`; hooks compare against posix, repo-relative anchor targets. */
15
+ export function normalizeTouchedPath(repoRoot, filePath) {
16
+ const posixAbs = toPosix(filePath);
17
+ const posixRoot = toPosix(repoRoot);
18
+ if (posixAbs.toLowerCase().startsWith(posixRoot.toLowerCase())) {
19
+ return toRepoRelative(repoRoot, posixAbs);
20
+ }
21
+ return posixAbs.replace(/^[A-Za-z]:/, "").replace(/^\//, "");
22
+ }
23
+ export function buildAdvisoryText(anchors, config) {
24
+ const shown = anchors.slice(0, config.hook.maxClaimsInContext);
25
+ const lines = shown.map((a) => {
26
+ const target = `${a.target.path}${a.target.symbol ? `#${a.target.symbol}` : ""}`;
27
+ const claimText = a.claim ? `"${a.claim.excerpt}"` : "(whole-file binding, no inline claim)";
28
+ return `- ${a.doc ?? "(lockfile-only)"} asserts ${claimText} about ${target} [tiers: ${a.tiers.join(",")}]`;
29
+ });
30
+ const more = anchors.length > shown.length ? `\n…and ${anchors.length - shown.length} more.` : "";
31
+ return [
32
+ `lockwire: documentation makes claims about this code:`,
33
+ ...lines,
34
+ more,
35
+ `If this edit changes what any of these claims assert, update the doc and run \`lockwire link <doc>\`.`,
36
+ ]
37
+ .filter(Boolean)
38
+ .join("\n");
39
+ }
40
+ export async function claimsForPath(repoRoot, touchedPath) {
41
+ return refs(repoRoot, touchedPath);
42
+ }
43
+ export async function reportDriftFor(repoRoot, touchedPath) {
44
+ const config = await readConfig(repoRoot);
45
+ const result = await check(repoRoot, config, [touchedPath]);
46
+ const relevant = result.results.filter((r) => r.anchor.target.path === touchedPath && (r.status === "drifted" || r.status === "orphaned"));
47
+ if (relevant.length === 0)
48
+ return { text: "", anyDrift: false };
49
+ const lines = relevant.map((r) => {
50
+ const target = `${r.anchor.target.path}${r.anchor.target.symbol ? `#${r.anchor.target.symbol}` : ""}`;
51
+ return `- ${r.anchor.doc ?? "(lockfile-only)"} on ${target} is now ${r.status}${r.driftedTiers.length ? ` (${r.driftedTiers.join(",")})` : ""}`;
52
+ });
53
+ return {
54
+ text: [
55
+ `lockwire: this edit drifted documentation claims:`,
56
+ ...lines,
57
+ `Update the doc and run \`lockwire link <doc>\`, or \`lockwire ack\`/\`lockwire waive\` if this is expected.`,
58
+ ].join("\n"),
59
+ anyDrift: true,
60
+ };
61
+ }
62
+ export async function logHookError(repoRoot, adapter, err) {
63
+ try {
64
+ await mkdir(`${repoRoot}/.lockwire`, { recursive: true });
65
+ const msg = err instanceof Error ? (err.stack ?? err.message) : String(err);
66
+ await appendFile(`${repoRoot}/.lockwire/hook.log`, `[${new Date().toISOString()}] ${adapter}: ${msg}\n`, "utf8");
67
+ }
68
+ catch {
69
+ // fail-open invariant: a broken hook must never break the session, not even to log
70
+ }
71
+ }
72
+ //# sourceMappingURL=hook-common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-common.js","sourceRoot":"","sources":["../src/hook-common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export { ack, check, discoverDocs, history, linkDoc, linkLockfileOnly, refs, resolveTarget, status, unlink, waive, } from "./actions.js";
2
+ export { readConfig, writeConfig } from "./config.js";
3
+ export { computeWholeFileTiers, extractFileSymbols } from "./extract.js";
4
+ export { formatGithub, formatJson, formatText } from "./format.js";
5
+ export { langForPath } from "./grammar.js";
6
+ export { canonicalJson, fingerprint, fingerprintSet } from "./hash.js";
7
+ export { historyFor, readLedger, verifyLedger } from "./ledger.js";
8
+ export { readLockfile, writeLockfile } from "./lockfile.js";
9
+ export { scanMarkers } from "./markers.js";
10
+ export { findRepoRoot } from "./repo.js";
11
+ export * from "./types.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,KAAK,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,IAAI,EACJ,aAAa,EACb,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export { ack, check, discoverDocs, history, linkDoc, linkLockfileOnly, refs, resolveTarget, status, unlink, waive, } from "./actions.js";
2
+ export { readConfig, writeConfig } from "./config.js";
3
+ export { computeWholeFileTiers, extractFileSymbols } from "./extract.js";
4
+ export { formatGithub, formatJson, formatText } from "./format.js";
5
+ export { langForPath } from "./grammar.js";
6
+ export { canonicalJson, fingerprint, fingerprintSet } from "./hash.js";
7
+ export { historyFor, readLedger, verifyLedger } from "./ledger.js";
8
+ export { readLockfile, writeLockfile } from "./lockfile.js";
9
+ export { scanMarkers } from "./markers.js";
10
+ export { findRepoRoot } from "./repo.js";
11
+ export * from "./types.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,KAAK,EACL,YAAY,EACZ,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,IAAI,EACJ,aAAa,EACb,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,cAAc,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { LedgerRecord } from "./types.js";
2
+ export declare function ledgerPath(repoRoot: string): string;
3
+ export declare function appendEvent(repoRoot: string, record: Omit<LedgerRecord, "v" | "id" | "hash">): Promise<LedgerRecord>;
4
+ export declare function readLedger(repoRoot: string): Promise<LedgerRecord[]>;
5
+ export interface VerifyResult {
6
+ ok: boolean;
7
+ total: number;
8
+ badLines: number[];
9
+ root: string;
10
+ }
11
+ export declare function verifyLedger(repoRoot: string): Promise<VerifyResult>;
12
+ export declare function historyFor(records: LedgerRecord[], anchorId: string): LedgerRecord[];
13
+ //# sourceMappingURL=ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAUD,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,GAC9C,OAAO,CAAC,YAAY,CAAC,CAQvB;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAc1E;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB1E;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAEpF"}
package/dist/ledger.js ADDED
@@ -0,0 +1,69 @@
1
+ import { existsSync } from "node:fs";
2
+ import { appendFile, mkdir, readFile } from "node:fs/promises";
3
+ import { dirname } from "node:path";
4
+ import { canonicalJson, fingerprint, fingerprintSet } from "./hash.js";
5
+ export function ledgerPath(repoRoot) {
6
+ return `${repoRoot}/.lockwire/ledger.jsonl`;
7
+ }
8
+ function eventId() {
9
+ // Not a real ULID library dependency for v0.1 — monotonic-enough for a local, single-writer append.
10
+ // Sortable by time; uniqueness comes from the timestamp + a short random suffix.
11
+ const time = Date.now().toString(36).padStart(9, "0");
12
+ const rand = Math.random().toString(36).slice(2, 8);
13
+ return `${time}${rand}`.toUpperCase();
14
+ }
15
+ export async function appendEvent(repoRoot, record) {
16
+ const withoutHash = { v: 1, id: eventId(), ...record };
17
+ const hash = fingerprint(canonicalJson(withoutHash));
18
+ const full = { ...withoutHash, hash };
19
+ const path = ledgerPath(repoRoot);
20
+ await mkdir(dirname(path), { recursive: true });
21
+ await appendFile(path, `${JSON.stringify(full)}\n`, "utf8");
22
+ return full;
23
+ }
24
+ export async function readLedger(repoRoot) {
25
+ const path = ledgerPath(repoRoot);
26
+ if (!existsSync(path))
27
+ return [];
28
+ const raw = await readFile(path, "utf8");
29
+ const records = [];
30
+ for (const line of raw.split("\n")) {
31
+ if (!line.trim())
32
+ continue;
33
+ try {
34
+ records.push(JSON.parse(line));
35
+ }
36
+ catch {
37
+ // malformed line: `ledger verify` reports this explicitly; readers skip it rather than crash
38
+ }
39
+ }
40
+ return records;
41
+ }
42
+ export async function verifyLedger(repoRoot) {
43
+ const path = ledgerPath(repoRoot);
44
+ if (!existsSync(path))
45
+ return { ok: true, total: 0, badLines: [], root: fingerprintSet([]) };
46
+ const raw = await readFile(path, "utf8");
47
+ const lines = raw.split("\n").filter((l) => l.trim() !== "");
48
+ const badLines = [];
49
+ const hashes = [];
50
+ lines.forEach((line, idx) => {
51
+ try {
52
+ const record = JSON.parse(line);
53
+ const { hash, ...rest } = record;
54
+ const recomputed = fingerprint(canonicalJson(rest));
55
+ if (recomputed !== hash)
56
+ badLines.push(idx);
57
+ else
58
+ hashes.push(hash);
59
+ }
60
+ catch {
61
+ badLines.push(idx);
62
+ }
63
+ });
64
+ return { ok: badLines.length === 0, total: lines.length, badLines, root: fingerprintSet(hashes) };
65
+ }
66
+ export function historyFor(records, anchorId) {
67
+ return records.filter((r) => r.anchor === anchorId).sort((a, b) => a.ts.localeCompare(b.ts));
68
+ }
69
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Anchor, Lockfile } from "./types.js";
2
+ export declare function lockfilePath(repoRoot: string): string;
3
+ export declare function readLockfile(repoRoot: string): Promise<Lockfile>;
4
+ export declare function writeLockfile(repoRoot: string, lockfile: Lockfile): Promise<void>;
5
+ export declare function upsertAnchor(lockfile: Lockfile, anchor: Anchor): Lockfile;
6
+ export declare function removeAnchor(lockfile: Lockfile, id: string): Lockfile;
7
+ export declare function anchorsForPath(lockfile: Lockfile, repoRelativePath: string): Anchor[];
8
+ export declare function newAnchorId(): string;
9
+ //# sourceMappingURL=lockfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAInD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAMtE;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAIzE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAErE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CAErF;AAID,wBAAgB,WAAW,IAAI,MAAM,CAIpC"}