voracode 0.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 +21 -0
- package/README.md +146 -0
- package/dist/main.js +2842 -0
- package/package.json +57 -0
- package/src/cli/audit.ts +34 -0
- package/src/cli/config.ts +54 -0
- package/src/cli/doctor.ts +61 -0
- package/src/cli/init.ts +62 -0
- package/src/cli/key.ts +67 -0
- package/src/cli/lite.ts +65 -0
- package/src/cli/mcp.ts +221 -0
- package/src/cli/model.ts +103 -0
- package/src/cli/plugin.ts +49 -0
- package/src/cli/pro.ts +97 -0
- package/src/cli/run.ts +101 -0
- package/src/cli/session.ts +138 -0
- package/src/cli/skill.ts +156 -0
- package/src/cli/stats.ts +16 -0
- package/src/cli/update.ts +28 -0
- package/src/engine/agent.ts +256 -0
- package/src/engine/sub-agent.ts +122 -0
- package/src/main.ts +77 -0
- package/src/models/adapters/all-providers.ts +302 -0
- package/src/models/router.ts +426 -0
- package/src/security/owasp.ts +254 -0
- package/src/session/manager.ts +118 -0
- package/src/skills/self-improve/engine.ts +336 -0
- package/src/storage/config.ts +213 -0
- package/src/storage/database.ts +253 -0
- package/src/storage/mcp-config.ts +170 -0
- package/src/tools/executor.ts +362 -0
- package/src/ui/theme.ts +163 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* voracode update — Self-update command
|
|
3
|
+
*
|
|
4
|
+
* Checks for new versions on GitHub and applies updates.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
|
|
9
|
+
export const updateCommand = new Command("update")
|
|
10
|
+
.description("Check for updates and update VORACODE")
|
|
11
|
+
.option("--check", "Only check for updates, don't install")
|
|
12
|
+
.option("--channel <channel>", "Release channel (stable|beta)", "stable")
|
|
13
|
+
.option("--force", "Force reinstall current version")
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
const currentVersion = "0.0.1"; // from package.json
|
|
16
|
+
|
|
17
|
+
console.log(`\n 📦 VORACODE v${currentVersion}`);
|
|
18
|
+
console.log(` 🔄 Channel: ${options.channel}`);
|
|
19
|
+
console.log(" 🔍 Checking for updates...");
|
|
20
|
+
|
|
21
|
+
// TODO: Implement actual GitHub release check
|
|
22
|
+
console.log(" (Coming in Phase 1.4 — update system)");
|
|
23
|
+
|
|
24
|
+
console.log("\n To update manually, run:");
|
|
25
|
+
console.log(" npm update -g voracode");
|
|
26
|
+
console.log(" # or: brew upgrade voracode");
|
|
27
|
+
console.log(" # or: scoop update voracode\n");
|
|
28
|
+
});
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VORACODE Agent — Tool-calling agent loop
|
|
3
|
+
*
|
|
4
|
+
* The core intelligence: model suggests tool calls → tools execute →
|
|
5
|
+
* results fed back → model continues → repeat until done.
|
|
6
|
+
*
|
|
7
|
+
* Uses OpenAI function calling to give the model real tool access.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { ModelRouter, type ChatMessage, type ChatOptions } from "../models/router";
|
|
11
|
+
import { VoraDatabase } from "../storage/database";
|
|
12
|
+
import { ToolExecutor } from "../tools/executor";
|
|
13
|
+
import { SelfImprovementEngine } from "../skills/self-improve/engine";
|
|
14
|
+
|
|
15
|
+
export interface AgentResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
content: string;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
tokensUsed: number;
|
|
20
|
+
turns: number;
|
|
21
|
+
steps: number;
|
|
22
|
+
error?: string;
|
|
23
|
+
patternSuggestion?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class Agent {
|
|
27
|
+
private router: ModelRouter;
|
|
28
|
+
private db: VoraDatabase;
|
|
29
|
+
private tools: ToolExecutor;
|
|
30
|
+
private sie: SelfImprovementEngine;
|
|
31
|
+
private systemPrompt: string;
|
|
32
|
+
|
|
33
|
+
constructor() {
|
|
34
|
+
this.router = new ModelRouter();
|
|
35
|
+
this.db = new VoraDatabase();
|
|
36
|
+
this.tools = new ToolExecutor(this.db);
|
|
37
|
+
this.sie = new SelfImprovementEngine(this.db);
|
|
38
|
+
this.systemPrompt = this.buildSystemPrompt();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private buildSystemPrompt(): string {
|
|
42
|
+
return `You are VORACODE, an AI engineering partner that lives in the terminal.
|
|
43
|
+
|
|
44
|
+
You help users with coding tasks. You have access to real tools that let you read, write, and execute code.
|
|
45
|
+
|
|
46
|
+
## How you work
|
|
47
|
+
1. Understand what the user wants
|
|
48
|
+
2. Use tools to explore the project when needed
|
|
49
|
+
3. Plan the changes
|
|
50
|
+
4. Execute step by step using the tools available to you
|
|
51
|
+
5. Tell the user when you're done
|
|
52
|
+
|
|
53
|
+
## Rules
|
|
54
|
+
- NEVER execute dangerous commands (rm -rf /, sudo, mkfs, dd, fork bombs)
|
|
55
|
+
- NEVER output API keys, passwords, or secrets
|
|
56
|
+
- Show what you're doing before doing it
|
|
57
|
+
- Ask the user before destructive operations
|
|
58
|
+
- Use the think tool to reason through complex problems before acting
|
|
59
|
+
- When the task is complete, summarize what you did
|
|
60
|
+
|
|
61
|
+
## Available Tools
|
|
62
|
+
You have file_read, file_write, file_edit, bash, git_status, git_diff, git_commit,
|
|
63
|
+
code_search, web_fetch, think, and list_files at your disposal.
|
|
64
|
+
Use them to accomplish the task. Do NOT just describe what to do — USE the tools.
|
|
65
|
+
|
|
66
|
+
When the task is complete, summarize what was done.`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Run the agent loop with full tool-calling
|
|
71
|
+
*/
|
|
72
|
+
async runTurn(sessionId: string, userMessage: string, modelRef: string, options?: { maxTurns?: number }): Promise<AgentResult> {
|
|
73
|
+
const startTime = Date.now();
|
|
74
|
+
const maxTurns = options?.maxTurns || 15;
|
|
75
|
+
let totalTokens = 0;
|
|
76
|
+
let turns = 0;
|
|
77
|
+
let steps = 0;
|
|
78
|
+
let toolOnlyTurns = 0; // Detection: model only using tools, never summarizing
|
|
79
|
+
|
|
80
|
+
// Get tool schemas to send with each API call
|
|
81
|
+
const toolSchemas = this.tools.getToolSchemas();
|
|
82
|
+
|
|
83
|
+
// Build message history
|
|
84
|
+
const messages: ChatMessage[] = [
|
|
85
|
+
{ role: "system", content: this.systemPrompt },
|
|
86
|
+
{ role: "user", content: userMessage },
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
// Store the initial user message
|
|
90
|
+
this.db.addMessage(sessionId, "user", userMessage);
|
|
91
|
+
|
|
92
|
+
const toolsUsed: string[] = [];
|
|
93
|
+
const filesChanged: string[] = [];
|
|
94
|
+
const commandsRun: string[] = [];
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
while (turns < maxTurns) {
|
|
98
|
+
turns++;
|
|
99
|
+
|
|
100
|
+
const chatOptions: ChatOptions = {
|
|
101
|
+
model: modelRef,
|
|
102
|
+
maxTokens: 2048,
|
|
103
|
+
temperature: 0.3,
|
|
104
|
+
tools: toolSchemas,
|
|
105
|
+
toolChoice: "auto",
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Call the model
|
|
109
|
+
const response = await this.router.chat(modelRef, messages, chatOptions);
|
|
110
|
+
totalTokens += response.usage.totalTokens;
|
|
111
|
+
this.db.recordApiCall(response.usage.inputTokens, response.usage.outputTokens);
|
|
112
|
+
|
|
113
|
+
// Store assistant response
|
|
114
|
+
if (response.content) {
|
|
115
|
+
this.db.addMessage(sessionId, "assistant", response.content, response.usage.totalTokens);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// CASE 1: Model wants to use tools
|
|
119
|
+
if (response.toolCalls && response.toolCalls.length > 0) {
|
|
120
|
+
// If model keeps using tools without responding, detect infinite loop
|
|
121
|
+
toolOnlyTurns++;
|
|
122
|
+
if (toolOnlyTurns > 10) {
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
content: "Task reached maximum tool iterations. Results so far are applied.",
|
|
126
|
+
sessionId,
|
|
127
|
+
tokensUsed: totalTokens,
|
|
128
|
+
turns,
|
|
129
|
+
steps,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// Add the assistant message with tool_calls to history
|
|
133
|
+
messages.push({
|
|
134
|
+
role: "assistant",
|
|
135
|
+
content: response.content || "",
|
|
136
|
+
tool_calls: response.toolCalls,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Track tools used for self-improvement
|
|
140
|
+
|
|
141
|
+
// Execute each tool call
|
|
142
|
+
for (const toolCall of response.toolCalls) {
|
|
143
|
+
steps++;
|
|
144
|
+
toolsUsed.push(toolCall.function.name);
|
|
145
|
+
|
|
146
|
+
// Track file changes and commands for self-improvement
|
|
147
|
+
try {
|
|
148
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
149
|
+
if ((toolCall.function.name === "file_write" || toolCall.function.name === "file_edit") && args.path) {
|
|
150
|
+
filesChanged.push(args.path);
|
|
151
|
+
}
|
|
152
|
+
if (toolCall.function.name === "bash" && args.command) {
|
|
153
|
+
commandsRun.push(args.command);
|
|
154
|
+
}
|
|
155
|
+
} catch {}
|
|
156
|
+
|
|
157
|
+
let result: unknown;
|
|
158
|
+
let error = false;
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
result = await this.tools.execute(toolCall.function.name, toolCall.function.arguments);
|
|
162
|
+
} catch (e) {
|
|
163
|
+
result = `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
164
|
+
error = true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const resultStr = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
168
|
+
|
|
169
|
+
// Truncate very long results
|
|
170
|
+
const truncated = resultStr.length > 5000 ? resultStr.slice(0, 5000) + "\n... (truncated)" : resultStr;
|
|
171
|
+
|
|
172
|
+
// Audit log
|
|
173
|
+
this.db.logAudit(
|
|
174
|
+
error ? "tool_error" : "tool_execute",
|
|
175
|
+
JSON.stringify({ tool: toolCall.function.name }),
|
|
176
|
+
!error,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Add tool result to conversation history
|
|
180
|
+
messages.push({
|
|
181
|
+
role: "tool",
|
|
182
|
+
content: truncated,
|
|
183
|
+
tool_call_id: toolCall.id,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Continue the loop — model will see tool results and decide next step
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// CASE 2: Model responded with text (no tool calls) — task is complete
|
|
192
|
+
this.db.updateSession(sessionId, {
|
|
193
|
+
total_tokens: totalTokens,
|
|
194
|
+
total_turns: turns,
|
|
195
|
+
status: "completed",
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Self-improvement: record task pattern and check for suggestions
|
|
199
|
+
let patternSuggestion: string | undefined;
|
|
200
|
+
if (toolsUsed.length > 0) {
|
|
201
|
+
const pattern = this.sie.recordTask(
|
|
202
|
+
userMessage,
|
|
203
|
+
toolsUsed,
|
|
204
|
+
filesChanged,
|
|
205
|
+
commandsRun,
|
|
206
|
+
true, // success
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
if (pattern) {
|
|
210
|
+
patternSuggestion = `\n\n💡 VORACODE noticed you've done this ${pattern.successCount + 1} times with ${(pattern.successCount / (pattern.successCount + pattern.failureCount) * 100).toFixed(0)}% success.\n Would you like me to create a reusable skill for this?\n Run: voracode skill create ${pattern.description.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 30)}`;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
success: true,
|
|
216
|
+
content: response.content + (patternSuggestion || ""),
|
|
217
|
+
sessionId,
|
|
218
|
+
tokensUsed: totalTokens,
|
|
219
|
+
turns,
|
|
220
|
+
steps,
|
|
221
|
+
patternSuggestion,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// MAX TURNS REACHED
|
|
226
|
+
this.db.updateSession(sessionId, {
|
|
227
|
+
total_tokens: totalTokens,
|
|
228
|
+
total_turns: turns,
|
|
229
|
+
status: "completed",
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
success: true,
|
|
234
|
+
content: "Task reached maximum turns. You can continue with more instructions.",
|
|
235
|
+
sessionId,
|
|
236
|
+
tokensUsed: totalTokens,
|
|
237
|
+
turns,
|
|
238
|
+
steps,
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
242
|
+
this.db.logAudit("agent_error", errorMsg, false);
|
|
243
|
+
this.db.updateSession(sessionId, { status: "error" });
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
success: false,
|
|
247
|
+
content: "",
|
|
248
|
+
sessionId,
|
|
249
|
+
tokensUsed: totalTokens,
|
|
250
|
+
turns,
|
|
251
|
+
steps,
|
|
252
|
+
error: errorMsg,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VORACODE Sub-Agent System — Parallel task execution agents
|
|
3
|
+
*
|
|
4
|
+
* Like Claude Code's sub-agents, Cursor's parallel agents:
|
|
5
|
+
* - Each sub-agent gets its own context window
|
|
6
|
+
* - Runs independently with specific tools
|
|
7
|
+
* - Reports back to main agent
|
|
8
|
+
* - Can use different models per task
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { ModelRouter, type ChatMessage } from "../models/router";
|
|
12
|
+
import { ToolExecutor } from "../tools/executor";
|
|
13
|
+
import { VoraDatabase } from "../storage/database";
|
|
14
|
+
|
|
15
|
+
export interface SubAgentTask {
|
|
16
|
+
id: string;
|
|
17
|
+
description: string;
|
|
18
|
+
modelRef?: string;
|
|
19
|
+
tools?: string[];
|
|
20
|
+
context?: string;
|
|
21
|
+
maxTurns?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SubAgentResult {
|
|
25
|
+
id: string;
|
|
26
|
+
success: boolean;
|
|
27
|
+
content: string;
|
|
28
|
+
tokensUsed: number;
|
|
29
|
+
turns: number;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class SubAgentManager {
|
|
34
|
+
private router: ModelRouter;
|
|
35
|
+
private tools: ToolExecutor;
|
|
36
|
+
private db: VoraDatabase;
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
this.router = new ModelRouter();
|
|
40
|
+
this.db = new VoraDatabase();
|
|
41
|
+
this.tools = new ToolExecutor(this.db);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Run multiple sub-agents in parallel
|
|
46
|
+
*/
|
|
47
|
+
async runParallel(tasks: SubAgentTask[], mainModel = "deepseek/deepseek-chat"): Promise<SubAgentResult[]> {
|
|
48
|
+
const results: SubAgentResult[] = [];
|
|
49
|
+
const BATCH_SIZE = 3; // Max 3 parallel agents
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < tasks.length; i += BATCH_SIZE) {
|
|
52
|
+
const batch = tasks.slice(i, i + BATCH_SIZE);
|
|
53
|
+
const batchResults = await Promise.all(
|
|
54
|
+
batch.map((task) => this.runSingle(task, mainModel)),
|
|
55
|
+
);
|
|
56
|
+
results.push(...batchResults);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Run a single sub-agent
|
|
64
|
+
*/
|
|
65
|
+
async runSingle(task: SubAgentTask, defaultModel: string): Promise<SubAgentResult> {
|
|
66
|
+
const modelRef = task.modelRef || defaultModel;
|
|
67
|
+
const maxTurns = task.maxTurns || 5;
|
|
68
|
+
let turns = 0;
|
|
69
|
+
let totalTokens = 0;
|
|
70
|
+
|
|
71
|
+
const systemPrompt = `You are a VORACODE sub-agent handling a specific task.
|
|
72
|
+
Your task: ${task.description}
|
|
73
|
+
|
|
74
|
+
You have access to tools: ${(task.tools || ["file_read", "file_write", "bash", "think"]).join(", ")}
|
|
75
|
+
|
|
76
|
+
Focus ONLY on your assigned task. Report back concisely.`;
|
|
77
|
+
|
|
78
|
+
const messages: ChatMessage[] = [
|
|
79
|
+
{ role: "system", content: systemPrompt },
|
|
80
|
+
...(task.context ? [{ role: "user" as const, content: task.context }] : []),
|
|
81
|
+
{ role: "user" as const, content: `Execute this task: ${task.description}` },
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
while (turns < maxTurns) {
|
|
86
|
+
turns++;
|
|
87
|
+
const response = await this.router.chat(modelRef, messages, {
|
|
88
|
+
model: modelRef,
|
|
89
|
+
maxTokens: 1024,
|
|
90
|
+
temperature: 0.3,
|
|
91
|
+
tools: this.getToolSchemas(task.tools),
|
|
92
|
+
toolChoice: "auto" as const,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
totalTokens += response.usage.totalTokens;
|
|
96
|
+
|
|
97
|
+
if (response.toolCalls && response.toolCalls.length > 0) {
|
|
98
|
+
messages.push({ role: "assistant", content: response.content || "", tool_calls: response.toolCalls });
|
|
99
|
+
|
|
100
|
+
for (const tc of response.toolCalls) {
|
|
101
|
+
const result = await this.tools.execute(tc.function.name, tc.function.arguments);
|
|
102
|
+
const resultStr = typeof result === "string" ? result : JSON.stringify(result);
|
|
103
|
+
messages.push({ role: "tool", content: resultStr.slice(0, 3000), tool_call_id: tc.id });
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { id: task.id, success: true, content: response.content, tokensUsed: totalTokens, turns };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { id: task.id, success: true, content: "Sub-agent reached max turns.", tokensUsed: totalTokens, turns };
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return { id: task.id, success: false, content: "", tokensUsed: totalTokens, turns, error: String(error) };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private getToolSchemas(allowedTools?: string[]) {
|
|
118
|
+
const all = this.tools.getToolSchemas();
|
|
119
|
+
if (!allowedTools) return all;
|
|
120
|
+
return all.filter((t) => allowedTools.includes(t.function.name));
|
|
121
|
+
}
|
|
122
|
+
}
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* VORACODE — AI Coding Agent
|
|
4
|
+
* One agent, every surface.
|
|
5
|
+
*
|
|
6
|
+
* Premium CLI with ALL features integrated.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
import { runCommand } from "./cli/run";
|
|
11
|
+
import { initCommand } from "./cli/init";
|
|
12
|
+
import { sessionCommand } from "./cli/session";
|
|
13
|
+
import { modelCommand } from "./cli/model";
|
|
14
|
+
import { skillCommand } from "./cli/skill";
|
|
15
|
+
import { keyCommand } from "./cli/key";
|
|
16
|
+
import { configCommand } from "./cli/config";
|
|
17
|
+
import { pluginCommand } from "./cli/plugin";
|
|
18
|
+
import { mcpCommand } from "./cli/mcp";
|
|
19
|
+
import { statsCommand } from "./cli/stats";
|
|
20
|
+
import { doctorCommand } from "./cli/doctor";
|
|
21
|
+
import { auditCommand } from "./cli/audit";
|
|
22
|
+
import { liteCommand } from "./cli/lite";
|
|
23
|
+
import { proCommand } from "./cli/pro";
|
|
24
|
+
import { updateCommand } from "./cli/update";
|
|
25
|
+
import { version } from "../package.json";
|
|
26
|
+
import { c, printBanner, box, footer } from "./ui/theme";
|
|
27
|
+
import { ALL_PROVIDERS, BUILTIN_MCP_SERVERS } from "./models/adapters/all-providers";
|
|
28
|
+
|
|
29
|
+
const VERSION = version || "0.0.1";
|
|
30
|
+
const NAME = "voracode";
|
|
31
|
+
|
|
32
|
+
async function main(): Promise<void> {
|
|
33
|
+
const program = new Command();
|
|
34
|
+
|
|
35
|
+
program
|
|
36
|
+
.name(NAME)
|
|
37
|
+
.description(`${c.brand}${c.bold}${NAME}${c.reset} — ${c.dim}AI Coding Agent${c.reset}`)
|
|
38
|
+
.version(VERSION, "-v, --version", "Show version")
|
|
39
|
+
.helpOption("-h, --help", "Show help")
|
|
40
|
+
.helpCommand(false);
|
|
41
|
+
|
|
42
|
+
program.addCommand(runCommand);
|
|
43
|
+
program.addCommand(initCommand);
|
|
44
|
+
program.addCommand(sessionCommand);
|
|
45
|
+
program.addCommand(modelCommand);
|
|
46
|
+
program.addCommand(skillCommand);
|
|
47
|
+
program.addCommand(keyCommand);
|
|
48
|
+
program.addCommand(configCommand);
|
|
49
|
+
program.addCommand(pluginCommand);
|
|
50
|
+
program.addCommand(mcpCommand);
|
|
51
|
+
program.addCommand(auditCommand);
|
|
52
|
+
program.addCommand(liteCommand);
|
|
53
|
+
program.addCommand(proCommand);
|
|
54
|
+
program.addCommand(statsCommand);
|
|
55
|
+
program.addCommand(doctorCommand);
|
|
56
|
+
program.addCommand(updateCommand);
|
|
57
|
+
|
|
58
|
+
if (process.argv.length <= 2) {
|
|
59
|
+
printBanner();
|
|
60
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}run <task>${c.reset} Execute a task`);
|
|
61
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}init${c.reset} Initialize project`);
|
|
62
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}session list${c.reset} Manage sessions`);
|
|
63
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}model list${c.reset} ${ALL_PROVIDERS.length} providers ready`);
|
|
64
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}mcp list${c.reset} ${BUILTIN_MCP_SERVERS.length} MCP servers`);
|
|
65
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}doctor${c.reset} Health check`);
|
|
66
|
+
console.log(` ${c.dim}${c.bold}${NAME}${c.reset} ${c.dim}--help${c.reset} All commands`);
|
|
67
|
+
footer();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await program.parseAsync(process.argv);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main().catch((error) => {
|
|
75
|
+
console.error(`\n ${c.error}✖ ${c.reset}${c.error}${error instanceof Error ? error.message : String(error)}${c.reset}\n`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|