loopforge 1.0.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/adapter.d.ts +17 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +228 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/backends/fs.d.ts +31 -0
  8. package/dist/backends/fs.d.ts.map +1 -0
  9. package/dist/backends/fs.js +308 -0
  10. package/dist/backends/fs.js.map +1 -0
  11. package/dist/backends/interface.d.ts +42 -0
  12. package/dist/backends/interface.d.ts.map +1 -0
  13. package/dist/backends/interface.js +7 -0
  14. package/dist/backends/interface.js.map +1 -0
  15. package/dist/builder.d.ts +17 -0
  16. package/dist/builder.d.ts.map +1 -0
  17. package/dist/builder.js +205 -0
  18. package/dist/builder.js.map +1 -0
  19. package/dist/cli.d.ts +7 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +360 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/engine.d.ts +42 -0
  24. package/dist/engine.d.ts.map +1 -0
  25. package/dist/engine.js +595 -0
  26. package/dist/engine.js.map +1 -0
  27. package/dist/generate-schema.d.ts +12 -0
  28. package/dist/generate-schema.d.ts.map +1 -0
  29. package/dist/generate-schema.js +278 -0
  30. package/dist/generate-schema.js.map +1 -0
  31. package/dist/index.d.ts +27 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +30 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/loop-compiler.d.ts +37 -0
  36. package/dist/loop-compiler.d.ts.map +1 -0
  37. package/dist/loop-compiler.js +1232 -0
  38. package/dist/loop-compiler.js.map +1 -0
  39. package/dist/policy.d.ts +44 -0
  40. package/dist/policy.d.ts.map +1 -0
  41. package/dist/policy.js +111 -0
  42. package/dist/policy.js.map +1 -0
  43. package/dist/protocol.d.ts +167 -0
  44. package/dist/protocol.d.ts.map +1 -0
  45. package/dist/protocol.js +198 -0
  46. package/dist/protocol.js.map +1 -0
  47. package/dist/replay.d.ts +19 -0
  48. package/dist/replay.d.ts.map +1 -0
  49. package/dist/replay.js +198 -0
  50. package/dist/replay.js.map +1 -0
  51. package/dist/tests/adapter.test.d.ts +2 -0
  52. package/dist/tests/adapter.test.d.ts.map +1 -0
  53. package/dist/tests/adapter.test.js +104 -0
  54. package/dist/tests/adapter.test.js.map +1 -0
  55. package/dist/tests/builder.test.d.ts +2 -0
  56. package/dist/tests/builder.test.d.ts.map +1 -0
  57. package/dist/tests/builder.test.js +122 -0
  58. package/dist/tests/builder.test.js.map +1 -0
  59. package/dist/tests/engine.test.d.ts +2 -0
  60. package/dist/tests/engine.test.d.ts.map +1 -0
  61. package/dist/tests/engine.test.js +200 -0
  62. package/dist/tests/engine.test.js.map +1 -0
  63. package/dist/tests/generate-schema.test.d.ts +8 -0
  64. package/dist/tests/generate-schema.test.d.ts.map +1 -0
  65. package/dist/tests/generate-schema.test.js +196 -0
  66. package/dist/tests/generate-schema.test.js.map +1 -0
  67. package/dist/tests/loop-compiler.test.d.ts +2 -0
  68. package/dist/tests/loop-compiler.test.d.ts.map +1 -0
  69. package/dist/tests/loop-compiler.test.js +387 -0
  70. package/dist/tests/loop-compiler.test.js.map +1 -0
  71. package/dist/tests/policy.test.d.ts +2 -0
  72. package/dist/tests/policy.test.d.ts.map +1 -0
  73. package/dist/tests/policy.test.js +59 -0
  74. package/dist/tests/policy.test.js.map +1 -0
  75. package/dist/tests/protocol.test.d.ts +2 -0
  76. package/dist/tests/protocol.test.d.ts.map +1 -0
  77. package/dist/tests/protocol.test.js +63 -0
  78. package/dist/tests/protocol.test.js.map +1 -0
  79. package/dist/tests/replay.test.d.ts +2 -0
  80. package/dist/tests/replay.test.d.ts.map +1 -0
  81. package/dist/tests/replay.test.js +194 -0
  82. package/dist/tests/replay.test.js.map +1 -0
  83. package/loop_policy.json +44 -0
  84. package/package.json +58 -0
@@ -0,0 +1,200 @@
1
+ /** Tests for engine: lifecycle, feedback, circuit breaker, metrics. */
2
+ import { describe, it, beforeEach } from "node:test";
3
+ import assert from "node:assert/strict";
4
+ import { LoopForgeEngine, createEngine, } from "../engine.js";
5
+ import { AgentStatus, Mode, makeExecutionFeedback, } from "../protocol.js";
6
+ import { resetPolicy } from "../policy.js";
7
+ function makeRequest(overrides = {}) {
8
+ return {
9
+ task: "Audit ERC20 token",
10
+ mode: Mode.BUILD,
11
+ vault_config: {
12
+ project_vault: ".promptcraft/prompt_vault.json",
13
+ global_vault: "~/.promptcraft/global_vault.json",
14
+ skills_dir: "skills",
15
+ no_global: false,
16
+ },
17
+ feedback: null,
18
+ skill_name: null,
19
+ task_id: null,
20
+ ...overrides,
21
+ };
22
+ }
23
+ describe("Engine — Initialisation", () => {
24
+ beforeEach(() => resetPolicy());
25
+ it("createEngine returns LoopForgeEngine instance", () => {
26
+ const engine = createEngine("skills");
27
+ assert.ok(engine instanceof LoopForgeEngine);
28
+ assert.equal(engine.skillsDir, "skills");
29
+ assert.equal(engine.state, null);
30
+ });
31
+ it("engine lazy-inits state on first invocation", () => {
32
+ const engine = createEngine();
33
+ engine.invokeBuild(makeRequest());
34
+ assert.notEqual(engine.state, null);
35
+ assert.equal(engine.state.call_count, 0);
36
+ });
37
+ });
38
+ describe("Engine — Build mode (internal)", () => {
39
+ beforeEach(() => resetPolicy());
40
+ it("returns OK with generated prompt", () => {
41
+ const engine = createEngine();
42
+ const result = engine.invokeBuild(makeRequest({ task: "Audit ERC20" }));
43
+ assert.equal(result.status, AgentStatus.OK);
44
+ assert.ok(result.response.prompt.includes("LoopForge Build"));
45
+ assert.ok(result.response.prompt.includes("Audit ERC20"));
46
+ assert.notEqual(result.response.analysis, null);
47
+ });
48
+ it("sets technique in analysis", () => {
49
+ const engine = createEngine();
50
+ const result = engine.invokeBuild(makeRequest({
51
+ task: "Rename getCwd to getCurrentWorkingDirectory",
52
+ }));
53
+ assert.equal(result.response.analysis.technique, "zero-shot");
54
+ });
55
+ });
56
+ describe("Engine — Feedback mode", () => {
57
+ beforeEach(() => resetPolicy());
58
+ it("returns error when no feedback payload", () => {
59
+ const engine = createEngine();
60
+ const result = engine.invokeFeedback(makeRequest());
61
+ assert.equal(result.status, AgentStatus.ERROR);
62
+ assert.ok(result.response.error.includes("feedback payload"));
63
+ });
64
+ it("returns OK with quality score when feedback provided", () => {
65
+ const engine = createEngine();
66
+ const req = makeRequest({
67
+ mode: Mode.FEEDBACK,
68
+ feedback: makeExecutionFeedback({
69
+ success: true,
70
+ constraint_violations: [],
71
+ manual_fixes_needed: "",
72
+ output: "All tests passed",
73
+ }),
74
+ });
75
+ const result = engine.invokeFeedback(req);
76
+ assert.equal(result.status, AgentStatus.OK);
77
+ assert.ok(result.response.prompt.includes("Quality Score: 5/5"));
78
+ });
79
+ it("scores quality=4 for success with fixes but no violations", () => {
80
+ const engine = createEngine();
81
+ const req = makeRequest({
82
+ mode: Mode.FEEDBACK,
83
+ feedback: makeExecutionFeedback({
84
+ success: true,
85
+ constraint_violations: [],
86
+ manual_fixes_needed: "formatting",
87
+ output: "Works with manual tweaks",
88
+ }),
89
+ });
90
+ const result = engine.invokeFeedback(req);
91
+ assert.ok(result.response.prompt.includes("Quality Score: 4/5"));
92
+ });
93
+ it("updates quality trend in state", () => {
94
+ const engine = createEngine();
95
+ const req = makeRequest({
96
+ mode: Mode.FEEDBACK,
97
+ feedback: makeExecutionFeedback({ success: true, output: "ok" }),
98
+ });
99
+ engine.invokeFeedback(req);
100
+ assert.equal(engine.state.quality_trend.length, 1);
101
+ assert.equal(engine.state.quality_trend[0], 5);
102
+ });
103
+ });
104
+ describe("Engine — Circuit breaker", () => {
105
+ beforeEach(() => resetPolicy());
106
+ it("returns false when no state", () => {
107
+ const engine = createEngine();
108
+ assert.equal(engine.shouldBreak(), false);
109
+ });
110
+ it("returns false when not enough data points", () => {
111
+ const engine = createEngine();
112
+ engine.invokeBuild(makeRequest()); // init state
113
+ engine.state.quality_trend = [5, 4];
114
+ assert.equal(engine.shouldBreak(), false);
115
+ });
116
+ it("returns true when quality is non-increasing for 3 rounds", () => {
117
+ const engine = createEngine();
118
+ engine.invokeBuild(makeRequest());
119
+ engine.state.quality_trend = [3, 3, 3];
120
+ assert.equal(engine.shouldBreak(), true);
121
+ });
122
+ it("returns false when quality is improving", () => {
123
+ const engine = createEngine();
124
+ engine.invokeBuild(makeRequest());
125
+ engine.state.quality_trend = [3, 4, 5];
126
+ assert.equal(engine.shouldBreak(), false);
127
+ });
128
+ });
129
+ describe("Engine — Loop Compile mode", () => {
130
+ beforeEach(() => resetPolicy());
131
+ it("returns OK with compiled prompt for round 1", () => {
132
+ const engine = createEngine();
133
+ const req = makeRequest({
134
+ mode: Mode.LOOP_COMPILE,
135
+ loop_id: "test",
136
+ round: 1,
137
+ goal_id: "audit",
138
+ task: "Audit ERC20 token",
139
+ });
140
+ const result = engine.invokeLoopCompile(req);
141
+ assert.equal(result.status, AgentStatus.OK);
142
+ assert.ok(result.response.prompt.includes("L2 Compile"));
143
+ });
144
+ it("includes loop health in prompt", () => {
145
+ const engine = createEngine();
146
+ const req = makeRequest({
147
+ mode: Mode.LOOP_COMPILE,
148
+ loop_id: "test",
149
+ round: 1,
150
+ goal_id: "audit",
151
+ task: "Audit ERC20 token",
152
+ loop_objective: {
153
+ objective: "Full security audit",
154
+ success_criteria: ["All tests pass"],
155
+ hard_constraints: [],
156
+ created_at_round: 1,
157
+ loop_id: "test",
158
+ },
159
+ });
160
+ const result = engine.invokeLoopCompile(req);
161
+ assert.ok(result.response.prompt.includes("Loop Objective"));
162
+ });
163
+ it("handles round 2 with existing vault context", () => {
164
+ const engine = createEngine();
165
+ const req = makeRequest({
166
+ mode: Mode.LOOP_COMPILE,
167
+ loop_id: "test-r2",
168
+ round: 2,
169
+ goal_id: "audit",
170
+ task: "Check approve race condition",
171
+ });
172
+ // Should fail gracefully to build mode fallback when no prior lineage
173
+ const result = engine.invokeLoopCompile(req);
174
+ assert.equal(result.status, AgentStatus.OK);
175
+ });
176
+ });
177
+ describe("Engine — Review mode", () => {
178
+ beforeEach(() => resetPolicy());
179
+ it("returns error when no hydrate results", () => {
180
+ const engine = createEngine();
181
+ const result = engine.handleReview(makeRequest());
182
+ assert.equal(result.status, AgentStatus.ERROR);
183
+ assert.ok(result.response.error.includes("hydrate_results"));
184
+ });
185
+ it("returns report when hydrate results provided", () => {
186
+ const engine = createEngine();
187
+ const hydrateResults = {
188
+ results: [
189
+ {
190
+ full_prompt: "角色: Security Auditor\n任务: Audit\n输入: Contract\n输出格式: Report\n硬约束: No deps\n生成要求: Complete",
191
+ },
192
+ ],
193
+ global_entries: [],
194
+ };
195
+ const result = engine.handleReview(makeRequest({ mode: Mode.REVIEW }), hydrateResults);
196
+ assert.equal(result.status, AgentStatus.OK);
197
+ assert.ok(result.response.prompt.includes("Review Report"));
198
+ });
199
+ });
200
+ //# sourceMappingURL=engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.js","sourceRoot":"","sources":["../../src/tests/engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /** Tests for auto-generated JSON Schema.
2
+ *
3
+ * Validates that the schema generated from protocol.ts is structurally correct,
4
+ * has proper type mappings (boolean, number, array, $ref), and includes all
5
+ * expected $defs.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=generate-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-schema.test.d.ts","sourceRoot":"","sources":["../../src/tests/generate-schema.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,196 @@
1
+ /** Tests for auto-generated JSON Schema.
2
+ *
3
+ * Validates that the schema generated from protocol.ts is structurally correct,
4
+ * has proper type mappings (boolean, number, array, $ref), and includes all
5
+ * expected $defs.
6
+ */
7
+ import { describe, it } from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import { readFileSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ // In npm scripts, process.cwd() is the package root (loopforge/).
12
+ // The generated schema is written to the repo root (../loopforge-protocol.json).
13
+ const schema = JSON.parse(readFileSync(resolve(process.cwd(), "..", "loopforge-protocol.json"), "utf-8"));
14
+ const defs = (schema.$defs ?? {});
15
+ // Helper: typed access to defs + properties
16
+ function def(name) {
17
+ return defs[name];
18
+ }
19
+ function props(name) {
20
+ return (def(name).properties ?? {});
21
+ }
22
+ function required(name) {
23
+ return (def(name).required ?? []);
24
+ }
25
+ // ═══════════════════════════════════════════════════════════════════════════
26
+ // Top-level structure
27
+ // ═══════════════════════════════════════════════════════════════════════════
28
+ describe("Generated JSON Schema — top-level", () => {
29
+ it("is draft 2020-12", () => {
30
+ assert.equal(schema.$schema, "https://json-schema.org/draft/2020-12/schema");
31
+ });
32
+ it("has $id and title", () => {
33
+ assert.ok(String(schema.$id ?? "").includes("loopforge"));
34
+ assert.ok(String(schema.title ?? "").includes("LoopForge"));
35
+ });
36
+ it("has 17 $defs (3 enums + 14 interfaces)", () => {
37
+ const names = Object.keys(defs);
38
+ assert.equal(names.length, 17, `expected 17, got ${names.length}: ${names.join(", ")}`);
39
+ });
40
+ });
41
+ // ═══════════════════════════════════════════════════════════════════════════
42
+ // Enums
43
+ // ═══════════════════════════════════════════════════════════════════════════
44
+ describe("Enums", () => {
45
+ it("Mode — 4 values", () => {
46
+ assert.equal(def("Mode").type, "string");
47
+ assert.deepEqual(def("Mode").enum, [
48
+ "loop_compile", "feedback", "review", "build",
49
+ ]);
50
+ });
51
+ it("AgentStatus — 3 values", () => {
52
+ assert.equal(def("AgentStatus").type, "string");
53
+ assert.deepEqual(def("AgentStatus").enum, ["ok", "error", "stalled"]);
54
+ });
55
+ it("Technique — 7 values", () => {
56
+ assert.equal(def("Technique").type, "string");
57
+ assert.deepEqual(def("Technique").enum, [
58
+ "zero-shot", "few-shot", "zero-shot-cot", "few-shot-cot",
59
+ "step-back", "least-to-most", "tree-of-thought",
60
+ ]);
61
+ });
62
+ });
63
+ // ═══════════════════════════════════════════════════════════════════════════
64
+ // Interfaces — type correctness (fixes hand-written schema bugs)
65
+ // ═══════════════════════════════════════════════════════════════════════════
66
+ describe("Interface type correctness", () => {
67
+ it("Analysis — booleans are boolean, not string", () => {
68
+ assert.equal(def("Analysis").type, "object");
69
+ assert.equal(props("Analysis").was_rotated.type, "boolean", "was_rotated should be boolean (hand-written schema had it as string)");
70
+ });
71
+ it("LoopHealth — numbers are number, booleans are boolean", () => {
72
+ const p = props("LoopHealth");
73
+ assert.equal(p.goal_alignment.type, "number");
74
+ assert.equal(p.constraint_integrity.type, "number");
75
+ assert.equal(p.task_continuity.type, "number");
76
+ assert.equal(p.drift_detected.type, "boolean");
77
+ assert.equal(p.strategy_stability.type, "boolean");
78
+ });
79
+ it("LoopCompileRequest — numbers are number", () => {
80
+ const p = props("LoopCompileRequest");
81
+ assert.equal(p.round.type, "number");
82
+ assert.equal(p.health_check_interval.type, "number");
83
+ });
84
+ it("TaskAlignment — is_aligned is boolean, alignment_score is number", () => {
85
+ const p = props("TaskAlignment");
86
+ assert.equal(p.is_aligned.type, "boolean");
87
+ assert.equal(p.alignment_score.type, "number");
88
+ });
89
+ it("LoopRoundResult — round is number, success is boolean, quality_score is number", () => {
90
+ const p = props("LoopRoundResult");
91
+ assert.equal(p.round.type, "number");
92
+ assert.equal(p.success.type, "boolean");
93
+ assert.equal(p.quality_score.type, "number");
94
+ });
95
+ });
96
+ // ═══════════════════════════════════════════════════════════════════════════
97
+ // Array properties
98
+ // ═══════════════════════════════════════════════════════════════════════════
99
+ describe("Array properties", () => {
100
+ it("LoopObjective — success_criteria and hard_constraints are string arrays", () => {
101
+ const p = props("LoopObjective");
102
+ assert.equal(p.success_criteria.type, "array");
103
+ assert.equal(p.success_criteria.items.type, "string");
104
+ assert.equal(p.hard_constraints.type, "array");
105
+ assert.equal(p.hard_constraints.items.type, "string");
106
+ });
107
+ it("LoopCompileResponse — warnings and lineage are string arrays", () => {
108
+ const p = props("LoopCompileResponse");
109
+ assert.equal(p.warnings.type, "array");
110
+ assert.equal(p.warnings.items.type, "string");
111
+ assert.equal(p.lineage.type, "array");
112
+ });
113
+ it("RollingSummary — quality_trajectory is number array", () => {
114
+ const p = props("RollingSummary");
115
+ assert.equal(p.quality_trajectory.type, "array");
116
+ assert.equal(p.quality_trajectory.items.type, "number");
117
+ });
118
+ });
119
+ // ═══════════════════════════════════════════════════════════════════════════
120
+ // $ref links (interface/enum references)
121
+ // ═══════════════════════════════════════════════════════════════════════════
122
+ describe("$ref links", () => {
123
+ it("LoopCompileRequest.loop_objective → LoopObjective | null (anyOf)", () => {
124
+ const loProp = props("LoopCompileRequest").loop_objective;
125
+ assert.ok(loProp.anyOf, "loop_objective should use anyOf for T | null");
126
+ const refs = loProp.anyOf.map((x) => x.$ref).filter(Boolean);
127
+ const nulls = loProp.anyOf.filter((x) => x.type === "null");
128
+ assert.ok(refs.includes("#/$defs/LoopObjective"));
129
+ assert.equal(nulls.length, 1);
130
+ });
131
+ it("LoopCompileRequest.vault_config → VaultConfig ($ref)", () => {
132
+ assert.equal(props("LoopCompileRequest").vault_config.$ref, "#/$defs/VaultConfig");
133
+ });
134
+ it("LoopForgeResponse.status → AgentStatus ($ref)", () => {
135
+ assert.equal(props("LoopForgeResponse").status.$ref, "#/$defs/AgentStatus");
136
+ });
137
+ it("LoopForgeResponse.analysis → Analysis | null (anyOf)", () => {
138
+ const aProp = props("LoopForgeResponse").analysis;
139
+ assert.ok(aProp.anyOf);
140
+ const refs = aProp.anyOf.map((x) => x.$ref).filter(Boolean);
141
+ assert.ok(refs.includes("#/$defs/Analysis"));
142
+ });
143
+ it("AgentLoopResult.response → LoopForgeResponse | null (anyOf)", () => {
144
+ const rProp = props("AgentLoopResult").response;
145
+ assert.ok(rProp.anyOf);
146
+ const refs = rProp.anyOf.map((x) => x.$ref).filter(Boolean);
147
+ assert.ok(refs.includes("#/$defs/LoopForgeResponse"));
148
+ });
149
+ });
150
+ // ═══════════════════════════════════════════════════════════════════════════
151
+ // Index signature → additionalProperties
152
+ // ═══════════════════════════════════════════════════════════════════════════
153
+ describe("Index signature handling", () => {
154
+ it("LoopForgeRequest has additionalProperties: true (index signature)", () => {
155
+ assert.equal(def("LoopForgeRequest").additionalProperties, true, "LoopForgeRequest has [key: string]: unknown → additionalProperties");
156
+ });
157
+ });
158
+ // ═══════════════════════════════════════════════════════════════════════════
159
+ // required arrays
160
+ // ═══════════════════════════════════════════════════════════════════════════
161
+ describe("required arrays", () => {
162
+ it("LoopForgeRequest — task is required", () => {
163
+ assert.ok(required("LoopForgeRequest").includes("task"));
164
+ });
165
+ it("LoopCompileRequest — all non-optional fields are required, nullable not", () => {
166
+ const req = required("LoopCompileRequest");
167
+ assert.ok(req.includes("mode"));
168
+ assert.ok(req.includes("loop_id"));
169
+ assert.ok(req.includes("round"));
170
+ assert.ok(req.includes("task"));
171
+ assert.ok(req.includes("vault_config"));
172
+ // Optional (nullable) fields should NOT be in required
173
+ assert.ok(!req.includes("loop_objective"));
174
+ assert.ok(!req.includes("plan_source"));
175
+ assert.ok(!req.includes("last_round_result"));
176
+ });
177
+ it("Analysis — 6 required fields", () => {
178
+ const req = required("Analysis");
179
+ assert.equal(req.length, 6);
180
+ assert.ok(req.includes("was_rotated"));
181
+ assert.ok(req.includes("reference_file"));
182
+ });
183
+ });
184
+ // ═══════════════════════════════════════════════════════════════════════════
185
+ // Record<string, unknown> special case
186
+ // ═══════════════════════════════════════════════════════════════════════════
187
+ describe("Record<string, unknown> handling", () => {
188
+ it("SessionState.feedback_buffer is array of objects with additionalProperties", () => {
189
+ const fb = props("SessionState").feedback_buffer;
190
+ assert.equal(fb.type, "array");
191
+ const items = fb.items;
192
+ assert.equal(items.type, "object");
193
+ assert.equal(items.additionalProperties, true);
194
+ });
195
+ });
196
+ //# sourceMappingURL=generate-schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-schema.test.js","sourceRoot":"","sources":["../../src/tests/generate-schema.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=loop-compiler.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-compiler.test.d.ts","sourceRoot":"","sources":["../../src/tests/loop-compiler.test.ts"],"names":[],"mappings":""}