@winspan/claude-forge 1.52.0 → 1.53.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 (42) hide show
  1. package/README.md +4 -4
  2. package/dist/config/defaults.js +1 -1
  3. package/dist/config/defaults.js.map +1 -1
  4. package/dist/config/schema.js +2 -2
  5. package/dist/config/schema.js.map +1 -1
  6. package/dist/convention/convention-manager.d.ts.map +1 -1
  7. package/dist/convention/convention-manager.js +4 -1
  8. package/dist/convention/convention-manager.js.map +1 -1
  9. package/dist/daemon/handlers/stages/09-pipeline-active.d.ts.map +1 -1
  10. package/dist/daemon/handlers/stages/09-pipeline-active.js +18 -12
  11. package/dist/daemon/handlers/stages/09-pipeline-active.js.map +1 -1
  12. package/dist/daemon/index.d.ts.map +1 -1
  13. package/dist/daemon/index.js +0 -8
  14. package/dist/daemon/index.js.map +1 -1
  15. package/dist/pipeline/index.d.ts +2 -6
  16. package/dist/pipeline/index.d.ts.map +1 -1
  17. package/dist/pipeline/index.js +86 -64
  18. package/dist/pipeline/index.js.map +1 -1
  19. package/dist/storage/sqlite.d.ts.map +1 -1
  20. package/dist/storage/sqlite.js +9 -1
  21. package/dist/storage/sqlite.js.map +1 -1
  22. package/dist/web/routes/node-types.d.ts.map +1 -1
  23. package/dist/web/routes/node-types.js +20 -1
  24. package/dist/web/routes/node-types.js.map +1 -1
  25. package/dist/web-static/assets/index-Bv6kBfyq.css +1 -0
  26. package/dist/web-static/assets/index-IOh9Pj5N.js +76 -0
  27. package/dist/web-static/index.html +2 -2
  28. package/package.json +1 -1
  29. package/dist/pipeline/store.legacy.d.ts +0 -48
  30. package/dist/pipeline/store.legacy.d.ts.map +0 -1
  31. package/dist/pipeline/store.legacy.js +0 -163
  32. package/dist/pipeline/store.legacy.js.map +0 -1
  33. package/dist/scripts/auto-migrate.d.ts +0 -9
  34. package/dist/scripts/auto-migrate.d.ts.map +0 -1
  35. package/dist/scripts/auto-migrate.js +0 -161
  36. package/dist/scripts/auto-migrate.js.map +0 -1
  37. package/dist/scripts/migrate-to-event-sourcing.d.ts +0 -16
  38. package/dist/scripts/migrate-to-event-sourcing.d.ts.map +0 -1
  39. package/dist/scripts/migrate-to-event-sourcing.js +0 -179
  40. package/dist/scripts/migrate-to-event-sourcing.js.map +0 -1
  41. package/dist/web-static/assets/index-B-S02jXH.css +0 -1
  42. package/dist/web-static/assets/index-BG4bejVq.js +0 -76
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Claude Forge - 管理后台</title>
7
- <script type="module" crossorigin src="/assets/index-BG4bejVq.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-B-S02jXH.css">
7
+ <script type="module" crossorigin src="/assets/index-IOh9Pj5N.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-Bv6kBfyq.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@winspan/claude-forge",
3
- "version": "1.52.0",
3
+ "version": "1.53.0",
4
4
  "description": "SDLC intelligent orchestration engine for Claude Code",
5
5
  "main": "dist/cli/index.js",
6
6
  "type": "module",
@@ -1,48 +0,0 @@
1
- import type { Pipeline, PipelineTask, PipelinePhase } from './types.js';
2
- import type { SQLiteStorage } from '../storage/sqlite.js';
3
- export declare class PipelineStore {
4
- private db;
5
- constructor(storage: SQLiteStorage);
6
- createPipeline(requirement: string, projectPath: string, sessionId: string, techStack?: string, complexity?: 'simple' | 'moderate' | 'complex', taskType?: 'bugfix' | 'feature' | 'refactor' | 'performance' | 'documentation' | 'other', plannedPhases?: PipelinePhase[], phaseArtifacts?: Record<string, string[]>, reasoning?: string): Pipeline;
7
- addTasks(pipelineId: string, tasks: Array<Omit<PipelineTask, 'id'>>): PipelineTask[];
8
- getActivePipeline(projectPath: string): Pipeline | null;
9
- getTasks(pipelineId: string): PipelineTask[];
10
- updatePhase(pipelineId: string, phase: PipelinePhase): void;
11
- /** 按 ID 关闭单个 Pipeline */
12
- closeById(pipelineId: string): void;
13
- /**
14
- * 关闭超过 ttlMs 未更新的所有活跃 Pipeline,返回被关闭的数量。
15
- * 默认 2 小时(7200000ms)。
16
- */
17
- closeExpired(ttlMs?: number): number;
18
- /** 列出所有非 done 的 Pipeline(跨项目,供 CLI 展示) */
19
- listActive(): Array<{
20
- id: string;
21
- requirement: string;
22
- projectPath: string;
23
- phase: PipelinePhase;
24
- updatedAt: string;
25
- }>;
26
- /**
27
- * 将指定 Pipeline 中所有 in_progress 任务重置为 pending。
28
- * 用于 ESC 中断后恢复:in_progress 表示"开始但未完成",中断后需重新检测。
29
- */
30
- resetInProgressTasks(pipelineId: string): number;
31
- getPhaseProgress(pipelineId: string, phase: PipelinePhase): {
32
- total: number;
33
- completed: number;
34
- };
35
- /**
36
- * 更新任务状态
37
- */
38
- updateTaskStatus(taskId: string, status: 'pending' | 'in_progress' | 'completed' | 'failed', output?: string): boolean;
39
- /**
40
- * 获取单个任务
41
- */
42
- getTask(taskId: string): PipelineTask | null;
43
- /**
44
- * 根据任务 ID 获取 Pipeline ID
45
- */
46
- getPipelineIdByTask(taskId: string): string | null;
47
- }
48
- //# sourceMappingURL=store.legacy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.legacy.d.ts","sourceRoot":"","sources":["../../src/pipeline/store.legacy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI1D,qBAAa,aAAa;IACxB,OAAO,CAAC,EAAE,CAAoB;gBAElB,OAAO,EAAE,aAAa;IAKlC,cAAc,CACZ,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,EAC9C,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,eAAe,GAAG,OAAO,EACxF,aAAa,CAAC,EAAE,aAAa,EAAE,EAC/B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACzC,SAAS,CAAC,EAAE,MAAM,GACjB,QAAQ;IAgCX,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,YAAY,EAAE;IAwBpF,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IA2BvD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,EAAE;IAiB5C,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI;IAM3D,yBAAyB;IACzB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMnC;;;OAGG;IACH,YAAY,CAAC,KAAK,SAAqB,GAAG,MAAM;IAQhD,0CAA0C;IAC1C,UAAU,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IActH;;;OAGG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAOhD,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAWhG;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;IActH;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAgB5C;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAInD"}
@@ -1,163 +0,0 @@
1
- import { randomUUID } from 'crypto';
2
- import { logger } from '../utils/logger.js';
3
- import { PIPELINE } from '../constants.js';
4
- export class PipelineStore {
5
- db;
6
- constructor(storage) {
7
- this.db = storage.getDatabase();
8
- // Schema 已在 SQLiteStorage 初始化时通过 schema.sql 创建,无需重复初始化
9
- }
10
- createPipeline(requirement, projectPath, sessionId, techStack, complexity, taskType, plannedPhases, phaseArtifacts, reasoning) {
11
- const id = randomUUID();
12
- const now = new Date().toISOString();
13
- this.db.prepare(`
14
- INSERT INTO pipelines (
15
- id, requirement, project_path, session_id, phase, tech_stack,
16
- complexity, task_type, planned_phases, phase_artifacts, reasoning,
17
- created_at, updated_at
18
- )
19
- VALUES (?, ?, ?, ?, 'analyze', ?, ?, ?, ?, ?, ?, ?, ?)
20
- `).run(id, requirement, projectPath, sessionId, techStack || null, complexity || 'moderate', taskType || 'other', plannedPhases ? JSON.stringify(plannedPhases) : null, phaseArtifacts ? JSON.stringify(phaseArtifacts) : null, reasoning || null, now, now);
21
- logger.info(`Pipeline 已创建:${id} — ${requirement} (${complexity || 'moderate'} ${taskType || 'other'})`);
22
- return {
23
- id, requirement, projectPath, sessionId,
24
- phase: 'analyze', tasks: [], techStack,
25
- complexity, taskType, plannedPhases, phaseArtifacts, reasoning,
26
- createdAt: now, updatedAt: now,
27
- };
28
- }
29
- addTasks(pipelineId, tasks) {
30
- const insertStmt = this.db.prepare(`
31
- INSERT INTO pipeline_tasks (id, pipeline_id, title, phase, status, description, dependencies, output, source)
32
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
33
- `);
34
- const result = [];
35
- const insertAll = this.db.transaction((items) => {
36
- for (const task of items) {
37
- const id = randomUUID();
38
- insertStmt.run(id, pipelineId, task.title, task.phase, task.status, task.description, JSON.stringify(task.dependencies), task.output || null, task.source || null);
39
- result.push({ ...task, id });
40
- }
41
- });
42
- insertAll(tasks);
43
- return result;
44
- }
45
- getActivePipeline(projectPath) {
46
- const row = this.db.prepare("SELECT * FROM pipelines WHERE project_path = ? AND phase != 'done' ORDER BY updated_at DESC LIMIT 1").get(projectPath);
47
- if (!row)
48
- return null;
49
- const tasks = this.getTasks(row.id);
50
- return {
51
- id: row.id,
52
- requirement: row.requirement,
53
- projectPath: row.project_path,
54
- sessionId: row.session_id,
55
- phase: row.phase,
56
- tasks,
57
- techStack: row.tech_stack,
58
- complexity: row.complexity || 'moderate',
59
- taskType: row.task_type || 'other',
60
- plannedPhases: row.planned_phases ? JSON.parse(row.planned_phases) : undefined,
61
- phaseArtifacts: row.phase_artifacts ? JSON.parse(row.phase_artifacts) : undefined,
62
- reasoning: row.reasoning,
63
- createdAt: row.created_at,
64
- updatedAt: row.updated_at,
65
- };
66
- }
67
- getTasks(pipelineId) {
68
- const rows = this.db.prepare('SELECT * FROM pipeline_tasks WHERE pipeline_id = ? ORDER BY phase, rowid').all(pipelineId);
69
- return rows.map(row => ({
70
- id: row.id,
71
- title: row.title,
72
- phase: row.phase,
73
- status: row.status,
74
- description: row.description,
75
- dependencies: JSON.parse(row.dependencies || '[]'),
76
- output: row.output,
77
- source: row.source,
78
- }));
79
- }
80
- updatePhase(pipelineId, phase) {
81
- this.db.prepare('UPDATE pipelines SET phase = ?, updated_at = ? WHERE id = ?').run(phase, new Date().toISOString(), pipelineId);
82
- }
83
- /** 按 ID 关闭单个 Pipeline */
84
- closeById(pipelineId) {
85
- this.db.prepare("UPDATE pipelines SET phase = 'done', updated_at = ? WHERE id = ?").run(new Date().toISOString(), pipelineId);
86
- }
87
- /**
88
- * 关闭超过 ttlMs 未更新的所有活跃 Pipeline,返回被关闭的数量。
89
- * 默认 2 小时(7200000ms)。
90
- */
91
- closeExpired(ttlMs = PIPELINE.EXPIRE_MS) {
92
- const cutoff = new Date(Date.now() - ttlMs).toISOString();
93
- const result = this.db.prepare("UPDATE pipelines SET phase = 'done', updated_at = ? WHERE phase != 'done' AND updated_at < ?").run(new Date().toISOString(), cutoff);
94
- return result.changes;
95
- }
96
- /** 列出所有非 done 的 Pipeline(跨项目,供 CLI 展示) */
97
- listActive() {
98
- const rows = this.db.prepare("SELECT id, requirement, project_path, phase, updated_at FROM pipelines WHERE phase != 'done' ORDER BY updated_at DESC").all();
99
- return rows.map(r => ({
100
- id: r.id,
101
- requirement: r.requirement,
102
- projectPath: r.project_path,
103
- phase: r.phase,
104
- updatedAt: r.updated_at,
105
- }));
106
- }
107
- /**
108
- * 将指定 Pipeline 中所有 in_progress 任务重置为 pending。
109
- * 用于 ESC 中断后恢复:in_progress 表示"开始但未完成",中断后需重新检测。
110
- */
111
- resetInProgressTasks(pipelineId) {
112
- const result = this.db.prepare("UPDATE pipeline_tasks SET status = 'pending' WHERE pipeline_id = ? AND status = 'in_progress'").run(pipelineId);
113
- return result.changes;
114
- }
115
- getPhaseProgress(pipelineId, phase) {
116
- const row = this.db.prepare(`
117
- SELECT
118
- COUNT(*) as total,
119
- SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed
120
- FROM pipeline_tasks WHERE pipeline_id = ? AND phase = ?
121
- `).get(pipelineId, phase);
122
- return { total: row.total || 0, completed: row.completed || 0 };
123
- }
124
- /**
125
- * 更新任务状态
126
- */
127
- updateTaskStatus(taskId, status, output) {
128
- if (output) {
129
- const result = this.db.prepare("UPDATE pipeline_tasks SET status = ?, output = ?, updated_at = datetime('now') WHERE id = ?").run(status, output, taskId);
130
- return result.changes > 0;
131
- }
132
- else {
133
- const result = this.db.prepare("UPDATE pipeline_tasks SET status = ?, updated_at = datetime('now') WHERE id = ?").run(status, taskId);
134
- return result.changes > 0;
135
- }
136
- }
137
- /**
138
- * 获取单个任务
139
- */
140
- getTask(taskId) {
141
- const row = this.db.prepare('SELECT * FROM pipeline_tasks WHERE id = ?').get(taskId);
142
- if (!row)
143
- return null;
144
- return {
145
- id: row.id,
146
- title: row.title,
147
- description: row.description,
148
- phase: row.phase,
149
- status: row.status,
150
- dependencies: [],
151
- source: row.source,
152
- output: row.output,
153
- };
154
- }
155
- /**
156
- * 根据任务 ID 获取 Pipeline ID
157
- */
158
- getPipelineIdByTask(taskId) {
159
- const row = this.db.prepare('SELECT pipeline_id FROM pipeline_tasks WHERE id = ?').get(taskId);
160
- return row?.pipeline_id || null;
161
- }
162
- }
163
- //# sourceMappingURL=store.legacy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.legacy.js","sourceRoot":"","sources":["../../src/pipeline/store.legacy.ts"],"names":[],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Auto Migration: Legacy Tables → Event Sourcing
4
- *
5
- * 在 daemon 启动时自动检测并迁移历史数据
6
- * 使用 schema_migrations 表记录迁移状态,避免重复执行
7
- */
8
- export declare function autoMigrate(dbPath: string): Promise<void>;
9
- //# sourceMappingURL=auto-migrate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-migrate.d.ts","sourceRoot":"","sources":["../../src/scripts/auto-migrate.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AA6BH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD/D"}
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Auto Migration: Legacy Tables → Event Sourcing
4
- *
5
- * 在 daemon 启动时自动检测并迁移历史数据
6
- * 使用 schema_migrations 表记录迁移状态,避免重复执行
7
- */
8
- import Database from 'better-sqlite3';
9
- import { EventStore } from '../pipeline/event-store.js';
10
- import { SnapshotStore } from '../pipeline/snapshot-store.js';
11
- import { OptimizedAggregator } from '../pipeline/optimized-aggregator.js';
12
- import { PipelineEventType } from '../pipeline/events.js';
13
- import { logger } from '../utils/logger.js';
14
- const MIGRATION_ID = 'pipeline-event-sourcing-v1';
15
- export async function autoMigrate(dbPath) {
16
- const db = new Database(dbPath);
17
- // 1. 确保 schema_migrations 表存在
18
- db.exec(`
19
- CREATE TABLE IF NOT EXISTS schema_migrations (
20
- id TEXT PRIMARY KEY,
21
- executed_at DATETIME DEFAULT CURRENT_TIMESTAMP
22
- )
23
- `);
24
- // 2. 检查是否已执行过此迁移
25
- const migrationRecord = db.prepare(`
26
- SELECT id FROM schema_migrations WHERE id = ?
27
- `).get(MIGRATION_ID);
28
- if (migrationRecord) {
29
- logger.debug('[Migration] 迁移已执行,跳过');
30
- return;
31
- }
32
- // 3. 检查是否有历史数据需要迁移
33
- const hasLegacyData = db.prepare(`SELECT COUNT(*) as count FROM pipelines`).get();
34
- if (hasLegacyData.count === 0) {
35
- logger.info('[Migration] 无历史数据,标记迁移完成');
36
- db.prepare(`INSERT INTO schema_migrations (id) VALUES (?)`).run(MIGRATION_ID);
37
- return;
38
- }
39
- logger.info(`[Migration] 检测到 ${hasLegacyData.count} 条历史数据,开始迁移...`);
40
- const eventStore = new EventStore(dbPath);
41
- const snapshotStore = new SnapshotStore(dbPath);
42
- const aggregator = new OptimizedAggregator(eventStore, snapshotStore);
43
- const pipelines = db.prepare(`SELECT * FROM pipelines ORDER BY created_at ASC`).all();
44
- const tasks = db.prepare(`SELECT * FROM pipeline_tasks ORDER BY updated_at ASC`).all();
45
- let migratedCount = 0;
46
- for (const pipeline of pipelines) {
47
- const pipelineTasks = tasks.filter(t => t.pipeline_id === pipeline.id);
48
- await migratePipeline(eventStore, aggregator, pipeline, pipelineTasks);
49
- migratedCount++;
50
- }
51
- // 4. 标记迁移完成
52
- db.prepare(`INSERT INTO schema_migrations (id) VALUES (?)`).run(MIGRATION_ID);
53
- logger.info(`[Migration] ✅ 迁移完成:${migratedCount} 个 Pipeline`);
54
- }
55
- async function migratePipeline(eventStore, aggregator, pipeline, tasks) {
56
- let currentTimestamp = new Date(pipeline.created_at).getTime();
57
- // 1. PIPELINE_CREATED
58
- eventStore.append({
59
- pipelineId: pipeline.id,
60
- type: PipelineEventType.PIPELINE_CREATED,
61
- payload: {
62
- requirement: '',
63
- projectPath: pipeline.project_path,
64
- sessionId: pipeline.session_id,
65
- plannedPhases: ['analyze', 'design', 'code', 'test', 'review'],
66
- },
67
- metadata: { sessionId: pipeline.session_id },
68
- });
69
- // 2. Tasks
70
- const phaseOrder = ['analyze', 'design', 'code', 'test', 'review'];
71
- const tasksByPhase = new Map();
72
- for (const task of tasks) {
73
- if (!tasksByPhase.has(task.phase))
74
- tasksByPhase.set(task.phase, []);
75
- tasksByPhase.get(task.phase).push(task);
76
- }
77
- for (let i = 0; i < phaseOrder.length; i++) {
78
- const phase = phaseOrder[i];
79
- const phaseTasks = tasksByPhase.get(phase) || [];
80
- if (phaseTasks.length === 0)
81
- continue;
82
- if (i > 0) {
83
- currentTimestamp += 1000;
84
- eventStore.append({
85
- pipelineId: pipeline.id,
86
- type: PipelineEventType.PHASE_ADVANCED,
87
- payload: {
88
- fromPhase: phaseOrder[i - 1],
89
- toPhase: phase,
90
- reason: 'task_complete',
91
- completedTasks: [],
92
- },
93
- metadata: { sessionId: pipeline.session_id },
94
- });
95
- }
96
- for (const task of phaseTasks) {
97
- currentTimestamp += 500;
98
- eventStore.append({
99
- pipelineId: pipeline.id,
100
- type: PipelineEventType.TASK_CREATED,
101
- payload: {
102
- taskId: task.id,
103
- title: task.title,
104
- phase: task.phase,
105
- },
106
- metadata: { sessionId: pipeline.session_id },
107
- });
108
- if (task.status !== 'pending') {
109
- currentTimestamp += 500;
110
- eventStore.append({
111
- pipelineId: pipeline.id,
112
- type: PipelineEventType.TASK_STARTED,
113
- payload: { taskId: task.id },
114
- metadata: { sessionId: pipeline.session_id },
115
- });
116
- }
117
- if (task.status === 'completed') {
118
- currentTimestamp += 500;
119
- eventStore.append({
120
- pipelineId: pipeline.id,
121
- type: PipelineEventType.TASK_COMPLETED,
122
- payload: {
123
- taskId: task.id,
124
- title: task.title,
125
- phase: task.phase,
126
- artifact: '',
127
- detectionMethod: 'heuristic',
128
- },
129
- metadata: { sessionId: pipeline.session_id },
130
- });
131
- }
132
- else if (task.status === 'failed') {
133
- currentTimestamp += 500;
134
- eventStore.append({
135
- pipelineId: pipeline.id,
136
- type: PipelineEventType.TASK_FAILED,
137
- payload: { taskId: task.id, reason: 'migrated from legacy' },
138
- metadata: { sessionId: pipeline.session_id },
139
- });
140
- }
141
- }
142
- }
143
- // 3. PIPELINE_CLOSED
144
- if (pipeline.status === 'closed') {
145
- currentTimestamp += 1000;
146
- eventStore.append({
147
- pipelineId: pipeline.id,
148
- type: PipelineEventType.PIPELINE_CLOSED,
149
- payload: {
150
- reason: 'manual',
151
- totalTasks: tasks.length,
152
- completedTasks: tasks.filter(t => t.status === 'completed').length,
153
- failedTasks: tasks.filter(t => t.status === 'failed').length,
154
- },
155
- metadata: { sessionId: pipeline.session_id },
156
- });
157
- }
158
- // 4. Build snapshot
159
- aggregator.rebuildAndSnapshot(pipeline.id);
160
- }
161
- //# sourceMappingURL=auto-migrate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-migrate.js","sourceRoot":"","sources":["../../src/scripts/auto-migrate.ts"],"names":[],"mappings":"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"}
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Data Migration Script: Legacy Tables → Event Sourcing
4
- *
5
- * Converts existing pipeline data from `pipelines` and `pipeline_tasks` tables
6
- * into event streams in `pipeline_events` table.
7
- *
8
- * Usage:
9
- * npx tsx src/scripts/migrate-to-event-sourcing.ts [--dry-run] [--force]
10
- *
11
- * Options:
12
- * --dry-run: Preview migration without writing to database
13
- * --force: Skip confirmation prompt
14
- */
15
- export {};
16
- //# sourceMappingURL=migrate-to-event-sourcing.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate-to-event-sourcing.d.ts","sourceRoot":"","sources":["../../src/scripts/migrate-to-event-sourcing.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
@@ -1,179 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Data Migration Script: Legacy Tables → Event Sourcing
4
- *
5
- * Converts existing pipeline data from `pipelines` and `pipeline_tasks` tables
6
- * into event streams in `pipeline_events` table.
7
- *
8
- * Usage:
9
- * npx tsx src/scripts/migrate-to-event-sourcing.ts [--dry-run] [--force]
10
- *
11
- * Options:
12
- * --dry-run: Preview migration without writing to database
13
- * --force: Skip confirmation prompt
14
- */
15
- import Database from 'better-sqlite3';
16
- import { resolve } from 'path';
17
- import { homedir } from 'os';
18
- import { EventStore } from '../pipeline/event-store.js';
19
- import { SnapshotStore } from '../pipeline/snapshot-store.js';
20
- import { OptimizedAggregator } from '../pipeline/optimized-aggregator.js';
21
- import { PipelineEventType } from '../pipeline/events.js';
22
- class MigrationRunner {
23
- db;
24
- eventStore;
25
- snapshotStore;
26
- aggregator;
27
- dryRun;
28
- constructor(dbPath, dryRun = false) {
29
- this.db = new Database(dbPath);
30
- this.eventStore = new EventStore(dbPath);
31
- this.snapshotStore = new SnapshotStore(dbPath);
32
- this.aggregator = new OptimizedAggregator(this.eventStore, this.snapshotStore);
33
- this.dryRun = dryRun;
34
- }
35
- async run() {
36
- console.log('🔍 Scanning legacy data...\n');
37
- const pipelines = this.getLegacyPipelines();
38
- const tasks = this.getLegacyTasks();
39
- console.log(`Found ${pipelines.length} pipelines and ${tasks.length} tasks\n`);
40
- if (pipelines.length === 0) {
41
- console.log('✅ No data to migrate');
42
- return;
43
- }
44
- if (this.dryRun) {
45
- console.log('🔎 DRY RUN MODE - No changes will be written\n');
46
- }
47
- let migratedCount = 0;
48
- let skippedCount = 0;
49
- for (const pipeline of pipelines) {
50
- const pipelineTasks = tasks.filter(t => t.pipeline_id === pipeline.id);
51
- // Check if already migrated
52
- const existingEvents = this.eventStore.getEvents(pipeline.id);
53
- if (existingEvents.length > 0) {
54
- console.log(`⏭️ Skipping ${pipeline.id} (already has ${existingEvents.length} events)`);
55
- skippedCount++;
56
- continue;
57
- }
58
- console.log(`📦 Migrating pipeline ${pipeline.id}...`);
59
- await this.migratePipeline(pipeline, pipelineTasks);
60
- migratedCount++;
61
- }
62
- console.log(`\n✅ Migration complete: ${migratedCount} migrated, ${skippedCount} skipped`);
63
- }
64
- getLegacyPipelines() {
65
- return this.db.prepare(`
66
- SELECT id, session_id, project_path, current_phase, status, created_at, updated_at
67
- FROM pipelines
68
- ORDER BY created_at ASC
69
- `).all();
70
- }
71
- getLegacyTasks() {
72
- return this.db.prepare(`
73
- SELECT id, pipeline_id, phase, description, status, created_at, updated_at
74
- FROM pipeline_tasks
75
- ORDER BY created_at ASC
76
- `).all();
77
- }
78
- async migratePipeline(pipeline, tasks) {
79
- let currentTimestamp = new Date(pipeline.created_at).getTime();
80
- const dryRunEvents = [];
81
- const emit = (type, payload, ts) => {
82
- if (this.dryRun) {
83
- dryRunEvents.push(type);
84
- return;
85
- }
86
- this.eventStore.append({ pipelineId: pipeline.id, type, payload, metadata: { sessionId: pipeline.session_id } });
87
- };
88
- // 1. PIPELINE_CREATED
89
- emit(PipelineEventType.PIPELINE_CREATED, {
90
- requirement: '',
91
- projectPath: pipeline.project_path,
92
- sessionId: pipeline.session_id,
93
- plannedPhases: ['analyze', 'design', 'code', 'test', 'review'],
94
- }, currentTimestamp);
95
- // 2. Tasks grouped by phase
96
- const phaseOrder = ['analyze', 'design', 'code', 'test', 'review'];
97
- const tasksByPhase = new Map();
98
- for (const task of tasks) {
99
- if (!tasksByPhase.has(task.phase))
100
- tasksByPhase.set(task.phase, []);
101
- tasksByPhase.get(task.phase).push(task);
102
- }
103
- for (let i = 0; i < phaseOrder.length; i++) {
104
- const phase = phaseOrder[i];
105
- const phaseTasks = tasksByPhase.get(phase) || [];
106
- if (phaseTasks.length === 0)
107
- continue;
108
- if (i > 0) {
109
- currentTimestamp += 1000;
110
- emit(PipelineEventType.PHASE_ADVANCED, {
111
- fromPhase: phaseOrder[i - 1],
112
- toPhase: phase,
113
- reason: 'task_complete',
114
- completedTasks: [],
115
- }, currentTimestamp);
116
- }
117
- for (const task of phaseTasks) {
118
- currentTimestamp += 500;
119
- emit(PipelineEventType.TASK_CREATED, {
120
- taskId: task.id,
121
- title: task.description,
122
- phase: task.phase,
123
- }, currentTimestamp);
124
- if (task.status !== 'pending') {
125
- currentTimestamp += 500;
126
- emit(PipelineEventType.TASK_STARTED, { taskId: task.id }, currentTimestamp);
127
- }
128
- if (task.status === 'completed') {
129
- currentTimestamp += 500;
130
- emit(PipelineEventType.TASK_COMPLETED, {
131
- taskId: task.id,
132
- title: task.description,
133
- phase: task.phase,
134
- artifact: '',
135
- detectionMethod: 'heuristic',
136
- }, currentTimestamp);
137
- }
138
- else if (task.status === 'failed') {
139
- currentTimestamp += 500;
140
- emit(PipelineEventType.TASK_FAILED, { taskId: task.id, reason: 'migrated from legacy' }, currentTimestamp);
141
- }
142
- }
143
- }
144
- // 3. PIPELINE_CLOSED
145
- if (pipeline.status === 'closed') {
146
- currentTimestamp += 1000;
147
- emit(PipelineEventType.PIPELINE_CLOSED, {
148
- reason: 'manual',
149
- totalTasks: tasks.length,
150
- completedTasks: tasks.filter(t => t.status === 'completed').length,
151
- failedTasks: tasks.filter(t => t.status === 'failed').length,
152
- }, currentTimestamp);
153
- }
154
- if (this.dryRun) {
155
- console.log(` → Would write ${dryRunEvents.length} events: ${dryRunEvents.join(', ')}`);
156
- return;
157
- }
158
- this.aggregator.rebuildAndSnapshot(pipeline.id);
159
- console.log(` ✓ Wrote events + snapshot`);
160
- }
161
- }
162
- async function main() {
163
- const args = process.argv.slice(2);
164
- const dryRun = args.includes('--dry-run');
165
- const force = args.includes('--force');
166
- const dbPath = resolve(homedir(), '.claude-forge', 'data.db');
167
- console.log(`Database: ${dbPath}\n`);
168
- if (!dryRun && !force) {
169
- console.log('⚠️ This will write events to the database. Use --dry-run to preview, or --force to skip this prompt.');
170
- process.exit(0);
171
- }
172
- const runner = new MigrationRunner(dbPath, dryRun);
173
- await runner.run();
174
- }
175
- main().catch(err => {
176
- console.error('Migration failed:', err);
177
- process.exit(1);
178
- });
179
- //# sourceMappingURL=migrate-to-event-sourcing.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate-to-event-sourcing.js","sourceRoot":"","sources":["../../src/scripts/migrate-to-event-sourcing.ts"],"names":[],"mappings":"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"}