@nclamvn/vibecode-cli 1.0.0 → 1.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.
@@ -3,51 +3,61 @@
3
3
  // Spec Hash: 0fe43335f5a325e3279a079ce616c052
4
4
  // ═══════════════════════════════════════════════════════════════════════════════
5
5
 
6
- export const VERSION = '1.0.0';
6
+ export const VERSION = '2.0.0';
7
7
  export const SPEC_HASH = '0fe43335f5a325e3279a079ce616c052';
8
8
 
9
9
  // ─────────────────────────────────────────────────────────────────────────────
10
- // State Machine
10
+ // State Machine - Phase A + B
11
11
  // ─────────────────────────────────────────────────────────────────────────────
12
12
 
13
13
  export const STATES = {
14
+ // Phase A: Planning
14
15
  INIT: 'INIT',
15
16
  INTAKE_CAPTURED: 'INTAKE_CAPTURED',
16
17
  BLUEPRINT_DRAFTED: 'BLUEPRINT_DRAFTED',
17
18
  CONTRACT_DRAFTED: 'CONTRACT_DRAFTED',
18
19
  CONTRACT_LOCKED: 'CONTRACT_LOCKED',
20
+ // Phase B: Execution
21
+ PLAN_CREATED: 'PLAN_CREATED',
19
22
  BUILD_IN_PROGRESS: 'BUILD_IN_PROGRESS',
20
23
  BUILD_DONE: 'BUILD_DONE',
21
24
  REVIEW_PASSED: 'REVIEW_PASSED',
22
- REVIEW_FAILED: 'REVIEW_FAILED'
25
+ REVIEW_FAILED: 'REVIEW_FAILED',
26
+ SHIPPED: 'SHIPPED'
23
27
  };
24
28
 
25
29
  export const TRANSITIONS = {
30
+ // Phase A transitions
26
31
  [STATES.INIT]: [STATES.INTAKE_CAPTURED],
27
32
  [STATES.INTAKE_CAPTURED]: [STATES.BLUEPRINT_DRAFTED],
28
33
  [STATES.BLUEPRINT_DRAFTED]: [STATES.CONTRACT_DRAFTED, STATES.INTAKE_CAPTURED],
29
34
  [STATES.CONTRACT_DRAFTED]: [STATES.CONTRACT_LOCKED, STATES.BLUEPRINT_DRAFTED],
30
- [STATES.CONTRACT_LOCKED]: [STATES.BUILD_IN_PROGRESS],
35
+ // Phase B transitions
36
+ [STATES.CONTRACT_LOCKED]: [STATES.PLAN_CREATED],
37
+ [STATES.PLAN_CREATED]: [STATES.BUILD_IN_PROGRESS],
31
38
  [STATES.BUILD_IN_PROGRESS]: [STATES.BUILD_DONE],
32
39
  [STATES.BUILD_DONE]: [STATES.REVIEW_PASSED, STATES.REVIEW_FAILED],
33
- [STATES.REVIEW_PASSED]: [],
34
- [STATES.REVIEW_FAILED]: [STATES.BUILD_IN_PROGRESS, STATES.CONTRACT_DRAFTED]
40
+ [STATES.REVIEW_PASSED]: [STATES.SHIPPED],
41
+ [STATES.REVIEW_FAILED]: [STATES.BUILD_IN_PROGRESS, STATES.PLAN_CREATED],
42
+ [STATES.SHIPPED]: []
35
43
  };
36
44
 
37
45
  // ─────────────────────────────────────────────────────────────────────────────
38
- // Progress Display Mapping
46
+ // Progress Display Mapping (7 stages)
39
47
  // ─────────────────────────────────────────────────────────────────────────────
40
48
 
41
49
  export const PROGRESS_MAP = {
42
- [STATES.INIT]: { intake: '🔄', blueprint: '⬜', contract: '⬜', build: '⬜', ship: '⬜' },
43
- [STATES.INTAKE_CAPTURED]: { intake: '✅', blueprint: '🔄', contract: '⬜', build: '⬜', ship: '⬜' },
44
- [STATES.BLUEPRINT_DRAFTED]: { intake: '✅', blueprint: '✅', contract: '🔄', build: '⬜', ship: '⬜' },
45
- [STATES.CONTRACT_DRAFTED]: { intake: '✅', blueprint: '✅', contract: '🔄', build: '⬜', ship: '⬜' },
46
- [STATES.CONTRACT_LOCKED]: { intake: '✅', blueprint: '✅', contract: '✅', build: '🔄', ship: '⬜' },
47
- [STATES.BUILD_IN_PROGRESS]: { intake: '✅', blueprint: '✅', contract: '✅', build: '🔄', ship: '⬜' },
48
- [STATES.BUILD_DONE]: { intake: '✅', blueprint: '✅', contract: '✅', build: '✅', ship: '🔄' },
49
- [STATES.REVIEW_PASSED]: { intake: '✅', blueprint: '✅', contract: '✅', build: '✅', ship: '' },
50
- [STATES.REVIEW_FAILED]: { intake: '✅', blueprint: '✅', contract: '✅', build: '⚠️', ship: '' }
50
+ [STATES.INIT]: { intake: '🔄', blueprint: '⬜', contract: '⬜', plan: '⬜', build: '⬜', review: '⬜', ship: '⬜' },
51
+ [STATES.INTAKE_CAPTURED]: { intake: '✅', blueprint: '🔄', contract: '⬜', plan: '⬜', build: '⬜', review: '⬜', ship: '⬜' },
52
+ [STATES.BLUEPRINT_DRAFTED]: { intake: '✅', blueprint: '✅', contract: '🔄', plan: '⬜', build: '⬜', review: '⬜', ship: '⬜' },
53
+ [STATES.CONTRACT_DRAFTED]: { intake: '✅', blueprint: '✅', contract: '🔄', plan: '⬜', build: '⬜', review: '⬜', ship: '⬜' },
54
+ [STATES.CONTRACT_LOCKED]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '🔄', build: '⬜', review: '⬜', ship: '⬜' },
55
+ [STATES.PLAN_CREATED]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '🔄', review: '⬜', ship: '⬜' },
56
+ [STATES.BUILD_IN_PROGRESS]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '🔄', review: '⬜', ship: '⬜' },
57
+ [STATES.BUILD_DONE]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '✅', review: '🔄', ship: '' },
58
+ [STATES.REVIEW_PASSED]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '', review: '✅', ship: '🔄' },
59
+ [STATES.REVIEW_FAILED]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '⚠️', review: '❌', ship: '⬜' },
60
+ [STATES.SHIPPED]: { intake: '✅', blueprint: '✅', contract: '✅', plan: '✅', build: '✅', review: '✅', ship: '✅' }
51
61
  };
52
62
 
53
63
  // ─────────────────────────────────────────────────────────────────────────────
@@ -188,7 +188,278 @@ export function getContractTemplate(projectName, sessionId) {
188
188
 
189
189
  ---
190
190
 
191
- *Generated by Vibecode CLI v1.0*
191
+ *Generated by Vibecode CLI v1.1*
192
192
  *Lock this contract with \`vibecode lock\` when ready*
193
193
  `;
194
194
  }
195
+
196
+ /**
197
+ * Get plan template
198
+ */
199
+ export function getPlanTemplate(projectName, sessionId, specHash, contractContent) {
200
+ const timestamp = new Date().toISOString();
201
+
202
+ // Extract deliverables from contract
203
+ const deliverablesMatch = contractContent.match(/## 📦 Deliverables[\s\S]*?\|[\s\S]*?(?=\n---|\n##|$)/);
204
+ const deliverables = deliverablesMatch ? deliverablesMatch[0] : '[Extract from contract]';
205
+
206
+ return `# 📋 EXECUTION PLAN: ${projectName}
207
+
208
+ ## Session: ${sessionId}
209
+ ## Created: ${timestamp}
210
+ ## Spec Hash: ${specHash}
211
+ ## Status: ACTIVE
212
+
213
+ ---
214
+
215
+ ## 🎯 Objective
216
+
217
+ Execute the locked contract deliverables in order.
218
+
219
+ ---
220
+
221
+ ## 📦 Deliverables from Contract
222
+
223
+ ${deliverables}
224
+
225
+ ---
226
+
227
+ ## 🔧 Execution Steps
228
+
229
+ | Step | Task | Command/Action | Status |
230
+ |------|------|----------------|--------|
231
+ | 1 | Setup | Initialize project structure | ⬜ |
232
+ | 2 | Core Build | Implement main functionality | ⬜ |
233
+ | 3 | Styling | Apply design system | ⬜ |
234
+ | 4 | Testing | Run tests and validate | ⬜ |
235
+ | 5 | Review | Check against acceptance criteria | ⬜ |
236
+
237
+ ---
238
+
239
+ ## 📝 Notes
240
+
241
+ - Follow contract scope strictly
242
+ - Capture evidence for each step
243
+ - No scope creep allowed
244
+
245
+ ---
246
+
247
+ ## ⏱️ Time Tracking
248
+
249
+ | Phase | Started | Completed | Duration |
250
+ |-------|---------|-----------|----------|
251
+ | Build | ${timestamp} | - | - |
252
+ | Review | - | - | - |
253
+
254
+ ---
255
+
256
+ *Generated by Vibecode CLI v1.1*
257
+ `;
258
+ }
259
+
260
+ /**
261
+ * Get coder pack template - instructions for AI coder
262
+ */
263
+ export function getCoderPackTemplate(projectName, sessionId, specHash, contractContent, blueprintContent) {
264
+ const timestamp = new Date().toISOString();
265
+
266
+ return `# 🏗️ CODER PACK: ${projectName}
267
+
268
+ ## Session: ${sessionId}
269
+ ## Generated: ${timestamp}
270
+ ## Spec Hash: ${specHash}
271
+
272
+ ---
273
+
274
+ ## ⚠️ IMPORTANT - READ FIRST
275
+
276
+ You are the **Thợ (Builder)**. Your job is to execute the locked contract exactly as specified.
277
+
278
+ **Rules:**
279
+ 1. Do NOT add features not in the contract
280
+ 2. Do NOT modify the contract
281
+ 3. Capture evidence of your work
282
+ 4. Report any blockers immediately
283
+
284
+ ---
285
+
286
+ ## 📜 CONTRACT (LOCKED)
287
+
288
+ ${contractContent}
289
+
290
+ ---
291
+
292
+ ## 📘 BLUEPRINT REFERENCE
293
+
294
+ ${blueprintContent}
295
+
296
+ ---
297
+
298
+ ## 🔧 BUILD INSTRUCTIONS
299
+
300
+ 1. Read the contract deliverables table
301
+ 2. Implement each item in order
302
+ 3. For each deliverable:
303
+ - Create/modify the required files
304
+ - Test the implementation
305
+ - Mark as complete
306
+ 4. Capture evidence:
307
+ - Screenshots if UI
308
+ - Terminal output if CLI
309
+ - Test results if automated
310
+
311
+ ---
312
+
313
+ ## 📁 Evidence Collection
314
+
315
+ Save evidence to: \`.vibecode/sessions/${sessionId}/evidence/\`
316
+
317
+ Required evidence:
318
+ - \`changes.diff\` - Git diff of all changes
319
+ - \`build.log\` - Terminal output during build
320
+ - \`screenshots/\` - Visual evidence if applicable
321
+
322
+ ---
323
+
324
+ ## ✅ Completion Checklist
325
+
326
+ - [ ] All deliverables implemented
327
+ - [ ] All acceptance criteria met
328
+ - [ ] Evidence captured
329
+ - [ ] No scope creep
330
+
331
+ ---
332
+
333
+ *Run \`vibecode build --complete\` when finished*
334
+
335
+ *Generated by Vibecode CLI v1.1*
336
+ `;
337
+ }
338
+
339
+ /**
340
+ * Get build report template
341
+ */
342
+ export function getBuildReportTemplate(projectName, sessionId, specHash, startTime, endTime, evidence) {
343
+ const duration = endTime ? Math.round((new Date(endTime) - new Date(startTime)) / 1000 / 60) : 'In progress';
344
+
345
+ return `# 🏗️ BUILD REPORT: ${projectName}
346
+
347
+ ## Session: ${sessionId}
348
+ ## Spec Hash: ${specHash}
349
+ ## Status: ${endTime ? 'COMPLETED' : 'IN PROGRESS'}
350
+
351
+ ---
352
+
353
+ ## ⏱️ Timeline
354
+
355
+ | Metric | Value |
356
+ |--------|-------|
357
+ | Started | ${startTime} |
358
+ | Completed | ${endTime || '-'} |
359
+ | Duration | ${duration} ${endTime ? 'minutes' : ''} |
360
+
361
+ ---
362
+
363
+ ## 📁 Evidence Collected
364
+
365
+ ${evidence.hasDiff ? '- ✅ changes.diff' : '- ⬜ changes.diff'}
366
+ ${evidence.hasLog ? '- ✅ build.log' : '- ⬜ build.log'}
367
+ ${evidence.screenshots > 0 ? `- ✅ ${evidence.screenshots} screenshots` : '- ⬜ No screenshots'}
368
+
369
+ ---
370
+
371
+ ## 📊 Summary
372
+
373
+ - Files changed: ${evidence.filesChanged || 'N/A'}
374
+ - Lines added: ${evidence.linesAdded || 'N/A'}
375
+ - Lines removed: ${evidence.linesRemoved || 'N/A'}
376
+
377
+ ---
378
+
379
+ ## 🔍 Next Steps
380
+
381
+ ${endTime ? '1. Run `vibecode review` to validate build' : '1. Continue building\n2. Run `vibecode build --complete` when done'}
382
+
383
+ ---
384
+
385
+ *Generated by Vibecode CLI v1.1*
386
+ `;
387
+ }
388
+
389
+ /**
390
+ * Get review report template
391
+ */
392
+ export function getReviewReportTemplate(projectName, sessionId, specHash, checks, passed) {
393
+ const timestamp = new Date().toISOString();
394
+
395
+ const checksList = checks.map(c =>
396
+ `| ${c.name} | ${c.passed ? '✅ PASS' : '❌ FAIL'} | ${c.message || '-'} |`
397
+ ).join('\n');
398
+
399
+ return `# 🔍 REVIEW REPORT: ${projectName}
400
+
401
+ ## Session: ${sessionId}
402
+ ## Spec Hash: ${specHash}
403
+ ## Reviewed: ${timestamp}
404
+ ## Result: ${passed ? '✅ PASSED' : '❌ FAILED'}
405
+
406
+ ---
407
+
408
+ ## 📋 Automated Checks
409
+
410
+ | Check | Result | Details |
411
+ |-------|--------|---------|
412
+ ${checksList}
413
+
414
+ ---
415
+
416
+ ## ✔️ Acceptance Criteria Review
417
+
418
+ [Manually verified against contract]
419
+
420
+ ---
421
+
422
+ ## 📊 Summary
423
+
424
+ - Total checks: ${checks.length}
425
+ - Passed: ${checks.filter(c => c.passed).length}
426
+ - Failed: ${checks.filter(c => !c.passed).length}
427
+
428
+ ---
429
+
430
+ ## 🎯 Verdict
431
+
432
+ ${passed ? `
433
+ **REVIEW PASSED**
434
+
435
+ All checks passed. Ready for shipping.
436
+ Run \`vibecode snapshot\` to create release.
437
+ ` : `
438
+ **REVIEW FAILED**
439
+
440
+ Some checks failed. Please fix the issues and run \`vibecode build\` again.
441
+ `}
442
+
443
+ ---
444
+
445
+ *Generated by Vibecode CLI v1.1*
446
+ `;
447
+ }
448
+
449
+ /**
450
+ * Get manifest template for release
451
+ */
452
+ export function getManifestTemplate(projectName, version, specHash, sessionId, files) {
453
+ const timestamp = new Date().toISOString();
454
+
455
+ return {
456
+ name: projectName,
457
+ version: version,
458
+ specHash: specHash,
459
+ sessionId: sessionId,
460
+ timestamp: timestamp,
461
+ generator: 'vibecode-cli@1.1.0',
462
+ files: files,
463
+ status: 'SHIPPED'
464
+ };
465
+ }
@@ -84,9 +84,16 @@ export async function getSessionFilesStatus() {
84
84
  if (!sessionPath) return null;
85
85
 
86
86
  return {
87
+ // Phase A files
87
88
  intake: await pathExists(path.join(sessionPath, 'intake.md')),
88
89
  blueprint: await pathExists(path.join(sessionPath, 'blueprint.md')),
89
- contract: await pathExists(path.join(sessionPath, 'contract.md'))
90
+ contract: await pathExists(path.join(sessionPath, 'contract.md')),
91
+ // Phase B files
92
+ plan: await pathExists(path.join(sessionPath, 'plan.md')),
93
+ coderPack: await pathExists(path.join(sessionPath, 'coder_pack.md')),
94
+ buildReport: await pathExists(path.join(sessionPath, 'build_report.md')),
95
+ reviewReport: await pathExists(path.join(sessionPath, 'review_report.md')),
96
+ manifest: await pathExists(path.join(sessionPath, 'manifest.json'))
90
97
  };
91
98
  }
92
99
 
package/src/index.js CHANGED
@@ -3,10 +3,24 @@
3
3
  // Spec Hash: 0fe43335f5a325e3279a079ce616c052
4
4
  // ═══════════════════════════════════════════════════════════════════════════════
5
5
 
6
+ // Phase A Commands
6
7
  export { initCommand } from './commands/init.js';
7
8
  export { startCommand } from './commands/start.js';
8
9
  export { statusCommand } from './commands/status.js';
9
10
  export { lockCommand } from './commands/lock.js';
10
11
  export { doctorCommand } from './commands/doctor.js';
11
12
 
13
+ // Phase B Commands
14
+ export { planCommand } from './commands/plan.js';
15
+ export { buildCommand } from './commands/build.js';
16
+ export { reviewCommand } from './commands/review.js';
17
+ export { snapshotCommand } from './commands/snapshot.js';
18
+
19
+ // Phase C Commands
20
+ export { configCommand } from './commands/config.js';
21
+
22
+ // Constants
12
23
  export { VERSION, SPEC_HASH, STATES } from './config/constants.js';
24
+
25
+ // Providers
26
+ export { PROVIDERS, getProvider, getDefaultProvider } from './providers/index.js';
@@ -0,0 +1,159 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE CLI - Claude Code Provider
3
+ // "Claude/LLM là PIPELINE, là KIẾN TRÚC SƯ"
4
+ // ═══════════════════════════════════════════════════════════════════════════════
5
+
6
+ import { spawn } from 'child_process';
7
+ import path from 'path';
8
+ import { pathExists, appendToFile } from '../utils/files.js';
9
+
10
+ /**
11
+ * Claude Code optimal configuration
12
+ * Contract LOCKED = License to build (không cần hỏi thêm)
13
+ */
14
+ export const CLAUDE_CODE_CONFIG = {
15
+ command: 'claude',
16
+ flags: [
17
+ '--dangerously-skip-permissions', // Trust the AI - Contract đã locked
18
+ ],
19
+ timeout: 30 * 60 * 1000, // 30 minutes max
20
+ };
21
+
22
+ /**
23
+ * Check if Claude Code CLI is available
24
+ */
25
+ export async function isClaudeCodeAvailable() {
26
+ return new Promise((resolve) => {
27
+ const proc = spawn('which', ['claude'], { shell: true });
28
+ proc.on('close', (code) => {
29
+ resolve(code === 0);
30
+ });
31
+ proc.on('error', () => {
32
+ resolve(false);
33
+ });
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Spawn Claude Code with optimal settings
39
+ *
40
+ * @param {string} prompt - The coder pack / prompt to send
41
+ * @param {object} options - Configuration options
42
+ * @param {string} options.cwd - Working directory
43
+ * @param {string} options.logPath - Path to write build logs
44
+ * @param {function} options.onOutput - Callback for output
45
+ * @returns {Promise<{success: boolean, code: number}>}
46
+ */
47
+ export async function spawnClaudeCode(prompt, options = {}) {
48
+ const { cwd, logPath, onOutput } = options;
49
+ const fs = await import('fs-extra');
50
+ const os = await import('os');
51
+
52
+ // Check if Claude Code is available
53
+ const available = await isClaudeCodeAvailable();
54
+ if (!available) {
55
+ throw new Error('Claude Code CLI not found. Install with: npm install -g @anthropic/claude-code');
56
+ }
57
+
58
+ // Write prompt to temp file to avoid shell escaping issues
59
+ const tempDir = os.default.tmpdir();
60
+ const promptFile = path.join(tempDir, `vibecode-prompt-${Date.now()}.md`);
61
+ await fs.default.writeFile(promptFile, prompt, 'utf-8');
62
+
63
+ return new Promise((resolve, reject) => {
64
+ // Use cat to pipe the prompt file content to claude
65
+ const command = `cat "${promptFile}" | claude ${CLAUDE_CODE_CONFIG.flags.join(' ')}`;
66
+
67
+ // Log the command being run
68
+ if (logPath) {
69
+ appendToFile(logPath, `\n[${new Date().toISOString()}] Running: claude with prompt from ${promptFile}\n`);
70
+ }
71
+
72
+ const proc = spawn(command, [], {
73
+ cwd: cwd || process.cwd(),
74
+ stdio: 'inherit', // Stream directly to terminal
75
+ shell: true,
76
+ });
77
+
78
+ let timeoutId = setTimeout(() => {
79
+ proc.kill();
80
+ // Cleanup temp file
81
+ fs.default.remove(promptFile).catch(() => {});
82
+ reject(new Error('Claude Code process timed out'));
83
+ }, CLAUDE_CODE_CONFIG.timeout);
84
+
85
+ proc.on('close', async (code) => {
86
+ clearTimeout(timeoutId);
87
+
88
+ // Cleanup temp file
89
+ await fs.default.remove(promptFile).catch(() => {});
90
+
91
+ const result = {
92
+ success: code === 0,
93
+ code: code || 0,
94
+ timestamp: new Date().toISOString()
95
+ };
96
+
97
+ if (logPath) {
98
+ const status = result.success ? 'SUCCESS' : 'FAILED';
99
+ appendToFile(logPath, `\n[${result.timestamp}] Claude Code ${status} (exit code: ${code})\n`);
100
+ }
101
+
102
+ resolve(result);
103
+ });
104
+
105
+ proc.on('error', async (error) => {
106
+ clearTimeout(timeoutId);
107
+ // Cleanup temp file
108
+ await fs.default.remove(promptFile).catch(() => {});
109
+
110
+ if (logPath) {
111
+ appendToFile(logPath, `\n[${new Date().toISOString()}] ERROR: ${error.message}\n`);
112
+ }
113
+ reject(error);
114
+ });
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Build prompt with optional CLAUDE.md injection
120
+ *
121
+ * @param {string} coderPackContent - Content of coder_pack.md
122
+ * @param {string} projectRoot - Project root directory
123
+ * @returns {Promise<string>} - Final prompt
124
+ */
125
+ export async function buildPromptWithContext(coderPackContent, projectRoot) {
126
+ let fullPrompt = coderPackContent;
127
+
128
+ // Check for CLAUDE.md in project root
129
+ const claudeMdPath = path.join(projectRoot, 'CLAUDE.md');
130
+ if (await pathExists(claudeMdPath)) {
131
+ const fs = await import('fs-extra');
132
+ const claudeMd = await fs.default.readFile(claudeMdPath, 'utf-8');
133
+
134
+ // Inject CLAUDE.md rules before coder pack
135
+ fullPrompt = `# PROJECT RULES (from CLAUDE.md)
136
+
137
+ ${claudeMd}
138
+
139
+ ---
140
+
141
+ # BUILD INSTRUCTIONS
142
+
143
+ ${coderPackContent}`;
144
+ }
145
+
146
+ return fullPrompt;
147
+ }
148
+
149
+ /**
150
+ * Get provider info for status display
151
+ */
152
+ export function getProviderInfo() {
153
+ return {
154
+ name: 'Claude Code',
155
+ command: CLAUDE_CODE_CONFIG.command,
156
+ mode: '--dangerously-skip-permissions',
157
+ description: 'AI coding with guardrails disabled (contract-approved)'
158
+ };
159
+ }
@@ -0,0 +1,45 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // VIBECODE CLI - AI Provider Manager
3
+ // ═══════════════════════════════════════════════════════════════════════════════
4
+
5
+ export {
6
+ spawnClaudeCode,
7
+ isClaudeCodeAvailable,
8
+ buildPromptWithContext,
9
+ getProviderInfo,
10
+ CLAUDE_CODE_CONFIG
11
+ } from './claude-code.js';
12
+
13
+ // Future providers:
14
+ // export { callAnthropicAPI } from './anthropic-api.js';
15
+ // export { spawnCursor } from './cursor.js';
16
+
17
+ /**
18
+ * Available providers
19
+ */
20
+ export const PROVIDERS = {
21
+ 'claude-code': {
22
+ name: 'Claude Code',
23
+ description: 'Official Claude CLI for coding',
24
+ available: true
25
+ },
26
+ 'anthropic-api': {
27
+ name: 'Anthropic API',
28
+ description: 'Direct API calls (coming soon)',
29
+ available: false
30
+ }
31
+ };
32
+
33
+ /**
34
+ * Get provider by name
35
+ */
36
+ export function getProvider(name) {
37
+ return PROVIDERS[name] || null;
38
+ }
39
+
40
+ /**
41
+ * Get default provider
42
+ */
43
+ export function getDefaultProvider() {
44
+ return 'claude-code';
45
+ }
package/src/ui/output.js CHANGED
@@ -52,11 +52,11 @@ export function printInfo(message) {
52
52
  export function printProgress(state) {
53
53
  const progress = PROGRESS_MAP[state] || PROGRESS_MAP.INIT;
54
54
 
55
- const bar = ` ${progress.intake} INTAKE ${progress.blueprint} BLUEPRINT ${progress.contract} CONTRACT ${progress.build} BUILD ${progress.ship} SHIP`;
55
+ const bar = ` ${progress.intake} INTAKE ${progress.blueprint} BLUEPRINT ${progress.contract} CONTRACT ${progress.plan} PLAN ${progress.build} BUILD ${progress.review} REVIEW ${progress.ship} SHIP`;
56
56
 
57
- console.log(chalk.gray('┌─ Progress ─────────────────────────────────────────────────────────┐'));
57
+ console.log(chalk.gray('┌─ Progress ───────────────────────────────────────────────────────────────────────────┐'));
58
58
  console.log(chalk.white(bar));
59
- console.log(chalk.gray('└────────────────────────────────────────────────────────────────────┘'));
59
+ console.log(chalk.gray('└──────────────────────────────────────────────────────────────────────────────────────┘'));
60
60
  }
61
61
 
62
62
  /**