ralphy-spec 0.1.0 → 0.2.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 (187) hide show
  1. package/README.ja.md +126 -0
  2. package/README.ko.md +126 -0
  3. package/README.md +77 -133
  4. package/README.zh.md +126 -0
  5. package/bin/ralphy-spec.js +0 -0
  6. package/dist/cli/checkpoint.d.ts +3 -0
  7. package/dist/cli/checkpoint.d.ts.map +1 -0
  8. package/dist/cli/checkpoint.js +23 -0
  9. package/dist/cli/checkpoint.js.map +1 -0
  10. package/dist/cli/init.d.ts +3 -0
  11. package/dist/cli/init.d.ts.map +1 -0
  12. package/dist/cli/init.js +66 -0
  13. package/dist/cli/init.js.map +1 -0
  14. package/dist/cli/report.d.ts +3 -0
  15. package/dist/cli/report.d.ts.map +1 -0
  16. package/dist/cli/report.js +53 -0
  17. package/dist/cli/report.js.map +1 -0
  18. package/dist/cli/run.d.ts +3 -0
  19. package/dist/cli/run.d.ts.map +1 -0
  20. package/dist/cli/run.js +79 -0
  21. package/dist/cli/run.js.map +1 -0
  22. package/dist/cli/status.d.ts +3 -0
  23. package/dist/cli/status.d.ts.map +1 -0
  24. package/dist/cli/status.js +45 -0
  25. package/dist/cli/status.js.map +1 -0
  26. package/dist/cli/tail.d.ts +3 -0
  27. package/dist/cli/tail.d.ts.map +1 -0
  28. package/dist/cli/tail.js +46 -0
  29. package/dist/cli/tail.js.map +1 -0
  30. package/dist/cli/update.d.ts +3 -0
  31. package/dist/cli/update.d.ts.map +1 -0
  32. package/dist/cli/update.js +62 -0
  33. package/dist/cli/update.js.map +1 -0
  34. package/dist/cli/validate.d.ts +3 -0
  35. package/dist/cli/validate.d.ts.map +1 -0
  36. package/dist/cli/validate.js +83 -0
  37. package/dist/cli/validate.js.map +1 -0
  38. package/dist/core/backends/claude-code.d.ts +17 -0
  39. package/dist/core/backends/claude-code.d.ts.map +1 -0
  40. package/dist/core/backends/claude-code.js +75 -0
  41. package/dist/core/backends/claude-code.js.map +1 -0
  42. package/dist/core/backends/cursor.d.ts +17 -0
  43. package/dist/core/backends/cursor.d.ts.map +1 -0
  44. package/dist/core/backends/cursor.js +75 -0
  45. package/dist/core/backends/cursor.js.map +1 -0
  46. package/dist/core/backends/noop.d.ts +10 -0
  47. package/dist/core/backends/noop.d.ts.map +1 -0
  48. package/dist/core/backends/noop.js +17 -0
  49. package/dist/core/backends/noop.js.map +1 -0
  50. package/dist/core/backends/opencode.d.ts +16 -0
  51. package/dist/core/backends/opencode.d.ts.map +1 -0
  52. package/dist/core/backends/opencode.js +73 -0
  53. package/dist/core/backends/opencode.js.map +1 -0
  54. package/dist/core/backends/types.d.ts +21 -0
  55. package/dist/core/backends/types.d.ts.map +1 -0
  56. package/dist/core/backends/types.js +3 -0
  57. package/dist/core/backends/types.js.map +1 -0
  58. package/dist/core/budgets/manager.d.ts +21 -0
  59. package/dist/core/budgets/manager.d.ts.map +1 -0
  60. package/dist/core/budgets/manager.js +48 -0
  61. package/dist/core/budgets/manager.js.map +1 -0
  62. package/dist/core/budgets/state.d.ts +25 -0
  63. package/dist/core/budgets/state.d.ts.map +1 -0
  64. package/dist/core/budgets/state.js +33 -0
  65. package/dist/core/budgets/state.js.map +1 -0
  66. package/dist/core/budgets/tiers.d.ts +32 -0
  67. package/dist/core/budgets/tiers.d.ts.map +1 -0
  68. package/dist/core/budgets/tiers.js +67 -0
  69. package/dist/core/budgets/tiers.js.map +1 -0
  70. package/dist/core/engine/context-pack.d.ts +12 -0
  71. package/dist/core/engine/context-pack.d.ts.map +1 -0
  72. package/dist/core/engine/context-pack.js +45 -0
  73. package/dist/core/engine/context-pack.js.map +1 -0
  74. package/dist/core/engine/loop.d.ts +28 -0
  75. package/dist/core/engine/loop.d.ts.map +1 -0
  76. package/dist/core/engine/loop.js +366 -0
  77. package/dist/core/engine/loop.js.map +1 -0
  78. package/dist/core/engine/phases.d.ts +2 -0
  79. package/dist/core/engine/phases.d.ts.map +1 -0
  80. package/dist/core/engine/phases.js +3 -0
  81. package/dist/core/engine/phases.js.map +1 -0
  82. package/dist/core/engine/repair.d.ts +6 -0
  83. package/dist/core/engine/repair.d.ts.map +1 -0
  84. package/dist/core/engine/repair.js +23 -0
  85. package/dist/core/engine/repair.js.map +1 -0
  86. package/dist/core/folders.d.ts +26 -0
  87. package/dist/core/folders.d.ts.map +1 -0
  88. package/dist/core/folders.js +58 -0
  89. package/dist/core/folders.js.map +1 -0
  90. package/dist/core/memory/ledger.d.ts +13 -0
  91. package/dist/core/memory/ledger.d.ts.map +1 -0
  92. package/dist/core/memory/ledger.js +24 -0
  93. package/dist/core/memory/ledger.js.map +1 -0
  94. package/dist/core/memory/persistence.d.ts +45 -0
  95. package/dist/core/memory/persistence.d.ts.map +1 -0
  96. package/dist/core/memory/persistence.js +162 -0
  97. package/dist/core/memory/persistence.js.map +1 -0
  98. package/dist/core/reporting/spend.d.ts +40 -0
  99. package/dist/core/reporting/spend.d.ts.map +1 -0
  100. package/dist/core/reporting/spend.js +157 -0
  101. package/dist/core/reporting/spend.js.map +1 -0
  102. package/dist/core/spec/dag.d.ts +7 -0
  103. package/dist/core/spec/dag.d.ts.map +1 -0
  104. package/dist/core/spec/dag.js +65 -0
  105. package/dist/core/spec/dag.js.map +1 -0
  106. package/dist/core/spec/file-contract.d.ts +13 -0
  107. package/dist/core/spec/file-contract.d.ts.map +1 -0
  108. package/dist/core/spec/file-contract.js +29 -0
  109. package/dist/core/spec/file-contract.js.map +1 -0
  110. package/dist/core/spec/loader.d.ts +8 -0
  111. package/dist/core/spec/loader.d.ts.map +1 -0
  112. package/dist/core/spec/loader.js +51 -0
  113. package/dist/core/spec/loader.js.map +1 -0
  114. package/dist/core/spec/schemas.d.ts +278 -0
  115. package/dist/core/spec/schemas.d.ts.map +1 -0
  116. package/dist/core/spec/schemas.js +207 -0
  117. package/dist/core/spec/schemas.js.map +1 -0
  118. package/dist/core/spec/types.d.ts +71 -0
  119. package/dist/core/spec/types.d.ts.map +1 -0
  120. package/dist/core/spec/types.js +3 -0
  121. package/dist/core/spec/types.js.map +1 -0
  122. package/dist/core/validators/parsers/eslint.d.ts +3 -0
  123. package/dist/core/validators/parsers/eslint.d.ts.map +1 -0
  124. package/dist/core/validators/parsers/eslint.js +35 -0
  125. package/dist/core/validators/parsers/eslint.js.map +1 -0
  126. package/dist/core/validators/parsers/jest.d.ts +3 -0
  127. package/dist/core/validators/parsers/jest.d.ts.map +1 -0
  128. package/dist/core/validators/parsers/jest.js +16 -0
  129. package/dist/core/validators/parsers/jest.js.map +1 -0
  130. package/dist/core/validators/parsers/tsc.d.ts +3 -0
  131. package/dist/core/validators/parsers/tsc.d.ts.map +1 -0
  132. package/dist/core/validators/parsers/tsc.js +32 -0
  133. package/dist/core/validators/parsers/tsc.js.map +1 -0
  134. package/dist/core/validators/runner.d.ts +8 -0
  135. package/dist/core/validators/runner.d.ts.map +1 -0
  136. package/dist/core/validators/runner.js +85 -0
  137. package/dist/core/validators/runner.js.map +1 -0
  138. package/dist/core/validators/signatures.d.ts +3 -0
  139. package/dist/core/validators/signatures.d.ts.map +1 -0
  140. package/dist/core/validators/signatures.js +10 -0
  141. package/dist/core/validators/signatures.js.map +1 -0
  142. package/dist/core/validators/types.d.ts +27 -0
  143. package/dist/core/validators/types.d.ts.map +1 -0
  144. package/dist/core/validators/types.js +3 -0
  145. package/dist/core/validators/types.js.map +1 -0
  146. package/dist/core/workspace/contract-enforcer.d.ts +54 -0
  147. package/dist/core/workspace/contract-enforcer.d.ts.map +1 -0
  148. package/dist/core/workspace/contract-enforcer.js +128 -0
  149. package/dist/core/workspace/contract-enforcer.js.map +1 -0
  150. package/dist/core/workspace/manager.d.ts +28 -0
  151. package/dist/core/workspace/manager.d.ts.map +1 -0
  152. package/dist/core/workspace/manager.js +3 -0
  153. package/dist/core/workspace/manager.js.map +1 -0
  154. package/dist/core/workspace/merge.d.ts +38 -0
  155. package/dist/core/workspace/merge.d.ts.map +1 -0
  156. package/dist/core/workspace/merge.js +92 -0
  157. package/dist/core/workspace/merge.js.map +1 -0
  158. package/dist/core/workspace/patch-mode.d.ts +22 -0
  159. package/dist/core/workspace/patch-mode.d.ts.map +1 -0
  160. package/dist/core/workspace/patch-mode.js +91 -0
  161. package/dist/core/workspace/patch-mode.js.map +1 -0
  162. package/dist/core/workspace/worktree-mode.d.ts +28 -0
  163. package/dist/core/workspace/worktree-mode.d.ts.map +1 -0
  164. package/dist/core/workspace/worktree-mode.js +156 -0
  165. package/dist/core/workspace/worktree-mode.js.map +1 -0
  166. package/dist/index.js +14 -4
  167. package/dist/index.js.map +1 -1
  168. package/dist/templates/claude-code/ralphy-archive.md +22 -0
  169. package/dist/templates/claude-code/ralphy-implement.md +30 -0
  170. package/dist/templates/claude-code/ralphy-plan.md +31 -0
  171. package/dist/templates/claude-code/ralphy-validate.md +21 -0
  172. package/dist/templates/cursor/ralphy-archive.md +20 -0
  173. package/dist/templates/cursor/ralphy-implement.md +31 -0
  174. package/dist/templates/cursor/ralphy-plan.md +39 -0
  175. package/dist/templates/cursor/ralphy-validate.md +24 -0
  176. package/dist/templates/opencode/AGENTS.md +46 -0
  177. package/dist/templates/shared/openspec-tasks-template.md +48 -0
  178. package/dist/templates/shared/project-template.yml +232 -0
  179. package/dist/templates/shared/ralph-loop-prompt-template.md +25 -0
  180. package/dist/utils/installer.d.ts.map +1 -1
  181. package/dist/utils/installer.js +31 -1
  182. package/dist/utils/installer.js.map +1 -1
  183. package/dist/utils/validator.d.ts.map +1 -1
  184. package/dist/utils/validator.js +10 -0
  185. package/dist/utils/validator.js.map +1 -1
  186. package/package.json +14 -4
  187. package/scripts/copy-templates.mjs +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsc.d.ts","sourceRoot":"","sources":["../../../../src/core/validators/parsers/tsc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAOtC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,CAyBtD"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTscOutput = parseTscOutput;
4
+ // Example:
5
+ // src/foo.ts(12,3): error TS2322: Type 'x' is not assignable...
6
+ const tscLineRe = /^(?<file>[^:(]+)\((?<line>\d+),(?<col>\d+)\):\s+(?<level>error|warning)\s+TS\d+:\s+(?<msg>.*)$/;
7
+ function parseTscOutput(output) {
8
+ const issues = [];
9
+ for (const line of output.split("\n")) {
10
+ const m = line.match(tscLineRe);
11
+ if (!m?.groups)
12
+ continue;
13
+ issues.push({
14
+ kind: "tsc",
15
+ level: m.groups.level === "warning" ? "warning" : "error",
16
+ message: m.groups.msg.trim(),
17
+ file: m.groups.file.trim(),
18
+ line: Number(m.groups.line),
19
+ raw: { line },
20
+ });
21
+ }
22
+ // If there is output but no matches, surface a generic issue.
23
+ if (!issues.length && output.trim()) {
24
+ issues.push({
25
+ kind: "tsc",
26
+ level: "error",
27
+ message: output.trim().slice(0, 4000),
28
+ });
29
+ }
30
+ return issues;
31
+ }
32
+ //# sourceMappingURL=tsc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsc.js","sourceRoot":"","sources":["../../../../src/core/validators/parsers/tsc.ts"],"names":[],"mappings":";;AAOA,wCAyBC;AA9BD,WAAW;AACX,gEAAgE;AAChE,MAAM,SAAS,GACb,gGAAgG,CAAC;AAEnG,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,EAAE,MAAM;YAAE,SAAS;QACzB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;YACzD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;YAC5B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;YAC1B,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;YAC3B,GAAG,EAAE,EAAE,IAAI,EAAE;SACd,CAAC,CAAC;IACL,CAAC;IAED,8DAA8D;IAC9D,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ValidateContext, ValidateResult, Validator } from "./types";
2
+ export declare class ValidatorRunner {
3
+ private readonly ctx;
4
+ constructor(ctx: ValidateContext);
5
+ runAll(validators: Validator[]): Promise<Record<string, ValidateResult>>;
6
+ runOne(validator: Validator): Promise<ValidateResult>;
7
+ }
8
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/core/validators/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA0B1E,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,eAAe;IAE3C,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAQxE,MAAM,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;CA6C5D"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValidatorRunner = void 0;
4
+ const execa_1 = require("execa");
5
+ const tsc_1 = require("./parsers/tsc");
6
+ const eslint_1 = require("./parsers/eslint");
7
+ const jest_1 = require("./parsers/jest");
8
+ function parseIssues(parser, combinedOutput) {
9
+ switch (parser) {
10
+ case "tsc":
11
+ return (0, tsc_1.parseTscOutput)(combinedOutput);
12
+ case "eslint":
13
+ return (0, eslint_1.parseEslintOutput)(combinedOutput);
14
+ case "jest":
15
+ return (0, jest_1.parseJestOutput)(combinedOutput);
16
+ default:
17
+ return combinedOutput.trim()
18
+ ? [
19
+ {
20
+ kind: "unknown",
21
+ level: "error",
22
+ message: combinedOutput.trim().slice(0, 4000),
23
+ },
24
+ ]
25
+ : [];
26
+ }
27
+ }
28
+ class ValidatorRunner {
29
+ ctx;
30
+ constructor(ctx) {
31
+ this.ctx = ctx;
32
+ }
33
+ async runAll(validators) {
34
+ const results = {};
35
+ for (const v of validators) {
36
+ results[v.id] = await this.runOne(v);
37
+ }
38
+ return results;
39
+ }
40
+ async runOne(validator) {
41
+ const started = Date.now();
42
+ const timeoutMs = validator.timeoutMs ?? this.ctx.commandTimeoutMs;
43
+ try {
44
+ const res = await (0, execa_1.execa)(validator.run, {
45
+ cwd: this.ctx.cwd,
46
+ shell: true,
47
+ timeout: timeoutMs,
48
+ reject: false,
49
+ stdio: "pipe",
50
+ });
51
+ const stdout = res.stdout ?? "";
52
+ const stderr = res.stderr ?? "";
53
+ const combined = [stdout, stderr].filter(Boolean).join("\n");
54
+ const issues = parseIssues(validator.parser, combined);
55
+ return {
56
+ ok: res.exitCode === 0,
57
+ exitCode: res.exitCode ?? null,
58
+ durationMs: Date.now() - started,
59
+ issues,
60
+ stdout,
61
+ stderr,
62
+ };
63
+ }
64
+ catch (err) {
65
+ const msg = err?.message ? String(err.message) : String(err);
66
+ return {
67
+ ok: false,
68
+ exitCode: null,
69
+ durationMs: Date.now() - started,
70
+ issues: [
71
+ {
72
+ kind: "unknown",
73
+ level: "error",
74
+ message: msg,
75
+ raw: err,
76
+ },
77
+ ],
78
+ stdout: "",
79
+ stderr: "",
80
+ };
81
+ }
82
+ }
83
+ }
84
+ exports.ValidatorRunner = ValidatorRunner;
85
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/core/validators/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Issue } from "./types";
2
+ export declare function issueSignature(i: Issue): string;
3
+ //# sourceMappingURL=signatures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatures.d.ts","sourceRoot":"","sources":["../../../src/core/validators/signatures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAK/C"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.issueSignature = issueSignature;
4
+ function issueSignature(i) {
5
+ const file = i.file ?? "";
6
+ const line = i.line ?? 0;
7
+ const msg = i.message.replace(/\s+/g, " ").trim();
8
+ return `${i.kind}|${file}|${line}|${msg}`;
9
+ }
10
+ //# sourceMappingURL=signatures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signatures.js","sourceRoot":"","sources":["../../../src/core/validators/signatures.ts"],"names":[],"mappings":";;AAEA,wCAKC;AALD,SAAgB,cAAc,CAAC,CAAQ;IACrC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IACzB,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,27 @@
1
+ export type Issue = {
2
+ kind: "tsc" | "eslint" | "jest" | "contract_violation" | "unknown";
3
+ level: "error" | "warning";
4
+ message: string;
5
+ file?: string;
6
+ line?: number;
7
+ raw?: unknown;
8
+ };
9
+ export type ValidateContext = {
10
+ cwd: string;
11
+ commandTimeoutMs: number;
12
+ };
13
+ export type ValidateResult = {
14
+ ok: boolean;
15
+ exitCode: number | null;
16
+ durationMs: number;
17
+ issues: Issue[];
18
+ stdout: string;
19
+ stderr: string;
20
+ };
21
+ export type Validator = {
22
+ id: string;
23
+ run: string;
24
+ timeoutMs?: number;
25
+ parser?: "tsc" | "eslint" | "jest" | string;
26
+ };
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/validators/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAAC;IACnE,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;CAC7C,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/validators/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import type { FileContract } from "../spec/types";
2
+ import { type ContractViolation } from "../spec/file-contract";
3
+ import type { Issue } from "../validators/types";
4
+ export type EnforcementResult = {
5
+ violations: ContractViolation[];
6
+ revertedFiles: string[];
7
+ issues: Issue[];
8
+ };
9
+ /**
10
+ * ContractEnforcer handles automatic reversion of files that violate contracts.
11
+ *
12
+ * Unlike WorkspaceManager.enforceContract which reverts ALL changes on violation,
13
+ * this enforcer can selectively revert only the violating files.
14
+ */
15
+ export declare class ContractEnforcer {
16
+ private readonly repoRoot;
17
+ constructor(repoRoot: string);
18
+ /**
19
+ * Check changed files against a contract and auto-revert violations.
20
+ *
21
+ * @param changedFiles - List of changed files with isNew flag
22
+ * @param contract - The file contract to enforce
23
+ * @param autoRevert - If true, automatically revert violating files
24
+ * @returns Enforcement result with violations, reverted files, and issues
25
+ */
26
+ enforce(args: {
27
+ changedFiles: Array<{
28
+ file: string;
29
+ isNew: boolean;
30
+ }>;
31
+ contract: FileContract;
32
+ autoRevert?: boolean;
33
+ }): Promise<EnforcementResult>;
34
+ /**
35
+ * Revert a single file to its last committed state.
36
+ */
37
+ private revertFile;
38
+ /**
39
+ * Get list of changed files in the working directory.
40
+ */
41
+ getChangedFiles(): Promise<Array<{
42
+ file: string;
43
+ isNew: boolean;
44
+ }>>;
45
+ }
46
+ /**
47
+ * Quick helper to enforce contract on current changes.
48
+ */
49
+ export declare function enforceFileContract(args: {
50
+ repoRoot: string;
51
+ contract: FileContract;
52
+ autoRevert?: boolean;
53
+ }): Promise<EnforcementResult>;
54
+ //# sourceMappingURL=contract-enforcer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-enforcer.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/contract-enforcer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAE7C;;;;;;;OAOG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,YAAY,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,OAAO,CAAA;SAAE,CAAC,CAAC;QACtD,QAAQ,EAAE,YAAY,CAAC;QACvB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA+C9B;;OAEG;YACW,UAAU;IAiBxB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CA6B1E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAQ7B"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractEnforcer = void 0;
4
+ exports.enforceFileContract = enforceFileContract;
5
+ const execa_1 = require("execa");
6
+ const file_contract_1 = require("../spec/file-contract");
7
+ /**
8
+ * ContractEnforcer handles automatic reversion of files that violate contracts.
9
+ *
10
+ * Unlike WorkspaceManager.enforceContract which reverts ALL changes on violation,
11
+ * this enforcer can selectively revert only the violating files.
12
+ */
13
+ class ContractEnforcer {
14
+ repoRoot;
15
+ constructor(repoRoot) {
16
+ this.repoRoot = repoRoot;
17
+ }
18
+ /**
19
+ * Check changed files against a contract and auto-revert violations.
20
+ *
21
+ * @param changedFiles - List of changed files with isNew flag
22
+ * @param contract - The file contract to enforce
23
+ * @param autoRevert - If true, automatically revert violating files
24
+ * @returns Enforcement result with violations, reverted files, and issues
25
+ */
26
+ async enforce(args) {
27
+ const { changedFiles, contract, autoRevert = true } = args;
28
+ const violations = (0, file_contract_1.evaluateFileContract)({ changedFiles, contract });
29
+ if (violations.length === 0) {
30
+ return { violations: [], revertedFiles: [], issues: [] };
31
+ }
32
+ const revertedFiles = [];
33
+ const issues = [];
34
+ if (autoRevert) {
35
+ for (const v of violations) {
36
+ try {
37
+ await this.revertFile(v.file, changedFiles.find((f) => f.file === v.file)?.isNew ?? false);
38
+ revertedFiles.push(v.file);
39
+ }
40
+ catch (err) {
41
+ // If revert fails, create an issue instead
42
+ issues.push({
43
+ kind: "contract_violation",
44
+ level: "error",
45
+ message: `Failed to auto-revert ${v.file}: ${err?.message ?? String(err)}`,
46
+ file: v.file,
47
+ raw: { violation: v, error: err?.message },
48
+ });
49
+ }
50
+ }
51
+ }
52
+ // Create issues for all violations
53
+ for (const v of violations) {
54
+ const wasReverted = revertedFiles.includes(v.file);
55
+ issues.push({
56
+ kind: "contract_violation",
57
+ level: wasReverted ? "warning" : "error",
58
+ message: wasReverted
59
+ ? `File contract violation (auto-reverted): ${v.reason} - ${v.file}`
60
+ : `File contract violation: ${v.reason} - ${v.file}`,
61
+ file: v.file,
62
+ raw: { violation: v, reverted: wasReverted },
63
+ });
64
+ }
65
+ return { violations, revertedFiles, issues };
66
+ }
67
+ /**
68
+ * Revert a single file to its last committed state.
69
+ */
70
+ async revertFile(file, isNew) {
71
+ if (isNew) {
72
+ // For new files, remove them
73
+ await (0, execa_1.execa)("git", ["rm", "-f", file], {
74
+ cwd: this.repoRoot,
75
+ stdio: "pipe",
76
+ reject: false,
77
+ });
78
+ }
79
+ else {
80
+ // For modified files, checkout from HEAD
81
+ await (0, execa_1.execa)("git", ["checkout", "HEAD", "--", file], {
82
+ cwd: this.repoRoot,
83
+ stdio: "pipe",
84
+ });
85
+ }
86
+ }
87
+ /**
88
+ * Get list of changed files in the working directory.
89
+ */
90
+ async getChangedFiles() {
91
+ // Get staged + unstaged changes
92
+ const res = await (0, execa_1.execa)("git", ["status", "--porcelain"], {
93
+ cwd: this.repoRoot,
94
+ stdio: "pipe",
95
+ });
96
+ const lines = res.stdout
97
+ .split("\n")
98
+ .map((l) => l.trim())
99
+ .filter(Boolean);
100
+ const changed = [];
101
+ for (const line of lines) {
102
+ // Format: XY filename or XY -> filename (for renames)
103
+ const status = line.substring(0, 2);
104
+ let file = line.substring(3);
105
+ // Handle renames: "R old -> new"
106
+ if (file.includes(" -> ")) {
107
+ file = file.split(" -> ")[1] ?? file;
108
+ }
109
+ const isNew = status.includes("A") || status.includes("?");
110
+ changed.push({ file, isNew });
111
+ }
112
+ return changed;
113
+ }
114
+ }
115
+ exports.ContractEnforcer = ContractEnforcer;
116
+ /**
117
+ * Quick helper to enforce contract on current changes.
118
+ */
119
+ async function enforceFileContract(args) {
120
+ const enforcer = new ContractEnforcer(args.repoRoot);
121
+ const changedFiles = await enforcer.getChangedFiles();
122
+ return enforcer.enforce({
123
+ changedFiles,
124
+ contract: args.contract,
125
+ autoRevert: args.autoRevert,
126
+ });
127
+ }
128
+ //# sourceMappingURL=contract-enforcer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-enforcer.js","sourceRoot":"","sources":["../../../src/core/workspace/contract-enforcer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { FileContract } from "../spec/types";
2
+ export type WorkspaceMode = "worktree" | "patch";
3
+ export type WorkspaceContext = {
4
+ taskId: string;
5
+ workingDir: string;
6
+ };
7
+ export type CheckpointRef = {
8
+ ref: string;
9
+ };
10
+ export type ContractViolation = {
11
+ file: string;
12
+ reason: "forbidden" | "not_allowed" | "new_file_disallowed";
13
+ };
14
+ export interface WorkspaceManager {
15
+ mode: WorkspaceMode;
16
+ prepare(taskId: string): Promise<WorkspaceContext>;
17
+ getWorkingDir(taskId: string): string;
18
+ getChangedFiles(taskId: string): Promise<Array<{
19
+ file: string;
20
+ isNew: boolean;
21
+ }>>;
22
+ enforceContract(taskId: string, contract: FileContract): Promise<ContractViolation[]>;
23
+ checkpoint(taskId: string, message: string): Promise<CheckpointRef>;
24
+ merge(taskId: string): Promise<void>;
25
+ revert(taskId: string): Promise<void>;
26
+ cleanup(taskId: string): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,qBAAqB,CAAC;CAC7D,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,aAAa,CAAC;IAEpB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEnD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;IAElF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAEtF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEpE,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/core/workspace/manager.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ export type MergeStrategy = "squash" | "merge" | "rebase";
2
+ export type MergeOptions = {
3
+ repoRoot: string;
4
+ sourceBranch: string;
5
+ targetBranch?: string;
6
+ strategy: MergeStrategy;
7
+ message?: string;
8
+ };
9
+ export type MergeResult = {
10
+ ok: boolean;
11
+ commitRef?: string;
12
+ error?: string;
13
+ };
14
+ /**
15
+ * Merge a source branch into the current (or target) branch.
16
+ *
17
+ * Strategies:
18
+ * - squash: Combines all commits into one (cleanest history)
19
+ * - merge: Standard merge commit
20
+ * - rebase: Rebase source onto target
21
+ */
22
+ export declare function mergeBranch(opts: MergeOptions): Promise<MergeResult>;
23
+ /**
24
+ * Apply a patch file to the current working directory.
25
+ */
26
+ export declare function applyPatch(opts: {
27
+ repoRoot: string;
28
+ patchContent: string;
29
+ }): Promise<MergeResult>;
30
+ /**
31
+ * Generate a patch from changes between two refs.
32
+ */
33
+ export declare function generatePatch(opts: {
34
+ repoRoot: string;
35
+ fromRef: string;
36
+ toRef?: string;
37
+ }): Promise<string>;
38
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/merge.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuC1E;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiBvB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAWlB"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeBranch = mergeBranch;
4
+ exports.applyPatch = applyPatch;
5
+ exports.generatePatch = generatePatch;
6
+ const execa_1 = require("execa");
7
+ /**
8
+ * Merge a source branch into the current (or target) branch.
9
+ *
10
+ * Strategies:
11
+ * - squash: Combines all commits into one (cleanest history)
12
+ * - merge: Standard merge commit
13
+ * - rebase: Rebase source onto target
14
+ */
15
+ async function mergeBranch(opts) {
16
+ const { repoRoot, sourceBranch, targetBranch, strategy, message } = opts;
17
+ try {
18
+ // If target branch specified, checkout to it first
19
+ if (targetBranch) {
20
+ await git(["checkout", targetBranch], repoRoot);
21
+ }
22
+ switch (strategy) {
23
+ case "squash": {
24
+ await git(["merge", "--squash", sourceBranch], repoRoot);
25
+ const commitMsg = message ?? `Squash merge ${sourceBranch}`;
26
+ await git(["commit", "-m", commitMsg], repoRoot);
27
+ break;
28
+ }
29
+ case "merge": {
30
+ const commitMsg = message ?? `Merge branch '${sourceBranch}'`;
31
+ await git(["merge", sourceBranch, "-m", commitMsg], repoRoot);
32
+ break;
33
+ }
34
+ case "rebase": {
35
+ await git(["rebase", sourceBranch], repoRoot);
36
+ break;
37
+ }
38
+ }
39
+ const commitRef = await git(["rev-parse", "HEAD"], repoRoot);
40
+ return { ok: true, commitRef };
41
+ }
42
+ catch (err) {
43
+ return {
44
+ ok: false,
45
+ error: err?.message ?? String(err),
46
+ };
47
+ }
48
+ }
49
+ /**
50
+ * Apply a patch file to the current working directory.
51
+ */
52
+ async function applyPatch(opts) {
53
+ try {
54
+ const res = await (0, execa_1.execa)("git", ["apply", "--3way", "-"], {
55
+ cwd: opts.repoRoot,
56
+ input: opts.patchContent,
57
+ stdio: ["pipe", "pipe", "pipe"],
58
+ reject: false,
59
+ });
60
+ if (res.exitCode !== 0) {
61
+ return { ok: false, error: res.stderr || "Patch apply failed" };
62
+ }
63
+ return { ok: true };
64
+ }
65
+ catch (err) {
66
+ return { ok: false, error: err?.message ?? String(err) };
67
+ }
68
+ }
69
+ /**
70
+ * Generate a patch from changes between two refs.
71
+ */
72
+ async function generatePatch(opts) {
73
+ const { repoRoot, fromRef, toRef } = opts;
74
+ const args = toRef ? ["diff", fromRef, toRef] : ["diff", fromRef];
75
+ const res = await (0, execa_1.execa)("git", args, {
76
+ cwd: repoRoot,
77
+ stdio: "pipe",
78
+ });
79
+ return res.stdout;
80
+ }
81
+ async function git(args, cwd) {
82
+ const res = await (0, execa_1.execa)("git", args, {
83
+ cwd,
84
+ stdio: "pipe",
85
+ reject: false,
86
+ });
87
+ if (res.exitCode !== 0) {
88
+ throw new Error(`git ${args.join(" ")} failed: ${res.stderr || res.stdout}`);
89
+ }
90
+ return res.stdout.trim();
91
+ }
92
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/core/workspace/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { FileContract } from "../spec/types";
2
+ import type { CheckpointRef, ContractViolation, WorkspaceContext, WorkspaceManager } from "./manager";
3
+ export declare class PatchModeWorkspace implements WorkspaceManager {
4
+ private readonly repoRoot;
5
+ mode: "patch";
6
+ private readonly stateByTask;
7
+ constructor(repoRoot: string);
8
+ prepare(taskId: string): Promise<WorkspaceContext>;
9
+ getWorkingDir(_taskId: string): string;
10
+ getChangedFiles(_taskId: string): Promise<Array<{
11
+ file: string;
12
+ isNew: boolean;
13
+ }>>;
14
+ enforceContract(taskId: string, contract: FileContract): Promise<ContractViolation[]>;
15
+ checkpoint(taskId: string, message: string): Promise<CheckpointRef>;
16
+ merge(_taskId: string): Promise<void>;
17
+ revert(taskId: string): Promise<void>;
18
+ cleanup(_taskId: string): Promise<void>;
19
+ private git;
20
+ }
21
+ export declare function getPatchWorkspaceRoot(repoRoot: string): string;
22
+ //# sourceMappingURL=patch-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patch-mode.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/patch-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,KAAK,EACV,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAMnB,qBAAa,kBAAmB,YAAW,gBAAgB;IAI7C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAHrC,IAAI,EAAE,OAAO,CAAW;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;gBAEpC,QAAQ,EAAE,MAAM;IAEvC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMxD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIhC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAmBlF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IASrF,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAanE,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAI/B,GAAG;CAOlB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D"}