@litmers/cursorflow-orchestrator 0.1.0 → 0.1.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.
@@ -1,129 +1,129 @@
1
- # CursorFlow Run
2
-
3
- ## Overview
4
- 준비된 태스크를 실행합니다. 단일 레인 또는 멀티 레인 오케스트레이션을 수행합니다.
5
-
6
- ## Steps
7
-
8
- 1. **태스크 디렉토리 확인**
9
- ```bash
10
- ls _cursorflow/tasks/
11
- ```
12
-
13
- 2. **멀티 레인 실행**
14
- ```bash
15
- cursorflow run _cursorflow/tasks/MyFeature/
16
- ```
17
-
18
- 3. **단일 레인 실행**
19
- ```bash
20
- cursorflow lane _cursorflow/tasks/MyFeature/01-task.json
21
- ```
22
-
23
- 4. **Dry run (실행 계획 확인)**
24
- ```bash
25
- cursorflow run _cursorflow/tasks/MyFeature/ --dry-run
26
- ```
27
-
28
- 5. **실행 모니터링**
29
-
30
- 실행 중에는 다른 터미널에서 모니터링:
31
- ```bash
32
- cursorflow monitor --watch
33
- ```
34
-
35
- ## 옵션
36
-
37
- | 옵션 | 설명 |
38
- |------|------|
39
- | `--dry-run` | 실제 실행 없이 계획만 확인 |
40
- | `--executor <type>` | 실행 방식 (cursor-agent \| cloud) |
41
- | `--no-review` | 코드 리뷰 비활성화 |
42
- | `--config <path>` | 커스텀 설정 파일 경로 |
43
-
44
- ## 예제
45
-
46
- ### 기본 실행
47
- ```bash
48
- cursorflow run _cursorflow/tasks/2512191700_MyFeature/
49
- ```
50
-
51
- ### Cloud 실행 (API 키 필요)
52
- ```bash
53
- export CURSOR_API_KEY=your_key
54
- cursorflow run _cursorflow/tasks/MyFeature/ --executor cloud
55
- ```
56
-
57
- ### 리뷰 없이 빠른 실행
58
- ```bash
59
- cursorflow run _cursorflow/tasks/MyFeature/ --no-review
60
- ```
61
-
62
- ## 실행 프로세스
63
-
64
- 1. **초기화**
65
- - 설정 로드
66
- - cursor-agent CLI 확인
67
- - Git 저장소 확인
68
-
69
- 2. **레인 준비**
70
- - Worktree 생성
71
- - 브랜치 체크아웃
72
- - 환경 설정
73
-
74
- 3. **태스크 실행**
75
- - 순차적으로 태스크 수행
76
- - 태스크 완료 후 커밋
77
- - 리뷰 활성화 자동 리뷰
78
-
79
- 4. **완료**
80
- - 변경사항 푸시
81
- - PR 생성 (설정에 따라)
82
- - 로그 저장
83
-
84
- ## 로그 위치
85
-
86
- 실행 로그는 `_cursorflow/logs/runs/` 에 저장됩니다:
87
-
88
- ```
89
- _cursorflow/logs/runs/<lane>-<timestamp>/
90
- ├── state.json # 레인 상태
91
- ├── results.json # 태스크 결과
92
- ├── conversation.jsonl # 에이전트 대화
93
- ├── git-operations.jsonl # Git 작업 로그
94
- └── events.jsonl # 이벤트 로그
95
- ```
96
-
97
- ## Checklist
98
- - [ ] cursor-agent CLI 설치되어 있는가?
99
- - [ ] Git worktree가 사용 가능한가?
100
- - [ ] 태스크 파일이 올바른가?
101
- - [ ] 브랜치 이름이 충돌하지 않는가?
102
- - [ ] 필요한 환경 변수가 설정되었는가? (Cloud 실행 )
103
-
104
- ## 트러블슈팅
105
-
106
- ### 브랜치 충돌
107
- ```bash
108
- # 기존 브랜치 정리
109
- cursorflow clean branches --pattern "feature/my-*"
110
- ```
111
-
112
- ### Worktree 충돌
113
- ```bash
114
- # 기존 worktree 정리
115
- cursorflow clean worktrees --all
116
- ```
117
-
118
- ### 실행 실패
119
- ```bash
120
- # 로그 확인
121
- cursorflow monitor
122
- # 또는
123
- cat _cursorflow/logs/runs/latest/*/state.json
124
- ```
125
-
126
- ## Next Steps
127
- 1. `cursorflow monitor --watch`로 진행 상황 모니터링
128
- 2. 완료 PR 확인 리뷰
129
- 3. 실패 `cursorflow resume <lane>`로 재개
1
+ # CursorFlow Run
2
+
3
+ ## Overview
4
+ Execute prepared tasks with single-lane or multi-lane orchestration.
5
+
6
+ ## Steps
7
+
8
+ 1. **Check the task directory**
9
+ ```bash
10
+ ls _cursorflow/tasks/
11
+ ```
12
+
13
+ 2. **Run multiple lanes**
14
+ ```bash
15
+ cursorflow run _cursorflow/tasks/MyFeature/
16
+ ```
17
+
18
+ 3. **Run a single lane**
19
+ ```bash
20
+ cursorflow lane _cursorflow/tasks/MyFeature/01-task.json
21
+ ```
22
+
23
+ 4. **Dry run (preview the plan)**
24
+ ```bash
25
+ cursorflow run _cursorflow/tasks/MyFeature/ --dry-run
26
+ ```
27
+
28
+ 5. **Monitor execution**
29
+
30
+ Watch progress from another terminal while the run is in progress:
31
+ ```bash
32
+ cursorflow monitor --watch
33
+ ```
34
+
35
+ ## Options
36
+
37
+ | Option | Description |
38
+ |------|------|
39
+ | `--dry-run` | Preview the plan without executing |
40
+ | `--executor <type>` | Execution mode (`cursor-agent` \| `cloud`) |
41
+ | `--no-review` | Disable code review |
42
+ | `--config <path>` | Use a custom config file |
43
+
44
+ ## Examples
45
+
46
+ ### Standard run
47
+ ```bash
48
+ cursorflow run _cursorflow/tasks/2512191700_MyFeature/
49
+ ```
50
+
51
+ ### Cloud run (requires API key)
52
+ ```bash
53
+ export CURSOR_API_KEY=your_key
54
+ cursorflow run _cursorflow/tasks/MyFeature/ --executor cloud
55
+ ```
56
+
57
+ ### Fast run without review
58
+ ```bash
59
+ cursorflow run _cursorflow/tasks/MyFeature/ --no-review
60
+ ```
61
+
62
+ ## Execution process
63
+
64
+ 1. **Initialization**
65
+ - Load configuration
66
+ - Verify the `cursor-agent` CLI
67
+ - Confirm Git repository status
68
+
69
+ 2. **Prepare lanes**
70
+ - Create worktrees
71
+ - Check out branches
72
+ - Configure the environment
73
+
74
+ 3. **Run tasks**
75
+ - Execute tasks sequentially
76
+ - Commit after each task
77
+ - Trigger automatic review when enabled
78
+
79
+ 4. **Complete**
80
+ - Push changes
81
+ - Create a PR (depending on settings)
82
+ - Store logs
83
+
84
+ ## Log location
85
+
86
+ Run logs are stored in `_cursorflow/logs/runs/`:
87
+
88
+ ```
89
+ _cursorflow/logs/runs/<lane>-<timestamp>/
90
+ ├── state.json # Lane status
91
+ ├── results.json # Task results
92
+ ├── conversation.jsonl # Agent conversation
93
+ ├── git-operations.jsonl # Git activity log
94
+ └── events.jsonl # Event log
95
+ ```
96
+
97
+ ## Checklist
98
+ - [ ] Is the `cursor-agent` CLI installed?
99
+ - [ ] Are Git worktrees available?
100
+ - [ ] Are the task files valid?
101
+ - [ ] Do branch names avoid collisions?
102
+ - [ ] Are required environment variables set? (for cloud runs)
103
+
104
+ ## Troubleshooting
105
+
106
+ ### Branch conflicts
107
+ ```bash
108
+ # Clean up existing branches
109
+ cursorflow clean branches --pattern "feature/my-*"
110
+ ```
111
+
112
+ ### Worktree conflicts
113
+ ```bash
114
+ # Clean up existing worktrees
115
+ cursorflow clean worktrees --all
116
+ ```
117
+
118
+ ### Run failures
119
+ ```bash
120
+ # Inspect logs
121
+ cursorflow monitor
122
+ # or
123
+ cat _cursorflow/logs/runs/latest/*/state.json
124
+ ```
125
+
126
+ ## Next steps
127
+ 1. Monitor progress with `cursorflow monitor --watch`.
128
+ 2. Review the PR when the run completes.
129
+ 3. If a run fails, resume with `cursorflow resume <lane>`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litmers/cursorflow-orchestrator",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Git worktree-based parallel AI agent orchestration system for Cursor",
5
5
  "main": "src/cli/index.js",
6
6
  "bin": {
@@ -8,8 +8,17 @@
8
8
  "cursorflow-setup": "src/cli/setup-commands.js"
9
9
  },
10
10
  "scripts": {
11
- "test": "node test/run.js",
12
- "postinstall": "node scripts/postinstall.js"
11
+ "postinstall": "node scripts/postinstall.js",
12
+ "prepublishOnly": "npm run validate",
13
+ "validate": "npm pack --dry-run",
14
+ "release": "scripts/release.sh",
15
+ "release:patch": "scripts/release.sh patch",
16
+ "release:minor": "scripts/release.sh minor",
17
+ "release:major": "scripts/release.sh major",
18
+ "security:check": "npm audit && node scripts/ai-security-check.js",
19
+ "security:audit": "npm audit",
20
+ "security:audit:fix": "npm audit fix",
21
+ "security:setup": "scripts/setup-security.sh"
13
22
  },
14
23
  "keywords": [
15
24
  "cursor",
@@ -44,7 +53,7 @@
44
53
  "scripts/",
45
54
  "commands/",
46
55
  "templates/",
47
- "docs/",
56
+ "examples/",
48
57
  "README.md",
49
58
  "LICENSE",
50
59
  "CHANGELOG.md"
@@ -0,0 +1,224 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AI 기반 보안 검사 스크립트
5
+ * OpenAI API를 사용하여 코드의 보안 취약점을 분석합니다.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const { execSync } = require('child_process');
11
+
12
+ // 색상 정의
13
+ const colors = {
14
+ red: '\x1b[31m',
15
+ green: '\x1b[32m',
16
+ yellow: '\x1b[33m',
17
+ blue: '\x1b[34m',
18
+ reset: '\x1b[0m'
19
+ };
20
+
21
+ // OpenAI API 키 확인
22
+ const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
23
+ if (!OPENAI_API_KEY) {
24
+ console.log(`${colors.yellow}⚠️ OPENAI_API_KEY not set. Skipping AI security check.${colors.reset}`);
25
+ process.exit(0);
26
+ }
27
+
28
+ // 변경된 파일 가져오기 (PR인 경우)
29
+ function getChangedFiles() {
30
+ try {
31
+ const baseBranch = process.env.GITHUB_BASE_REF || 'main';
32
+ const diffCommand = `git diff --name-only origin/${baseBranch}...HEAD`;
33
+ const files = execSync(diffCommand, { encoding: 'utf-8' })
34
+ .split('\n')
35
+ .filter(f => f.endsWith('.js') || f.endsWith('.ts') || f.endsWith('.jsx') || f.endsWith('.tsx'))
36
+ .filter(f => f && fs.existsSync(f));
37
+ return files;
38
+ } catch (error) {
39
+ // PR이 아닌 경우 최근 커밋의 파일들
40
+ try {
41
+ const files = execSync('git diff-tree --no-commit-id --name-only -r HEAD', { encoding: 'utf-8' })
42
+ .split('\n')
43
+ .filter(f => f.endsWith('.js') || f.endsWith('.ts') || f.endsWith('.jsx') || f.endsWith('.tsx'))
44
+ .filter(f => f && fs.existsSync(f));
45
+ return files;
46
+ } catch {
47
+ return [];
48
+ }
49
+ }
50
+ }
51
+
52
+ // AI 보안 검사 프롬프트
53
+ function createSecurityPrompt(code, filename) {
54
+ return `You are a security expert analyzing code for vulnerabilities. Analyze the following code and identify any security issues.
55
+
56
+ File: ${filename}
57
+
58
+ Code:
59
+ \`\`\`javascript
60
+ ${code}
61
+ \`\`\`
62
+
63
+ Please analyze for:
64
+ 1. **Injection vulnerabilities** (SQL, NoSQL, Command, XSS, etc.)
65
+ 2. **Authentication/Authorization issues**
66
+ 3. **Sensitive data exposure** (hardcoded secrets, credentials, API keys)
67
+ 4. **Insecure dependencies or imports**
68
+ 5. **Path traversal vulnerabilities**
69
+ 6. **Insecure randomness or cryptography**
70
+ 7. **Unsafe deserialization**
71
+ 8. **Rate limiting or DoS vulnerabilities**
72
+ 9. **CSRF/SSRF vulnerabilities**
73
+ 10. **Any OWASP Top 10 issues**
74
+
75
+ Respond in JSON format:
76
+ {
77
+ "has_issues": true/false,
78
+ "severity": "critical" | "high" | "medium" | "low" | "none",
79
+ "issues": [
80
+ {
81
+ "type": "vulnerability type",
82
+ "severity": "critical/high/medium/low",
83
+ "line": "approximate line number or area",
84
+ "description": "detailed description",
85
+ "recommendation": "how to fix"
86
+ }
87
+ ],
88
+ "summary": "overall security assessment"
89
+ }`;
90
+ }
91
+
92
+ // OpenAI API 호출
93
+ async function analyzeCodeWithAI(code, filename) {
94
+ const prompt = createSecurityPrompt(code, filename);
95
+
96
+ try {
97
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Content-Type': 'application/json',
101
+ 'Authorization': `Bearer ${OPENAI_API_KEY}`
102
+ },
103
+ body: JSON.stringify({
104
+ model: 'gpt-4o',
105
+ messages: [
106
+ {
107
+ role: 'system',
108
+ content: 'You are a security expert specializing in code security analysis. Provide detailed, actionable security assessments in JSON format.'
109
+ },
110
+ {
111
+ role: 'user',
112
+ content: prompt
113
+ }
114
+ ],
115
+ temperature: 0.3,
116
+ response_format: { type: "json_object" }
117
+ })
118
+ });
119
+
120
+ if (!response.ok) {
121
+ throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`);
122
+ }
123
+
124
+ const data = await response.json();
125
+ const content = data.choices[0].message.content;
126
+ return JSON.parse(content);
127
+ } catch (error) {
128
+ console.error(`${colors.red}Error calling OpenAI API: ${error.message}${colors.reset}`);
129
+ return null;
130
+ }
131
+ }
132
+
133
+ // 보안 이슈 출력
134
+ function printSecurityIssues(filename, analysis) {
135
+ if (!analysis.has_issues) {
136
+ console.log(`${colors.green}✓ ${filename}: No security issues found${colors.reset}`);
137
+ return false;
138
+ }
139
+
140
+ console.log(`\n${colors.red}⚠️ Security issues found in ${filename}${colors.reset}`);
141
+ console.log(`${colors.yellow}Severity: ${analysis.severity.toUpperCase()}${colors.reset}`);
142
+ console.log(`\n${analysis.summary}\n`);
143
+
144
+ analysis.issues.forEach((issue, index) => {
145
+ const severityColor = {
146
+ critical: colors.red,
147
+ high: colors.red,
148
+ medium: colors.yellow,
149
+ low: colors.blue
150
+ }[issue.severity] || colors.reset;
151
+
152
+ console.log(`${index + 1}. ${severityColor}[${issue.severity.toUpperCase()}]${colors.reset} ${issue.type}`);
153
+ console.log(` Location: ${issue.line}`);
154
+ console.log(` ${issue.description}`);
155
+ console.log(` ${colors.green}Fix: ${issue.recommendation}${colors.reset}\n`);
156
+ });
157
+
158
+ return analysis.severity === 'critical' || analysis.severity === 'high';
159
+ }
160
+
161
+ // 메인 실행
162
+ async function main() {
163
+ console.log(`${colors.blue}🔍 Starting AI Security Analysis...${colors.reset}\n`);
164
+
165
+ const changedFiles = getChangedFiles();
166
+
167
+ if (changedFiles.length === 0) {
168
+ console.log(`${colors.yellow}No code files changed. Skipping AI security check.${colors.reset}`);
169
+ process.exit(0);
170
+ }
171
+
172
+ console.log(`Analyzing ${changedFiles.length} file(s):\n`);
173
+ changedFiles.forEach(f => console.log(` - ${f}`));
174
+ console.log('');
175
+
176
+ let hasBlockingIssues = false;
177
+ let totalIssues = 0;
178
+
179
+ for (const file of changedFiles) {
180
+ try {
181
+ const code = fs.readFileSync(file, 'utf-8');
182
+
183
+ // 파일이 너무 크면 스킵
184
+ if (code.length > 50000) {
185
+ console.log(`${colors.yellow}⚠️ ${file}: File too large, skipping${colors.reset}`);
186
+ continue;
187
+ }
188
+
189
+ console.log(`Analyzing ${file}...`);
190
+ const analysis = await analyzeCodeWithAI(code, file);
191
+
192
+ if (analysis) {
193
+ const hasIssues = printSecurityIssues(file, analysis);
194
+ if (hasIssues) {
195
+ hasBlockingIssues = true;
196
+ totalIssues += analysis.issues.length;
197
+ }
198
+ }
199
+ } catch (error) {
200
+ console.error(`${colors.red}Error analyzing ${file}: ${error.message}${colors.reset}`);
201
+ }
202
+ }
203
+
204
+ console.log(`\n${colors.blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
205
+ console.log(`${colors.blue}📊 Security Analysis Summary${colors.reset}`);
206
+ console.log(`${colors.blue}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`);
207
+ console.log(`Files analyzed: ${changedFiles.length}`);
208
+ console.log(`Security issues found: ${totalIssues}`);
209
+
210
+ if (hasBlockingIssues) {
211
+ console.log(`\n${colors.red}❌ CRITICAL/HIGH severity security issues found!${colors.reset}`);
212
+ console.log(`${colors.red}Deployment blocked. Please fix the issues above.${colors.reset}\n`);
213
+ process.exit(1);
214
+ } else {
215
+ console.log(`\n${colors.green}✅ No blocking security issues found${colors.reset}\n`);
216
+ process.exit(0);
217
+ }
218
+ }
219
+
220
+ main().catch(error => {
221
+ console.error(`${colors.red}Fatal error: ${error.message}${colors.reset}`);
222
+ process.exit(1);
223
+ });
224
+
@@ -0,0 +1,109 @@
1
+ #!/bin/bash
2
+
3
+ # NPM 배포 스크립트
4
+ # 사용법: ./scripts/release.sh [patch|minor|major]
5
+
6
+ set -e
7
+
8
+ # 색상 정의
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ BLUE='\033[0;34m'
13
+ NC='\033[0m' # No Color
14
+
15
+ # 버전 타입 확인
16
+ VERSION_TYPE=${1:-patch}
17
+
18
+ if [[ ! "$VERSION_TYPE" =~ ^(patch|minor|major|prerelease)$ ]]; then
19
+ echo -e "${RED}Error: Invalid version type. Use: patch, minor, major, or prerelease${NC}"
20
+ exit 1
21
+ fi
22
+
23
+ echo -e "${BLUE}=== CursorFlow Release Script ===${NC}\n"
24
+
25
+ # Git 상태 확인
26
+ echo -e "${YELLOW}Checking git status...${NC}"
27
+ if [[ -n $(git status -s) ]]; then
28
+ echo -e "${RED}Error: Working directory is not clean. Commit or stash your changes first.${NC}"
29
+ git status -s
30
+ exit 1
31
+ fi
32
+ echo -e "${GREEN}✓ Working directory is clean${NC}\n"
33
+
34
+ # 현재 브랜치 확인
35
+ CURRENT_BRANCH=$(git branch --show-current)
36
+ echo -e "${YELLOW}Current branch: ${CURRENT_BRANCH}${NC}"
37
+ if [[ "$CURRENT_BRANCH" != "main" ]] && [[ "$CURRENT_BRANCH" != "master" ]]; then
38
+ echo -e "${YELLOW}Warning: You are not on main/master branch${NC}"
39
+ read -p "Continue anyway? (y/N): " -n 1 -r
40
+ echo
41
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
42
+ exit 1
43
+ fi
44
+ fi
45
+
46
+ # 최신 코드 받기
47
+ echo -e "\n${YELLOW}Pulling latest changes...${NC}"
48
+ git pull origin "$CURRENT_BRANCH"
49
+ echo -e "${GREEN}✓ Up to date${NC}\n"
50
+
51
+ # 현재 버전 확인
52
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
53
+ echo -e "${BLUE}Current version: ${CURRENT_VERSION}${NC}"
54
+
55
+ # 버전 업데이트
56
+ echo -e "\n${YELLOW}Updating version ($VERSION_TYPE)...${NC}"
57
+ NEW_VERSION=$(npm version $VERSION_TYPE --no-git-tag-version)
58
+ echo -e "${GREEN}✓ New version: ${NEW_VERSION}${NC}\n"
59
+
60
+ # CHANGELOG 업데이트 확인
61
+ echo -e "${YELLOW}Have you updated CHANGELOG.md for this release?${NC}"
62
+ read -p "Press Enter to edit CHANGELOG.md, or 's' to skip: " -n 1 -r
63
+ echo
64
+ if [[ ! $REPLY =~ ^[Ss]$ ]]; then
65
+ ${EDITOR:-nano} CHANGELOG.md
66
+ fi
67
+
68
+ # 변경사항 커밋
69
+ echo -e "\n${YELLOW}Committing version bump...${NC}"
70
+ git add package.json CHANGELOG.md
71
+ git commit -m "chore: bump version to ${NEW_VERSION}"
72
+ echo -e "${GREEN}✓ Version bump committed${NC}\n"
73
+
74
+ # 태그 생성
75
+ TAG_NAME="v${NEW_VERSION#v}"
76
+ echo -e "${YELLOW}Creating tag: ${TAG_NAME}${NC}"
77
+ git tag -a "$TAG_NAME" -m "Release ${TAG_NAME}"
78
+ echo -e "${GREEN}✓ Tag created${NC}\n"
79
+
80
+ # 푸시 전 확인
81
+ echo -e "${BLUE}Ready to push:${NC}"
82
+ echo -e " - Commit: chore: bump version to ${NEW_VERSION}"
83
+ echo -e " - Tag: ${TAG_NAME}"
84
+ echo -e " - Branch: ${CURRENT_BRANCH}"
85
+ echo
86
+
87
+ read -p "Push to GitHub and trigger deployment? (y/N): " -n 1 -r
88
+ echo
89
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
90
+ echo -e "${YELLOW}Aborted. To push manually later:${NC}"
91
+ echo -e " git push origin ${CURRENT_BRANCH}"
92
+ echo -e " git push origin ${TAG_NAME}"
93
+ exit 0
94
+ fi
95
+
96
+ # 푸시
97
+ echo -e "\n${YELLOW}Pushing to GitHub...${NC}"
98
+ git push origin "$CURRENT_BRANCH"
99
+ git push origin "$TAG_NAME"
100
+ echo -e "${GREEN}✓ Pushed successfully${NC}\n"
101
+
102
+ # 완료 메시지
103
+ echo -e "${GREEN}=== Release Process Complete! ===${NC}\n"
104
+ echo -e "${BLUE}Next steps:${NC}"
105
+ echo -e " 1. Monitor GitHub Actions: https://github.com/eungjin-cigro/cursorflow/actions"
106
+ echo -e " 2. Check npm package: https://www.npmjs.com/package/@litmers/cursorflow-orchestrator"
107
+ echo -e " 3. Verify GitHub Release: https://github.com/eungjin-cigro/cursorflow/releases/tag/${TAG_NAME}"
108
+ echo -e "\n${GREEN}Release ${NEW_VERSION} is being deployed! 🚀${NC}"
109
+