@itsthelore/proofkeeper 2026.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +10 -0
  3. package/README.md +207 -0
  4. package/dist/agent/adapters/claude.d.ts +93 -0
  5. package/dist/agent/adapters/claude.d.ts.map +1 -0
  6. package/dist/agent/adapters/claude.js +96 -0
  7. package/dist/agent/adapters/claude.js.map +1 -0
  8. package/dist/agent/drive.d.ts +53 -0
  9. package/dist/agent/drive.d.ts.map +1 -0
  10. package/dist/agent/drive.js +194 -0
  11. package/dist/agent/drive.js.map +1 -0
  12. package/dist/agent/loop.d.ts +40 -0
  13. package/dist/agent/loop.d.ts.map +1 -0
  14. package/dist/agent/loop.js +29 -0
  15. package/dist/agent/loop.js.map +1 -0
  16. package/dist/agent/model.d.ts +43 -0
  17. package/dist/agent/model.d.ts.map +1 -0
  18. package/dist/agent/model.js +10 -0
  19. package/dist/agent/model.js.map +1 -0
  20. package/dist/agent/observe.d.ts +48 -0
  21. package/dist/agent/observe.d.ts.map +1 -0
  22. package/dist/agent/observe.js +65 -0
  23. package/dist/agent/observe.js.map +1 -0
  24. package/dist/agent/tools.d.ts +74 -0
  25. package/dist/agent/tools.d.ts.map +1 -0
  26. package/dist/agent/tools.js +257 -0
  27. package/dist/agent/tools.js.map +1 -0
  28. package/dist/cli.d.ts +61 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +648 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/compiler/actions.d.ts +101 -0
  33. package/dist/compiler/actions.d.ts.map +1 -0
  34. package/dist/compiler/actions.js +13 -0
  35. package/dist/compiler/actions.js.map +1 -0
  36. package/dist/compiler/compiler.d.ts +25 -0
  37. package/dist/compiler/compiler.d.ts.map +1 -0
  38. package/dist/compiler/compiler.js +42 -0
  39. package/dist/compiler/compiler.js.map +1 -0
  40. package/dist/compiler/emit.d.ts +21 -0
  41. package/dist/compiler/emit.d.ts.map +1 -0
  42. package/dist/compiler/emit.js +164 -0
  43. package/dist/compiler/emit.js.map +1 -0
  44. package/dist/compiler/http.d.ts +30 -0
  45. package/dist/compiler/http.d.ts.map +1 -0
  46. package/dist/compiler/http.js +30 -0
  47. package/dist/compiler/http.js.map +1 -0
  48. package/dist/compiler/recorder.d.ts +62 -0
  49. package/dist/compiler/recorder.d.ts.map +1 -0
  50. package/dist/compiler/recorder.js +148 -0
  51. package/dist/compiler/recorder.js.map +1 -0
  52. package/dist/compiler/summary.d.ts +11 -0
  53. package/dist/compiler/summary.d.ts.map +1 -0
  54. package/dist/compiler/summary.js +56 -0
  55. package/dist/compiler/summary.js.map +1 -0
  56. package/dist/compiler/terminal.d.ts +42 -0
  57. package/dist/compiler/terminal.d.ts.map +1 -0
  58. package/dist/compiler/terminal.js +47 -0
  59. package/dist/compiler/terminal.js.map +1 -0
  60. package/dist/compiler/types.d.ts +25 -0
  61. package/dist/compiler/types.d.ts.map +1 -0
  62. package/dist/compiler/types.js +10 -0
  63. package/dist/compiler/types.js.map +1 -0
  64. package/dist/coverage/graph.d.ts +55 -0
  65. package/dist/coverage/graph.d.ts.map +1 -0
  66. package/dist/coverage/graph.js +87 -0
  67. package/dist/coverage/graph.js.map +1 -0
  68. package/dist/coverage/model.d.ts +36 -0
  69. package/dist/coverage/model.d.ts.map +1 -0
  70. package/dist/coverage/model.js +57 -0
  71. package/dist/coverage/model.js.map +1 -0
  72. package/dist/coverage/report.d.ts +27 -0
  73. package/dist/coverage/report.d.ts.map +1 -0
  74. package/dist/coverage/report.js +45 -0
  75. package/dist/coverage/report.js.map +1 -0
  76. package/dist/coverage/source.d.ts +23 -0
  77. package/dist/coverage/source.d.ts.map +1 -0
  78. package/dist/coverage/source.js +48 -0
  79. package/dist/coverage/source.js.map +1 -0
  80. package/dist/fidelity/gate.d.ts +34 -0
  81. package/dist/fidelity/gate.d.ts.map +1 -0
  82. package/dist/fidelity/gate.js +38 -0
  83. package/dist/fidelity/gate.js.map +1 -0
  84. package/dist/index.d.ts +69 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +49 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/learning/store.d.ts +44 -0
  89. package/dist/learning/store.d.ts.map +1 -0
  90. package/dist/learning/store.js +64 -0
  91. package/dist/learning/store.js.map +1 -0
  92. package/dist/qa/concurrency.d.ts +7 -0
  93. package/dist/qa/concurrency.d.ts.map +1 -0
  94. package/dist/qa/concurrency.js +21 -0
  95. package/dist/qa/concurrency.js.map +1 -0
  96. package/dist/qa/run-qa.d.ts +87 -0
  97. package/dist/qa/run-qa.d.ts.map +1 -0
  98. package/dist/qa/run-qa.js +106 -0
  99. package/dist/qa/run-qa.js.map +1 -0
  100. package/dist/qa/run-scoped.d.ts +82 -0
  101. package/dist/qa/run-scoped.d.ts.map +1 -0
  102. package/dist/qa/run-scoped.js +96 -0
  103. package/dist/qa/run-scoped.js.map +1 -0
  104. package/dist/runner/playwright-report.d.ts +52 -0
  105. package/dist/runner/playwright-report.d.ts.map +1 -0
  106. package/dist/runner/playwright-report.js +90 -0
  107. package/dist/runner/playwright-report.js.map +1 -0
  108. package/dist/runner/playwright-runner.d.ts +38 -0
  109. package/dist/runner/playwright-runner.d.ts.map +1 -0
  110. package/dist/runner/playwright-runner.js +73 -0
  111. package/dist/runner/playwright-runner.js.map +1 -0
  112. package/dist/runner/types.d.ts +45 -0
  113. package/dist/runner/types.d.ts.map +1 -0
  114. package/dist/runner/types.js +10 -0
  115. package/dist/runner/types.js.map +1 -0
  116. package/dist/scaffold/scaffold.d.ts +22 -0
  117. package/dist/scaffold/scaffold.d.ts.map +1 -0
  118. package/dist/scaffold/scaffold.js +34 -0
  119. package/dist/scaffold/scaffold.js.map +1 -0
  120. package/dist/scope/config.d.ts +89 -0
  121. package/dist/scope/config.d.ts.map +1 -0
  122. package/dist/scope/config.js +172 -0
  123. package/dist/scope/config.js.map +1 -0
  124. package/dist/scope/diff-scope.d.ts +31 -0
  125. package/dist/scope/diff-scope.d.ts.map +1 -0
  126. package/dist/scope/diff-scope.js +42 -0
  127. package/dist/scope/diff-scope.js.map +1 -0
  128. package/dist/scope/glob.d.ts +17 -0
  129. package/dist/scope/glob.d.ts.map +1 -0
  130. package/dist/scope/glob.js +50 -0
  131. package/dist/scope/glob.js.map +1 -0
  132. package/dist/writeback/comment.d.ts +103 -0
  133. package/dist/writeback/comment.d.ts.map +1 -0
  134. package/dist/writeback/comment.js +150 -0
  135. package/dist/writeback/comment.js.map +1 -0
  136. package/dist/writeback/gateways/github-rest.d.ts +66 -0
  137. package/dist/writeback/gateways/github-rest.d.ts.map +1 -0
  138. package/dist/writeback/gateways/github-rest.js +107 -0
  139. package/dist/writeback/gateways/github-rest.js.map +1 -0
  140. package/dist/writeback/merge.d.ts +27 -0
  141. package/dist/writeback/merge.d.ts.map +1 -0
  142. package/dist/writeback/merge.js +89 -0
  143. package/dist/writeback/merge.js.map +1 -0
  144. package/dist/writeback/proposal.d.ts +52 -0
  145. package/dist/writeback/proposal.d.ts.map +1 -0
  146. package/dist/writeback/proposal.js +79 -0
  147. package/dist/writeback/proposal.js.map +1 -0
  148. package/dist/writeback/proposer.d.ts +94 -0
  149. package/dist/writeback/proposer.d.ts.map +1 -0
  150. package/dist/writeback/proposer.js +79 -0
  151. package/dist/writeback/proposer.js.map +1 -0
  152. package/dist/writeback/verified-by.d.ts +56 -0
  153. package/dist/writeback/verified-by.d.ts.map +1 -0
  154. package/dist/writeback/verified-by.js +60 -0
  155. package/dist/writeback/verified-by.js.map +1 -0
  156. package/package.json +62 -0
@@ -0,0 +1,148 @@
1
+ /**
2
+ * The session recorder (Proofkeeper Initiative 2, the moat).
3
+ *
4
+ * Wraps a Playwright {@link Page} and, for each interaction or assertion,
5
+ * performs it against the real page FIRST and records the {@link Action} only
6
+ * if it succeeded. A recorded trace is therefore a sequence that actually held
7
+ * during the drive — the faithful half of "faithful session→test". The
8
+ * deterministic {@link emitSpec} half turns that trace into a committed test.
9
+ *
10
+ * In v0.0.1 the drive is scripted by the caller (or a BYO-model agent calling
11
+ * these methods); the recorder's contract is the same either way.
12
+ */
13
+ import { expect } from "@playwright/test";
14
+ import { runCommand, evalOutputMatch } from "./terminal.js";
15
+ import { httpRequest, jsonPath } from "./http.js";
16
+ export class Recorder {
17
+ page;
18
+ options;
19
+ actions = [];
20
+ /** The most recently run command's result; terminal assertions target it. */
21
+ last;
22
+ /** The most recently issued request's response; HTTP assertions target it. */
23
+ lastHttp;
24
+ constructor(page, options) {
25
+ this.page = page;
26
+ this.options = options;
27
+ }
28
+ resolve(loc) {
29
+ switch (loc.kind) {
30
+ case "role":
31
+ return this.page.getByRole(loc.role, { name: loc.name });
32
+ case "testId":
33
+ return this.page.getByTestId(loc.testId);
34
+ case "text":
35
+ return this.page.getByText(loc.text);
36
+ case "label":
37
+ return this.page.getByLabel(loc.label);
38
+ case "css":
39
+ return this.page.locator(loc.selector);
40
+ }
41
+ }
42
+ /** Navigate to the session's start URL (or another url), recording it. */
43
+ async goto(url = this.options.startUrl) {
44
+ await this.page.goto(url);
45
+ this.actions.push({ type: "goto", url });
46
+ }
47
+ async click(locator) {
48
+ await this.resolve(locator).click();
49
+ this.actions.push({ type: "click", locator });
50
+ }
51
+ async fill(locator, value) {
52
+ await this.resolve(locator).fill(value);
53
+ this.actions.push({ type: "fill", locator, value });
54
+ }
55
+ async check(locator) {
56
+ await this.resolve(locator).check();
57
+ this.actions.push({ type: "check", locator });
58
+ }
59
+ async press(locator, key) {
60
+ await this.resolve(locator).press(key);
61
+ this.actions.push({ type: "press", locator, key });
62
+ }
63
+ /** Assert text, recording the assertion only if it currently holds. */
64
+ async expectText(locator, text) {
65
+ await expect(this.resolve(locator)).toHaveText(text);
66
+ this.actions.push({ type: "expectText", locator, text });
67
+ }
68
+ async expectVisible(locator) {
69
+ await expect(this.resolve(locator)).toBeVisible();
70
+ this.actions.push({ type: "expectVisible", locator });
71
+ }
72
+ /**
73
+ * Run a shell command, record it, and return its result so the caller can
74
+ * decide what to assert. The result becomes the target for the next
75
+ * {@link expectOutput} / {@link expectExit}.
76
+ */
77
+ async run(command, options = {}) {
78
+ this.last = runCommand(command, options);
79
+ this.actions.push({ type: "run", command, ...(options.cwd !== undefined ? { cwd: options.cwd } : {}) });
80
+ return this.last;
81
+ }
82
+ /** Assert the last command's output, recording the assertion only if it holds. */
83
+ async expectOutput(assertion) {
84
+ if (!this.last)
85
+ throw new Error("expect_output called before any run_command");
86
+ if (!evalOutputMatch(this.last, assertion)) {
87
+ throw new Error(`output assertion failed: ${assertion.stream} did not ${assertion.match} ${JSON.stringify(assertion.value)}`);
88
+ }
89
+ this.actions.push({ type: "expectOutput", match: assertion.match, stream: assertion.stream, value: assertion.value });
90
+ }
91
+ /** Assert the last command's exit code, recording the assertion only if it holds. */
92
+ async expectExit(code) {
93
+ if (!this.last)
94
+ throw new Error("expect_exit called before any run_command");
95
+ if (this.last.code !== code) {
96
+ throw new Error(`exit assertion failed: expected ${code}, got ${this.last.code}`);
97
+ }
98
+ this.actions.push({ type: "expectExit", code });
99
+ }
100
+ /** Issue an HTTP request, record it, and return its response for assertions. */
101
+ async request(input) {
102
+ this.lastHttp = await httpRequest(input);
103
+ this.actions.push({
104
+ type: "request",
105
+ method: input.method,
106
+ url: input.url,
107
+ ...(input.headers !== undefined ? { headers: input.headers } : {}),
108
+ ...(input.body !== undefined ? { body: input.body } : {}),
109
+ });
110
+ return this.lastHttp;
111
+ }
112
+ /** Assert the last response's status, recording the assertion only if it holds. */
113
+ async expectStatus(status) {
114
+ if (!this.lastHttp)
115
+ throw new Error("expect_status called before any request");
116
+ if (this.lastHttp.status !== status) {
117
+ throw new Error(`status assertion failed: expected ${status}, got ${this.lastHttp.status}`);
118
+ }
119
+ this.actions.push({ type: "expectStatus", status });
120
+ }
121
+ /** Assert a JSON field of the last response, recording only if it holds. */
122
+ async expectJson(path, equals) {
123
+ if (!this.lastHttp)
124
+ throw new Error("expect_json called before any request");
125
+ let parsed;
126
+ try {
127
+ parsed = JSON.parse(this.lastHttp.body);
128
+ }
129
+ catch {
130
+ throw new Error("expect_json: response body is not valid JSON");
131
+ }
132
+ const actual = jsonPath(parsed, path);
133
+ if (actual !== equals) {
134
+ throw new Error(`json assertion failed at ${path}: expected ${JSON.stringify(equals)}, got ${JSON.stringify(actual)}`);
135
+ }
136
+ this.actions.push({ type: "expectJson", path, equals });
137
+ }
138
+ /** The recorded session so far, ready to hand to the compiler. */
139
+ recording() {
140
+ return {
141
+ capabilityId: this.options.capabilityId,
142
+ title: this.options.title,
143
+ startUrl: this.options.startUrl,
144
+ actions: [...this.actions],
145
+ };
146
+ }
147
+ }
148
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/compiler/recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Render a recorded session into readable steps — the human-facing companion to
3
+ * the compiled spec. Where the emitter produces code for the machine to re-run,
4
+ * {@link summarizeSession} produces prose for a reviewer to read in the pull
5
+ * request: "Navigate to …", "Click the button 'Verify'", "Run `npm test`",
6
+ * "Expect the last command to exit 0". Pure: it reads the same {@link Action} IR.
7
+ */
8
+ import type { RecordedSession } from "./actions.js";
9
+ /** One readable line per recorded action, in order. */
10
+ export declare function summarizeSession(session: RecordedSession): string[];
11
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../src/compiler/summary.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,cAAc,CAAC;AAgDrE,uDAAuD;AACvD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAEnE"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Render a recorded session into readable steps — the human-facing companion to
3
+ * the compiled spec. Where the emitter produces code for the machine to re-run,
4
+ * {@link summarizeSession} produces prose for a reviewer to read in the pull
5
+ * request: "Navigate to …", "Click the button 'Verify'", "Run `npm test`",
6
+ * "Expect the last command to exit 0". Pure: it reads the same {@link Action} IR.
7
+ */
8
+ function locatorLabel(loc) {
9
+ switch (loc.kind) {
10
+ case "role":
11
+ return loc.name !== undefined ? `the ${loc.role} "${loc.name}"` : `the ${loc.role}`;
12
+ case "testId":
13
+ return `[${loc.testId}]`;
14
+ case "text":
15
+ return `"${loc.text}"`;
16
+ case "label":
17
+ return `the "${loc.label}" field`;
18
+ case "css":
19
+ return `\`${loc.selector}\``;
20
+ }
21
+ }
22
+ function describeAction(action) {
23
+ switch (action.type) {
24
+ case "goto":
25
+ return `Navigate to ${action.url}`;
26
+ case "click":
27
+ return `Click ${locatorLabel(action.locator)}`;
28
+ case "fill":
29
+ return `Fill ${locatorLabel(action.locator)} with "${action.value}"`;
30
+ case "check":
31
+ return `Check ${locatorLabel(action.locator)}`;
32
+ case "press":
33
+ return `Press ${action.key} on ${locatorLabel(action.locator)}`;
34
+ case "expectText":
35
+ return `Expect ${locatorLabel(action.locator)} to read "${action.text}"`;
36
+ case "expectVisible":
37
+ return `Expect ${locatorLabel(action.locator)} to be visible`;
38
+ case "run":
39
+ return `Run \`${action.command}\``;
40
+ case "expectOutput":
41
+ return `Expect the last command's ${action.stream} to ${action.match} "${action.value}"`;
42
+ case "expectExit":
43
+ return `Expect the last command to exit ${action.code}`;
44
+ case "request":
45
+ return `Request ${action.method} ${action.url}`;
46
+ case "expectStatus":
47
+ return `Expect HTTP status ${action.status}`;
48
+ case "expectJson":
49
+ return `Expect JSON ${action.path} to equal ${JSON.stringify(action.equals)}`;
50
+ }
51
+ }
52
+ /** One readable line per recorded action, in order. */
53
+ export function summarizeSession(session) {
54
+ return session.actions.map(describeAction);
55
+ }
56
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/compiler/summary.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,SAAS,YAAY,CAAC,GAAY;IAChC,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,MAAM;YACT,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QACtF,KAAK,QAAQ;YACX,OAAO,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAC3B,KAAK,MAAM;YACT,OAAO,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;QACzB,KAAK,OAAO;YACV,OAAO,QAAQ,GAAG,CAAC,KAAK,SAAS,CAAC;QACpC,KAAK,KAAK;YACR,OAAO,KAAK,GAAG,CAAC,QAAQ,IAAI,CAAC;IACjC,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,OAAO,eAAe,MAAM,CAAC,GAAG,EAAE,CAAC;QACrC,KAAK,OAAO;YACV,OAAO,SAAS,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,KAAK,MAAM;YACT,OAAO,QAAQ,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,MAAM,CAAC,KAAK,GAAG,CAAC;QACvE,KAAK,OAAO;YACV,OAAO,SAAS,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,KAAK,OAAO;YACV,OAAO,SAAS,MAAM,CAAC,GAAG,OAAO,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,KAAK,YAAY;YACf,OAAO,UAAU,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,MAAM,CAAC,IAAI,GAAG,CAAC;QAC3E,KAAK,eAAe;YAClB,OAAO,UAAU,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAChE,KAAK,KAAK;YACR,OAAO,SAAS,MAAM,CAAC,OAAO,IAAI,CAAC;QACrC,KAAK,cAAc;YACjB,OAAO,6BAA6B,MAAM,CAAC,MAAM,OAAO,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,GAAG,CAAC;QAC3F,KAAK,YAAY;YACf,OAAO,mCAAmC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1D,KAAK,SAAS;YACZ,OAAO,WAAW,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QAClD,KAAK,cAAc;YACjB,OAAO,sBAAsB,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/C,KAAK,YAAY;YACf,OAAO,eAAe,MAAM,CAAC,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IAClF,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,gBAAgB,CAAC,OAAwB;IACvD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The terminal half of the drive — running shell commands and asserting their
3
+ * output, the second of the "browser and a terminal" tools ADR-083 sanctions.
4
+ *
5
+ * {@link runCommand} and {@link evalOutputMatch} are the single source of truth
6
+ * for how a command is executed and how its output is matched. The {@link
7
+ * Recorder} uses them while driving, and the emitted spec inlines an equivalent
8
+ * `runCommand` + the same `expect` shapes — so record and replay agree exactly,
9
+ * which is what lets the fidelity gate mean something for terminal sessions.
10
+ */
11
+ /** The observable result of running one command. */
12
+ export interface CommandResult {
13
+ stdout: string;
14
+ stderr: string;
15
+ /** Process exit code (0 when the process did not set one). */
16
+ code: number;
17
+ }
18
+ /** How a {@link CommandResult} stream is matched against an expected value. */
19
+ export interface OutputAssertion {
20
+ match: "exact" | "contains" | "regex";
21
+ stream: "stdout" | "stderr";
22
+ value: string;
23
+ }
24
+ /**
25
+ * Run a shell command and capture its result. Uses `shell: true` so a recorded
26
+ * command string (pipes, args, redirects) runs as written. The command executes
27
+ * in the caller's own environment — a developer's terminal — exactly as the
28
+ * committed test will when re-run (the trust boundary stays human PR review,
29
+ * ADR-065).
30
+ *
31
+ * @throws when the process could not be spawned (a runner error, not a verdict).
32
+ */
33
+ export declare function runCommand(command: string, options?: {
34
+ cwd?: string;
35
+ }): CommandResult;
36
+ /**
37
+ * Evaluate an output assertion against a result. This mirrors, byte for byte,
38
+ * the assertions {@link emitSpec} renders, so a recording that held here re-runs
39
+ * green in the compiled test.
40
+ */
41
+ export declare function evalOutputMatch(result: CommandResult, assertion: OutputAssertion): boolean;
42
+ //# sourceMappingURL=terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/compiler/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,aAAa,CAQzF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAU1F"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The terminal half of the drive — running shell commands and asserting their
3
+ * output, the second of the "browser and a terminal" tools ADR-083 sanctions.
4
+ *
5
+ * {@link runCommand} and {@link evalOutputMatch} are the single source of truth
6
+ * for how a command is executed and how its output is matched. The {@link
7
+ * Recorder} uses them while driving, and the emitted spec inlines an equivalent
8
+ * `runCommand` + the same `expect` shapes — so record and replay agree exactly,
9
+ * which is what lets the fidelity gate mean something for terminal sessions.
10
+ */
11
+ import { spawnSync } from "node:child_process";
12
+ /**
13
+ * Run a shell command and capture its result. Uses `shell: true` so a recorded
14
+ * command string (pipes, args, redirects) runs as written. The command executes
15
+ * in the caller's own environment — a developer's terminal — exactly as the
16
+ * committed test will when re-run (the trust boundary stays human PR review,
17
+ * ADR-065).
18
+ *
19
+ * @throws when the process could not be spawned (a runner error, not a verdict).
20
+ */
21
+ export function runCommand(command, options = {}) {
22
+ const result = spawnSync(command, {
23
+ shell: true,
24
+ encoding: "utf8",
25
+ ...(options.cwd !== undefined ? { cwd: options.cwd } : {}),
26
+ });
27
+ if (result.error)
28
+ throw result.error;
29
+ return { stdout: result.stdout ?? "", stderr: result.stderr ?? "", code: result.status ?? 0 };
30
+ }
31
+ /**
32
+ * Evaluate an output assertion against a result. This mirrors, byte for byte,
33
+ * the assertions {@link emitSpec} renders, so a recording that held here re-runs
34
+ * green in the compiled test.
35
+ */
36
+ export function evalOutputMatch(result, assertion) {
37
+ const actual = result[assertion.stream];
38
+ switch (assertion.match) {
39
+ case "exact":
40
+ return actual.trim() === assertion.value;
41
+ case "contains":
42
+ return actual.includes(assertion.value);
43
+ case "regex":
44
+ return new RegExp(assertion.value).test(actual);
45
+ }
46
+ }
47
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/compiler/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiB/C;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,UAA4B,EAAE;IACxE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE;QAChC,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,MAAM;QAChB,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,KAAK;QAAE,MAAM,MAAM,CAAC,KAAK,CAAC;IACrC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAqB,EAAE,SAA0B;IAC/E,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,SAAS,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS,CAAC,KAAK,CAAC;QAC3C,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1C,KAAK,OAAO;YACV,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The session→test compiler interface — Proofkeeper Initiative 2 (the moat).
3
+ *
4
+ * Faithfully compiling a real drive session into a durable, deterministic
5
+ * Playwright test — and proving it stable — is the hard, differentiating
6
+ * problem. The compiler reduces a {@link RecordedSession} (the authoritative
7
+ * recorded-action trace) to a candidate test.
8
+ */
9
+ import type { RecordedSession } from "./actions.js";
10
+ import type { CompiledTest } from "../runner/types.js";
11
+ /** A test the compiler emitted from a session — a candidate, not yet trusted. */
12
+ export interface CandidateTest extends CompiledTest {
13
+ /** The recorded session this test was compiled from. */
14
+ fromSession: RecordedSession;
15
+ }
16
+ /**
17
+ * Compiles a {@link RecordedSession} into a candidate Playwright test.
18
+ *
19
+ * The output is a *candidate*: it has not yet passed the fidelity gate
20
+ * (Initiative 3) and must not be trusted until it has.
21
+ */
22
+ export interface Compiler {
23
+ compile(session: RecordedSession): Promise<CandidateTest>;
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/compiler/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,iFAAiF;AACjF,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,wDAAwD;IACxD,WAAW,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3D"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The session→test compiler interface — Proofkeeper Initiative 2 (the moat).
3
+ *
4
+ * Faithfully compiling a real drive session into a durable, deterministic
5
+ * Playwright test — and proving it stable — is the hard, differentiating
6
+ * problem. The compiler reduces a {@link RecordedSession} (the authoritative
7
+ * recorded-action trace) to a candidate test.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/compiler/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * The `rac export --graph` contract, as Proofkeeper consumes it.
3
+ *
4
+ * This mirrors the engine's published shape (rac-core `services/export.py`,
5
+ * ADR-074): a single whole-graph JSON object of typed nodes and edges. We
6
+ * model only what the coverage read-model needs and treat everything else as
7
+ * additive — unknown fields are ignored, never required — so the engine can
8
+ * grow the contract without breaking us (ADR-007, JSON contract stability).
9
+ *
10
+ * We are a contract consumer (ADR-063, ADR-083): this file parses the
11
+ * published JSON. It never reaches into the engine's internals.
12
+ */
13
+ /** The edge kind Proofkeeper's coverage signal keys on (ADR-084). */
14
+ export declare const VERIFIED_BY = "verified_by";
15
+ /** A classified corpus artifact. Capabilities are nodes of type `requirement`. */
16
+ export interface GraphNode {
17
+ id: string;
18
+ type: string;
19
+ status: string;
20
+ title: string;
21
+ }
22
+ /**
23
+ * One typed relationship edge. `verified_by` is directed (capability → test)
24
+ * and external-target, so it is always emitted with `resolved: false` and the
25
+ * literal test/trace reference as `target` (ADR-084).
26
+ */
27
+ export interface GraphEdge {
28
+ source: string;
29
+ target: string;
30
+ type: string;
31
+ directed: boolean;
32
+ resolved: boolean;
33
+ }
34
+ /** The whole-graph projection emitted by `rac export --graph`. */
35
+ export interface Graph {
36
+ schema_version: string;
37
+ source: string;
38
+ nodes: GraphNode[];
39
+ edges: GraphEdge[];
40
+ }
41
+ /** Raised when input is not a recognizable graph export. Maps to exit code 2. */
42
+ export declare class GraphParseError extends Error {
43
+ constructor(message: string);
44
+ }
45
+ /**
46
+ * Parse a `rac export --graph` JSON string into a typed {@link Graph}.
47
+ *
48
+ * Strict about the shape the coverage model depends on (nodes/edges arrays and
49
+ * their required string fields), tolerant of additive fields the engine may
50
+ * introduce later.
51
+ *
52
+ * @throws {GraphParseError} when the input is not a recognizable graph export.
53
+ */
54
+ export declare function parseGraph(json: string): Graph;
55
+ //# sourceMappingURL=graph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/coverage/graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qEAAqE;AACrE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,kFAAkF;AAClF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,kEAAkE;AAClE,MAAM,WAAW,KAAK;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,iFAAiF;AACjF,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAsCD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAsB9C"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The `rac export --graph` contract, as Proofkeeper consumes it.
3
+ *
4
+ * This mirrors the engine's published shape (rac-core `services/export.py`,
5
+ * ADR-074): a single whole-graph JSON object of typed nodes and edges. We
6
+ * model only what the coverage read-model needs and treat everything else as
7
+ * additive — unknown fields are ignored, never required — so the engine can
8
+ * grow the contract without breaking us (ADR-007, JSON contract stability).
9
+ *
10
+ * We are a contract consumer (ADR-063, ADR-083): this file parses the
11
+ * published JSON. It never reaches into the engine's internals.
12
+ */
13
+ /** The edge kind Proofkeeper's coverage signal keys on (ADR-084). */
14
+ export const VERIFIED_BY = "verified_by";
15
+ /** Raised when input is not a recognizable graph export. Maps to exit code 2. */
16
+ export class GraphParseError extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "GraphParseError";
20
+ }
21
+ }
22
+ function isObject(value) {
23
+ return typeof value === "object" && value !== null && !Array.isArray(value);
24
+ }
25
+ function asString(value, where) {
26
+ if (typeof value !== "string") {
27
+ throw new GraphParseError(`expected a string at ${where}, got ${typeof value}`);
28
+ }
29
+ return value;
30
+ }
31
+ function parseNode(raw, index) {
32
+ if (!isObject(raw)) {
33
+ throw new GraphParseError(`nodes[${index}] is not an object`);
34
+ }
35
+ return {
36
+ id: asString(raw["id"], `nodes[${index}].id`),
37
+ type: asString(raw["type"], `nodes[${index}].type`),
38
+ status: asString(raw["status"], `nodes[${index}].status`),
39
+ title: asString(raw["title"], `nodes[${index}].title`),
40
+ };
41
+ }
42
+ function parseEdge(raw, index) {
43
+ if (!isObject(raw)) {
44
+ throw new GraphParseError(`edges[${index}] is not an object`);
45
+ }
46
+ return {
47
+ source: asString(raw["source"], `edges[${index}].source`),
48
+ target: asString(raw["target"], `edges[${index}].target`),
49
+ type: asString(raw["type"], `edges[${index}].type`),
50
+ directed: Boolean(raw["directed"]),
51
+ resolved: Boolean(raw["resolved"]),
52
+ };
53
+ }
54
+ /**
55
+ * Parse a `rac export --graph` JSON string into a typed {@link Graph}.
56
+ *
57
+ * Strict about the shape the coverage model depends on (nodes/edges arrays and
58
+ * their required string fields), tolerant of additive fields the engine may
59
+ * introduce later.
60
+ *
61
+ * @throws {GraphParseError} when the input is not a recognizable graph export.
62
+ */
63
+ export function parseGraph(json) {
64
+ let raw;
65
+ try {
66
+ raw = JSON.parse(json);
67
+ }
68
+ catch (err) {
69
+ throw new GraphParseError(`input is not valid JSON: ${err.message}`);
70
+ }
71
+ if (!isObject(raw)) {
72
+ throw new GraphParseError("graph export must be a JSON object");
73
+ }
74
+ if (!Array.isArray(raw["nodes"])) {
75
+ throw new GraphParseError("graph export is missing a `nodes` array");
76
+ }
77
+ if (!Array.isArray(raw["edges"])) {
78
+ throw new GraphParseError("graph export is missing an `edges` array");
79
+ }
80
+ return {
81
+ schema_version: typeof raw["schema_version"] === "string" ? raw["schema_version"] : "",
82
+ source: typeof raw["source"] === "string" ? raw["source"] : "",
83
+ nodes: raw["nodes"].map(parseNode),
84
+ edges: raw["edges"].map(parseEdge),
85
+ };
86
+ }
87
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/coverage/graph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The coverage read-model — Proofkeeper Initiative 1.
3
+ *
4
+ * Pure functions over a parsed {@link Graph}: no I/O, no browser, no model.
5
+ * The signal is exact and deterministic (ADR-084): a *capability* is a
6
+ * requirement node, and it is *verified* iff some `verified_by` edge has it as
7
+ * source. Because `verified_by` targets are external test/trace paths, those
8
+ * edges always carry `resolved: false` and a literal target — which is the
9
+ * reference we surface, not a corpus id.
10
+ */
11
+ import { type Graph } from "./graph.js";
12
+ /** The artifact type whose nodes are product capabilities (ADR-020). */
13
+ export declare const CAPABILITY_TYPE = "requirement";
14
+ /** A capability with the (external) references that verify it, if any. */
15
+ export interface CapabilityCoverage {
16
+ id: string;
17
+ title: string;
18
+ status: string;
19
+ /** Literal `verified_by` targets (test/trace paths). Empty ⇒ unverified. */
20
+ verifiedBy: string[];
21
+ }
22
+ /** The whole-corpus coverage answer to "what is unverified?". */
23
+ export interface CoverageReport {
24
+ source: string;
25
+ total: number;
26
+ verified: CapabilityCoverage[];
27
+ unverified: CapabilityCoverage[];
28
+ }
29
+ /**
30
+ * Compute verification coverage over a graph export.
31
+ *
32
+ * Capabilities are sorted by id for deterministic output (the engine already
33
+ * emits sorted nodes, but we do not depend on that).
34
+ */
35
+ export declare function computeCoverage(graph: Graph): CoverageReport;
36
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/coverage/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAe,KAAK,KAAK,EAAkB,MAAM,YAAY,CAAC;AAErE,wEAAwE;AACxE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,UAAU,EAAE,kBAAkB,EAAE,CAAC;CAClC;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,cAAc,CAkC5D"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The coverage read-model — Proofkeeper Initiative 1.
3
+ *
4
+ * Pure functions over a parsed {@link Graph}: no I/O, no browser, no model.
5
+ * The signal is exact and deterministic (ADR-084): a *capability* is a
6
+ * requirement node, and it is *verified* iff some `verified_by` edge has it as
7
+ * source. Because `verified_by` targets are external test/trace paths, those
8
+ * edges always carry `resolved: false` and a literal target — which is the
9
+ * reference we surface, not a corpus id.
10
+ */
11
+ import { VERIFIED_BY } from "./graph.js";
12
+ /** The artifact type whose nodes are product capabilities (ADR-020). */
13
+ export const CAPABILITY_TYPE = "requirement";
14
+ function isCapability(node) {
15
+ return node.type === CAPABILITY_TYPE;
16
+ }
17
+ /**
18
+ * Compute verification coverage over a graph export.
19
+ *
20
+ * Capabilities are sorted by id for deterministic output (the engine already
21
+ * emits sorted nodes, but we do not depend on that).
22
+ */
23
+ export function computeCoverage(graph) {
24
+ // Map each capability id to its external verifier references.
25
+ const verifiersById = new Map();
26
+ for (const node of graph.nodes) {
27
+ if (isCapability(node)) {
28
+ verifiersById.set(node.id, []);
29
+ }
30
+ }
31
+ for (const edge of graph.edges) {
32
+ if (edge.type !== VERIFIED_BY)
33
+ continue;
34
+ const targets = verifiersById.get(edge.source);
35
+ // Only count edges originating at a known capability node.
36
+ if (targets)
37
+ targets.push(edge.target);
38
+ }
39
+ const capabilities = graph.nodes
40
+ .filter(isCapability)
41
+ .map((node) => ({
42
+ id: node.id,
43
+ title: node.title,
44
+ status: node.status,
45
+ verifiedBy: verifiersById.get(node.id) ?? [],
46
+ }))
47
+ .sort((a, b) => a.id.localeCompare(b.id));
48
+ const verified = capabilities.filter((c) => c.verifiedBy.length > 0);
49
+ const unverified = capabilities.filter((c) => c.verifiedBy.length === 0);
50
+ return {
51
+ source: graph.source,
52
+ total: capabilities.length,
53
+ verified,
54
+ unverified,
55
+ };
56
+ }
57
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/coverage/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAA8B,MAAM,YAAY,CAAC;AAErE,wEAAwE;AACxE,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAmB7C,SAAS,YAAY,CAAC,IAAe;IACnC,OAAO,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAAY;IAC1C,8DAA8D;IAC9D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAoB,CAAC;IAClD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACxC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,2DAA2D;QAC3D,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK;SAC7B,MAAM,CAAC,YAAY,CAAC;SACpB,GAAG,CAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAClC,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;KAC7C,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE5C,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IAEzE,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,YAAY,CAAC,MAAM;QAC1B,QAAQ;QACR,UAAU;KACX,CAAC;AACJ,CAAC"}