@litmers/cursorflow-orchestrator 0.2.3 → 0.2.6

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.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,32 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.6] - 2025-12-30
9
+
10
+ ### Added
11
+ - **Flow Auto-Completion**: Automatic merging of all successful lane branches into a unified `feature/{flow}-integrated` branch.
12
+ - **Cleanup Automation**: Automatic deletion of temporary lane branches and worktrees after successful integration.
13
+ - **Manual Completion CLI**: New `cursorflow complete <flow>` command for manual flow integration and recovery.
14
+ - **Flow Meta Tracking**: Enhanced `flow.meta.json` with integration status, target branch, and error reporting.
15
+
16
+ ### Changed
17
+ - **Event System**: Refactored `CursorFlowEvents` to better handle `runId` and completion events.
18
+ - **Interactive Dashboard**: Updated UI to reflect completion and integration states.
19
+ - **Architecture**: Added ADR-0006 and updated high-level workflow diagrams.
20
+
21
+ ## [0.2.5] - 2025-12-28
22
+ - Internal release with logging and hook improvements.
23
+
24
+ ## [0.2.4] - 2025-12-28
25
+ - Internal release with build fixes and monitor UI updates.
26
+
27
+ ## [0.2.3] - 2025-12-28
28
+ - Chore: bump version to v0.2.3.
29
+
7
30
 
8
31
  ## [0.1.37] - 2025-12-26
9
32
 
package/README.md CHANGED
@@ -157,6 +157,7 @@ mobile: └─→ [app]
157
157
  | `new` | Flow와 Lane 생성 | `cursorflow new Feature --lanes "api,web"` |
158
158
  | `add` | Lane에 Task 추가 | `cursorflow add Feature api --task "..."` |
159
159
  | `run` | Flow 실행 | `cursorflow run Feature` |
160
+ | `complete` | Flow 통합 및 마무리 | `cursorflow complete Feature` |
160
161
 
161
162
  ## 🎮 Dashboard Controls
162
163
 
@@ -391,7 +392,7 @@ module.exports = {
391
392
  ## 📖 Documentation
392
393
 
393
394
  ### Core Guides
394
- - [🏛️ Architecture](docs/ARCHITECTURE.md) - Core principles, isolation, and recovery mechanisms
395
+ - [🏛️ Architecture](docs/ARCHITECTURE.md) - Core principles, isolation, and recovery mechanisms (includes Workflow & States)
395
396
  - [📘 Module Guide](docs/MODULE_GUIDE.md) - Architecture and module structure
396
397
  - [🤖 cursor-agent Guide](docs/CURSOR_AGENT_GUIDE.md) - CLI usage and output parsing
397
398
  - [🧪 Test Architecture](docs/TEST_ARCHITECTURE.md) - Test layers and strategies
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CursorFlow 'complete' command
3
+ *
4
+ * Consolidates all lanes of a flow into a single branch and cleans up.
5
+ */
6
+ declare function complete(args: string[]): Promise<void>;
7
+ export = complete;
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ /**
3
+ * CursorFlow 'complete' command
4
+ *
5
+ * Consolidates all lanes of a flow into a single branch and cleans up.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const logger = __importStar(require("../utils/logger"));
43
+ const git = __importStar(require("../utils/git"));
44
+ const config_1 = require("../utils/config");
45
+ const path_1 = require("../utils/path");
46
+ const run_service_1 = require("../utils/run-service");
47
+ const flow_1 = require("../utils/flow");
48
+ const process_1 = require("../services/process");
49
+ function printHelp() {
50
+ console.log(`
51
+ \x1b[1mcursorflow complete\x1b[0m - Flow 통합 및 마무리
52
+
53
+ \x1b[1m사용법:\x1b[0m
54
+ cursorflow complete <flow-dir> [options]
55
+
56
+ \x1b[1m설명:\x1b[0m
57
+ 모든 레인의 작업이 완료된 후, 각 레인의 브랜치들을 하나의 통합 브랜치로 병합합니다.
58
+ 병합이 성공하면 임시로 사용된 레인 브랜치들과 워크트리들을 삭제합니다.
59
+
60
+ \x1b[33m참고:\x1b[0m Flow가 성공적으로 완료되면 자동으로 통합됩니다.
61
+ 이 명령어는 자동 통합이 실패했을 때 수동으로 복구하거나,
62
+ 특정 옵션으로 통합하고 싶을 때 사용합니다.
63
+
64
+ \x1b[1m옵션:\x1b[0m
65
+ --branch <name> 통합 브랜치 이름 지정 (기본값: feature/<FlowName>-integrated)
66
+ --force 완료되지 않은 레인이 있어도 강제로 진행
67
+ --dry-run 실제로 병합하거나 삭제하지 않고 계획만 출력
68
+ --no-cleanup 병합 후 브랜치 및 워크트리를 삭제하지 않음
69
+ --help, -h 도움말 출력
70
+
71
+ \x1b[1m예시:\x1b[0m
72
+ # 자동 통합 실패 후 수동 복구
73
+ cursorflow complete ShopFeature
74
+
75
+ # 특정 브랜치 이름으로 통합
76
+ cursorflow complete ShopFeature --branch feat/shop-v1
77
+
78
+ # 정리 없이 통합만 수행
79
+ cursorflow complete ShopFeature --no-cleanup
80
+ `);
81
+ }
82
+ function parseArgs(args) {
83
+ const branchIdx = args.indexOf('--branch');
84
+ return {
85
+ flowDir: args.find(a => !a.startsWith('--')),
86
+ targetBranch: branchIdx >= 0 ? args[branchIdx + 1] : undefined,
87
+ force: args.includes('--force'),
88
+ help: args.includes('--help') || args.includes('-h'),
89
+ dryRun: args.includes('--dry-run'),
90
+ noCleanup: args.includes('--no-cleanup'),
91
+ };
92
+ }
93
+ async function complete(args) {
94
+ const options = parseArgs(args);
95
+ if (options.help) {
96
+ printHelp();
97
+ return;
98
+ }
99
+ const config = (0, config_1.loadConfig)();
100
+ git.setVerboseGit(config.verboseGit || false);
101
+ const repoRoot = git.getRepoRoot();
102
+ const logsDir = (0, config_1.getLogsDir)(config);
103
+ const runService = (0, run_service_1.createRunService)(config.projectRoot);
104
+ // 1. Find Flow Directory
105
+ let flowDir = '';
106
+ if (!options.flowDir) {
107
+ flowDir = (0, flow_1.findLatestFlowOrTask)(config) || '';
108
+ }
109
+ else {
110
+ const flowsDir = (0, path_1.safeJoin)(config.projectRoot, config.flowsDir);
111
+ flowDir = (0, flow_1.findFlowDir)(flowsDir, options.flowDir) || path.resolve(options.flowDir);
112
+ }
113
+ if (!flowDir || !fs.existsSync(flowDir)) {
114
+ throw new Error(`Flow 디렉토리를 찾을 수 없습니다: ${options.flowDir || 'latest'}`);
115
+ }
116
+ logger.section(`🏁 Completing Flow: ${path.basename(flowDir)}`);
117
+ // 2. Find Latest Run
118
+ const runs = runService.listRuns().filter(run => {
119
+ // Check if this run belongs to the target flowDir
120
+ // We look at the first lane's state to check tasksFile
121
+ if (run.lanes.length === 0)
122
+ return false;
123
+ const laneDir = (0, path_1.safeJoin)(run.path, 'lanes', run.lanes[0].name);
124
+ const statePath = (0, path_1.safeJoin)(laneDir, 'state.json');
125
+ if (!fs.existsSync(statePath))
126
+ return false;
127
+ try {
128
+ const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
129
+ return state.tasksFile && path.resolve(path.dirname(state.tasksFile)) === path.resolve(flowDir);
130
+ }
131
+ catch {
132
+ return false;
133
+ }
134
+ });
135
+ if (runs.length === 0) {
136
+ throw new Error(`이 Flow에 대한 실행 기록(Run)을 찾을 수 없습니다.`);
137
+ }
138
+ const latestRun = runs[0];
139
+ logger.info(`Run ID: ${latestRun.id}`);
140
+ // 3. Verify Status
141
+ const summary = (0, process_1.getFlowSummary)(latestRun.path);
142
+ logger.info(`Status: ${summary.completed}/${summary.total} lanes completed`);
143
+ if (summary.completed < summary.total && !options.force) {
144
+ logger.error(`모든 레인이 완료되지 않았습니다 (${summary.completed}/${summary.total}).`);
145
+ logger.info('완료되지 않은 레인:');
146
+ const statuses = (0, process_1.getAllLaneProcessStatuses)(latestRun.path);
147
+ for (const s of statuses) {
148
+ if (s.actualStatus !== 'completed') {
149
+ logger.info(` - ${s.laneName}: ${s.actualStatus}`);
150
+ }
151
+ }
152
+ logger.info('\n강제로 통합하려면 --force 옵션을 사용하세요.');
153
+ process.exit(1);
154
+ }
155
+ // 4. Determine Target Branch Name
156
+ const flowName = path.basename(flowDir).replace(/^\d+_/, '');
157
+ const targetBranch = options.targetBranch || `feature/${flowName}-integrated`;
158
+ // 5. Get Base Branch from flow.meta.json
159
+ let baseBranch = 'main';
160
+ const metaPath = (0, path_1.safeJoin)(flowDir, 'flow.meta.json');
161
+ if (fs.existsSync(metaPath)) {
162
+ try {
163
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
164
+ baseBranch = meta.baseBranch || 'main';
165
+ }
166
+ catch (e) {
167
+ logger.warn(`flow.meta.json 읽기 실패, 기본값 main 사용: ${e}`);
168
+ }
169
+ }
170
+ logger.info(`Target Branch: ${targetBranch}`);
171
+ logger.info(`Base Branch: ${baseBranch}`);
172
+ const laneBranches = latestRun.lanes
173
+ .filter(l => l.pipelineBranch)
174
+ .map(l => l.pipelineBranch);
175
+ if (laneBranches.length === 0) {
176
+ throw new Error(`통합할 브랜치가 없습니다.`);
177
+ }
178
+ logger.info(`Lanes to merge: ${laneBranches.length}`);
179
+ for (const b of laneBranches) {
180
+ logger.info(` - ${b}`);
181
+ }
182
+ if (options.dryRun) {
183
+ logger.section('🧪 Dry Run: No changes will be made');
184
+ logger.info(`Would create branch '${targetBranch}' from '${baseBranch}'`);
185
+ for (const b of laneBranches) {
186
+ logger.info(`Would merge '${b}' into '${targetBranch}'`);
187
+ }
188
+ if (!options.noCleanup) {
189
+ logger.info(`Would delete ${laneBranches.length} lane branches and ${latestRun.worktrees.length} worktrees`);
190
+ }
191
+ return;
192
+ }
193
+ // 6. Perform Merges
194
+ try {
195
+ // Ensure we are on a clean state in the main repo
196
+ const currentBranch = git.getCurrentBranch(repoRoot);
197
+ if (git.hasUncommittedChanges(repoRoot)) {
198
+ throw new Error('메인 저장소에 커밋되지 않은 변경사항이 있습니다. 커밋하거나 스태시한 후 다시 시도하세요.');
199
+ }
200
+ // Checkout base branch and create target branch
201
+ logger.info(`Creating target branch '${targetBranch}' from '${baseBranch}'...`);
202
+ git.runGit(['checkout', baseBranch], { cwd: repoRoot });
203
+ git.runGit(['checkout', '-B', targetBranch], { cwd: repoRoot });
204
+ // Merge each lane branch
205
+ for (const branch of laneBranches) {
206
+ logger.info(`Merging ${branch}...`);
207
+ // Fetch remote branch if needed
208
+ if (!git.branchExists(branch, { cwd: repoRoot })) {
209
+ logger.info(` Fetching ${branch} from remote...`);
210
+ try {
211
+ git.runGit(['fetch', 'origin', branch], { cwd: repoRoot });
212
+ }
213
+ catch (e) {
214
+ logger.warn(` Failed to fetch ${branch}: ${e}`);
215
+ }
216
+ }
217
+ const branchRef = git.branchExists(branch, { cwd: repoRoot }) ? branch : `origin/${branch}`;
218
+ const mergeResult = git.safeMerge(branchRef, {
219
+ cwd: repoRoot,
220
+ noFf: true,
221
+ message: `chore: merge lane ${branch} into flow integration`,
222
+ abortOnConflict: false, // We'll handle it below
223
+ });
224
+ if (!mergeResult.success) {
225
+ if (mergeResult.conflict) {
226
+ logger.error(`❌ '${branch}' 병합 중 충돌이 발생했습니다.`);
227
+ logger.error(`충돌 파일: ${mergeResult.conflictingFiles.join(', ')}`);
228
+ logger.info('\n충돌을 해결한 후 다시 시도하거나, 수동으로 마무리하세요.');
229
+ // Don't abort here, let the user see the state or suggest cleanup
230
+ throw new Error('Merge conflict occurred during integration.');
231
+ }
232
+ else {
233
+ throw new Error(`병합 실패 (${branch}): ${mergeResult.error}`);
234
+ }
235
+ }
236
+ logger.success(`✓ Merged ${branch}`);
237
+ }
238
+ // 7. Push final branch
239
+ logger.info(`Pushing '${targetBranch}' to remote...`);
240
+ git.push(targetBranch, { cwd: repoRoot, setUpstream: true });
241
+ logger.success(`✓ Pushed ${targetBranch}`);
242
+ // 8. Cleanup
243
+ if (!options.noCleanup) {
244
+ logger.section('🧹 Cleaning Up');
245
+ // Delete local and remote lane branches
246
+ for (const branch of laneBranches) {
247
+ logger.info(`Deleting branch: ${branch}`);
248
+ try {
249
+ git.deleteBranch(branch, { cwd: repoRoot, force: true });
250
+ // Try deleting remote branch too
251
+ try {
252
+ git.deleteBranch(branch, { cwd: repoRoot, remote: true });
253
+ }
254
+ catch {
255
+ // Might not exist on remote or no permission
256
+ }
257
+ }
258
+ catch (e) {
259
+ logger.warn(` Failed to delete branch ${branch}: ${e}`);
260
+ }
261
+ }
262
+ // Remove worktrees
263
+ for (const wtPath of latestRun.worktrees) {
264
+ if (fs.existsSync(wtPath)) {
265
+ logger.info(`Removing worktree: ${wtPath}`);
266
+ try {
267
+ git.removeWorktree(wtPath, { cwd: repoRoot, force: true });
268
+ if (fs.existsSync(wtPath)) {
269
+ fs.rmSync(wtPath, { recursive: true, force: true });
270
+ }
271
+ }
272
+ catch (e) {
273
+ logger.warn(` Failed to remove worktree ${wtPath}: ${e}`);
274
+ }
275
+ }
276
+ }
277
+ // Optional: Delete run directory? Maybe keep logs for a while.
278
+ // logger.info(`Deleting run directory: ${latestRun.path}`);
279
+ // fs.rmSync(latestRun.path, { recursive: true, force: true });
280
+ }
281
+ // 9. Update flow status in meta
282
+ if (fs.existsSync(metaPath)) {
283
+ try {
284
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
285
+ meta.status = 'completed';
286
+ meta.integratedBranch = targetBranch;
287
+ meta.integratedAt = new Date().toISOString();
288
+ fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2));
289
+ }
290
+ catch (e) {
291
+ logger.warn(`flow.meta.json 업데이트 실패: ${e}`);
292
+ }
293
+ }
294
+ logger.section(`🎉 Flow Completion Success!`);
295
+ logger.info(`Final integrated branch: ${targetBranch}`);
296
+ logger.info(`You are now on branch: ${targetBranch}`);
297
+ }
298
+ catch (error) {
299
+ logger.error(`\n❌ Flow completion failed: ${error.message}`);
300
+ process.exit(1);
301
+ }
302
+ }
303
+ module.exports = complete;
304
+ //# sourceMappingURL=complete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/cli/complete.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAC7B,wDAA0C;AAC1C,kDAAoC;AACpC,4CAAyD;AACzD,wCAAyC;AACzC,sDAAwD;AACxD,wCAAkE;AAClE,iDAAgF;AAWhF,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BX,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5C,YAAY,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QAC9D,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC/B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpD,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;QAClC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAc;IACpC,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,MAAM,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,IAAA,8BAAgB,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAExD,yBAAyB;IACzB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,OAAO,GAAG,IAAA,2BAAoB,EAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,IAAA,eAAQ,EAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/D,OAAO,GAAG,IAAA,kBAAW,EAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,OAAO,IAAI,QAAQ,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,uBAAuB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEhE,qBAAqB;IACrB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;QAC9C,kDAAkD;QAClD,uDAAuD;QACvD,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,OAAO,GAAG,IAAA,eAAQ,EAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,SAAS,GAAG,IAAA,eAAQ,EAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7D,OAAO,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,WAAW,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;IAEvC,mBAAmB;IACnB,MAAM,OAAO,GAAG,IAAA,wBAAc,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,KAAK,kBAAkB,CAAC,CAAC;IAE7E,IAAI,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,sBAAsB,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAA,mCAAyB,EAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,YAAY,KAAK,WAAW,EAAE,CAAC;gBACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kCAAkC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,WAAW,QAAQ,aAAa,CAAC;IAE9E,yCAAyC;IACzC,IAAI,UAAU,GAAG,MAAM,CAAC;IACxB,MAAM,QAAQ,GAAG,IAAA,eAAQ,EAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACrD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;YAC3D,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC;QACzC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC;IAC9C,MAAM,CAAC,IAAI,CAAC,gBAAgB,UAAU,EAAE,CAAC,CAAC;IAE1C,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK;SACjC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAe,CAAC,CAAC;IAE/B,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,mBAAmB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,wBAAwB,YAAY,WAAW,UAAU,GAAG,CAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,WAAW,YAAY,GAAG,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,gBAAgB,YAAY,CAAC,MAAM,sBAAsB,SAAS,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC,CAAC;QAC/G,CAAC;QACD,OAAO;IACT,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC;QACH,kDAAkD;QAClD,MAAM,aAAa,GAAG,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,GAAG,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QAED,gDAAgD;QAChD,MAAM,CAAC,IAAI,CAAC,2BAA2B,YAAY,WAAW,UAAU,MAAM,CAAC,CAAC;QAChF,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,GAAG,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEhE,yBAAyB;QACzB,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,KAAK,CAAC,CAAC;YAEpC,gCAAgC;YAChC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;gBACjD,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,iBAAiB,CAAC,CAAC;gBACnD,IAAI,CAAC;oBACH,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC7D,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,qBAAqB,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC;YAE5F,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE;gBAC3C,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,qBAAqB,MAAM,wBAAwB;gBAC5D,eAAe,EAAE,KAAK,EAAE,wBAAwB;aACjD,CAAC,CAAC;YAEH,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;gBACzB,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;oBACzB,MAAM,CAAC,KAAK,CAAC,MAAM,MAAM,oBAAoB,CAAC,CAAC;oBAC/C,MAAM,CAAC,KAAK,CAAC,UAAU,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClE,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;oBAClD,kEAAkE;oBAClE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;YACD,MAAM,CAAC,OAAO,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;QACvC,CAAC;QAED,uBAAuB;QACvB,MAAM,CAAC,IAAI,CAAC,YAAY,YAAY,gBAAgB,CAAC,CAAC;QACtD,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,YAAY,YAAY,EAAE,CAAC,CAAC;QAE3C,aAAa;QACb,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YAEjC,wCAAwC;YACxC,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;gBAC1C,IAAI,CAAC;oBACH,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;oBACzD,iCAAiC;oBACjC,IAAI,CAAC;wBACH,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC5D,CAAC;oBAAC,MAAM,CAAC;wBACP,6CAA6C;oBAC/C,CAAC;gBACH,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,IAAI,CAAC,6BAA6B,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,mBAAmB;YACnB,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,SAAS,EAAE,CAAC;gBACzC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,CAAC,sBAAsB,MAAM,EAAE,CAAC,CAAC;oBAC5C,IAAI,CAAC;wBACH,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC3D,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC1B,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;wBACtD,CAAC;oBACH,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,MAAM,CAAC,IAAI,CAAC,+BAA+B,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;YACH,CAAC;YAED,+DAA+D;YAC/D,4DAA4D;YAC5D,+DAA+D;QACjE,CAAC;QAED,gCAAgC;QAChC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC3D,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC1B,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAC;gBACrC,IAAI,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC7C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAED,MAAM,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;IAExD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,iBAAS,QAAQ,CAAC"}
package/dist/cli/index.js CHANGED
@@ -53,6 +53,7 @@ const COMMANDS = {
53
53
  run: require('./run'),
54
54
  monitor: require('./monitor'),
55
55
  clean: require('./clean'),
56
+ complete: require('./complete'),
56
57
  resume: require('./resume'),
57
58
  doctor: require('./doctor'),
58
59
  signal: require('./signal'),
@@ -77,6 +78,7 @@ function printHelp() {
77
78
  \x1b[1mEXECUTION\x1b[0m
78
79
  \x1b[33mrun\x1b[0m <flow> [options] Run orchestration (DAG-based)
79
80
  \x1b[33mmonitor\x1b[0m [run-dir] [options] \x1b[36mInteractive\x1b[0m lane dashboard
81
+ \x1b[33mcomplete\x1b[0m <flow> [options] Consolidate all lanes into one branch
80
82
  \x1b[33mstop\x1b[0m [run-id] [options] Stop running workflows
81
83
  \x1b[33mresume\x1b[0m [lane] [options] Resume lane(s)
82
84
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -592,6 +592,7 @@ class InteractiveMonitor {
592
592
  getLaneActions(lane) {
593
593
  const status = this.getLaneStatus(lane.path, lane.name);
594
594
  const isRunning = status.status === 'running';
595
+ const isCompleted = status.status === 'completed';
595
596
  return [
596
597
  {
597
598
  id: 'message',