codevf 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.
- package/LICENSE +30 -21
- package/README.md +6 -1
- package/bin/codevf-mcp.js +11 -0
- package/dist/commands/fix.d.ts +5 -1
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +170 -13
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +72 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp-tools.d.ts +17 -0
- package/dist/commands/mcp-tools.d.ts.map +1 -0
- package/dist/commands/mcp-tools.js +237 -0
- package/dist/commands/mcp-tools.js.map +1 -0
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +250 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/welcome.d.ts +9 -0
- package/dist/commands/welcome.d.ts.map +1 -0
- package/dist/commands/welcome.js +175 -0
- package/dist/commands/welcome.js.map +1 -0
- package/dist/index.js +194 -149
- package/dist/index.js.map +1 -1
- package/dist/lib/api/client.d.ts +28 -0
- package/dist/lib/api/client.d.ts.map +1 -0
- package/dist/lib/api/client.js +66 -0
- package/dist/lib/api/client.js.map +1 -0
- package/dist/lib/api/tasks.d.ts +36 -0
- package/dist/lib/api/tasks.d.ts.map +1 -0
- package/dist/lib/api/tasks.js +62 -0
- package/dist/lib/api/tasks.js.map +1 -0
- package/dist/lib/api/websocket.d.ts +50 -0
- package/dist/lib/api/websocket.d.ts.map +1 -0
- package/dist/lib/api/websocket.js +153 -0
- package/dist/lib/api/websocket.js.map +1 -0
- package/dist/lib/auth/oauth-flow.d.ts +37 -0
- package/dist/lib/auth/oauth-flow.d.ts.map +1 -0
- package/dist/lib/auth/oauth-flow.js +119 -0
- package/dist/lib/auth/oauth-flow.js.map +1 -0
- package/dist/lib/auth/token-manager.d.ts +26 -0
- package/dist/lib/auth/token-manager.d.ts.map +1 -0
- package/dist/lib/auth/token-manager.js +87 -0
- package/dist/lib/auth/token-manager.js.map +1 -0
- package/dist/lib/config/manager.d.ts +50 -0
- package/dist/lib/config/manager.d.ts.map +1 -0
- package/dist/lib/config/manager.js +84 -0
- package/dist/lib/config/manager.js.map +1 -0
- package/dist/lib/utils/errors.d.ts +28 -0
- package/dist/lib/utils/errors.d.ts.map +1 -0
- package/dist/lib/utils/errors.js +44 -0
- package/dist/lib/utils/errors.js.map +1 -0
- package/dist/lib/utils/logger.d.ts +20 -0
- package/dist/lib/utils/logger.d.ts.map +1 -0
- package/dist/lib/utils/logger.js +40 -0
- package/dist/lib/utils/logger.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +158 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/tools/chat.d.ts +30 -0
- package/dist/mcp/tools/chat.d.ts.map +1 -0
- package/dist/mcp/tools/chat.js +82 -0
- package/dist/mcp/tools/chat.js.map +1 -0
- package/dist/mcp/tools/instant.d.ts +36 -0
- package/dist/mcp/tools/instant.d.ts.map +1 -0
- package/dist/mcp/tools/instant.js +100 -0
- package/dist/mcp/tools/instant.js.map +1 -0
- package/dist/modules/aiAgent.d.ts +75 -0
- package/dist/modules/aiAgent.d.ts.map +1 -0
- package/dist/modules/aiAgent.js +707 -0
- package/dist/modules/aiAgent.js.map +1 -0
- package/dist/modules/api.d.ts +7 -0
- package/dist/modules/api.d.ts.map +1 -1
- package/dist/modules/api.js +13 -4
- package/dist/modules/api.js.map +1 -1
- package/dist/modules/commandHandler.d.ts +40 -0
- package/dist/modules/commandHandler.d.ts.map +1 -0
- package/dist/modules/commandHandler.js +345 -0
- package/dist/modules/commandHandler.js.map +1 -0
- package/dist/modules/config.d.ts +2 -0
- package/dist/modules/config.d.ts.map +1 -1
- package/dist/modules/config.js +9 -0
- package/dist/modules/config.js.map +1 -1
- package/dist/modules/constants.d.ts +83 -0
- package/dist/modules/constants.d.ts.map +1 -0
- package/dist/modules/constants.js +75 -0
- package/dist/modules/constants.js.map +1 -0
- package/dist/modules/permissions.d.ts +14 -0
- package/dist/modules/permissions.d.ts.map +1 -1
- package/dist/modules/permissions.js +94 -0
- package/dist/modules/permissions.js.map +1 -1
- package/dist/modules/toolRegistry.d.ts +50 -0
- package/dist/modules/toolRegistry.d.ts.map +1 -0
- package/dist/modules/toolRegistry.js +114 -0
- package/dist/modules/toolRegistry.js.map +1 -0
- package/dist/modules/tunnel.d.ts +33 -0
- package/dist/modules/tunnel.d.ts.map +1 -0
- package/dist/modules/tunnel.js +79 -0
- package/dist/modules/tunnel.js.map +1 -0
- package/dist/modules/vibeHelper.d.ts +16 -0
- package/dist/modules/vibeHelper.d.ts.map +1 -0
- package/dist/modules/vibeHelper.js +38 -0
- package/dist/modules/vibeHelper.js.map +1 -0
- package/dist/modules/websocket.d.ts +9 -0
- package/dist/modules/websocket.d.ts.map +1 -1
- package/dist/modules/websocket.js +70 -0
- package/dist/modules/websocket.js.map +1 -1
- package/dist/tools/consultEngineer.d.ts +13 -0
- package/dist/tools/consultEngineer.d.ts.map +1 -0
- package/dist/tools/consultEngineer.js +161 -0
- package/dist/tools/consultEngineer.js.map +1 -0
- package/dist/tools/realtimeChat.d.ts +9 -0
- package/dist/tools/realtimeChat.d.ts.map +1 -0
- package/dist/tools/realtimeChat.js +101 -0
- package/dist/tools/realtimeChat.js.map +1 -0
- package/dist/types/index.d.ts +183 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/ui/InteractiveApp.d.ts +13 -0
- package/dist/ui/InteractiveApp.d.ts.map +1 -0
- package/dist/ui/InteractiveApp.js +84 -0
- package/dist/ui/InteractiveApp.js.map +1 -0
- package/dist/ui/InteractivePrompt.d.ts +53 -0
- package/dist/ui/InteractivePrompt.d.ts.map +1 -0
- package/dist/ui/InteractivePrompt.js +422 -0
- package/dist/ui/InteractivePrompt.js.map +1 -0
- package/dist/ui/LiveSession.d.ts +2 -0
- package/dist/ui/LiveSession.d.ts.map +1 -1
- package/dist/ui/LiveSession.js +461 -180
- package/dist/ui/LiveSession.js.map +1 -1
- package/dist/ui/PromptInput.d.ts +14 -0
- package/dist/ui/PromptInput.d.ts.map +1 -0
- package/dist/ui/PromptInput.js +206 -0
- package/dist/ui/PromptInput.js.map +1 -0
- package/dist/ui/SessionUI.d.ts +40 -0
- package/dist/ui/SessionUI.d.ts.map +1 -0
- package/dist/ui/SessionUI.js +227 -0
- package/dist/ui/SessionUI.js.map +1 -0
- package/dist/ui/input/Command.d.ts +22 -0
- package/dist/ui/input/Command.d.ts.map +1 -0
- package/dist/ui/input/Command.js +30 -0
- package/dist/ui/input/Command.js.map +1 -0
- package/dist/ui/input/CustomInput.d.ts +15 -0
- package/dist/ui/input/CustomInput.d.ts.map +1 -0
- package/dist/ui/input/CustomInput.js +182 -0
- package/dist/ui/input/CustomInput.js.map +1 -0
- package/dist/ui/input/handlers/handleCursor.d.ts +22 -0
- package/dist/ui/input/handlers/handleCursor.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleCursor.js +53 -0
- package/dist/ui/input/handlers/handleCursor.js.map +1 -0
- package/dist/ui/input/handlers/handleEdit.d.ts +18 -0
- package/dist/ui/input/handlers/handleEdit.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleEdit.js +55 -0
- package/dist/ui/input/handlers/handleEdit.js.map +1 -0
- package/dist/ui/input/handlers/handleHistory.d.ts +18 -0
- package/dist/ui/input/handlers/handleHistory.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleHistory.js +85 -0
- package/dist/ui/input/handlers/handleHistory.js.map +1 -0
- package/dist/ui/input/handlers/handlePaste.d.ts +19 -0
- package/dist/ui/input/handlers/handlePaste.d.ts.map +1 -0
- package/dist/ui/input/handlers/handlePaste.js +49 -0
- package/dist/ui/input/handlers/handlePaste.js.map +1 -0
- package/dist/ui/input/handlers/handleSubmit.d.ts +18 -0
- package/dist/ui/input/handlers/handleSubmit.d.ts.map +1 -0
- package/dist/ui/input/handlers/handleSubmit.js +39 -0
- package/dist/ui/input/handlers/handleSubmit.js.map +1 -0
- package/dist/ui/input/helpers.d.ts +4 -0
- package/dist/ui/input/helpers.d.ts.map +1 -0
- package/dist/ui/input/helpers.js +13 -0
- package/dist/ui/input/helpers.js.map +1 -0
- package/dist/ui/input/keyMatchers.d.ts +14 -0
- package/dist/ui/input/keyMatchers.d.ts.map +1 -0
- package/dist/ui/input/keyMatchers.js +49 -0
- package/dist/ui/input/keyMatchers.js.map +1 -0
- package/dist/ui/input/types.d.ts +33 -0
- package/dist/ui/input/types.d.ts.map +1 -0
- package/dist/ui/input/types.js +2 -0
- package/dist/ui/input/types.js.map +1 -0
- package/dist/ui/promptWithModes.d.ts +12 -0
- package/dist/ui/promptWithModes.d.ts.map +1 -0
- package/dist/ui/promptWithModes.js +24 -0
- package/dist/ui/promptWithModes.js.map +1 -0
- package/dist/ui/renderPrompt.d.ts +12 -0
- package/dist/ui/renderPrompt.d.ts.map +1 -0
- package/dist/ui/renderPrompt.js +14 -0
- package/dist/ui/renderPrompt.js.map +1 -0
- package/dist/ui/simplePrompt.d.ts +7 -0
- package/dist/ui/simplePrompt.d.ts.map +1 -0
- package/dist/ui/simplePrompt.js +38 -0
- package/dist/ui/simplePrompt.js.map +1 -0
- package/dist/ui/spinner.d.ts +7 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +13 -0
- package/dist/ui/spinner.js.map +1 -0
- package/package.json +36 -25
- package/ARCHITECTURE.md +0 -285
- package/BUILD_SUMMARY.md +0 -340
- package/QUICKSTART.md +0 -180
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Welcome screen for first-time users
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import prompts from 'prompts';
|
|
6
|
+
import { setupCommand } from './setup.js';
|
|
7
|
+
import { ConfigManager } from '../lib/config/manager.js';
|
|
8
|
+
const WELCOME_ART = `
|
|
9
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
10
|
+
║ ║
|
|
11
|
+
║ █████╗ ██████╗ ██████╗ ███████╗██╗ ██╗███████╗ ║
|
|
12
|
+
║ ██╔══██╗██╔═══██╗██╔══██╗██╔════╝██║ ██║██╔════╝ ║
|
|
13
|
+
║ ██║ ╚═╝██║ ██║██║ ██║█████╗ ╚██╗ ██╔╝█████╗ ║
|
|
14
|
+
║ ██║ ██╗██║ ██║██║ ██║██╔══╝ ╚████╔╝ ██╔══╝ ║
|
|
15
|
+
║ ╚█████╔╝╚██████╔╝██████╔╝███████╗ ╚██╔╝ ██║ ║
|
|
16
|
+
║ ╚════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ║
|
|
17
|
+
║ ║
|
|
18
|
+
║ Live Debugging with Vetted Engineers ║
|
|
19
|
+
║ ║
|
|
20
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
21
|
+
`;
|
|
22
|
+
export async function welcomeCommand() {
|
|
23
|
+
console.clear();
|
|
24
|
+
console.log(chalk.cyan(WELCOME_ART));
|
|
25
|
+
console.log(chalk.bold('\n👋 Welcome to CodeVF!\n'));
|
|
26
|
+
console.log('Get help from expert engineers when you need it most.\n');
|
|
27
|
+
const { setupType } = await prompts({
|
|
28
|
+
type: 'select',
|
|
29
|
+
name: 'setupType',
|
|
30
|
+
message: 'How would you like to use CodeVF?',
|
|
31
|
+
choices: [
|
|
32
|
+
{
|
|
33
|
+
title: chalk.bold.green('🤖 Claude Code Integration') + chalk.dim(' (Recommended)'),
|
|
34
|
+
description: 'Add CodeVF tools to Claude Code - ask Claude to consult engineers',
|
|
35
|
+
value: 'mcp',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: chalk.bold.blue('💻 Standalone CLI') + chalk.dim(' (Beta)'),
|
|
39
|
+
description: 'Use CodeVF directly from your terminal for live debugging sessions',
|
|
40
|
+
value: 'cli',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: chalk.dim('ℹ️ Learn More'),
|
|
44
|
+
description: 'Show me what CodeVF can do',
|
|
45
|
+
value: 'info',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: chalk.dim('❌ Exit'),
|
|
49
|
+
description: 'Exit setup',
|
|
50
|
+
value: 'exit',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
initial: 0,
|
|
54
|
+
});
|
|
55
|
+
if (!setupType || setupType === 'exit') {
|
|
56
|
+
console.log(chalk.dim('\n👋 Run `codevf` anytime to get started!\n'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
switch (setupType) {
|
|
60
|
+
case 'mcp':
|
|
61
|
+
await setupMCPFlow();
|
|
62
|
+
break;
|
|
63
|
+
case 'cli':
|
|
64
|
+
await setupCLIFlow();
|
|
65
|
+
break;
|
|
66
|
+
case 'info':
|
|
67
|
+
await showInfo();
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function setupMCPFlow() {
|
|
72
|
+
console.log(chalk.bold.cyan('\n🤖 Claude Code Integration Setup\n'));
|
|
73
|
+
console.log(chalk.dim('This will:'));
|
|
74
|
+
console.log(chalk.dim(' 1. Authenticate with CodeVF'));
|
|
75
|
+
console.log(chalk.dim(' 2. Configure Claude Code to use CodeVF tools'));
|
|
76
|
+
console.log(chalk.dim(' 3. Enable codevf-instant and codevf-chat commands\n'));
|
|
77
|
+
const { proceed } = await prompts({
|
|
78
|
+
type: 'confirm',
|
|
79
|
+
name: 'proceed',
|
|
80
|
+
message: 'Ready to set up?',
|
|
81
|
+
initial: true,
|
|
82
|
+
});
|
|
83
|
+
if (!proceed) {
|
|
84
|
+
console.log(chalk.dim('\n👋 Run `codevf setup` anytime to configure!\n'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Run the setup command
|
|
88
|
+
await setupCommand();
|
|
89
|
+
console.log(chalk.bold.green('\n✨ All set! Here\'s what you can do:\n'));
|
|
90
|
+
console.log(chalk.cyan('In Claude Code, you can now ask:\n'));
|
|
91
|
+
console.log(chalk.dim(' "Use codevf-instant to ask an engineer if this fix works"'));
|
|
92
|
+
console.log(chalk.dim(' "Use codevf-chat to debug this complex issue with an engineer"\n'));
|
|
93
|
+
console.log(chalk.bold('Available Tools:'));
|
|
94
|
+
console.log(chalk.green(' • codevf-instant') + chalk.dim(' - Quick validation (1-10 credits, ~2 min)'));
|
|
95
|
+
console.log(chalk.green(' • codevf-chat') + chalk.dim(' - Extended session (4-1920 credits, up to 16 hours)\n'));
|
|
96
|
+
}
|
|
97
|
+
async function setupCLIFlow() {
|
|
98
|
+
console.log(chalk.bold.blue('\n💻 Standalone CLI Setup\n'));
|
|
99
|
+
console.log(chalk.yellow('⚠️ The CLI is currently in beta. For the best experience, we recommend'));
|
|
100
|
+
console.log(chalk.yellow(' using Claude Code integration instead.\n'));
|
|
101
|
+
console.log(chalk.dim('CLI Features:'));
|
|
102
|
+
console.log(chalk.dim(' • Live debugging sessions with engineers'));
|
|
103
|
+
console.log(chalk.dim(' • Real-time chat and screen sharing'));
|
|
104
|
+
console.log(chalk.dim(' • Project initialization and sync\n'));
|
|
105
|
+
const { proceed } = await prompts({
|
|
106
|
+
type: 'confirm',
|
|
107
|
+
name: 'proceed',
|
|
108
|
+
message: 'Continue with CLI setup?',
|
|
109
|
+
initial: false,
|
|
110
|
+
});
|
|
111
|
+
if (!proceed) {
|
|
112
|
+
console.log(chalk.dim('\n💡 Tip: Try `codevf` again and choose Claude Code Integration!\n'));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
console.log(chalk.bold('\n📚 CLI Commands:\n'));
|
|
116
|
+
console.log(chalk.cyan(' codevf login') + chalk.dim(' - Authenticate with CodeVF'));
|
|
117
|
+
console.log(chalk.cyan(' codevf init') + chalk.dim(' - Initialize project'));
|
|
118
|
+
console.log(chalk.cyan(' codevf fix') + chalk.dim(' - Start live debugging session'));
|
|
119
|
+
console.log(chalk.cyan(' codevf sync') + chalk.dim(' - Sync your code\n'));
|
|
120
|
+
const { startLogin } = await prompts({
|
|
121
|
+
type: 'confirm',
|
|
122
|
+
name: 'startLogin',
|
|
123
|
+
message: 'Start with login?',
|
|
124
|
+
initial: true,
|
|
125
|
+
});
|
|
126
|
+
if (startLogin) {
|
|
127
|
+
console.log(chalk.dim('\nRun: codevf login\n'));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function showInfo() {
|
|
131
|
+
console.log(chalk.bold.cyan('\n📖 What is CodeVF?\n'));
|
|
132
|
+
console.log('CodeVF connects you with vetted software engineers for live debugging');
|
|
133
|
+
console.log('and code review. Get expert help when you need it most.\n');
|
|
134
|
+
console.log(chalk.bold('🎯 Use Cases:\n'));
|
|
135
|
+
console.log(chalk.green(' ✓ ') + 'Complex bugs that AI can\'t solve alone');
|
|
136
|
+
console.log(chalk.green(' ✓ ') + 'Architecture and design decisions');
|
|
137
|
+
console.log(chalk.green(' ✓ ') + 'Code review and security audits');
|
|
138
|
+
console.log(chalk.green(' ✓ ') + 'Performance optimization');
|
|
139
|
+
console.log(chalk.green(' ✓ ') + 'Learning from experienced developers\n');
|
|
140
|
+
console.log(chalk.bold('💰 Credit-Based Pricing:\n'));
|
|
141
|
+
console.log(chalk.dim(' • Quick questions: 1-10 credits (~$0.10-$1.00)'));
|
|
142
|
+
console.log(chalk.dim(' • Extended sessions: 2 credits/minute (~$0.20/min)\n'));
|
|
143
|
+
console.log(chalk.bold('🔒 Security:\n'));
|
|
144
|
+
console.log(chalk.dim(' • Engineers only see what you share'));
|
|
145
|
+
console.log(chalk.dim(' • All sessions are private and secure'));
|
|
146
|
+
console.log(chalk.dim(' • No code is stored after sessions\n'));
|
|
147
|
+
const { next } = await prompts({
|
|
148
|
+
type: 'select',
|
|
149
|
+
name: 'next',
|
|
150
|
+
message: 'What would you like to do?',
|
|
151
|
+
choices: [
|
|
152
|
+
{ title: 'Set up Claude Code Integration', value: 'mcp' },
|
|
153
|
+
{ title: 'Set up Standalone CLI', value: 'cli' },
|
|
154
|
+
{ title: 'Exit', value: 'exit' },
|
|
155
|
+
],
|
|
156
|
+
});
|
|
157
|
+
switch (next) {
|
|
158
|
+
case 'mcp':
|
|
159
|
+
await setupMCPFlow();
|
|
160
|
+
break;
|
|
161
|
+
case 'cli':
|
|
162
|
+
await setupCLIFlow();
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Check if this is the first run
|
|
168
|
+
*/
|
|
169
|
+
export function isFirstRun() {
|
|
170
|
+
const mcpConfig = new ConfigManager('mcp-config.json');
|
|
171
|
+
const cliConfig = new ConfigManager('config.json');
|
|
172
|
+
// First run if neither config exists
|
|
173
|
+
return !mcpConfig.exists() && !cliConfig.exists();
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=welcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.js","sourceRoot":"","sources":["../../src/commands/welcome.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,177 +4,189 @@ import 'dotenv/config';
|
|
|
4
4
|
import yargs from 'yargs';
|
|
5
5
|
import { hideBin } from 'yargs/helpers';
|
|
6
6
|
import chalk from 'chalk';
|
|
7
|
-
import prompts from 'prompts';
|
|
8
|
-
import { exec, spawn } from 'child_process';
|
|
9
|
-
import { promisify } from 'util';
|
|
10
7
|
import { loginCommand } from './commands/login.js';
|
|
11
8
|
import { logoutCommand } from './commands/logout.js';
|
|
9
|
+
import { setupCommand } from './commands/setup.js';
|
|
10
|
+
import { welcomeCommand, isFirstRun } from './commands/welcome.js';
|
|
12
11
|
import { initCommand } from './commands/init.js';
|
|
13
12
|
import { syncCommand } from './commands/sync.js';
|
|
14
13
|
import { fixCommand } from './commands/fix.js';
|
|
15
14
|
import { tasksCommand } from './commands/tasks.js';
|
|
16
15
|
import { handleError } from './utils/errors.js';
|
|
17
16
|
import { ConfigManager } from './modules/config.js';
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
import { AiAgent } from './modules/aiAgent.js';
|
|
18
|
+
import React from 'react';
|
|
19
|
+
import { render } from 'ink';
|
|
20
|
+
import { CLI_VERSION } from './modules/constants.js';
|
|
21
|
+
import { InteractiveApp } from './ui/InteractiveApp.js';
|
|
22
|
+
import { renderHeader, renderQuickCommands, showModeSwitched, } from './ui/SessionUI.js';
|
|
23
|
+
import { handleSlashCommand, isSlashCommand, handleHybridMode, handleAiMode, handleHumanMode, } from './modules/commandHandler.js';
|
|
20
24
|
const args = hideBin(process.argv);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Safely loads config without throwing errors
|
|
27
|
+
*/
|
|
28
|
+
function loadConfigSafely(configManager) {
|
|
29
|
+
if (configManager.isInitialized()) {
|
|
24
30
|
try {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
['/exit', 'quit the CLI'],
|
|
59
|
-
];
|
|
60
|
-
commands.forEach(([cmd, desc]) => {
|
|
61
|
-
console.log(`${chalk.white(cmd.padEnd(15))}${chalk.dim('–')} ${chalk.gray(desc)}`);
|
|
31
|
+
return configManager.loadConfig();
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Interactive session mode - main entry point when no arguments provided
|
|
41
|
+
*/
|
|
42
|
+
async function runInteractiveMode() {
|
|
43
|
+
try {
|
|
44
|
+
const configManager = new ConfigManager();
|
|
45
|
+
let loadedConfig = loadConfigSafely(configManager);
|
|
46
|
+
const isInitialized = configManager.isInitialized();
|
|
47
|
+
let aiEnabled = !!loadedConfig?.ai?.enabled;
|
|
48
|
+
let routingMode = aiEnabled ? 'hybrid' : 'human';
|
|
49
|
+
let agentMode = 'build';
|
|
50
|
+
const aiAgent = new AiAgent(configManager);
|
|
51
|
+
const logUserMessage = (message) => {
|
|
52
|
+
// Display the user's input inside a full-width highlight block, left-aligned
|
|
53
|
+
const columns = process.stdout.columns || 80;
|
|
54
|
+
const lines = message.split(/\r?\n/);
|
|
55
|
+
const contentWidth = Math.min(Math.max(...lines.map((line) => line.length), 1), columns - 6);
|
|
56
|
+
const horizontalPad = ' ';
|
|
57
|
+
const totalWidth = Math.min(columns, contentWidth + horizontalPad.length * 2);
|
|
58
|
+
const fullLine = (text) => {
|
|
59
|
+
const padded = text.padEnd(contentWidth, ' ');
|
|
60
|
+
return chalk.bgGray.white(`${horizontalPad}${padded}${horizontalPad}`);
|
|
61
|
+
};
|
|
62
|
+
lines.forEach((line) => {
|
|
63
|
+
console.log(fullLine(line));
|
|
62
64
|
});
|
|
63
|
-
|
|
65
|
+
};
|
|
66
|
+
// Render header and quick commands
|
|
67
|
+
renderHeader(isInitialized, loadedConfig);
|
|
68
|
+
renderQuickCommands(isInitialized, aiEnabled, aiEnabled, agentMode);
|
|
69
|
+
// Command submission handler
|
|
70
|
+
const handleSubmit = async (text, mode) => {
|
|
71
|
+
const trimmed = text.trim();
|
|
72
|
+
logUserMessage(trimmed);
|
|
73
|
+
// Handle slash commands
|
|
74
|
+
if (isSlashCommand(trimmed)) {
|
|
75
|
+
await handleSlashCommand(trimmed, {
|
|
76
|
+
configManager,
|
|
77
|
+
aiAgent,
|
|
78
|
+
routingMode: mode,
|
|
79
|
+
agentMode,
|
|
80
|
+
aiEnabled,
|
|
81
|
+
autoAcceptMode: false,
|
|
82
|
+
loadedConfig,
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Route to appropriate mode handler
|
|
87
|
+
if (mode === 'hybrid' && aiEnabled) {
|
|
88
|
+
await handleHybridMode(trimmed, {
|
|
89
|
+
configManager,
|
|
90
|
+
aiAgent,
|
|
91
|
+
routingMode: mode,
|
|
92
|
+
agentMode,
|
|
93
|
+
aiEnabled,
|
|
94
|
+
autoAcceptMode: false,
|
|
95
|
+
loadedConfig,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
else if (mode === 'ai' && aiEnabled) {
|
|
99
|
+
await handleAiMode(trimmed, {
|
|
100
|
+
configManager,
|
|
101
|
+
aiAgent,
|
|
102
|
+
routingMode: mode,
|
|
103
|
+
agentMode,
|
|
104
|
+
aiEnabled,
|
|
105
|
+
autoAcceptMode: false,
|
|
106
|
+
loadedConfig,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await handleHumanMode(trimmed);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
// Try to use ink - it will handle raw mode setup internally
|
|
114
|
+
try {
|
|
115
|
+
// Render ink app and keep it mounted
|
|
116
|
+
render(React.createElement(InteractiveApp, {
|
|
117
|
+
initialRoutingMode: routingMode,
|
|
118
|
+
initialAgentMode: agentMode,
|
|
119
|
+
aiEnabled,
|
|
120
|
+
onSubmit: handleSubmit,
|
|
121
|
+
onModeChange: (mode) => {
|
|
122
|
+
routingMode = mode;
|
|
123
|
+
showModeSwitched(mode);
|
|
124
|
+
},
|
|
125
|
+
onAgentModeChange: (mode) => {
|
|
126
|
+
agentMode = mode;
|
|
127
|
+
},
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
catch (inkError) {
|
|
131
|
+
// Fallback if ink fails
|
|
132
|
+
console.error(chalk.yellow('\nWarning: Interactive mode requires TTY support'));
|
|
133
|
+
console.log(chalk.yellow('\nFalling back to compatibility mode (paste support disabled)'));
|
|
134
|
+
console.log(chalk.cyan('\nFor full features with paste support, run directly:'));
|
|
135
|
+
console.log(chalk.white(' cd ' + process.cwd()));
|
|
136
|
+
console.log(chalk.white(' CODEVF_API_URL=http://localhost:3000 tsx src/index.ts\n'));
|
|
137
|
+
const readline = await import('readline');
|
|
64
138
|
while (true) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const { line } = await prompts({
|
|
69
|
-
type: 'text',
|
|
70
|
-
name: 'line',
|
|
71
|
-
message: chalk.bold('codevf> '),
|
|
139
|
+
const rl = readline.createInterface({
|
|
140
|
+
input: process.stdin,
|
|
141
|
+
output: process.stdout,
|
|
72
142
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
console.log(chalk.white('/shell').padEnd(18) + chalk.gray('local shell (not shared)'));
|
|
84
|
-
console.log(chalk.white('/codevf').padEnd(18) + chalk.gray('back to session'));
|
|
85
|
-
console.log(chalk.white('/end').padEnd(18) + chalk.gray('end the session'));
|
|
86
|
-
console.log(chalk.white('/tasks').padEnd(18) + chalk.gray('list open tasks'));
|
|
87
|
-
console.log(chalk.white('/cancel <id>').padEnd(18) + chalk.gray('cancel a task'));
|
|
88
|
-
console.log(chalk.white('/?').padEnd(18) + chalk.gray('list commands'));
|
|
89
|
-
console.log(chalk.white('/exit').padEnd(18) + chalk.gray('quit'));
|
|
90
|
-
console.log();
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
else if (trimmed === '/tasks') {
|
|
94
|
-
await tasksCommand(undefined);
|
|
143
|
+
const getModeIndicator = (mode) => {
|
|
144
|
+
switch (mode) {
|
|
145
|
+
case 'hybrid':
|
|
146
|
+
return chalk.green('[Hybrid]');
|
|
147
|
+
case 'ai':
|
|
148
|
+
return chalk.cyan('[AI]');
|
|
149
|
+
case 'human':
|
|
150
|
+
return chalk.magenta('[Human]');
|
|
151
|
+
default:
|
|
152
|
+
return chalk.white('[Unknown]');
|
|
95
153
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
else if (trimmed === '/exit' || trimmed === '/quit') {
|
|
106
|
-
console.log(chalk.dim('Goodbye.'));
|
|
107
|
-
process.exit(0);
|
|
108
|
-
}
|
|
109
|
-
else if (trimmed === '/shell') {
|
|
110
|
-
shellMode = true;
|
|
111
|
-
console.log(chalk.dim('Entered local shell mode (not shared). Type /resume to go back.'));
|
|
112
|
-
// enter shell loop
|
|
113
|
-
while (shellMode) {
|
|
114
|
-
const { line: shellLine } = await prompts({
|
|
115
|
-
type: 'text',
|
|
116
|
-
name: 'line',
|
|
117
|
-
message: chalk.bold('shell> ') + chalk.dim('(local)'),
|
|
118
|
-
});
|
|
119
|
-
if (!shellLine) {
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
const shellTrimmed = shellLine.trim();
|
|
123
|
-
if (shellTrimmed === '/resume' || shellTrimmed === '/session' || shellTrimmed === '/codevf') {
|
|
124
|
-
shellMode = false;
|
|
125
|
-
console.log(chalk.dim('Back to CodeVF prompt.'));
|
|
126
|
-
continue;
|
|
127
|
-
}
|
|
128
|
-
if (shellTrimmed === '/exit' || shellTrimmed === '/quit') {
|
|
129
|
-
console.log(chalk.dim('Goodbye.'));
|
|
130
|
-
process.exit(0);
|
|
131
|
-
}
|
|
132
|
-
if (shellTrimmed.startsWith('/')) {
|
|
133
|
-
console.log(chalk.yellow(`Unknown command in shell: ${shellTrimmed}`));
|
|
134
|
-
console.log(chalk.dim('Use /resume to return to the session prompt.'));
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
try {
|
|
138
|
-
await new Promise((resolve) => {
|
|
139
|
-
const child = spawn(shellTrimmed, {
|
|
140
|
-
shell: true,
|
|
141
|
-
stdio: 'inherit',
|
|
142
|
-
cwd: process.cwd(),
|
|
143
|
-
});
|
|
144
|
-
child.on('exit', () => resolve());
|
|
145
|
-
child.on('error', (err) => {
|
|
146
|
-
console.log(chalk.red(`Command failed: ${err.message}`));
|
|
147
|
-
resolve();
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
shellHistory.push(`$ ${shellTrimmed} (ran with stdio:inherit)`);
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
console.log(chalk.red(`Command failed: ${error.message || error}`));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
console.log(chalk.yellow(`Unknown command: ${trimmed}`));
|
|
159
|
-
console.log(chalk.dim('Type /? to see available commands.'));
|
|
160
|
-
}
|
|
161
|
-
continue;
|
|
154
|
+
};
|
|
155
|
+
const answer = await new Promise((resolve) => {
|
|
156
|
+
rl.question(` ${getModeIndicator(routingMode)} ${chalk.dim('›')} `, (answer) => {
|
|
157
|
+
rl.close();
|
|
158
|
+
resolve(answer);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
if (answer.trim()) {
|
|
162
|
+
await handleSubmit(answer.trim(), routingMode);
|
|
162
163
|
}
|
|
163
|
-
await fixCommand(trimmed);
|
|
164
|
-
// After session ends, return to prompt loop
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
handleError(error);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Command-line argument mode - handle specific commands
|
|
173
|
+
*/
|
|
174
|
+
if (args.length === 0) {
|
|
175
|
+
// Check if this is the first run
|
|
176
|
+
if (isFirstRun()) {
|
|
177
|
+
welcomeCommand().catch(handleError);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
runInteractiveMode();
|
|
181
|
+
}
|
|
171
182
|
}
|
|
172
183
|
else {
|
|
173
184
|
yargs(args)
|
|
174
185
|
.scriptName('codevf')
|
|
175
186
|
.version(CLI_VERSION)
|
|
176
187
|
.usage('$0 <command> [options]')
|
|
177
|
-
.
|
|
188
|
+
.epilogue('For first-time setup, run: codevf welcome\nDocumentation: https://docs.codevf.com')
|
|
189
|
+
.command('login', 'Authenticate with CodeVF (for CLI usage)', () => { }, async () => {
|
|
178
190
|
try {
|
|
179
191
|
await loginCommand();
|
|
180
192
|
}
|
|
@@ -189,6 +201,22 @@ else {
|
|
|
189
201
|
catch (error) {
|
|
190
202
|
handleError(error);
|
|
191
203
|
}
|
|
204
|
+
})
|
|
205
|
+
.command('setup', 'Configure MCP server for Claude Code integration', () => { }, async () => {
|
|
206
|
+
try {
|
|
207
|
+
await setupCommand();
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
handleError(error);
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
.command('welcome', 'Show welcome screen and setup guide', () => { }, async () => {
|
|
214
|
+
try {
|
|
215
|
+
await welcomeCommand();
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
handleError(error);
|
|
219
|
+
}
|
|
192
220
|
})
|
|
193
221
|
.command('init', 'Initialize CodeVF in your project', () => { }, async () => {
|
|
194
222
|
try {
|
|
@@ -222,13 +250,30 @@ else {
|
|
|
222
250
|
}
|
|
223
251
|
})
|
|
224
252
|
.command('fix <issue>', 'Start a live debugging session', (yargs) => {
|
|
225
|
-
return yargs
|
|
253
|
+
return yargs
|
|
254
|
+
.positional('issue', {
|
|
226
255
|
type: 'string',
|
|
227
256
|
describe: 'Description of the issue to fix (or type commands like /human need help with X)',
|
|
228
257
|
demandOption: true,
|
|
258
|
+
})
|
|
259
|
+
.option('ai', {
|
|
260
|
+
type: 'boolean',
|
|
261
|
+
default: false,
|
|
262
|
+
describe: 'Route through local AI (opencode SDK) if enabled',
|
|
263
|
+
})
|
|
264
|
+
.option('no-start-server', {
|
|
265
|
+
type: 'boolean',
|
|
266
|
+
default: false,
|
|
267
|
+
describe: 'Do not auto-start opencode server; require existing server',
|
|
229
268
|
});
|
|
230
269
|
}, async (argv) => {
|
|
231
270
|
try {
|
|
271
|
+
if (argv.ai) {
|
|
272
|
+
const configManager = new ConfigManager();
|
|
273
|
+
const aiAgent = new AiAgent(configManager);
|
|
274
|
+
await aiAgent.run(argv.issue, { startServer: !argv['no-start-server'] });
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
232
277
|
await fixCommand(argv.issue);
|
|
233
278
|
}
|
|
234
279
|
catch (error) {
|