@auto-engineer/pipeline 0.0.1

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 (270) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/LICENSE +10 -0
  3. package/claude.md +160 -0
  4. package/dist/src/builder/define.d.ts +90 -0
  5. package/dist/src/builder/define.d.ts.map +1 -0
  6. package/dist/src/builder/define.js +425 -0
  7. package/dist/src/builder/define.js.map +1 -0
  8. package/dist/src/builder/define.specs.d.ts +2 -0
  9. package/dist/src/builder/define.specs.d.ts.map +1 -0
  10. package/dist/src/builder/define.specs.js +435 -0
  11. package/dist/src/builder/define.specs.js.map +1 -0
  12. package/dist/src/config/pipeline-config.d.ts +13 -0
  13. package/dist/src/config/pipeline-config.d.ts.map +1 -0
  14. package/dist/src/config/pipeline-config.js +15 -0
  15. package/dist/src/config/pipeline-config.js.map +1 -0
  16. package/dist/src/core/descriptors.d.ts +84 -0
  17. package/dist/src/core/descriptors.d.ts.map +1 -0
  18. package/dist/src/core/descriptors.js +2 -0
  19. package/dist/src/core/descriptors.js.map +1 -0
  20. package/dist/src/core/descriptors.specs.d.ts +2 -0
  21. package/dist/src/core/descriptors.specs.d.ts.map +1 -0
  22. package/dist/src/core/descriptors.specs.js +24 -0
  23. package/dist/src/core/descriptors.specs.js.map +1 -0
  24. package/dist/src/core/types.d.ts +10 -0
  25. package/dist/src/core/types.d.ts.map +1 -0
  26. package/dist/src/core/types.js +4 -0
  27. package/dist/src/core/types.js.map +1 -0
  28. package/dist/src/core/types.specs.d.ts +2 -0
  29. package/dist/src/core/types.specs.d.ts.map +1 -0
  30. package/dist/src/core/types.specs.js +40 -0
  31. package/dist/src/core/types.specs.js.map +1 -0
  32. package/dist/src/graph/types.d.ts +17 -0
  33. package/dist/src/graph/types.d.ts.map +1 -0
  34. package/dist/src/graph/types.js +2 -0
  35. package/dist/src/graph/types.js.map +1 -0
  36. package/dist/src/graph/types.specs.d.ts +2 -0
  37. package/dist/src/graph/types.specs.d.ts.map +1 -0
  38. package/dist/src/graph/types.specs.js +148 -0
  39. package/dist/src/graph/types.specs.js.map +1 -0
  40. package/dist/src/index.d.ts +20 -0
  41. package/dist/src/index.d.ts.map +1 -0
  42. package/dist/src/index.js +12 -0
  43. package/dist/src/index.js.map +1 -0
  44. package/dist/src/logging/event-logger.d.ts +21 -0
  45. package/dist/src/logging/event-logger.d.ts.map +1 -0
  46. package/dist/src/logging/event-logger.js +31 -0
  47. package/dist/src/logging/event-logger.js.map +1 -0
  48. package/dist/src/logging/event-logger.specs.d.ts +2 -0
  49. package/dist/src/logging/event-logger.specs.d.ts.map +1 -0
  50. package/dist/src/logging/event-logger.specs.js +81 -0
  51. package/dist/src/logging/event-logger.specs.js.map +1 -0
  52. package/dist/src/plugins/handler-adapter.d.ts +5 -0
  53. package/dist/src/plugins/handler-adapter.d.ts.map +1 -0
  54. package/dist/src/plugins/handler-adapter.js +17 -0
  55. package/dist/src/plugins/handler-adapter.js.map +1 -0
  56. package/dist/src/plugins/handler-adapter.specs.d.ts +2 -0
  57. package/dist/src/plugins/handler-adapter.specs.d.ts.map +1 -0
  58. package/dist/src/plugins/handler-adapter.specs.js +129 -0
  59. package/dist/src/plugins/handler-adapter.specs.js.map +1 -0
  60. package/dist/src/plugins/plugin-loader.d.ts +25 -0
  61. package/dist/src/plugins/plugin-loader.d.ts.map +1 -0
  62. package/dist/src/plugins/plugin-loader.js +150 -0
  63. package/dist/src/plugins/plugin-loader.js.map +1 -0
  64. package/dist/src/plugins/plugin-loader.specs.d.ts +2 -0
  65. package/dist/src/plugins/plugin-loader.specs.d.ts.map +1 -0
  66. package/dist/src/plugins/plugin-loader.specs.js +246 -0
  67. package/dist/src/plugins/plugin-loader.specs.js.map +1 -0
  68. package/dist/src/runtime/await-tracker.d.ts +10 -0
  69. package/dist/src/runtime/await-tracker.d.ts.map +1 -0
  70. package/dist/src/runtime/await-tracker.js +42 -0
  71. package/dist/src/runtime/await-tracker.js.map +1 -0
  72. package/dist/src/runtime/await-tracker.specs.d.ts +2 -0
  73. package/dist/src/runtime/await-tracker.specs.d.ts.map +1 -0
  74. package/dist/src/runtime/await-tracker.specs.js +46 -0
  75. package/dist/src/runtime/await-tracker.specs.js.map +1 -0
  76. package/dist/src/runtime/context.d.ts +12 -0
  77. package/dist/src/runtime/context.d.ts.map +1 -0
  78. package/dist/src/runtime/context.js +2 -0
  79. package/dist/src/runtime/context.js.map +1 -0
  80. package/dist/src/runtime/context.specs.d.ts +2 -0
  81. package/dist/src/runtime/context.specs.d.ts.map +1 -0
  82. package/dist/src/runtime/context.specs.js +26 -0
  83. package/dist/src/runtime/context.specs.js.map +1 -0
  84. package/dist/src/runtime/event-command-map.d.ts +15 -0
  85. package/dist/src/runtime/event-command-map.d.ts.map +1 -0
  86. package/dist/src/runtime/event-command-map.js +26 -0
  87. package/dist/src/runtime/event-command-map.js.map +1 -0
  88. package/dist/src/runtime/event-command-map.specs.d.ts +2 -0
  89. package/dist/src/runtime/event-command-map.specs.d.ts.map +1 -0
  90. package/dist/src/runtime/event-command-map.specs.js +108 -0
  91. package/dist/src/runtime/event-command-map.specs.js.map +1 -0
  92. package/dist/src/runtime/phased-executor.d.ts +29 -0
  93. package/dist/src/runtime/phased-executor.d.ts.map +1 -0
  94. package/dist/src/runtime/phased-executor.js +164 -0
  95. package/dist/src/runtime/phased-executor.js.map +1 -0
  96. package/dist/src/runtime/phased-executor.specs.d.ts +2 -0
  97. package/dist/src/runtime/phased-executor.specs.d.ts.map +1 -0
  98. package/dist/src/runtime/phased-executor.specs.js +256 -0
  99. package/dist/src/runtime/phased-executor.specs.js.map +1 -0
  100. package/dist/src/runtime/pipeline-runtime.d.ts +17 -0
  101. package/dist/src/runtime/pipeline-runtime.d.ts.map +1 -0
  102. package/dist/src/runtime/pipeline-runtime.js +87 -0
  103. package/dist/src/runtime/pipeline-runtime.js.map +1 -0
  104. package/dist/src/runtime/pipeline-runtime.specs.d.ts +2 -0
  105. package/dist/src/runtime/pipeline-runtime.specs.d.ts.map +1 -0
  106. package/dist/src/runtime/pipeline-runtime.specs.js +192 -0
  107. package/dist/src/runtime/pipeline-runtime.specs.js.map +1 -0
  108. package/dist/src/runtime/settled-tracker.d.ts +42 -0
  109. package/dist/src/runtime/settled-tracker.d.ts.map +1 -0
  110. package/dist/src/runtime/settled-tracker.js +161 -0
  111. package/dist/src/runtime/settled-tracker.js.map +1 -0
  112. package/dist/src/runtime/settled-tracker.specs.d.ts +2 -0
  113. package/dist/src/runtime/settled-tracker.specs.d.ts.map +1 -0
  114. package/dist/src/runtime/settled-tracker.specs.js +361 -0
  115. package/dist/src/runtime/settled-tracker.specs.js.map +1 -0
  116. package/dist/src/server/full-orchestration.e2e.specs.d.ts +2 -0
  117. package/dist/src/server/full-orchestration.e2e.specs.d.ts.map +1 -0
  118. package/dist/src/server/full-orchestration.e2e.specs.js +561 -0
  119. package/dist/src/server/full-orchestration.e2e.specs.js.map +1 -0
  120. package/dist/src/server/pipeline-server.d.ts +59 -0
  121. package/dist/src/server/pipeline-server.d.ts.map +1 -0
  122. package/dist/src/server/pipeline-server.e2e.specs.d.ts +2 -0
  123. package/dist/src/server/pipeline-server.e2e.specs.d.ts.map +1 -0
  124. package/dist/src/server/pipeline-server.e2e.specs.js +381 -0
  125. package/dist/src/server/pipeline-server.e2e.specs.js.map +1 -0
  126. package/dist/src/server/pipeline-server.js +527 -0
  127. package/dist/src/server/pipeline-server.js.map +1 -0
  128. package/dist/src/server/pipeline-server.specs.d.ts +2 -0
  129. package/dist/src/server/pipeline-server.specs.d.ts.map +1 -0
  130. package/dist/src/server/pipeline-server.specs.js +662 -0
  131. package/dist/src/server/pipeline-server.specs.js.map +1 -0
  132. package/dist/src/server/sse-manager.d.ts +12 -0
  133. package/dist/src/server/sse-manager.d.ts.map +1 -0
  134. package/dist/src/server/sse-manager.js +63 -0
  135. package/dist/src/server/sse-manager.js.map +1 -0
  136. package/dist/src/server/sse-manager.specs.d.ts +2 -0
  137. package/dist/src/server/sse-manager.specs.d.ts.map +1 -0
  138. package/dist/src/server/sse-manager.specs.js +158 -0
  139. package/dist/src/server/sse-manager.specs.js.map +1 -0
  140. package/dist/src/testing/event-capture.d.ts +14 -0
  141. package/dist/src/testing/event-capture.d.ts.map +1 -0
  142. package/dist/src/testing/event-capture.js +55 -0
  143. package/dist/src/testing/event-capture.js.map +1 -0
  144. package/dist/src/testing/event-capture.specs.d.ts +2 -0
  145. package/dist/src/testing/event-capture.specs.d.ts.map +1 -0
  146. package/dist/src/testing/event-capture.specs.js +114 -0
  147. package/dist/src/testing/event-capture.specs.js.map +1 -0
  148. package/dist/src/testing/fixtures/kanban-full.pipeline.d.ts +7 -0
  149. package/dist/src/testing/fixtures/kanban-full.pipeline.d.ts.map +1 -0
  150. package/dist/src/testing/fixtures/kanban-full.pipeline.js +168 -0
  151. package/dist/src/testing/fixtures/kanban-full.pipeline.js.map +1 -0
  152. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.d.ts +2 -0
  153. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.d.ts.map +1 -0
  154. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.js +263 -0
  155. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.js.map +1 -0
  156. package/dist/src/testing/fixtures/kanban-todo.config.d.ts +3 -0
  157. package/dist/src/testing/fixtures/kanban-todo.config.d.ts.map +1 -0
  158. package/dist/src/testing/fixtures/kanban-todo.config.js +19 -0
  159. package/dist/src/testing/fixtures/kanban-todo.config.js.map +1 -0
  160. package/dist/src/testing/fixtures/kanban.pipeline.d.ts +5 -0
  161. package/dist/src/testing/fixtures/kanban.pipeline.d.ts.map +1 -0
  162. package/dist/src/testing/fixtures/kanban.pipeline.js +76 -0
  163. package/dist/src/testing/fixtures/kanban.pipeline.js.map +1 -0
  164. package/dist/src/testing/fixtures/kanban.pipeline.specs.d.ts +2 -0
  165. package/dist/src/testing/fixtures/kanban.pipeline.specs.d.ts.map +1 -0
  166. package/dist/src/testing/fixtures/kanban.pipeline.specs.js +29 -0
  167. package/dist/src/testing/fixtures/kanban.pipeline.specs.js.map +1 -0
  168. package/dist/src/testing/kanban-todo.e2e.specs.d.ts +2 -0
  169. package/dist/src/testing/kanban-todo.e2e.specs.d.ts.map +1 -0
  170. package/dist/src/testing/kanban-todo.e2e.specs.js +160 -0
  171. package/dist/src/testing/kanban-todo.e2e.specs.js.map +1 -0
  172. package/dist/src/testing/mock-handlers.d.ts +21 -0
  173. package/dist/src/testing/mock-handlers.d.ts.map +1 -0
  174. package/dist/src/testing/mock-handlers.js +34 -0
  175. package/dist/src/testing/mock-handlers.js.map +1 -0
  176. package/dist/src/testing/mock-handlers.specs.d.ts +2 -0
  177. package/dist/src/testing/mock-handlers.specs.d.ts.map +1 -0
  178. package/dist/src/testing/mock-handlers.specs.js +193 -0
  179. package/dist/src/testing/mock-handlers.specs.js.map +1 -0
  180. package/dist/src/testing/real-execution.e2e.specs.d.ts +2 -0
  181. package/dist/src/testing/real-execution.e2e.specs.d.ts.map +1 -0
  182. package/dist/src/testing/real-execution.e2e.specs.js +140 -0
  183. package/dist/src/testing/real-execution.e2e.specs.js.map +1 -0
  184. package/dist/src/testing/real-plugin.e2e.specs.d.ts +2 -0
  185. package/dist/src/testing/real-plugin.e2e.specs.d.ts.map +1 -0
  186. package/dist/src/testing/real-plugin.e2e.specs.js +65 -0
  187. package/dist/src/testing/real-plugin.e2e.specs.js.map +1 -0
  188. package/dist/src/testing/server-startup.e2e.specs.d.ts +2 -0
  189. package/dist/src/testing/server-startup.e2e.specs.d.ts.map +1 -0
  190. package/dist/src/testing/server-startup.e2e.specs.js +104 -0
  191. package/dist/src/testing/server-startup.e2e.specs.js.map +1 -0
  192. package/dist/src/testing/snapshot-compare.d.ts +18 -0
  193. package/dist/src/testing/snapshot-compare.d.ts.map +1 -0
  194. package/dist/src/testing/snapshot-compare.js +86 -0
  195. package/dist/src/testing/snapshot-compare.js.map +1 -0
  196. package/dist/src/testing/snapshot-compare.specs.d.ts +2 -0
  197. package/dist/src/testing/snapshot-compare.specs.d.ts.map +1 -0
  198. package/dist/src/testing/snapshot-compare.specs.js +112 -0
  199. package/dist/src/testing/snapshot-compare.specs.js.map +1 -0
  200. package/dist/src/testing/snapshot-sanitize.d.ts +8 -0
  201. package/dist/src/testing/snapshot-sanitize.d.ts.map +1 -0
  202. package/dist/src/testing/snapshot-sanitize.js +10 -0
  203. package/dist/src/testing/snapshot-sanitize.js.map +1 -0
  204. package/dist/src/testing/snapshot-sanitize.specs.d.ts +2 -0
  205. package/dist/src/testing/snapshot-sanitize.specs.d.ts.map +1 -0
  206. package/dist/src/testing/snapshot-sanitize.specs.js +104 -0
  207. package/dist/src/testing/snapshot-sanitize.specs.js.map +1 -0
  208. package/dist/tsconfig.tsbuildinfo +1 -0
  209. package/docs/testing-analysis.md +395 -0
  210. package/package.json +31 -0
  211. package/pipeline-api-new.md +1078 -0
  212. package/pomodoro-plan.md +651 -0
  213. package/scripts/run-kanban-e2e.ts +219 -0
  214. package/scripts/start-server.ts +64 -0
  215. package/snapshots/e2e-run-2025-12-22T15-52-03.json +613 -0
  216. package/snapshots/e2e-run-2025-12-22T16-51-30.json +699 -0
  217. package/src/builder/define.specs.ts +531 -0
  218. package/src/builder/define.ts +700 -0
  219. package/src/config/pipeline-config.ts +32 -0
  220. package/src/core/descriptors.specs.ts +28 -0
  221. package/src/core/descriptors.ts +99 -0
  222. package/src/core/types.specs.ts +44 -0
  223. package/src/core/types.ts +16 -0
  224. package/src/graph/types.specs.ts +176 -0
  225. package/src/graph/types.ts +19 -0
  226. package/src/index.ts +54 -0
  227. package/src/logging/event-logger.specs.ts +100 -0
  228. package/src/logging/event-logger.ts +50 -0
  229. package/src/plugins/handler-adapter.specs.ts +164 -0
  230. package/src/plugins/handler-adapter.ts +21 -0
  231. package/src/plugins/plugin-loader.specs.ts +295 -0
  232. package/src/plugins/plugin-loader.ts +202 -0
  233. package/src/runtime/await-tracker.specs.ts +52 -0
  234. package/src/runtime/await-tracker.ts +50 -0
  235. package/src/runtime/context.specs.ts +28 -0
  236. package/src/runtime/context.ts +13 -0
  237. package/src/runtime/event-command-map.specs.ts +136 -0
  238. package/src/runtime/event-command-map.ts +38 -0
  239. package/src/runtime/phased-executor.specs.ts +358 -0
  240. package/src/runtime/phased-executor.ts +224 -0
  241. package/src/runtime/pipeline-runtime.specs.ts +214 -0
  242. package/src/runtime/pipeline-runtime.ts +119 -0
  243. package/src/runtime/settled-tracker.specs.ts +448 -0
  244. package/src/runtime/settled-tracker.ts +237 -0
  245. package/src/server/full-orchestration.e2e.specs.ts +672 -0
  246. package/src/server/pipeline-server.e2e.specs.ts +505 -0
  247. package/src/server/pipeline-server.specs.ts +761 -0
  248. package/src/server/pipeline-server.ts +656 -0
  249. package/src/server/sse-manager.specs.ts +208 -0
  250. package/src/server/sse-manager.ts +79 -0
  251. package/src/testing/event-capture.specs.ts +143 -0
  252. package/src/testing/event-capture.ts +65 -0
  253. package/src/testing/fixtures/kanban-full.pipeline.specs.ts +337 -0
  254. package/src/testing/fixtures/kanban-full.pipeline.ts +225 -0
  255. package/src/testing/fixtures/kanban-todo.config.ts +19 -0
  256. package/src/testing/fixtures/kanban.pipeline.specs.ts +33 -0
  257. package/src/testing/fixtures/kanban.pipeline.ts +124 -0
  258. package/src/testing/kanban-todo.e2e.specs.ts +209 -0
  259. package/src/testing/mock-handlers.specs.ts +229 -0
  260. package/src/testing/mock-handlers.ts +58 -0
  261. package/src/testing/real-execution.e2e.specs.ts +193 -0
  262. package/src/testing/real-plugin.e2e.specs.ts +94 -0
  263. package/src/testing/server-startup.e2e.specs.ts +162 -0
  264. package/src/testing/snapshot-compare.specs.ts +136 -0
  265. package/src/testing/snapshot-compare.ts +106 -0
  266. package/src/testing/snapshot-sanitize.specs.ts +131 -0
  267. package/src/testing/snapshot-sanitize.ts +17 -0
  268. package/tsconfig.json +11 -0
  269. package/tsconfig.test.json +9 -0
  270. package/vitest.config.ts +29 -0
@@ -0,0 +1,219 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { config } from 'dotenv';
5
+ import { loadPipelineConfig } from '../src/config/pipeline-config';
6
+ import { PipelineServer } from '../src/server/pipeline-server';
7
+ import { resetKanbanState } from '../src/testing/fixtures/kanban-full.pipeline';
8
+ import kanbanTodoConfig from '../src/testing/fixtures/kanban-todo.config';
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const PIPELINE_ROOT = path.resolve(__dirname, '..');
12
+ const PACKAGES_DIR = path.resolve(__dirname, '../..');
13
+ const EXAMPLE_DIR = path.resolve(PACKAGES_DIR, '../examples/kanban-todo');
14
+ const SNAPSHOTS_DIR = path.join(PIPELINE_ROOT, 'snapshots');
15
+
16
+ config({ path: path.join(PIPELINE_ROOT, '.env') });
17
+
18
+ interface StoredMessage {
19
+ message: {
20
+ type: string;
21
+ data: Record<string, unknown>;
22
+ requestId?: string;
23
+ correlationId?: string;
24
+ };
25
+ position: string;
26
+ revision: string;
27
+ messageType: string;
28
+ timestamp: string;
29
+ sessionId?: string;
30
+ }
31
+
32
+ function formatTimestamp(): string {
33
+ const now = new Date();
34
+ return now.toISOString().replace(/[:.]/g, '-').slice(0, 19);
35
+ }
36
+
37
+ interface LogOptions {
38
+ data?: unknown;
39
+ inline?: boolean;
40
+ meta?: { requestId?: string; correlationId?: string };
41
+ }
42
+
43
+ function log(prefix: string, message: string, options: LogOptions = {}): void {
44
+ const timestamp = new Date().toISOString().slice(11, 23);
45
+ const color = prefix === 'EVENT' ? '\x1b[32m' : prefix === 'CMD' ? '\x1b[36m' : '\x1b[33m';
46
+ const reset = '\x1b[0m';
47
+ const gray = '\x1b[38;5;245m';
48
+
49
+ const metaParts: string[] = [];
50
+ if (options.meta?.correlationId) {
51
+ metaParts.push(`corr:${options.meta.correlationId.slice(0, 8)}`);
52
+ }
53
+ if (options.meta?.requestId) {
54
+ metaParts.push(`req:${options.meta.requestId.slice(0, 8)}`);
55
+ }
56
+ const metaStr = metaParts.length > 0 ? ` ${gray}[${metaParts.join(' ')}]${reset}` : '';
57
+
58
+ if (options.inline && options.data !== undefined) {
59
+ const dataStr = JSON.stringify(options.data);
60
+ console.log(`${color}[${timestamp}] ${prefix}${reset} ${message}\n ${metaStr} ${gray}${dataStr}${reset}`);
61
+ } else {
62
+ console.log(`${color}[${timestamp}] ${prefix}${reset} ${message}\n ${metaStr}`);
63
+ if (options.data !== undefined) {
64
+ console.log(` ${gray}${JSON.stringify(options.data, null, 2).split('\n').join('\n ')}${reset}`);
65
+ }
66
+ }
67
+ }
68
+
69
+ async function pollAndStreamMessages(
70
+ server: PipelineServer,
71
+ seenPositions: Set<string>,
72
+ timeoutMs: number,
73
+ pollIntervalMs: number,
74
+ ): Promise<StoredMessage[]> {
75
+ const startTime = Date.now();
76
+ let lastMessageCount = 0;
77
+ let stableCount = 0;
78
+ const stableThreshold = 15;
79
+
80
+ while (Date.now() - startTime < timeoutMs) {
81
+ const response = await fetch(`http://localhost:${server.port}/messages`);
82
+ const messages = (await response.json()) as StoredMessage[];
83
+
84
+ for (const msg of messages) {
85
+ if (!seenPositions.has(msg.position)) {
86
+ seenPositions.add(msg.position);
87
+ const prefix = msg.messageType === 'event' ? 'EVENT' : 'CMD';
88
+ const isFailed = msg.message.type.includes('Failed');
89
+ log(prefix, msg.message.type, {
90
+ data: msg.message.data,
91
+ inline: !isFailed,
92
+ meta: {
93
+ requestId: msg.message.requestId,
94
+ correlationId: msg.message.correlationId,
95
+ },
96
+ });
97
+ }
98
+ }
99
+
100
+ if (messages.length === lastMessageCount) {
101
+ stableCount++;
102
+ if (stableCount >= stableThreshold) {
103
+ log('INFO', `Pipeline stable after ${stableThreshold} polls (${messages.length} messages)`);
104
+ return messages;
105
+ }
106
+ } else {
107
+ stableCount = 0;
108
+ lastMessageCount = messages.length;
109
+ }
110
+
111
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
112
+ }
113
+
114
+ log('INFO', `Timeout reached after ${timeoutMs}ms`);
115
+ const response = await fetch(`http://localhost:${server.port}/messages`);
116
+ return (await response.json()) as StoredMessage[];
117
+ }
118
+
119
+ async function main(): Promise<void> {
120
+ console.log('\n\x1b[1m=== Kanban E2E Pipeline Runner ===\x1b[0m\n');
121
+
122
+ if (process.env.ANTHROPIC_API_KEY === undefined) {
123
+ console.error('\x1b[31mError: ANTHROPIC_API_KEY not set. Run: source .env\x1b[0m');
124
+ process.exit(1);
125
+ }
126
+
127
+ log('INFO', 'Loading pipeline configuration...');
128
+ const loaded = await loadPipelineConfig(kanbanTodoConfig);
129
+ log('INFO', `Loaded ${loaded.handlers.length} handlers`);
130
+
131
+ resetKanbanState();
132
+
133
+ const server = new PipelineServer({ port: 0 });
134
+ server.registerCommandHandlers(loaded.handlers);
135
+ server.registerPipeline(loaded.pipeline);
136
+ await server.start();
137
+
138
+ log('INFO', `Server started on port ${server.port}`);
139
+ log('INFO', `Target directory: ${EXAMPLE_DIR}`);
140
+
141
+ console.log('\n\x1b[1m--- Pipeline Execution ---\x1b[0m\n');
142
+
143
+ const dispatchResponse = await fetch(`http://localhost:${server.port}/command`, {
144
+ method: 'POST',
145
+ headers: { 'Content-Type': 'application/json' },
146
+ body: JSON.stringify({
147
+ type: 'ExportSchema',
148
+ data: { directory: EXAMPLE_DIR },
149
+ }),
150
+ });
151
+
152
+ const dispatchResult = (await dispatchResponse.json()) as { status: string; commandId: string };
153
+ if (dispatchResult.status !== 'ack') {
154
+ console.error('\x1b[31mFailed to dispatch ExportSchema\x1b[0m');
155
+ await server.stop();
156
+ process.exit(1);
157
+ }
158
+
159
+ const seenPositions = new Set<string>();
160
+ const messages = await pollAndStreamMessages(server, seenPositions, 10 * 60 * 1000, 1000);
161
+
162
+ await server.stop();
163
+
164
+ console.log('\n\x1b[1m--- Summary ---\x1b[0m\n');
165
+
166
+ const events = messages.filter((m) => m.messageType === 'event');
167
+ const commands = messages.filter((m) => m.messageType === 'command');
168
+
169
+ console.log(`Total messages: ${messages.length}`);
170
+ console.log(` Events: ${events.length}`);
171
+ console.log(` Commands: ${commands.length}`);
172
+
173
+ const eventCounts = new Map<string, number>();
174
+ for (const e of events) {
175
+ eventCounts.set(e.message.type, (eventCounts.get(e.message.type) ?? 0) + 1);
176
+ }
177
+
178
+ console.log('\nEvent breakdown:');
179
+ for (const [type, count] of [...eventCounts.entries()].sort((a, b) => b[1] - a[1])) {
180
+ const isFailed = type.includes('Failed');
181
+ const color = isFailed ? '\x1b[31m' : '\x1b[32m';
182
+ console.log(` ${color}${type}\x1b[0m: ${count}`);
183
+ }
184
+
185
+ if (!existsSync(SNAPSHOTS_DIR)) {
186
+ mkdirSync(SNAPSHOTS_DIR, { recursive: true });
187
+ }
188
+
189
+ const timestamp = formatTimestamp();
190
+ const snapshotPath = path.join(SNAPSHOTS_DIR, `e2e-run-${timestamp}.json`);
191
+
192
+ const snapshot = {
193
+ timestamp: new Date().toISOString(),
194
+ config: {
195
+ exampleDir: EXAMPLE_DIR,
196
+ handlersLoaded: loaded.handlers.length,
197
+ },
198
+ summary: {
199
+ totalMessages: messages.length,
200
+ events: events.length,
201
+ commands: commands.length,
202
+ eventCounts: Object.fromEntries(eventCounts),
203
+ },
204
+ messages: messages.map((m) => ({
205
+ type: m.message.type,
206
+ data: m.message.data,
207
+ messageType: m.messageType,
208
+ position: m.position,
209
+ })),
210
+ };
211
+
212
+ writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2));
213
+ console.log(`\nSnapshot saved to: \x1b[36m${snapshotPath}\x1b[0m\n`);
214
+ }
215
+
216
+ main().catch((err) => {
217
+ console.error('\x1b[31mFatal error:\x1b[0m', err);
218
+ process.exit(1);
219
+ });
@@ -0,0 +1,64 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { config } from 'dotenv';
4
+ import { loadPipelineConfig } from '../src/config/pipeline-config';
5
+ import { PipelineServer } from '../src/server/pipeline-server';
6
+ import { resetKanbanState } from '../src/testing/fixtures/kanban-full.pipeline';
7
+ import kanbanTodoConfig from '../src/testing/fixtures/kanban-todo.config';
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const PIPELINE_ROOT = path.resolve(__dirname, '..');
11
+
12
+ config({ path: path.join(PIPELINE_ROOT, '.env') });
13
+
14
+ const PORT = parseInt(process.env.PIPELINE_PORT ?? '3456', 10);
15
+
16
+ async function main(): Promise<void> {
17
+ console.log('\n\x1b[1m=== Pipeline Server ===\x1b[0m\n');
18
+
19
+ if (process.env.ANTHROPIC_API_KEY === undefined) {
20
+ console.error('\x1b[31mError: ANTHROPIC_API_KEY not set\x1b[0m');
21
+ process.exit(1);
22
+ }
23
+
24
+ console.log('Loading pipeline configuration...');
25
+ const loaded = await loadPipelineConfig(kanbanTodoConfig);
26
+ console.log(`Loaded ${loaded.handlers.length} handlers:`);
27
+ loaded.handlers.forEach((h) => console.log(` - ${h.name}`));
28
+
29
+ resetKanbanState();
30
+
31
+ const server = new PipelineServer({ port: PORT });
32
+ server.registerCommandHandlers(loaded.handlers);
33
+ server.registerPipeline(loaded.pipeline);
34
+ await server.start();
35
+
36
+ console.log(`\n\x1b[32mServer running on http://localhost:${server.port}\x1b[0m\n`);
37
+ console.log('Endpoints:');
38
+ console.log(` GET http://localhost:${server.port}/health`);
39
+ console.log(` GET http://localhost:${server.port}/registry`);
40
+ console.log(` GET http://localhost:${server.port}/pipeline`);
41
+ console.log(` GET http://localhost:${server.port}/messages`);
42
+ console.log(` POST http://localhost:${server.port}/command`);
43
+ console.log('\nExample:');
44
+ console.log(` curl -X POST http://localhost:${server.port}/command \\`);
45
+ console.log(` -H "Content-Type: application/json" \\`);
46
+ console.log(` -d '{"type":"ExportSchema","data":{"directory":"/path/to/project"}}'`);
47
+ console.log('\nPress Ctrl+C to stop\n');
48
+
49
+ process.on('SIGINT', async () => {
50
+ console.log('\nShutting down...');
51
+ await server.stop();
52
+ process.exit(0);
53
+ });
54
+
55
+ process.on('SIGTERM', async () => {
56
+ await server.stop();
57
+ process.exit(0);
58
+ });
59
+ }
60
+
61
+ main().catch((err) => {
62
+ console.error('\x1b[31mFatal error:\x1b[0m', err);
63
+ process.exit(1);
64
+ });