@sourcepress/server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/.omc/state/agent-replay-31d84b63-606a-4368-b9e6-93fe4f5ae0f7.jsonl +2 -0
  2. package/.omc/state/last-tool-error.json +7 -0
  3. package/.omc/state/mission-state.json +53 -0
  4. package/.omc/state/subagent-tracking.json +17 -0
  5. package/.turbo/turbo-build.log +4 -0
  6. package/.turbo/turbo-test.log +26 -0
  7. package/dist/__tests__/app-integration.test.d.ts +2 -0
  8. package/dist/__tests__/app-integration.test.d.ts.map +1 -0
  9. package/dist/__tests__/app-integration.test.js +71 -0
  10. package/dist/__tests__/app-integration.test.js.map +1 -0
  11. package/dist/__tests__/approval.test.d.ts +2 -0
  12. package/dist/__tests__/approval.test.d.ts.map +1 -0
  13. package/dist/__tests__/approval.test.js +170 -0
  14. package/dist/__tests__/approval.test.js.map +1 -0
  15. package/dist/__tests__/content.test.d.ts +2 -0
  16. package/dist/__tests__/content.test.d.ts.map +1 -0
  17. package/dist/__tests__/content.test.js +187 -0
  18. package/dist/__tests__/content.test.js.map +1 -0
  19. package/dist/__tests__/engine.test.d.ts +2 -0
  20. package/dist/__tests__/engine.test.d.ts.map +1 -0
  21. package/dist/__tests__/engine.test.js +77 -0
  22. package/dist/__tests__/engine.test.js.map +1 -0
  23. package/dist/__tests__/eval.test.d.ts +2 -0
  24. package/dist/__tests__/eval.test.d.ts.map +1 -0
  25. package/dist/__tests__/eval.test.js +320 -0
  26. package/dist/__tests__/eval.test.js.map +1 -0
  27. package/dist/__tests__/graph.test.d.ts +2 -0
  28. package/dist/__tests__/graph.test.d.ts.map +1 -0
  29. package/dist/__tests__/graph.test.js +169 -0
  30. package/dist/__tests__/graph.test.js.map +1 -0
  31. package/dist/__tests__/health.test.d.ts +2 -0
  32. package/dist/__tests__/health.test.d.ts.map +1 -0
  33. package/dist/__tests__/health.test.js +56 -0
  34. package/dist/__tests__/health.test.js.map +1 -0
  35. package/dist/__tests__/import.test.d.ts +2 -0
  36. package/dist/__tests__/import.test.d.ts.map +1 -0
  37. package/dist/__tests__/import.test.js +138 -0
  38. package/dist/__tests__/import.test.js.map +1 -0
  39. package/dist/__tests__/intent.test.d.ts +2 -0
  40. package/dist/__tests__/intent.test.d.ts.map +1 -0
  41. package/dist/__tests__/intent.test.js +122 -0
  42. package/dist/__tests__/intent.test.js.map +1 -0
  43. package/dist/__tests__/jobs.test.d.ts +2 -0
  44. package/dist/__tests__/jobs.test.d.ts.map +1 -0
  45. package/dist/__tests__/jobs.test.js +96 -0
  46. package/dist/__tests__/jobs.test.js.map +1 -0
  47. package/dist/__tests__/knowledge.test.d.ts +2 -0
  48. package/dist/__tests__/knowledge.test.d.ts.map +1 -0
  49. package/dist/__tests__/knowledge.test.js +110 -0
  50. package/dist/__tests__/knowledge.test.js.map +1 -0
  51. package/dist/__tests__/media-routes.test.d.ts +2 -0
  52. package/dist/__tests__/media-routes.test.d.ts.map +1 -0
  53. package/dist/__tests__/media-routes.test.js +88 -0
  54. package/dist/__tests__/media-routes.test.js.map +1 -0
  55. package/dist/__tests__/schema.test.d.ts +2 -0
  56. package/dist/__tests__/schema.test.d.ts.map +1 -0
  57. package/dist/__tests__/schema.test.js +92 -0
  58. package/dist/__tests__/schema.test.js.map +1 -0
  59. package/dist/app.d.ts +7 -0
  60. package/dist/app.d.ts.map +1 -0
  61. package/dist/app.js +85 -0
  62. package/dist/app.js.map +1 -0
  63. package/dist/engine.d.ts +38 -0
  64. package/dist/engine.d.ts.map +1 -0
  65. package/dist/engine.js +106 -0
  66. package/dist/engine.js.map +1 -0
  67. package/dist/index.d.ts +8 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +9 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/middleware/auth.d.ts +17 -0
  72. package/dist/middleware/auth.d.ts.map +1 -0
  73. package/dist/middleware/auth.js +54 -0
  74. package/dist/middleware/auth.js.map +1 -0
  75. package/dist/middleware/cors.d.ts +2 -0
  76. package/dist/middleware/cors.d.ts.map +1 -0
  77. package/dist/middleware/cors.js +13 -0
  78. package/dist/middleware/cors.js.map +1 -0
  79. package/dist/middleware/error-handler.d.ts +24 -0
  80. package/dist/middleware/error-handler.d.ts.map +1 -0
  81. package/dist/middleware/error-handler.js +30 -0
  82. package/dist/middleware/error-handler.js.map +1 -0
  83. package/dist/middleware/index.d.ts +7 -0
  84. package/dist/middleware/index.d.ts.map +1 -0
  85. package/dist/middleware/index.js +5 -0
  86. package/dist/middleware/index.js.map +1 -0
  87. package/dist/middleware/rate-limit.d.ts +11 -0
  88. package/dist/middleware/rate-limit.d.ts.map +1 -0
  89. package/dist/middleware/rate-limit.js +26 -0
  90. package/dist/middleware/rate-limit.js.map +1 -0
  91. package/dist/middleware/route-error-handler.d.ts +12 -0
  92. package/dist/middleware/route-error-handler.d.ts.map +1 -0
  93. package/dist/middleware/route-error-handler.js +9 -0
  94. package/dist/middleware/route-error-handler.js.map +1 -0
  95. package/dist/routes/approval.d.ts +4 -0
  96. package/dist/routes/approval.d.ts.map +1 -0
  97. package/dist/routes/approval.js +70 -0
  98. package/dist/routes/approval.js.map +1 -0
  99. package/dist/routes/content.d.ts +4 -0
  100. package/dist/routes/content.d.ts.map +1 -0
  101. package/dist/routes/content.js +145 -0
  102. package/dist/routes/content.js.map +1 -0
  103. package/dist/routes/eval.d.ts +4 -0
  104. package/dist/routes/eval.d.ts.map +1 -0
  105. package/dist/routes/eval.js +178 -0
  106. package/dist/routes/eval.js.map +1 -0
  107. package/dist/routes/graph.d.ts +4 -0
  108. package/dist/routes/graph.d.ts.map +1 -0
  109. package/dist/routes/graph.js +90 -0
  110. package/dist/routes/graph.js.map +1 -0
  111. package/dist/routes/health.d.ts +13 -0
  112. package/dist/routes/health.d.ts.map +1 -0
  113. package/dist/routes/health.js +19 -0
  114. package/dist/routes/health.js.map +1 -0
  115. package/dist/routes/import.d.ts +4 -0
  116. package/dist/routes/import.d.ts.map +1 -0
  117. package/dist/routes/import.js +85 -0
  118. package/dist/routes/import.js.map +1 -0
  119. package/dist/routes/index.d.ts +12 -0
  120. package/dist/routes/index.d.ts.map +1 -0
  121. package/dist/routes/index.js +12 -0
  122. package/dist/routes/index.js.map +1 -0
  123. package/dist/routes/intent.d.ts +4 -0
  124. package/dist/routes/intent.d.ts.map +1 -0
  125. package/dist/routes/intent.js +80 -0
  126. package/dist/routes/intent.js.map +1 -0
  127. package/dist/routes/jobs.d.ts +4 -0
  128. package/dist/routes/jobs.d.ts.map +1 -0
  129. package/dist/routes/jobs.js +67 -0
  130. package/dist/routes/jobs.js.map +1 -0
  131. package/dist/routes/knowledge.d.ts +4 -0
  132. package/dist/routes/knowledge.d.ts.map +1 -0
  133. package/dist/routes/knowledge.js +48 -0
  134. package/dist/routes/knowledge.js.map +1 -0
  135. package/dist/routes/media.d.ts +4 -0
  136. package/dist/routes/media.d.ts.map +1 -0
  137. package/dist/routes/media.js +87 -0
  138. package/dist/routes/media.js.map +1 -0
  139. package/dist/routes/schema.d.ts +4 -0
  140. package/dist/routes/schema.d.ts.map +1 -0
  141. package/dist/routes/schema.js +54 -0
  142. package/dist/routes/schema.js.map +1 -0
  143. package/dist/standalone.d.ts +2 -0
  144. package/dist/standalone.d.ts.map +1 -0
  145. package/dist/standalone.js +115 -0
  146. package/dist/standalone.js.map +1 -0
  147. package/package.json +36 -0
  148. package/src/__tests__/app-integration.test.ts +80 -0
  149. package/src/__tests__/approval.test.ts +195 -0
  150. package/src/__tests__/content.test.ts +202 -0
  151. package/src/__tests__/engine.test.ts +86 -0
  152. package/src/__tests__/eval.test.ts +343 -0
  153. package/src/__tests__/graph.test.ts +182 -0
  154. package/src/__tests__/health.test.ts +68 -0
  155. package/src/__tests__/import.test.ts +148 -0
  156. package/src/__tests__/intent.test.ts +133 -0
  157. package/src/__tests__/jobs.test.ts +107 -0
  158. package/src/__tests__/knowledge.test.ts +121 -0
  159. package/src/__tests__/media-routes.test.ts +109 -0
  160. package/src/__tests__/schema.test.ts +100 -0
  161. package/src/app.ts +92 -0
  162. package/src/engine.ts +168 -0
  163. package/src/index.ts +31 -0
  164. package/src/middleware/auth.ts +66 -0
  165. package/src/middleware/cors.ts +15 -0
  166. package/src/middleware/error-handler.ts +42 -0
  167. package/src/middleware/index.ts +6 -0
  168. package/src/middleware/rate-limit.ts +27 -0
  169. package/src/middleware/route-error-handler.ts +13 -0
  170. package/src/routes/approval.ts +90 -0
  171. package/src/routes/content.ts +256 -0
  172. package/src/routes/eval.ts +262 -0
  173. package/src/routes/graph.ts +111 -0
  174. package/src/routes/health.ts +33 -0
  175. package/src/routes/import.ts +122 -0
  176. package/src/routes/index.ts +11 -0
  177. package/src/routes/intent.ts +105 -0
  178. package/src/routes/jobs.ts +84 -0
  179. package/src/routes/knowledge.ts +73 -0
  180. package/src/routes/media.ts +117 -0
  181. package/src/routes/schema.ts +75 -0
  182. package/src/standalone.ts +130 -0
  183. package/tsconfig.json +8 -0
  184. package/vitest.config.ts +7 -0
@@ -0,0 +1,2 @@
1
+ {"t":0,"agent":"a5b0959","agent_type":"executor","event":"agent_start","parent_mode":"none"}
2
+ {"t":0,"agent":"a5b0959","agent_type":"executor","event":"agent_stop","success":true,"duration_ms":123831}
@@ -0,0 +1,7 @@
1
+ {
2
+ "tool_name": "Bash",
3
+ "tool_input_preview": "{\"command\":\"git add packages/server/ pnpm-lock.yaml && git commit -m \\\"$(cat <<'EOF'\\nfeat(server): add media and job API routes\\n\\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>...",
4
+ "error": "Exit code 128\nfatal: pathspec 'packages/server/' did not match any files",
5
+ "timestamp": "2026-04-04T20:23:16.081Z",
6
+ "retry_count": 1
7
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "updatedAt": "2026-04-04T20:23:10.366Z",
3
+ "missions": [
4
+ {
5
+ "id": "session:31d84b63-606a-4368-b9e6-93fe4f5ae0f7:none",
6
+ "source": "session",
7
+ "name": "none",
8
+ "objective": "Session mission",
9
+ "createdAt": "2026-04-04T20:21:06.535Z",
10
+ "updatedAt": "2026-04-04T20:23:10.366Z",
11
+ "status": "done",
12
+ "workerCount": 1,
13
+ "taskCounts": {
14
+ "total": 1,
15
+ "pending": 0,
16
+ "blocked": 0,
17
+ "inProgress": 0,
18
+ "completed": 1,
19
+ "failed": 0
20
+ },
21
+ "agents": [
22
+ {
23
+ "name": "executor:a5b0959",
24
+ "role": "executor",
25
+ "ownership": "a5b09596248675932",
26
+ "status": "done",
27
+ "currentStep": null,
28
+ "latestUpdate": "completed",
29
+ "completedSummary": null,
30
+ "updatedAt": "2026-04-04T20:23:10.366Z"
31
+ }
32
+ ],
33
+ "timeline": [
34
+ {
35
+ "id": "session-start:a5b09596248675932:2026-04-04T20:21:06.535Z",
36
+ "at": "2026-04-04T20:21:06.535Z",
37
+ "kind": "update",
38
+ "agent": "executor:a5b0959",
39
+ "detail": "started executor:a5b0959",
40
+ "sourceKey": "session-start:a5b09596248675932"
41
+ },
42
+ {
43
+ "id": "session-stop:a5b09596248675932:2026-04-04T20:23:10.366Z",
44
+ "at": "2026-04-04T20:23:10.366Z",
45
+ "kind": "completion",
46
+ "agent": "executor:a5b0959",
47
+ "detail": "completed",
48
+ "sourceKey": "session-stop:a5b09596248675932"
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "agents": [
3
+ {
4
+ "agent_id": "a5b09596248675932",
5
+ "agent_type": "oh-my-claudecode:executor",
6
+ "started_at": "2026-04-04T20:21:06.535Z",
7
+ "parent_mode": "none",
8
+ "status": "completed",
9
+ "completed_at": "2026-04-04T20:23:10.366Z",
10
+ "duration_ms": 123831
11
+ }
12
+ ],
13
+ "total_spawned": 1,
14
+ "total_completed": 1,
15
+ "total_failed": 0,
16
+ "last_updated": "2026-04-04T20:23:10.469Z"
17
+ }
@@ -0,0 +1,4 @@
1
+
2
+ > @sourcepress/server@0.1.0 build /Users/fabianvontiedemann/Developer/org/sourcepress/packages/server
3
+ > tsc
4
+
@@ -0,0 +1,26 @@
1
+
2
+ > @sourcepress/server@0.1.0 test /Users/fabianvontiedemann/Developer/org/sourcepress/packages/server
3
+ > vitest run
4
+
5
+
6
+ RUN v3.2.4 /Users/fabianvontiedemann/Developer/org/sourcepress/packages/server
7
+
8
+ ✓ src/__tests__/graph.test.ts (7 tests) 17ms
9
+ ✓ src/__tests__/jobs.test.ts (6 tests) 40ms
10
+ ✓ src/__tests__/knowledge.test.ts (5 tests) 11ms
11
+ ✓ src/__tests__/import.test.ts (6 tests) 12ms
12
+ ✓ src/__tests__/media-routes.test.ts (6 tests) 13ms
13
+ ✓ src/__tests__/intent.test.ts (7 tests) 9ms
14
+ ✓ src/__tests__/content.test.ts (10 tests) 19ms
15
+ ✓ src/__tests__/schema.test.ts (3 tests) 8ms
16
+ ✓ src/__tests__/eval.test.ts (17 tests) 18ms
17
+ ✓ src/__tests__/engine.test.ts (4 tests) 2ms
18
+ ✓ src/__tests__/approval.test.ts (7 tests) 9ms
19
+ ✓ src/__tests__/health.test.ts (6 tests) 7ms
20
+ ✓ src/__tests__/app-integration.test.ts (2 tests) 8ms
21
+
22
+ Test Files 13 passed (13)
23
+ Tests 86 passed (86)
24
+ Start at 14:13:19
25
+ Duration 1.19s (transform 590ms, setup 0ms, collect 2.44s, tests 174ms, environment 2ms, prepare 1.39s)
26
+
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/app-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { createApp } from "../app.js";
3
+ function createMinimalMockEngine() {
4
+ return {
5
+ config: {
6
+ intent: { path: "intent/" },
7
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
8
+ },
9
+ github: {
10
+ getTree: vi.fn().mockResolvedValue([]),
11
+ getFile: vi.fn().mockResolvedValue(null),
12
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
13
+ },
14
+ knowledge: {
15
+ getGraph: vi.fn().mockReturnValue(null),
16
+ query: vi.fn().mockReturnValue(null),
17
+ findStale: vi.fn().mockReturnValue([]),
18
+ findGaps: vi.fn().mockReturnValue([]),
19
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
20
+ },
21
+ knowledgeStore: {
22
+ list: vi.fn().mockResolvedValue([]),
23
+ retrieve: vi.fn().mockResolvedValue(null),
24
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
25
+ },
26
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
27
+ cache: {},
28
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
29
+ budget: {},
30
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
31
+ provider: {},
32
+ listContent: vi.fn().mockResolvedValue([]),
33
+ getContent: vi.fn().mockResolvedValue(null),
34
+ getCollectionDef: vi.fn().mockReturnValue(null),
35
+ listCollections: vi.fn().mockReturnValue([]),
36
+ };
37
+ }
38
+ describe("Full app integration", () => {
39
+ it("creates app without engine (health-only mode)", async () => {
40
+ const app = createApp();
41
+ const res = await app.request("/api/health");
42
+ expect(res.status).toBe(200);
43
+ });
44
+ it("creates app with engine (all routes)", async () => {
45
+ const engine = createMinimalMockEngine();
46
+ const app = createApp(engine);
47
+ // Health works
48
+ const health = await app.request("/api/health");
49
+ expect(health.status).toBe(200);
50
+ // Schema works (empty)
51
+ const schema = await app.request("/api/schema");
52
+ expect(schema.status).toBe(200);
53
+ const schemaBody = (await schema.json());
54
+ expect(schemaBody.total).toBe(0);
55
+ // Knowledge works (empty)
56
+ const knowledge = await app.request("/api/knowledge");
57
+ expect(knowledge.status).toBe(200);
58
+ // Graph works (empty)
59
+ const graph = await app.request("/api/graph");
60
+ expect(graph.status).toBe(200);
61
+ const graphBody = (await graph.json());
62
+ expect(graphBody.status).toBe("empty");
63
+ // Content works (empty)
64
+ const content = await app.request("/api/content");
65
+ expect(content.status).toBe(200);
66
+ // Intent works (empty)
67
+ const intent = await app.request("/api/intent");
68
+ expect(intent.status).toBe(200);
69
+ });
70
+ });
71
+ //# sourceMappingURL=app-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/app-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=approval.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/approval.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,170 @@
1
+ import { Hono } from "hono";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { errorHandler } from "../middleware/error-handler.js";
4
+ import { approvalRoutes } from "../routes/approval.js";
5
+ const mockRequest = {
6
+ id: "42",
7
+ change: {
8
+ collection: "posts",
9
+ slug: "my-post",
10
+ path: "content/posts/my-post.md",
11
+ action: "create",
12
+ content: "# Hello",
13
+ frontmatter: { title: "My Post" },
14
+ provenance: {
15
+ generated_by: "claude-3-5-sonnet",
16
+ generated_at: "2026-04-04T10:00:00Z",
17
+ source_files: [],
18
+ prompt_version: "v1",
19
+ },
20
+ },
21
+ status: "pending",
22
+ submitted_at: "2026-04-04T10:00:00Z",
23
+ submitted_by: "claude-3-5-sonnet",
24
+ pr_url: "https://github.com/org/repo/pull/42",
25
+ pr_number: 42,
26
+ };
27
+ function createMockApproval() {
28
+ return {
29
+ submit: vi.fn().mockResolvedValue(mockRequest),
30
+ status: vi.fn().mockResolvedValue("pending"),
31
+ approve: vi.fn().mockResolvedValue(undefined),
32
+ reject: vi.fn().mockResolvedValue(undefined),
33
+ pending: vi.fn().mockResolvedValue([mockRequest]),
34
+ onStatusChange: vi.fn(),
35
+ };
36
+ }
37
+ function createMockEngine(withApproval = true) {
38
+ const approval = withApproval ? createMockApproval() : undefined;
39
+ const github = {
40
+ createOrUpdateFile: vi.fn().mockResolvedValue(undefined),
41
+ };
42
+ const config = {
43
+ approval: {
44
+ provider: "github-pr",
45
+ rules: {
46
+ "content/posts/*": "pr",
47
+ "content/pages/*": "direct",
48
+ },
49
+ },
50
+ collections: {},
51
+ repository: { owner: "org", repo: "repo", branch: "main" },
52
+ ai: { provider: "anthropic", model: "claude-3-5-sonnet", daily_limit_usd: 5 },
53
+ };
54
+ return { approval, github, config };
55
+ }
56
+ function createTestApp(engine) {
57
+ const app = new Hono().basePath("/api");
58
+ app.use("*", errorHandler());
59
+ app.route("/", approvalRoutes(engine));
60
+ return app;
61
+ }
62
+ describe("Approval routes", () => {
63
+ let engine;
64
+ let app;
65
+ beforeEach(() => {
66
+ engine = createMockEngine();
67
+ app = createTestApp(engine);
68
+ });
69
+ it("GET /api/approval/pending returns pending items", async () => {
70
+ const res = await app.request("/api/approval/pending");
71
+ expect(res.status).toBe(200);
72
+ const body = (await res.json());
73
+ expect(body.total).toBe(1);
74
+ const items = body.items;
75
+ expect(items[0].id).toBe("42");
76
+ });
77
+ it("POST /api/approval with 'pr' rule creates approval request", async () => {
78
+ const change = {
79
+ collection: "posts",
80
+ slug: "my-post",
81
+ path: "content/posts/my-post.md",
82
+ action: "create",
83
+ content: "# Hello",
84
+ frontmatter: { title: "My Post" },
85
+ provenance: {
86
+ generated_by: "claude-3-5-sonnet",
87
+ generated_at: "2026-04-04T10:00:00Z",
88
+ source_files: [],
89
+ prompt_version: "v1",
90
+ },
91
+ };
92
+ const res = await app.request("/api/approval", {
93
+ method: "POST",
94
+ headers: { "Content-Type": "application/json" },
95
+ body: JSON.stringify(change),
96
+ });
97
+ expect(res.status).toBe(201);
98
+ const body = (await res.json());
99
+ expect(body.status).toBe("pending");
100
+ expect(body.pr_number).toBe(42);
101
+ expect(engine.approval?.submit).toHaveBeenCalledWith(change);
102
+ });
103
+ it("POST /api/approval with 'direct' rule commits directly", async () => {
104
+ const change = {
105
+ collection: "pages",
106
+ slug: "about",
107
+ path: "content/pages/about.md",
108
+ action: "create",
109
+ content: "# About",
110
+ frontmatter: { title: "About" },
111
+ provenance: {
112
+ generated_by: "claude-3-5-sonnet",
113
+ generated_at: "2026-04-04T10:00:00Z",
114
+ source_files: [],
115
+ prompt_version: "v1",
116
+ },
117
+ };
118
+ const res = await app.request("/api/approval", {
119
+ method: "POST",
120
+ headers: { "Content-Type": "application/json" },
121
+ body: JSON.stringify(change),
122
+ });
123
+ expect(res.status).toBe(201);
124
+ const body = (await res.json());
125
+ expect(body.status).toBe("direct");
126
+ expect(body.path).toBe("content/pages/about.md");
127
+ expect(engine.approval?.submit).not.toHaveBeenCalled();
128
+ });
129
+ it("POST /api/approval/:id/approve calls provider.approve", async () => {
130
+ const res = await app.request("/api/approval/42/approve", {
131
+ method: "POST",
132
+ headers: { "Content-Type": "application/json" },
133
+ body: JSON.stringify({ by: "editor@example.com", comment: "Looks good!" }),
134
+ });
135
+ expect(res.status).toBe(200);
136
+ const body = (await res.json());
137
+ expect(body.status).toBe("approved");
138
+ expect(engine.approval?.approve).toHaveBeenCalledWith("42", "editor@example.com", "Looks good!");
139
+ });
140
+ it("POST /api/approval/:id/reject calls provider.reject", async () => {
141
+ const res = await app.request("/api/approval/42/reject", {
142
+ method: "POST",
143
+ headers: { "Content-Type": "application/json" },
144
+ body: JSON.stringify({ by: "editor@example.com", reason: "Needs revision" }),
145
+ });
146
+ expect(res.status).toBe(200);
147
+ const body = (await res.json());
148
+ expect(body.status).toBe("rejected");
149
+ expect(engine.approval?.reject).toHaveBeenCalledWith("42", "editor@example.com", "Needs revision");
150
+ });
151
+ it("returns 501 when approval not configured", async () => {
152
+ const noApprovalEngine = createMockEngine(false);
153
+ const noApprovalApp = createTestApp(noApprovalEngine);
154
+ const res = await noApprovalApp.request("/api/approval/pending");
155
+ expect(res.status).toBe(501);
156
+ const body = (await res.json());
157
+ expect(body.code).toBe("APPROVAL_NOT_CONFIGURED");
158
+ });
159
+ it("POST /api/approval validates required fields", async () => {
160
+ const res = await app.request("/api/approval", {
161
+ method: "POST",
162
+ headers: { "Content-Type": "application/json" },
163
+ body: JSON.stringify({ collection: "posts" }),
164
+ });
165
+ expect(res.status).toBe(400);
166
+ const body = (await res.json());
167
+ expect(body.code).toBe("INVALID_INPUT");
168
+ });
169
+ });
170
+ //# sourceMappingURL=approval.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.test.js","sourceRoot":"","sources":["../../src/__tests__/approval.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=content.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/content.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,187 @@
1
+ import { Hono } from "hono";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { errorHandler } from "../middleware/error-handler.js";
4
+ import { contentRoutes } from "../routes/content.js";
5
+ const mockPosts = [
6
+ {
7
+ collection: "posts",
8
+ slug: "hello-world",
9
+ path: "content/posts/hello-world.mdx",
10
+ frontmatter: { title: "Hello World", draft: false },
11
+ body: "# Hello World\n\nThis is a test post.",
12
+ },
13
+ {
14
+ collection: "posts",
15
+ slug: "second-post",
16
+ path: "content/posts/second-post.mdx",
17
+ frontmatter: { title: "Second Post", draft: true },
18
+ body: "# Second Post\n\nAnother post.",
19
+ },
20
+ ];
21
+ const mockCollections = {
22
+ posts: {
23
+ name: "Blog Posts",
24
+ path: "content/posts",
25
+ format: "mdx",
26
+ fields: { title: { type: "string", required: true } },
27
+ },
28
+ };
29
+ function createMockEngine() {
30
+ return {
31
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
32
+ config: {},
33
+ github: {
34
+ createBranch: vi.fn().mockResolvedValue("abc123"),
35
+ createOrUpdateFile: vi.fn().mockResolvedValue({ sha: "def456", commit_sha: "ghi789" }),
36
+ createPR: vi
37
+ .fn()
38
+ .mockResolvedValue({ number: 42, html_url: "https://github.com/test/pr/42" }),
39
+ getFile: vi.fn().mockResolvedValue({ sha: "existing-sha" }),
40
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
41
+ },
42
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
43
+ knowledge: {},
44
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
45
+ knowledgeStore: {},
46
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
47
+ cache: {},
48
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
49
+ budget: {},
50
+ // biome-ignore lint/suspicious/noExplicitAny: partial mock of EngineContext
51
+ provider: {},
52
+ listContent: vi.fn().mockImplementation(async (collection) => {
53
+ if (collection === "posts")
54
+ return mockPosts;
55
+ return [];
56
+ }),
57
+ getContent: vi.fn().mockImplementation(async (collection, slug) => {
58
+ if (collection === "posts")
59
+ return mockPosts.find((p) => p.slug === slug) ?? null;
60
+ return null;
61
+ }),
62
+ getCollectionDef: vi.fn().mockImplementation((collection) => {
63
+ return mockCollections[collection] ?? null;
64
+ }),
65
+ listCollections: vi.fn().mockReturnValue(["posts"]),
66
+ };
67
+ }
68
+ function createTestApp(engine) {
69
+ const app = new Hono().basePath("/api");
70
+ app.use("*", errorHandler());
71
+ app.route("/", contentRoutes(engine));
72
+ return app;
73
+ }
74
+ describe("Content routes", () => {
75
+ let engine;
76
+ let app;
77
+ beforeEach(() => {
78
+ engine = createMockEngine();
79
+ app = createTestApp(engine);
80
+ });
81
+ describe("GET /api/content", () => {
82
+ it("returns all content across collections", async () => {
83
+ const res = await app.request("/api/content");
84
+ expect(res.status).toBe(200);
85
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
86
+ const body = (await res.json());
87
+ expect(body.total).toBe(2);
88
+ expect(body.items[0].slug).toBe("hello-world");
89
+ });
90
+ });
91
+ describe("GET /api/content/:collection", () => {
92
+ it("returns content for a valid collection", async () => {
93
+ const res = await app.request("/api/content/posts");
94
+ expect(res.status).toBe(200);
95
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
96
+ const body = (await res.json());
97
+ expect(body.total).toBe(2);
98
+ expect(body.collection.name).toBe("Blog Posts");
99
+ });
100
+ it("returns 404 for unknown collection", async () => {
101
+ const res = await app.request("/api/content/unknown");
102
+ expect(res.status).toBe(404);
103
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
104
+ const body = (await res.json());
105
+ expect(body.code).toBe("COLLECTION_NOT_FOUND");
106
+ });
107
+ });
108
+ describe("GET /api/content/:collection/:slug", () => {
109
+ it("returns a single content file", async () => {
110
+ const res = await app.request("/api/content/posts/hello-world");
111
+ expect(res.status).toBe(200);
112
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
113
+ const body = (await res.json());
114
+ expect(body.slug).toBe("hello-world");
115
+ expect(body.body).toContain("Hello World");
116
+ });
117
+ it("returns 404 for unknown slug", async () => {
118
+ const res = await app.request("/api/content/posts/nonexistent");
119
+ expect(res.status).toBe(404);
120
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
121
+ const body = (await res.json());
122
+ expect(body.code).toBe("CONTENT_NOT_FOUND");
123
+ });
124
+ });
125
+ describe("POST /api/content/:collection", () => {
126
+ it("creates content and returns PR", async () => {
127
+ const res = await app.request("/api/content/posts", {
128
+ method: "POST",
129
+ headers: { "Content-Type": "application/json" },
130
+ body: JSON.stringify({
131
+ slug: "new-post",
132
+ frontmatter: { title: "New Post" },
133
+ body: "# New Post\n\nContent here.",
134
+ }),
135
+ });
136
+ expect(res.status).toBe(201);
137
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
138
+ const body = (await res.json());
139
+ expect(body.created).toBe(true);
140
+ expect(body.pr.number).toBe(42);
141
+ });
142
+ it("returns 400 for missing slug", async () => {
143
+ const res = await app.request("/api/content/posts", {
144
+ method: "POST",
145
+ headers: { "Content-Type": "application/json" },
146
+ body: JSON.stringify({ body: "content" }),
147
+ });
148
+ expect(res.status).toBe(400);
149
+ });
150
+ });
151
+ describe("PUT /api/content/:collection/:slug", () => {
152
+ it("updates content and returns PR", async () => {
153
+ const res = await app.request("/api/content/posts/hello-world", {
154
+ method: "PUT",
155
+ headers: { "Content-Type": "application/json" },
156
+ body: JSON.stringify({
157
+ frontmatter: { title: "Updated Title" },
158
+ body: "# Updated\n\nNew content.",
159
+ }),
160
+ });
161
+ expect(res.status).toBe(200);
162
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
163
+ const body = (await res.json());
164
+ expect(body.updated).toBe(true);
165
+ expect(body.pr.number).toBe(42);
166
+ });
167
+ });
168
+ describe("DELETE /api/content/:collection/:slug", () => {
169
+ it("deletes content and returns PR", async () => {
170
+ const res = await app.request("/api/content/posts/hello-world", {
171
+ method: "DELETE",
172
+ });
173
+ expect(res.status).toBe(200);
174
+ // biome-ignore lint/suspicious/noExplicitAny: typed JSON response parsing in tests
175
+ const body = (await res.json());
176
+ expect(body.deleted).toBe(true);
177
+ expect(body.pr.number).toBe(42);
178
+ });
179
+ it("returns 404 for unknown slug", async () => {
180
+ const res = await app.request("/api/content/posts/nonexistent", {
181
+ method: "DELETE",
182
+ });
183
+ expect(res.status).toBe(404);
184
+ });
185
+ });
186
+ });
187
+ //# sourceMappingURL=content.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.test.js","sourceRoot":"","sources":["../../src/__tests__/content.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,SAAS,GAAkB;IAChC;QACC,UAAU,EAAE,OAAO;QACnB,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,+BAA+B;QACrC,WAAW,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE;QACnD,IAAI,EAAE,uCAAuC;KAC7C;IACD;QACC,UAAU,EAAE,OAAO;QACnB,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,+BAA+B;QACrC,WAAW,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE;QAClD,IAAI,EAAE,gCAAgC;KACtC;CACD,CAAC;AAEF,MAAM,eAAe,GAAyC;IAC7D,KAAK,EAAE;QACN,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,eAAe;QACrB,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;KACrD;CACD,CAAC;AAEF,SAAS,gBAAgB;IACxB,OAAO;QACN,4EAA4E;QAC5E,MAAM,EAAE,EAAS;QACjB,MAAM,EAAE;YACP,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YACjD,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;YACtF,QAAQ,EAAE,EAAE;iBACV,EAAE,EAAE;iBACJ,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,+BAA+B,EAAE,CAAC;YAC9E,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,CAAC;YAC3D,4EAA4E;SACrE;QACR,4EAA4E;QAC5E,SAAS,EAAE,EAAS;QACpB,4EAA4E;QAC5E,cAAc,EAAE,EAAS;QACzB,4EAA4E;QAC5E,KAAK,EAAE,EAAS;QAChB,4EAA4E;QAC5E,MAAM,EAAE,EAAS;QACjB,4EAA4E;QAC5E,QAAQ,EAAE,EAAS;QACnB,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAkB,EAAE,EAAE;YACpE,IAAI,UAAU,KAAK,OAAO;gBAAE,OAAO,SAAS,CAAC;YAC7C,OAAO,EAAE,CAAC;QACX,CAAC,CAAC;QACF,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAkB,EAAE,IAAY,EAAE,EAAE;YACjF,IAAI,UAAU,KAAK,OAAO;gBAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;YAClF,OAAO,IAAI,CAAC;QACb,CAAC,CAAC;QACF,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,UAAkB,EAAE,EAAE;YACnE,OAAO,eAAe,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;QAC5C,CAAC,CAAC;QACF,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC;KACnD,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,MAAqB;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC;IAC7B,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC/B,IAAI,MAAqB,CAAC;IAC1B,IAAI,GAAS,CAAC;IAEd,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAC5B,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;QAC7C,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACvD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACpD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YACtD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QACnD,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;YAC9C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAChE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAChE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC9C,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACpB,IAAI,EAAE,UAAU;oBAChB,WAAW,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;oBAClC,IAAI,EAAE,6BAA6B;iBACnC,CAAC;aACF,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;aACzC,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;QACnD,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE;gBAC/D,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACpB,WAAW,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE;oBACvC,IAAI,EAAE,2BAA2B;iBACjC,CAAC;aACF,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;QACtD,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE;gBAC/D,MAAM,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,mFAAmF;YACnF,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE;gBAC/D,MAAM,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=engine.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/engine.test.ts"],"names":[],"mappings":""}