vibe-weaver 1.0.0
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/README.md +229 -0
- package/bin/vibe-weaver.js +8 -0
- package/dist/bin/vibe-weaver.js +8 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2018 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
- package/src/agent/deploy.ts +171 -0
- package/src/agent/swarm.ts +167 -0
- package/src/agent/tasks.ts +205 -0
- package/src/auth/index.ts +273 -0
- package/src/config/index.ts +86 -0
- package/src/index.ts +797 -0
- package/src/lib/code-parser.ts +150 -0
- package/src/lib/vibe-api.ts +197 -0
- package/src/mcp/index.ts +273 -0
- package/src/tools/files.ts +279 -0
- package/src/tools/git.ts +498 -0
- package/src/tools/shell.ts +248 -0
- package/tsconfig.json +25 -0
- package/tsup.config.ts +34 -0
- package/vibe-weaver-1.0.0.tgz +0 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2018 @@
|
|
|
1
|
+
import envPaths from 'env-paths';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path2 from 'path';
|
|
4
|
+
import chalk8 from 'chalk';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import open from 'open';
|
|
7
|
+
import { execaCommand } from 'execa';
|
|
8
|
+
import 'ora';
|
|
9
|
+
import simpleGit from 'simple-git';
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import fs2 from 'fs/promises';
|
|
12
|
+
|
|
13
|
+
var __defProp = Object.defineProperty;
|
|
14
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
21
|
+
var __esm = (fn, res) => function __init() {
|
|
22
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
23
|
+
};
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
function getConfigDir() {
|
|
29
|
+
const paths = envPaths("vibe-weaver", { suffix: "" });
|
|
30
|
+
if (!fs.existsSync(paths.config)) {
|
|
31
|
+
fs.mkdirSync(paths.config, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
fs.chmodSync(paths.config, 448);
|
|
34
|
+
return paths.config;
|
|
35
|
+
}
|
|
36
|
+
function getConfigPath() {
|
|
37
|
+
return path2.join(getConfigDir(), CONFIG_FILE_NAME);
|
|
38
|
+
}
|
|
39
|
+
function loadConfig() {
|
|
40
|
+
const configPath = getConfigPath();
|
|
41
|
+
try {
|
|
42
|
+
if (fs.existsSync(configPath)) {
|
|
43
|
+
const data = fs.readFileSync(configPath, "utf-8");
|
|
44
|
+
return JSON.parse(data);
|
|
45
|
+
}
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.warn("Warning: Failed to load config:", error);
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
function saveConfig(config) {
|
|
52
|
+
const configPath = getConfigPath();
|
|
53
|
+
try {
|
|
54
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), {
|
|
55
|
+
mode: 384
|
|
56
|
+
});
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new Error(`Failed to save config: ${error}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function getDefaultSupabaseUrl() {
|
|
62
|
+
return process.env.VW_SUPABASE_URL || "https://mmtsoqelnsjleusqyknc.supabase.co";
|
|
63
|
+
}
|
|
64
|
+
function getSupabaseUrl() {
|
|
65
|
+
const config = loadConfig();
|
|
66
|
+
return config.supabaseUrl || getDefaultSupabaseUrl();
|
|
67
|
+
}
|
|
68
|
+
var CONFIG_FILE_NAME;
|
|
69
|
+
var init_config = __esm({
|
|
70
|
+
"src/config/index.ts"() {
|
|
71
|
+
CONFIG_FILE_NAME = "config.json";
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
async function getSecret(account) {
|
|
75
|
+
if (keytar) {
|
|
76
|
+
try {
|
|
77
|
+
const value = await keytar.getPassword(SERVICE_NAME, account);
|
|
78
|
+
if (value) return value;
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const config = loadConfig();
|
|
83
|
+
if (account === API_KEY_ACCOUNT) return config.apiKey || null;
|
|
84
|
+
if (account === GITHUB_TOKEN_ACCOUNT) return config.githubToken || null;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
async function setSecret(account, value) {
|
|
88
|
+
if (keytar) {
|
|
89
|
+
try {
|
|
90
|
+
await keytar.setPassword(SERVICE_NAME, account, value);
|
|
91
|
+
const config2 = loadConfig();
|
|
92
|
+
if (account === API_KEY_ACCOUNT) config2.apiKey = value;
|
|
93
|
+
if (account === GITHUB_TOKEN_ACCOUNT) config2.githubToken = value;
|
|
94
|
+
saveConfig(config2);
|
|
95
|
+
return;
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const config = loadConfig();
|
|
100
|
+
if (account === API_KEY_ACCOUNT) config.apiKey = value;
|
|
101
|
+
if (account === GITHUB_TOKEN_ACCOUNT) config.githubToken = value;
|
|
102
|
+
saveConfig(config);
|
|
103
|
+
}
|
|
104
|
+
async function deleteSecret(account) {
|
|
105
|
+
if (keytar) {
|
|
106
|
+
try {
|
|
107
|
+
await keytar.deletePassword(SERVICE_NAME, account);
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const config = loadConfig();
|
|
112
|
+
if (account === API_KEY_ACCOUNT) {
|
|
113
|
+
config.apiKey = void 0;
|
|
114
|
+
}
|
|
115
|
+
if (account === GITHUB_TOKEN_ACCOUNT) {
|
|
116
|
+
config.githubToken = void 0;
|
|
117
|
+
}
|
|
118
|
+
saveConfig(config);
|
|
119
|
+
}
|
|
120
|
+
async function isLoggedIn() {
|
|
121
|
+
const apiKey = await getSecret(API_KEY_ACCOUNT);
|
|
122
|
+
return !!apiKey;
|
|
123
|
+
}
|
|
124
|
+
async function getApiKey() {
|
|
125
|
+
return getSecret(API_KEY_ACCOUNT);
|
|
126
|
+
}
|
|
127
|
+
async function getGithubToken() {
|
|
128
|
+
return getSecret(GITHUB_TOKEN_ACCOUNT);
|
|
129
|
+
}
|
|
130
|
+
async function login(options = {}) {
|
|
131
|
+
const supabaseUrl = getSupabaseUrl();
|
|
132
|
+
if (options.apiKey) {
|
|
133
|
+
await setSecret(API_KEY_ACCOUNT, options.apiKey);
|
|
134
|
+
console.log(chalk8.green("\u2713 API key saved securely"));
|
|
135
|
+
const userInfo2 = await getUserInfo();
|
|
136
|
+
if (userInfo2) {
|
|
137
|
+
console.log(chalk8.green(`\u2713 Logged in as ${userInfo2.email} (${userInfo2.plan} plan)`));
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (options.openBrowser) {
|
|
142
|
+
const apiPageUrl = `${supabaseUrl}/dashboard/api`;
|
|
143
|
+
console.log(chalk8.blue("Opening browser to create API key..."));
|
|
144
|
+
await open(apiPageUrl);
|
|
145
|
+
}
|
|
146
|
+
const answers = await inquirer.prompt([
|
|
147
|
+
{
|
|
148
|
+
type: "input",
|
|
149
|
+
name: "apiKey",
|
|
150
|
+
message: "Enter your Vibe-Weaver API key (vw_...):",
|
|
151
|
+
validate: (input) => {
|
|
152
|
+
if (!input.startsWith("vw_") && input.length < 10) {
|
|
153
|
+
return "Please enter a valid API key (starts with vw_)";
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
]);
|
|
159
|
+
await setSecret(API_KEY_ACCOUNT, answers.apiKey);
|
|
160
|
+
console.log(chalk8.green("\u2713 API key saved securely"));
|
|
161
|
+
const userInfo = await getUserInfo();
|
|
162
|
+
if (userInfo) {
|
|
163
|
+
console.log(chalk8.green(`\u2713 Logged in as ${userInfo.email} (${userInfo.plan} plan)`));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function loginGithub(token) {
|
|
167
|
+
if (!token) {
|
|
168
|
+
const answers = await inquirer.prompt([
|
|
169
|
+
{
|
|
170
|
+
type: "password",
|
|
171
|
+
name: "token",
|
|
172
|
+
message: "Enter your GitHub Personal Access Token:",
|
|
173
|
+
validate: (input) => {
|
|
174
|
+
if (input.length < 10) {
|
|
175
|
+
return "Please enter a valid GitHub token";
|
|
176
|
+
}
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
]);
|
|
181
|
+
token = answers.token;
|
|
182
|
+
}
|
|
183
|
+
await setSecret(GITHUB_TOKEN_ACCOUNT, token);
|
|
184
|
+
console.log(chalk8.green("\u2713 GitHub token saved securely"));
|
|
185
|
+
}
|
|
186
|
+
async function logout() {
|
|
187
|
+
await deleteSecret(API_KEY_ACCOUNT);
|
|
188
|
+
await deleteSecret(GITHUB_TOKEN_ACCOUNT);
|
|
189
|
+
console.log(chalk8.green("\u2713 Logged out successfully"));
|
|
190
|
+
}
|
|
191
|
+
async function getUserInfo() {
|
|
192
|
+
const apiKey = await getApiKey();
|
|
193
|
+
if (!apiKey) return null;
|
|
194
|
+
const supabaseUrl = getSupabaseUrl();
|
|
195
|
+
try {
|
|
196
|
+
const response = await fetch(`${supabaseUrl}/rest/v1/profiles?select=email,plan,credits`, {
|
|
197
|
+
headers: {
|
|
198
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
199
|
+
"apikey": `${supabaseUrl}/rest/v1/apikey`
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
if (response.ok) {
|
|
203
|
+
const data = await response.json();
|
|
204
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
205
|
+
return {
|
|
206
|
+
email: data[0].email || "Unknown",
|
|
207
|
+
plan: data[0].plan || "free",
|
|
208
|
+
credits: data[0].credits || 0
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.warn("Warning: Could not fetch user info:", error);
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
async function whoami() {
|
|
218
|
+
const apiKey = await getApiKey();
|
|
219
|
+
if (!apiKey) {
|
|
220
|
+
console.log(chalk8.yellow('Not logged in. Run "vibe-weaver login" first.'));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const userInfo = await getUserInfo();
|
|
224
|
+
if (userInfo) {
|
|
225
|
+
console.log(chalk8.bold("Logged in as:"));
|
|
226
|
+
console.log(` Email: ${userInfo.email}`);
|
|
227
|
+
console.log(` Plan: ${chalk8.cyan(userInfo.plan)}`);
|
|
228
|
+
console.log(` Credits: ${chalk8.green(userInfo.credits.toString())}`);
|
|
229
|
+
} else {
|
|
230
|
+
console.log(chalk8.yellow("API key is set but could not fetch user info."));
|
|
231
|
+
console.log(` API Key: ${chalk8.grey(apiKey.substring(0, 10))}...`);
|
|
232
|
+
}
|
|
233
|
+
const githubToken = await getGithubToken();
|
|
234
|
+
if (githubToken) {
|
|
235
|
+
console.log(chalk8.green("\u2713 GitHub token configured"));
|
|
236
|
+
} else {
|
|
237
|
+
console.log(chalk8.grey(' GitHub: Not configured (run "vibe-weaver login --github" to add)'));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
var SERVICE_NAME, API_KEY_ACCOUNT, GITHUB_TOKEN_ACCOUNT, keytar;
|
|
241
|
+
var init_auth = __esm({
|
|
242
|
+
"src/auth/index.ts"() {
|
|
243
|
+
init_config();
|
|
244
|
+
SERVICE_NAME = "vibe-weaver";
|
|
245
|
+
API_KEY_ACCOUNT = "api-key";
|
|
246
|
+
GITHUB_TOKEN_ACCOUNT = "github-token";
|
|
247
|
+
keytar = null;
|
|
248
|
+
try {
|
|
249
|
+
keytar = __require("keytar");
|
|
250
|
+
} catch {
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// src/lib/code-parser.ts
|
|
256
|
+
function parseCodeBlocks(response) {
|
|
257
|
+
const blocks = [];
|
|
258
|
+
const codeBlockRegex = /```(\w+)?\s+(.+?)\n([\s\S]*?)```/g;
|
|
259
|
+
let match;
|
|
260
|
+
while ((match = codeBlockRegex.exec(response)) !== null) {
|
|
261
|
+
const language = match[1] || "text";
|
|
262
|
+
const path4 = match[2].trim();
|
|
263
|
+
const content = match[3];
|
|
264
|
+
const beforeBlock = response.substring(0, match.index);
|
|
265
|
+
const startLine = (beforeBlock.match(/\n/g) || []).length + 1;
|
|
266
|
+
const endLine = startLine + (content.match(/\n/g) || []).length;
|
|
267
|
+
blocks.push({
|
|
268
|
+
language,
|
|
269
|
+
path: path4,
|
|
270
|
+
content,
|
|
271
|
+
startLine,
|
|
272
|
+
endLine
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
let explanation;
|
|
276
|
+
const firstCodeBlockIndex = response.indexOf("```");
|
|
277
|
+
if (firstCodeBlockIndex > 0) {
|
|
278
|
+
explanation = response.substring(0, firstCodeBlockIndex).trim();
|
|
279
|
+
}
|
|
280
|
+
return { blocks, explanation };
|
|
281
|
+
}
|
|
282
|
+
async function writeCodeBlocks(blocks, baseDir, options = {}) {
|
|
283
|
+
const fs3 = await import('fs/promises');
|
|
284
|
+
const path4 = await import('path');
|
|
285
|
+
const success = [];
|
|
286
|
+
const failed = [];
|
|
287
|
+
for (const block of blocks) {
|
|
288
|
+
try {
|
|
289
|
+
const fullPath = path4.join(baseDir, block.path);
|
|
290
|
+
const dir = path4.dirname(fullPath);
|
|
291
|
+
if (!options.dryRun) {
|
|
292
|
+
await fs3.mkdir(dir, { recursive: true });
|
|
293
|
+
await fs3.writeFile(fullPath, block.content, "utf-8");
|
|
294
|
+
}
|
|
295
|
+
success.push(block.path);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
failed.push({
|
|
298
|
+
path: block.path,
|
|
299
|
+
error: error instanceof Error ? error.message : String(error)
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return { success, failed };
|
|
304
|
+
}
|
|
305
|
+
function generateDiff(oldContent, newContent, filePath) {
|
|
306
|
+
const diff = __require("diff");
|
|
307
|
+
const changes = diff.diffLines(oldContent, newContent);
|
|
308
|
+
let result = `--- ${filePath}
|
|
309
|
+
+++ ${filePath}
|
|
310
|
+
`;
|
|
311
|
+
for (const change of changes) {
|
|
312
|
+
const prefix = change.added ? "+" : change.removed ? "-" : " ";
|
|
313
|
+
const lines = change.value.split("\n").filter((l) => l.length > 0);
|
|
314
|
+
for (const line of lines) {
|
|
315
|
+
result += `${prefix}${line}
|
|
316
|
+
`;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
var init_code_parser = __esm({
|
|
322
|
+
"src/lib/code-parser.ts"() {
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// src/lib/vibe-api.ts
|
|
327
|
+
function getCreditCost(modelId) {
|
|
328
|
+
const costs = {
|
|
329
|
+
"fast": 0.2,
|
|
330
|
+
"balanced": 0.5,
|
|
331
|
+
"deep_reasoning": 1,
|
|
332
|
+
"refactor": 1
|
|
333
|
+
};
|
|
334
|
+
return costs[modelId] || 0.5;
|
|
335
|
+
}
|
|
336
|
+
async function generateCode(options) {
|
|
337
|
+
const apiKey = await getApiKey();
|
|
338
|
+
if (!apiKey) {
|
|
339
|
+
throw new Error('Not logged in. Run "vibe-weaver login" first.');
|
|
340
|
+
}
|
|
341
|
+
const supabaseUrl = getSupabaseUrl();
|
|
342
|
+
const endpoint = `${supabaseUrl}/functions/v1/vibe-ai-api`;
|
|
343
|
+
const payload = {
|
|
344
|
+
goal: options.goal,
|
|
345
|
+
platform: options.platform || "web",
|
|
346
|
+
language: options.language || "typescript",
|
|
347
|
+
modelId: options.modelId || "balanced"
|
|
348
|
+
};
|
|
349
|
+
console.log(`
|
|
350
|
+
${"[Vibe-Weaver]".padEnd(20)} Calling ${payload.modelId.toUpperCase()} model for: ${options.goal.substring(0, 50)}...`);
|
|
351
|
+
const response = await fetch(endpoint, {
|
|
352
|
+
method: "POST",
|
|
353
|
+
headers: {
|
|
354
|
+
"Content-Type": "application/json",
|
|
355
|
+
"Authorization": `Bearer ${apiKey}`
|
|
356
|
+
},
|
|
357
|
+
body: JSON.stringify(payload)
|
|
358
|
+
});
|
|
359
|
+
if (!response.ok) {
|
|
360
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
361
|
+
if (response.status === 401) {
|
|
362
|
+
throw new Error('Authentication failed. Please run "vibe-weaver login" again.');
|
|
363
|
+
}
|
|
364
|
+
if (response.status === 402) {
|
|
365
|
+
throw new Error(`Insufficient credits: ${error.message}`);
|
|
366
|
+
}
|
|
367
|
+
throw new Error(`API error: ${error.error || error.message}`);
|
|
368
|
+
}
|
|
369
|
+
const result = await response.json();
|
|
370
|
+
const parsed = parseCodeBlocks(result.code);
|
|
371
|
+
return {
|
|
372
|
+
code: result.code,
|
|
373
|
+
explanation: result.explanation || "",
|
|
374
|
+
quality: result.quality || { score: 0, issues: [], suggestions: [] },
|
|
375
|
+
stats: result.stats || { mode: payload.modelId, parameters: "N/A", architecture: "N/A", inferenceTimeMs: 0 },
|
|
376
|
+
parsed
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
var init_vibe_api = __esm({
|
|
380
|
+
"src/lib/vibe-api.ts"() {
|
|
381
|
+
init_auth();
|
|
382
|
+
init_config();
|
|
383
|
+
init_code_parser();
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
async function runShell(command, options = {}) {
|
|
387
|
+
const startTime = Date.now();
|
|
388
|
+
if (options.dryRun) {
|
|
389
|
+
console.log(chalk8.grey(`[DRY-RUN] Would execute: ${command}`));
|
|
390
|
+
return {
|
|
391
|
+
success: true,
|
|
392
|
+
command,
|
|
393
|
+
exitCode: 0,
|
|
394
|
+
stdout: "",
|
|
395
|
+
stderr: "",
|
|
396
|
+
duration: 0
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
const result = await execaCommand(command, {
|
|
401
|
+
cwd: options.cwd || process.cwd(),
|
|
402
|
+
env: { ...process.env, ...options.env },
|
|
403
|
+
timeout: options.timeout || 12e4,
|
|
404
|
+
// 2 minute default timeout
|
|
405
|
+
shell: options.shell || true,
|
|
406
|
+
reject: false,
|
|
407
|
+
cleanup: true
|
|
408
|
+
});
|
|
409
|
+
const duration = Date.now() - startTime;
|
|
410
|
+
return {
|
|
411
|
+
success: result.exitCode === 0,
|
|
412
|
+
command,
|
|
413
|
+
exitCode: result.exitCode || 0,
|
|
414
|
+
stdout: result.stdout || "",
|
|
415
|
+
stderr: result.stderr || "",
|
|
416
|
+
duration
|
|
417
|
+
};
|
|
418
|
+
} catch (error) {
|
|
419
|
+
const duration = Date.now() - startTime;
|
|
420
|
+
return {
|
|
421
|
+
success: false,
|
|
422
|
+
command,
|
|
423
|
+
exitCode: 1,
|
|
424
|
+
stdout: "",
|
|
425
|
+
stderr: error instanceof Error ? error.message : String(error),
|
|
426
|
+
timedOut: error instanceof Error && error.message.includes("timeout"),
|
|
427
|
+
duration
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
432
|
+
const fs3 = __require("fs");
|
|
433
|
+
if (fs3.existsSync(`${cwd}/pnpm-lock.yaml`)) return "pnpm";
|
|
434
|
+
if (fs3.existsSync(`${cwd}/yarn.lock`)) return "yarn";
|
|
435
|
+
if (fs3.existsSync(`${cwd}/bun.lockb`)) return "bun";
|
|
436
|
+
return "npm";
|
|
437
|
+
}
|
|
438
|
+
function getInstallCommand(cwd = process.cwd()) {
|
|
439
|
+
const pm = detectPackageManager(cwd);
|
|
440
|
+
switch (pm) {
|
|
441
|
+
case "pnpm":
|
|
442
|
+
return buildCommands.pnpmInstall;
|
|
443
|
+
case "yarn":
|
|
444
|
+
return buildCommands.yarnInstall;
|
|
445
|
+
case "bun":
|
|
446
|
+
return buildCommands.bunInstall;
|
|
447
|
+
default:
|
|
448
|
+
return buildCommands.npmInstall;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function getBuildCommand(cwd = process.cwd()) {
|
|
452
|
+
const pm = detectPackageManager(cwd);
|
|
453
|
+
switch (pm) {
|
|
454
|
+
case "pnpm":
|
|
455
|
+
return buildCommands.pnpmBuild;
|
|
456
|
+
case "yarn":
|
|
457
|
+
return buildCommands.yarnBuild;
|
|
458
|
+
case "bun":
|
|
459
|
+
return buildCommands.bunBuild;
|
|
460
|
+
default:
|
|
461
|
+
return buildCommands.npmBuild;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
var buildCommands;
|
|
465
|
+
var init_shell = __esm({
|
|
466
|
+
"src/tools/shell.ts"() {
|
|
467
|
+
buildCommands = {
|
|
468
|
+
npmInstall: "npm install",
|
|
469
|
+
npmBuild: "npm run build",
|
|
470
|
+
npmTest: "npm test",
|
|
471
|
+
npmLint: "npm run lint",
|
|
472
|
+
npmTypecheck: "npm run typecheck",
|
|
473
|
+
pnpmInstall: "pnpm install",
|
|
474
|
+
pnpmBuild: "pnpm run build",
|
|
475
|
+
bunInstall: "bun install",
|
|
476
|
+
bunBuild: "bun run build",
|
|
477
|
+
yarnInstall: "yarn install",
|
|
478
|
+
yarnBuild: "yarn run build"
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// src/tools/git.ts
|
|
484
|
+
var git_exports = {};
|
|
485
|
+
__export(git_exports, {
|
|
486
|
+
checkout: () => checkout,
|
|
487
|
+
commit: () => commit,
|
|
488
|
+
commitAll: () => commitAll,
|
|
489
|
+
commitFilesToGithub: () => commitFilesToGithub,
|
|
490
|
+
createBranch: () => createBranch,
|
|
491
|
+
createBranchOnGithub: () => createBranchOnGithub,
|
|
492
|
+
createPullRequestOnGithub: () => createPullRequestOnGithub,
|
|
493
|
+
default: () => git_default,
|
|
494
|
+
fullPRWorkflow: () => fullPRWorkflow,
|
|
495
|
+
getBranch: () => getBranch,
|
|
496
|
+
getDiff: () => getDiff,
|
|
497
|
+
getGit: () => getGit,
|
|
498
|
+
getLog: () => getLog,
|
|
499
|
+
getRemote: () => getRemote,
|
|
500
|
+
getStatus: () => getStatus,
|
|
501
|
+
init: () => init,
|
|
502
|
+
isRepo: () => isRepo,
|
|
503
|
+
pull: () => pull,
|
|
504
|
+
push: () => push,
|
|
505
|
+
stage: () => stage,
|
|
506
|
+
stageAll: () => stageAll
|
|
507
|
+
});
|
|
508
|
+
function getGit(cwd = process.cwd()) {
|
|
509
|
+
return simpleGit(cwd);
|
|
510
|
+
}
|
|
511
|
+
async function getStatus(cwd = process.cwd()) {
|
|
512
|
+
const git = getGit(cwd);
|
|
513
|
+
const status = await git.status();
|
|
514
|
+
return {
|
|
515
|
+
current: status.current,
|
|
516
|
+
tracking: status.tracking,
|
|
517
|
+
ahead: status.ahead,
|
|
518
|
+
behind: status.behind,
|
|
519
|
+
staged: status.staged,
|
|
520
|
+
modified: status.modified,
|
|
521
|
+
untracked: status.not_added,
|
|
522
|
+
conflicted: status.conflicted
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
async function getBranch(cwd = process.cwd()) {
|
|
526
|
+
const git = getGit(cwd);
|
|
527
|
+
const branchSummary = await git.branch();
|
|
528
|
+
return branchSummary.current;
|
|
529
|
+
}
|
|
530
|
+
async function getLog(cwd = process.cwd(), maxCount = 10) {
|
|
531
|
+
const git = getGit(cwd);
|
|
532
|
+
const log = await git.log({ maxCount });
|
|
533
|
+
return log.all.map((entry) => ({
|
|
534
|
+
hash: entry.hash,
|
|
535
|
+
date: entry.date,
|
|
536
|
+
message: entry.message,
|
|
537
|
+
author_name: entry.author_name,
|
|
538
|
+
author_email: entry.author_email
|
|
539
|
+
}));
|
|
540
|
+
}
|
|
541
|
+
async function stage(files, cwd = process.cwd()) {
|
|
542
|
+
const git = getGit(cwd);
|
|
543
|
+
await git.add(files);
|
|
544
|
+
}
|
|
545
|
+
async function stageAll(cwd = process.cwd()) {
|
|
546
|
+
const git = getGit(cwd);
|
|
547
|
+
await git.add(".");
|
|
548
|
+
}
|
|
549
|
+
async function commit(message, cwd = process.cwd()) {
|
|
550
|
+
const git = getGit(cwd);
|
|
551
|
+
try {
|
|
552
|
+
const result = await git.commit(message);
|
|
553
|
+
return {
|
|
554
|
+
success: true,
|
|
555
|
+
commitSha: result.commit,
|
|
556
|
+
message: result.summary.changes + " file(s) changed"
|
|
557
|
+
};
|
|
558
|
+
} catch (error) {
|
|
559
|
+
return {
|
|
560
|
+
success: false,
|
|
561
|
+
error: error instanceof Error ? error.message : String(error)
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
async function commitAll(message, cwd = process.cwd()) {
|
|
566
|
+
await stageAll(cwd);
|
|
567
|
+
return commit(message, cwd);
|
|
568
|
+
}
|
|
569
|
+
async function push(options = {}, cwd = process.cwd()) {
|
|
570
|
+
const git = getGit(cwd);
|
|
571
|
+
try {
|
|
572
|
+
const result = await git.push(options.remote || "origin", options.branch || "HEAD", {
|
|
573
|
+
"--force": options.force || false
|
|
574
|
+
});
|
|
575
|
+
return {
|
|
576
|
+
success: true,
|
|
577
|
+
commitSha: result.pushed[0]?.hash,
|
|
578
|
+
message: "Push successful"
|
|
579
|
+
};
|
|
580
|
+
} catch (error) {
|
|
581
|
+
return {
|
|
582
|
+
success: false,
|
|
583
|
+
error: error instanceof Error ? error.message : String(error)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
async function pull(options = {}, cwd = process.cwd()) {
|
|
588
|
+
const git = getGit(cwd);
|
|
589
|
+
try {
|
|
590
|
+
const result = await git.pull(options.remote || "origin", options.branch || "HEAD");
|
|
591
|
+
return {
|
|
592
|
+
success: true,
|
|
593
|
+
message: "Pull successful"
|
|
594
|
+
};
|
|
595
|
+
} catch (error) {
|
|
596
|
+
return {
|
|
597
|
+
success: false,
|
|
598
|
+
error: error instanceof Error ? error.message : String(error)
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
async function createBranch(branchName, options = {}, cwd = process.cwd()) {
|
|
603
|
+
const git = getGit(cwd);
|
|
604
|
+
try {
|
|
605
|
+
if (options.checkout) {
|
|
606
|
+
await git.checkoutLocalBranch(branchName);
|
|
607
|
+
} else {
|
|
608
|
+
await git.branch([branchName]);
|
|
609
|
+
}
|
|
610
|
+
return {
|
|
611
|
+
success: true,
|
|
612
|
+
message: `Branch ${branchName} created`
|
|
613
|
+
};
|
|
614
|
+
} catch (error) {
|
|
615
|
+
return {
|
|
616
|
+
success: false,
|
|
617
|
+
error: error instanceof Error ? error.message : String(error)
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
async function checkout(branchName, cwd = process.cwd()) {
|
|
622
|
+
const git = getGit(cwd);
|
|
623
|
+
try {
|
|
624
|
+
await git.checkout(branchName);
|
|
625
|
+
return {
|
|
626
|
+
success: true,
|
|
627
|
+
message: `Switched to branch ${branchName}`
|
|
628
|
+
};
|
|
629
|
+
} catch (error) {
|
|
630
|
+
return {
|
|
631
|
+
success: false,
|
|
632
|
+
error: error instanceof Error ? error.message : String(error)
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async function getDiff(options = {}, cwd = process.cwd()) {
|
|
637
|
+
const git = getGit(cwd);
|
|
638
|
+
if (options.staged) {
|
|
639
|
+
return git.diff(["--staged"]);
|
|
640
|
+
}
|
|
641
|
+
if (options.from && options.to) {
|
|
642
|
+
return git.diff([options.from, options.to]);
|
|
643
|
+
}
|
|
644
|
+
return git.diff();
|
|
645
|
+
}
|
|
646
|
+
async function isRepo(cwd = process.cwd()) {
|
|
647
|
+
const git = getGit(cwd);
|
|
648
|
+
return git.checkIsRepo();
|
|
649
|
+
}
|
|
650
|
+
async function init(cwd = process.cwd()) {
|
|
651
|
+
const git = getGit(cwd);
|
|
652
|
+
try {
|
|
653
|
+
await git.init();
|
|
654
|
+
return {
|
|
655
|
+
success: true,
|
|
656
|
+
message: "Git repository initialized"
|
|
657
|
+
};
|
|
658
|
+
} catch (error) {
|
|
659
|
+
return {
|
|
660
|
+
success: false,
|
|
661
|
+
error: error instanceof Error ? error.message : String(error)
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
async function getRemote(cwd = process.cwd()) {
|
|
666
|
+
const git = getGit(cwd);
|
|
667
|
+
const remotes = await git.getRemotes(true);
|
|
668
|
+
const origin = remotes.find((r) => r.name === "origin");
|
|
669
|
+
return origin?.refs.fetch || null;
|
|
670
|
+
}
|
|
671
|
+
async function callGithubSync(action, params) {
|
|
672
|
+
const apiKey = await getGithubToken();
|
|
673
|
+
if (!apiKey) {
|
|
674
|
+
throw new Error('GitHub token not configured. Run "vibe-weaver login --github" first.');
|
|
675
|
+
}
|
|
676
|
+
const supabaseUrl = getSupabaseUrl();
|
|
677
|
+
const endpoint = `${supabaseUrl}/functions/v1/github-ai-sync`;
|
|
678
|
+
const response = await fetch(endpoint, {
|
|
679
|
+
method: "POST",
|
|
680
|
+
headers: {
|
|
681
|
+
"Content-Type": "application/json",
|
|
682
|
+
"Authorization": `Bearer ${apiKey}`
|
|
683
|
+
},
|
|
684
|
+
body: JSON.stringify({
|
|
685
|
+
action,
|
|
686
|
+
token: apiKey,
|
|
687
|
+
...params
|
|
688
|
+
})
|
|
689
|
+
});
|
|
690
|
+
if (!response.ok) {
|
|
691
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
692
|
+
throw new Error(`GitHub API error: ${error.error || error.message}`);
|
|
693
|
+
}
|
|
694
|
+
return response.json();
|
|
695
|
+
}
|
|
696
|
+
async function commitFilesToGithub(options) {
|
|
697
|
+
try {
|
|
698
|
+
const result = await callGithubSync("commit_files", options);
|
|
699
|
+
return {
|
|
700
|
+
success: true,
|
|
701
|
+
commitSha: result.commitSha,
|
|
702
|
+
message: `Committed ${result.files?.length || 0} file(s) to ${options.branch}`,
|
|
703
|
+
files: result.files
|
|
704
|
+
};
|
|
705
|
+
} catch (error) {
|
|
706
|
+
return {
|
|
707
|
+
success: false,
|
|
708
|
+
error: error instanceof Error ? error.message : String(error)
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
async function createBranchOnGithub(options) {
|
|
713
|
+
try {
|
|
714
|
+
const result = await callGithubSync("create_branch", options);
|
|
715
|
+
return {
|
|
716
|
+
success: true,
|
|
717
|
+
commitSha: result.sha,
|
|
718
|
+
message: `Created branch ${options.newBranch} from ${options.fromBranch}`
|
|
719
|
+
};
|
|
720
|
+
} catch (error) {
|
|
721
|
+
return {
|
|
722
|
+
success: false,
|
|
723
|
+
error: error instanceof Error ? error.message : String(error)
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
async function createPullRequestOnGithub(options) {
|
|
728
|
+
try {
|
|
729
|
+
const result = await callGithubSync("create_pr", options);
|
|
730
|
+
return {
|
|
731
|
+
success: true,
|
|
732
|
+
prNumber: result.prNumber,
|
|
733
|
+
prUrl: result.prUrl
|
|
734
|
+
};
|
|
735
|
+
} catch (error) {
|
|
736
|
+
return {
|
|
737
|
+
success: false,
|
|
738
|
+
error: error instanceof Error ? error.message : String(error)
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
async function fullPRWorkflow(options) {
|
|
743
|
+
console.log(chalk8.blue("\n=== GitHub PR Workflow ==="));
|
|
744
|
+
console.log(chalk8.gray("1. Creating branch..."));
|
|
745
|
+
const branchResult = await createBranchOnGithub({
|
|
746
|
+
owner: options.owner,
|
|
747
|
+
repo: options.repo,
|
|
748
|
+
newBranch: options.branchName,
|
|
749
|
+
fromBranch: options.baseBranch
|
|
750
|
+
});
|
|
751
|
+
if (!branchResult.success) {
|
|
752
|
+
return { success: false, error: `Failed to create branch: ${branchResult.error}` };
|
|
753
|
+
}
|
|
754
|
+
console.log(chalk8.green(` \u2713 Branch ${options.branchName} created`));
|
|
755
|
+
console.log(chalk8.gray("2. Committing files..."));
|
|
756
|
+
const commitResult = await commitFilesToGithub({
|
|
757
|
+
owner: options.owner,
|
|
758
|
+
repo: options.repo,
|
|
759
|
+
branch: options.branchName,
|
|
760
|
+
files: options.files,
|
|
761
|
+
commitMessage: options.commitMessage
|
|
762
|
+
});
|
|
763
|
+
if (!commitResult.success) {
|
|
764
|
+
return { success: false, error: `Failed to commit: ${commitResult.error}` };
|
|
765
|
+
}
|
|
766
|
+
console.log(chalk8.green(` \u2713 Committed ${commitResult.files?.length || 0} file(s)`));
|
|
767
|
+
console.log(chalk8.gray("3. Creating pull request..."));
|
|
768
|
+
const prResult = await createPullRequestOnGithub({
|
|
769
|
+
owner: options.owner,
|
|
770
|
+
repo: options.repo,
|
|
771
|
+
title: options.prTitle,
|
|
772
|
+
body: options.prBody,
|
|
773
|
+
head: options.branchName,
|
|
774
|
+
base: options.baseBranch
|
|
775
|
+
});
|
|
776
|
+
if (!prResult.success) {
|
|
777
|
+
return { success: false, error: `Failed to create PR: ${prResult.error}` };
|
|
778
|
+
}
|
|
779
|
+
console.log(chalk8.green(` \u2713 PR created: ${prResult.prUrl}`));
|
|
780
|
+
console.log(chalk8.blue("===========================\n"));
|
|
781
|
+
return {
|
|
782
|
+
success: true,
|
|
783
|
+
branch: options.branchName,
|
|
784
|
+
commitSha: commitResult.commitSha,
|
|
785
|
+
prUrl: prResult.prUrl,
|
|
786
|
+
prNumber: prResult.prNumber
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
var git_default;
|
|
790
|
+
var init_git = __esm({
|
|
791
|
+
"src/tools/git.ts"() {
|
|
792
|
+
init_auth();
|
|
793
|
+
init_config();
|
|
794
|
+
git_default = {
|
|
795
|
+
getGit,
|
|
796
|
+
getStatus,
|
|
797
|
+
getBranch,
|
|
798
|
+
getLog,
|
|
799
|
+
stage,
|
|
800
|
+
stageAll,
|
|
801
|
+
commit,
|
|
802
|
+
commitAll,
|
|
803
|
+
push,
|
|
804
|
+
pull,
|
|
805
|
+
createBranch,
|
|
806
|
+
checkout,
|
|
807
|
+
getDiff,
|
|
808
|
+
isRepo,
|
|
809
|
+
init,
|
|
810
|
+
getRemote,
|
|
811
|
+
commitFilesToGithub,
|
|
812
|
+
createBranchOnGithub,
|
|
813
|
+
createPullRequestOnGithub,
|
|
814
|
+
fullPRWorkflow
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
// src/mcp/index.ts
|
|
820
|
+
var mcp_exports = {};
|
|
821
|
+
__export(mcp_exports, {
|
|
822
|
+
MCPClient: () => MCPClient,
|
|
823
|
+
MCPManager: () => MCPManager,
|
|
824
|
+
default: () => mcp_default,
|
|
825
|
+
getDefaultMCPServers: () => getDefaultMCPServers
|
|
826
|
+
});
|
|
827
|
+
function getDefaultMCPServers() {
|
|
828
|
+
const supabaseUrl = getSupabaseUrl();
|
|
829
|
+
return [
|
|
830
|
+
{ name: "github-mcp", url: `${supabaseUrl}/functions/v1/github-mcp`, enabled: true },
|
|
831
|
+
{ name: "filesystem-mcp", url: `${supabaseUrl}/functions/v1/filesystem-mcp`, enabled: true },
|
|
832
|
+
{ name: "supabase-mcp", url: `${supabaseUrl}/functions/v1/supabase-mcp`, enabled: true },
|
|
833
|
+
{ name: "roblox-mcp", url: `${supabaseUrl}/functions/v1/roblox-mcp`, enabled: true },
|
|
834
|
+
{ name: "linear-mcp", url: `${supabaseUrl}/functions/v1/linear-mcp`, enabled: false },
|
|
835
|
+
{ name: "notion-mcp", url: `${supabaseUrl}/functions/v1/notion-mcp`, enabled: false },
|
|
836
|
+
{ name: "slack-mcp", url: `${supabaseUrl}/functions/v1/slack-mcp`, enabled: false },
|
|
837
|
+
{ name: "discord-mcp", url: `${supabaseUrl}/functions/v1/discord-mcp`, enabled: false },
|
|
838
|
+
{ name: "vercel-mcp", url: `${supabaseUrl}/functions/v1/vercel-mcp`, enabled: false },
|
|
839
|
+
{ name: "stripe-mcp", url: `${supabaseUrl}/functions/v1/stripe-mcp`, enabled: false }
|
|
840
|
+
];
|
|
841
|
+
}
|
|
842
|
+
var MCPClient, MCPManager, mcp_default;
|
|
843
|
+
var init_mcp = __esm({
|
|
844
|
+
"src/mcp/index.ts"() {
|
|
845
|
+
init_config();
|
|
846
|
+
MCPClient = class {
|
|
847
|
+
url;
|
|
848
|
+
initialized = false;
|
|
849
|
+
serverInfo = null;
|
|
850
|
+
capabilities = {};
|
|
851
|
+
requestId = 0;
|
|
852
|
+
constructor(url) {
|
|
853
|
+
this.url = url;
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* Send a JSON-RPC request
|
|
857
|
+
*/
|
|
858
|
+
async request(method, params) {
|
|
859
|
+
const id = ++this.requestId;
|
|
860
|
+
const response = await fetch(this.url, {
|
|
861
|
+
method: "POST",
|
|
862
|
+
headers: {
|
|
863
|
+
"Content-Type": "application/json"
|
|
864
|
+
},
|
|
865
|
+
body: JSON.stringify({
|
|
866
|
+
jsonrpc: "2.0",
|
|
867
|
+
id,
|
|
868
|
+
method,
|
|
869
|
+
params: params || {}
|
|
870
|
+
})
|
|
871
|
+
});
|
|
872
|
+
if (!response.ok) {
|
|
873
|
+
throw new Error(`MCP request failed: ${response.status} ${response.statusText}`);
|
|
874
|
+
}
|
|
875
|
+
const result = await response.json();
|
|
876
|
+
if (result.error) {
|
|
877
|
+
throw new Error(`MCP error: ${result.error.message}`);
|
|
878
|
+
}
|
|
879
|
+
return result.result;
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Initialize the MCP connection
|
|
883
|
+
*/
|
|
884
|
+
async initialize() {
|
|
885
|
+
try {
|
|
886
|
+
const result = await this.request("initialize", {
|
|
887
|
+
protocolVersion: "2024-11-05",
|
|
888
|
+
capabilities: {},
|
|
889
|
+
clientInfo: {
|
|
890
|
+
name: "vibe-weaver-cli",
|
|
891
|
+
version: "1.0.0"
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
this.initialized = true;
|
|
895
|
+
this.serverInfo = result.serverInfo;
|
|
896
|
+
this.capabilities = result.capabilities;
|
|
897
|
+
return result;
|
|
898
|
+
} catch (error) {
|
|
899
|
+
throw new Error(`Failed to initialize MCP server: ${error instanceof Error ? error.message : error}`);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* List available tools
|
|
904
|
+
*/
|
|
905
|
+
async listTools() {
|
|
906
|
+
if (!this.initialized) {
|
|
907
|
+
await this.initialize();
|
|
908
|
+
}
|
|
909
|
+
return this.request("tools/list");
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Call a tool
|
|
913
|
+
*/
|
|
914
|
+
async callTool(name, args) {
|
|
915
|
+
if (!this.initialized) {
|
|
916
|
+
await this.initialize();
|
|
917
|
+
}
|
|
918
|
+
return this.request("tools/call", {
|
|
919
|
+
name,
|
|
920
|
+
arguments: args
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Check if server is alive
|
|
925
|
+
*/
|
|
926
|
+
async ping() {
|
|
927
|
+
try {
|
|
928
|
+
await this.request("ping");
|
|
929
|
+
return true;
|
|
930
|
+
} catch {
|
|
931
|
+
return false;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
getServerInfo() {
|
|
935
|
+
return this.serverInfo;
|
|
936
|
+
}
|
|
937
|
+
isInitialized() {
|
|
938
|
+
return this.initialized;
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
MCPManager = class {
|
|
942
|
+
clients = /* @__PURE__ */ new Map();
|
|
943
|
+
servers = [];
|
|
944
|
+
constructor(servers) {
|
|
945
|
+
this.servers = servers || getDefaultMCPServers();
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Initialize all enabled MCP servers
|
|
949
|
+
*/
|
|
950
|
+
async initializeAll() {
|
|
951
|
+
const success = [];
|
|
952
|
+
const failed = [];
|
|
953
|
+
for (const server of this.servers) {
|
|
954
|
+
if (!server.enabled) continue;
|
|
955
|
+
const client = new MCPClient(server.url);
|
|
956
|
+
try {
|
|
957
|
+
const result = await client.initialize();
|
|
958
|
+
this.clients.set(server.name, client);
|
|
959
|
+
success.push(`${server.name} (${result.serverInfo.version})`);
|
|
960
|
+
console.log(chalk8.green(`\u2713 Connected to ${server.name}`));
|
|
961
|
+
} catch (error) {
|
|
962
|
+
failed.push({
|
|
963
|
+
name: server.name,
|
|
964
|
+
error: error instanceof Error ? error.message : String(error)
|
|
965
|
+
});
|
|
966
|
+
console.log(chalk8.red(`\u2717 Failed to connect to ${server.name}`));
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return { success, failed };
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* List all available tools from connected servers
|
|
973
|
+
*/
|
|
974
|
+
async listAllTools() {
|
|
975
|
+
const results = [];
|
|
976
|
+
for (const [name, client] of this.clients) {
|
|
977
|
+
try {
|
|
978
|
+
const result = await client.listTools();
|
|
979
|
+
results.push({ server: name, tools: result.tools });
|
|
980
|
+
} catch (error) {
|
|
981
|
+
console.warn(chalk8.yellow(`Warning: Failed to list tools from ${name}: ${error}`));
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return results;
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Call a tool on a specific server
|
|
988
|
+
*/
|
|
989
|
+
async callTool(serverName, toolName, args) {
|
|
990
|
+
const client = this.clients.get(serverName);
|
|
991
|
+
if (!client) {
|
|
992
|
+
throw new Error(`MCP server "${serverName}" not connected`);
|
|
993
|
+
}
|
|
994
|
+
return client.callTool(toolName, args);
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Get status of all servers
|
|
998
|
+
*/
|
|
999
|
+
getStatus() {
|
|
1000
|
+
const status = [];
|
|
1001
|
+
for (const server of this.servers) {
|
|
1002
|
+
const client = this.clients.get(server.name);
|
|
1003
|
+
status.push({
|
|
1004
|
+
name: server.name,
|
|
1005
|
+
connected: !!client && client.isInitialized(),
|
|
1006
|
+
tools: 0
|
|
1007
|
+
// Would need to cache tool list
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
return status;
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Enable/disable a server
|
|
1014
|
+
*/
|
|
1015
|
+
setServerEnabled(name, enabled) {
|
|
1016
|
+
const server = this.servers.find((s) => s.name === name);
|
|
1017
|
+
if (server) {
|
|
1018
|
+
server.enabled = enabled;
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
mcp_default = {
|
|
1023
|
+
MCPClient,
|
|
1024
|
+
MCPManager,
|
|
1025
|
+
getDefaultMCPServers
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
1030
|
+
// src/agent/swarm.ts
|
|
1031
|
+
var swarm_exports = {};
|
|
1032
|
+
__export(swarm_exports, {
|
|
1033
|
+
default: () => swarm_default,
|
|
1034
|
+
planSubTasks: () => planSubTasks,
|
|
1035
|
+
runSwarm: () => runSwarm
|
|
1036
|
+
});
|
|
1037
|
+
async function planSubTasks(goal) {
|
|
1038
|
+
const result = await generateCode({
|
|
1039
|
+
goal: `Break down this complex goal into 3-5 independent subtasks that can run in parallel. List only the subtask descriptions, one per line:
|
|
1040
|
+
|
|
1041
|
+
${goal}`,
|
|
1042
|
+
modelId: "balanced"
|
|
1043
|
+
});
|
|
1044
|
+
const lines = result.explanation.split("\n").filter((line) => line.trim().length > 0);
|
|
1045
|
+
return lines.slice(0, 5);
|
|
1046
|
+
}
|
|
1047
|
+
async function executeSubTask(task, baseDir) {
|
|
1048
|
+
task.status = "running";
|
|
1049
|
+
try {
|
|
1050
|
+
console.log(chalk8.gray(`[${task.id}] Starting: ${task.name}`));
|
|
1051
|
+
const result = await generateCode({
|
|
1052
|
+
goal: task.goal,
|
|
1053
|
+
modelId: "balanced"
|
|
1054
|
+
});
|
|
1055
|
+
if (result.parsed.blocks.length > 0) {
|
|
1056
|
+
const writeResult = await writeCodeBlocks(result.parsed.blocks, baseDir);
|
|
1057
|
+
if (writeResult.failed.length > 0) {
|
|
1058
|
+
task.status = "failed";
|
|
1059
|
+
task.error = `Failed to write files: ${writeResult.failed.map((f) => f.path).join(", ")}`;
|
|
1060
|
+
} else {
|
|
1061
|
+
task.status = "completed";
|
|
1062
|
+
task.result = `Generated ${writeResult.success.length} files: ${writeResult.success.join(", ")}`;
|
|
1063
|
+
}
|
|
1064
|
+
} else {
|
|
1065
|
+
task.status = "completed";
|
|
1066
|
+
task.result = result.explanation;
|
|
1067
|
+
}
|
|
1068
|
+
console.log(chalk8.green(`[${task.id}] Completed: ${task.name}`));
|
|
1069
|
+
} catch (error) {
|
|
1070
|
+
task.status = "failed";
|
|
1071
|
+
task.error = error instanceof Error ? error.message : String(error);
|
|
1072
|
+
console.log(chalk8.red(`[${task.id}] Failed: ${task.name} - ${task.error}`));
|
|
1073
|
+
}
|
|
1074
|
+
return task;
|
|
1075
|
+
}
|
|
1076
|
+
async function runSwarm(goal, options = {}) {
|
|
1077
|
+
const maxParallel = options.maxParallel || 3;
|
|
1078
|
+
const baseDir = options.baseDir || process.cwd();
|
|
1079
|
+
console.log(chalk8.cyan("\n\u{1F3AF} Vibe-Weaver Agent Swarm"));
|
|
1080
|
+
console.log(chalk8.gray(`Planning subtasks for: ${goal.substring(0, 50)}...
|
|
1081
|
+
`));
|
|
1082
|
+
const subtaskGoals = await planSubTasks(goal);
|
|
1083
|
+
if (subtaskGoals.length === 0) {
|
|
1084
|
+
console.log(chalk8.yellow("Could not generate subtasks. Running as single task."));
|
|
1085
|
+
subtaskGoals.push(goal);
|
|
1086
|
+
}
|
|
1087
|
+
console.log(chalk8.gray(`Found ${subtaskGoals.length} subtasks:
|
|
1088
|
+
`));
|
|
1089
|
+
for (let i = 0; i < subtaskGoals.length; i++) {
|
|
1090
|
+
console.log(chalk8.gray(` ${i + 1}. ${subtaskGoals[i].substring(0, 60)}...`));
|
|
1091
|
+
}
|
|
1092
|
+
console.log();
|
|
1093
|
+
const tasks = subtaskGoals.map((subGoal, i) => ({
|
|
1094
|
+
id: `agent-${i + 1}`,
|
|
1095
|
+
name: `Agent ${i + 1}`,
|
|
1096
|
+
goal: subGoal,
|
|
1097
|
+
status: "pending"
|
|
1098
|
+
}));
|
|
1099
|
+
const results = [];
|
|
1100
|
+
for (let i = 0; i < tasks.length; i += maxParallel) {
|
|
1101
|
+
const batch = tasks.slice(i, i + maxParallel);
|
|
1102
|
+
console.log(chalk8.cyan(`
|
|
1103
|
+
--- Running batch ${Math.floor(i / maxParallel) + 1} (${batch.length} agents) ---
|
|
1104
|
+
`));
|
|
1105
|
+
const batchResults = await Promise.all(
|
|
1106
|
+
batch.map((task) => executeSubTask(task, baseDir))
|
|
1107
|
+
);
|
|
1108
|
+
results.push(...batchResults);
|
|
1109
|
+
const completed2 = results.filter((t) => t.status === "completed").length;
|
|
1110
|
+
const failed2 = results.filter((t) => t.status === "failed").length;
|
|
1111
|
+
console.log(chalk8.gray(`
|
|
1112
|
+
Progress: ${completed2} completed, ${failed2} failed
|
|
1113
|
+
`));
|
|
1114
|
+
}
|
|
1115
|
+
const completed = results.filter((t) => t.status === "completed").length;
|
|
1116
|
+
const failed = results.filter((t) => t.status === "failed").length;
|
|
1117
|
+
console.log(chalk8.cyan("\n=== Swarm Results ==="));
|
|
1118
|
+
console.log(chalk8.green(`Completed: ${completed}`));
|
|
1119
|
+
if (failed > 0) {
|
|
1120
|
+
console.log(chalk8.red(`Failed: ${failed}`));
|
|
1121
|
+
}
|
|
1122
|
+
for (const task of results) {
|
|
1123
|
+
if (task.status === "completed") {
|
|
1124
|
+
console.log(chalk8.green(` \u2713 ${task.name}: ${task.result?.substring(0, 50)}...`));
|
|
1125
|
+
} else if (task.status === "failed") {
|
|
1126
|
+
console.log(chalk8.red(` \u2717 ${task.name}: ${task.error}`));
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
return {
|
|
1130
|
+
success: failed === 0,
|
|
1131
|
+
completed,
|
|
1132
|
+
failed,
|
|
1133
|
+
results
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
var swarm_default;
|
|
1137
|
+
var init_swarm = __esm({
|
|
1138
|
+
"src/agent/swarm.ts"() {
|
|
1139
|
+
init_vibe_api();
|
|
1140
|
+
init_code_parser();
|
|
1141
|
+
swarm_default = {
|
|
1142
|
+
runSwarm,
|
|
1143
|
+
planSubTasks
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
// src/agent/tasks.ts
|
|
1149
|
+
var tasks_exports = {};
|
|
1150
|
+
__export(tasks_exports, {
|
|
1151
|
+
default: () => tasks_default,
|
|
1152
|
+
displayTaskStatus: () => displayTaskStatus,
|
|
1153
|
+
getTaskStatus: () => getTaskStatus,
|
|
1154
|
+
streamTaskLogs: () => streamTaskLogs,
|
|
1155
|
+
submitTask: () => submitTask,
|
|
1156
|
+
waitForTask: () => waitForTask
|
|
1157
|
+
});
|
|
1158
|
+
async function submitTask(options) {
|
|
1159
|
+
const apiKey = await getApiKey();
|
|
1160
|
+
if (!apiKey) {
|
|
1161
|
+
throw new Error('Not logged in. Run "vibe-weaver login" first.');
|
|
1162
|
+
}
|
|
1163
|
+
const supabaseUrl = getSupabaseUrl();
|
|
1164
|
+
console.log(chalk8.gray(`
|
|
1165
|
+
Submitting background task: ${options.goal.substring(0, 50)}...`));
|
|
1166
|
+
const response = await fetch(`${supabaseUrl}/functions/v1/automation-executor`, {
|
|
1167
|
+
method: "POST",
|
|
1168
|
+
headers: {
|
|
1169
|
+
"Content-Type": "application/json",
|
|
1170
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1171
|
+
},
|
|
1172
|
+
body: JSON.stringify({
|
|
1173
|
+
goal: options.goal,
|
|
1174
|
+
platform: options.platform || "web",
|
|
1175
|
+
language: options.language || "typescript",
|
|
1176
|
+
modelId: options.modelId || "balanced"
|
|
1177
|
+
})
|
|
1178
|
+
});
|
|
1179
|
+
if (!response.ok) {
|
|
1180
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1181
|
+
throw new Error(`Failed to submit task: ${error.error || error.message}`);
|
|
1182
|
+
}
|
|
1183
|
+
const result = await response.json();
|
|
1184
|
+
console.log(chalk8.green(`\u2713 Task submitted: ${result.id}`));
|
|
1185
|
+
console.log(chalk8.gray(` Use "vibe-weaver task status ${result.id}" to check progress
|
|
1186
|
+
`));
|
|
1187
|
+
return {
|
|
1188
|
+
id: result.id,
|
|
1189
|
+
status: result.status || "pending"
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
async function getTaskStatus(taskId) {
|
|
1193
|
+
const apiKey = await getApiKey();
|
|
1194
|
+
if (!apiKey) {
|
|
1195
|
+
throw new Error('Not logged in. Run "vibe-weaver login" first.');
|
|
1196
|
+
}
|
|
1197
|
+
const supabaseUrl = getSupabaseUrl();
|
|
1198
|
+
const response = await fetch(`${supabaseUrl}/functions/v1/automation-executor?id=${taskId}`, {
|
|
1199
|
+
method: "GET",
|
|
1200
|
+
headers: {
|
|
1201
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
if (!response.ok) {
|
|
1205
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1206
|
+
throw new Error(`Failed to get task status: ${error.error || error.message}`);
|
|
1207
|
+
}
|
|
1208
|
+
return response.json();
|
|
1209
|
+
}
|
|
1210
|
+
async function* streamTaskLogs(taskId) {
|
|
1211
|
+
const apiKey = await getApiKey();
|
|
1212
|
+
if (!apiKey) {
|
|
1213
|
+
throw new Error('Not logged in. Run "vibe-weaver login" first.');
|
|
1214
|
+
}
|
|
1215
|
+
const supabaseUrl = getSupabaseUrl();
|
|
1216
|
+
const response = await fetch(`${supabaseUrl}/functions/v1/automation-executor/logs?id=${taskId}`, {
|
|
1217
|
+
method: "GET",
|
|
1218
|
+
headers: {
|
|
1219
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
if (!response.ok) {
|
|
1223
|
+
throw new Error(`Failed to get task logs: ${response.status}`);
|
|
1224
|
+
}
|
|
1225
|
+
const reader = response.body?.getReader();
|
|
1226
|
+
const decoder = new TextDecoder();
|
|
1227
|
+
if (!reader) {
|
|
1228
|
+
throw new Error("Could not read response body");
|
|
1229
|
+
}
|
|
1230
|
+
try {
|
|
1231
|
+
while (true) {
|
|
1232
|
+
const { done, value } = await reader.read();
|
|
1233
|
+
if (done) break;
|
|
1234
|
+
yield decoder.decode(value);
|
|
1235
|
+
}
|
|
1236
|
+
} finally {
|
|
1237
|
+
reader.releaseLock();
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
async function waitForTask(taskId, options = {}) {
|
|
1241
|
+
const pollInterval = options.pollInterval || 5e3;
|
|
1242
|
+
while (true) {
|
|
1243
|
+
const status = await getTaskStatus(taskId);
|
|
1244
|
+
if (options.onProgress) {
|
|
1245
|
+
options.onProgress(status);
|
|
1246
|
+
}
|
|
1247
|
+
if (status.status === "completed") {
|
|
1248
|
+
return status;
|
|
1249
|
+
}
|
|
1250
|
+
if (status.status === "failed") {
|
|
1251
|
+
throw new Error(`Task failed: ${status.error}`);
|
|
1252
|
+
}
|
|
1253
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
function displayTaskStatus(status) {
|
|
1257
|
+
const statusColor = {
|
|
1258
|
+
pending: chalk8.yellow,
|
|
1259
|
+
running: chalk8.blue,
|
|
1260
|
+
completed: chalk8.green,
|
|
1261
|
+
failed: chalk8.red
|
|
1262
|
+
};
|
|
1263
|
+
console.log(chalk8.bold(`
|
|
1264
|
+
Task: ${status.id}`));
|
|
1265
|
+
console.log(chalk8.gray(`Status: ${statusColor[status.status] ? statusColor[status.status](status.status) : chalk8.gray(status.status)}`));
|
|
1266
|
+
if (status.progress !== void 0) {
|
|
1267
|
+
console.log(chalk8.gray(`Progress: ${status.progress}%`));
|
|
1268
|
+
}
|
|
1269
|
+
if (status.result) {
|
|
1270
|
+
console.log(chalk8.gray(`
|
|
1271
|
+
Result:`));
|
|
1272
|
+
console.log(status.result);
|
|
1273
|
+
}
|
|
1274
|
+
if (status.error) {
|
|
1275
|
+
console.log(chalk8.red(`
|
|
1276
|
+
Error: ${status.error}`));
|
|
1277
|
+
}
|
|
1278
|
+
console.log(chalk8.gray(`
|
|
1279
|
+
Created: ${new Date(status.createdAt).toLocaleString()}`));
|
|
1280
|
+
console.log(chalk8.gray(`Updated: ${new Date(status.updatedAt).toLocaleString()}`));
|
|
1281
|
+
}
|
|
1282
|
+
var tasks_default;
|
|
1283
|
+
var init_tasks = __esm({
|
|
1284
|
+
"src/agent/tasks.ts"() {
|
|
1285
|
+
init_auth();
|
|
1286
|
+
init_config();
|
|
1287
|
+
tasks_default = {
|
|
1288
|
+
submitTask,
|
|
1289
|
+
getTaskStatus,
|
|
1290
|
+
streamTaskLogs,
|
|
1291
|
+
waitForTask,
|
|
1292
|
+
displayTaskStatus
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
|
|
1297
|
+
// src/agent/deploy.ts
|
|
1298
|
+
var deploy_exports = {};
|
|
1299
|
+
__export(deploy_exports, {
|
|
1300
|
+
default: () => deploy_default,
|
|
1301
|
+
deploy: () => deploy,
|
|
1302
|
+
submitDeploy: () => submitDeploy,
|
|
1303
|
+
verifyDeploy: () => verifyDeploy
|
|
1304
|
+
});
|
|
1305
|
+
async function submitDeploy(options) {
|
|
1306
|
+
const apiKey = await getApiKey();
|
|
1307
|
+
if (!apiKey) {
|
|
1308
|
+
throw new Error('Not logged in. Run "vibe-weaver login" first.');
|
|
1309
|
+
}
|
|
1310
|
+
const supabaseUrl = getSupabaseUrl();
|
|
1311
|
+
console.log(chalk8.cyan("\n\u{1F680} Submitting deployment..."));
|
|
1312
|
+
const response = await fetch(`${supabaseUrl}/functions/v1/deploy-bridge`, {
|
|
1313
|
+
method: "POST",
|
|
1314
|
+
headers: {
|
|
1315
|
+
"Content-Type": "application/json",
|
|
1316
|
+
"Authorization": `Bearer ${apiKey}`
|
|
1317
|
+
},
|
|
1318
|
+
body: JSON.stringify({
|
|
1319
|
+
projectId: options.projectId,
|
|
1320
|
+
platform: options.platform || "web"
|
|
1321
|
+
})
|
|
1322
|
+
});
|
|
1323
|
+
if (!response.ok) {
|
|
1324
|
+
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
1325
|
+
return {
|
|
1326
|
+
success: false,
|
|
1327
|
+
error: error.error || error.message
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
const result = await response.json();
|
|
1331
|
+
console.log(chalk8.green(`\u2713 Deployment submitted`));
|
|
1332
|
+
console.log(chalk8.gray(` URL: ${result.url}`));
|
|
1333
|
+
return {
|
|
1334
|
+
success: true,
|
|
1335
|
+
url: result.url,
|
|
1336
|
+
projectId: result.projectId
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
async function verifyDeploy(url, options = {}) {
|
|
1340
|
+
const timeout = options.timeout || 6e4;
|
|
1341
|
+
const expectedStatus = options.expectedStatus || 200;
|
|
1342
|
+
console.log(chalk8.gray(`
|
|
1343
|
+
Verifying deployment at ${url}...`));
|
|
1344
|
+
const startTime = Date.now();
|
|
1345
|
+
while (Date.now() - startTime < timeout) {
|
|
1346
|
+
try {
|
|
1347
|
+
const response = await fetch(url, { method: "HEAD" });
|
|
1348
|
+
if (response.status === expectedStatus) {
|
|
1349
|
+
console.log(chalk8.green(`\u2713 Deployment verified (${response.status})`));
|
|
1350
|
+
return { success: true, status: response.status };
|
|
1351
|
+
}
|
|
1352
|
+
if (response.status === 404) {
|
|
1353
|
+
console.log(chalk8.yellow(` Still deploying... (${response.status})`));
|
|
1354
|
+
} else {
|
|
1355
|
+
console.log(chalk8.yellow(` Unexpected status: ${response.status}`));
|
|
1356
|
+
}
|
|
1357
|
+
} catch (error) {
|
|
1358
|
+
console.log(chalk8.yellow(` Waiting for deployment...`));
|
|
1359
|
+
}
|
|
1360
|
+
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
1361
|
+
}
|
|
1362
|
+
console.log(chalk8.red(`\u2717 Deployment verification timed out`));
|
|
1363
|
+
return {
|
|
1364
|
+
success: false,
|
|
1365
|
+
error: "Deployment verification timed out"
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
async function deploy(options = {}) {
|
|
1369
|
+
const verify = options.verify !== false;
|
|
1370
|
+
console.log(chalk8.cyan("\n\u{1F680} Vibe-Weaver Deploy"));
|
|
1371
|
+
if (options.cwd) {
|
|
1372
|
+
console.log(chalk8.gray("\nBuilding project locally..."));
|
|
1373
|
+
const buildResult = await runShell("npm run build", { cwd: options.cwd });
|
|
1374
|
+
if (!buildResult.success) {
|
|
1375
|
+
return {
|
|
1376
|
+
success: false,
|
|
1377
|
+
error: `Build failed: ${buildResult.stderr}`
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
console.log(chalk8.green("\u2713 Build successful"));
|
|
1381
|
+
}
|
|
1382
|
+
console.log(chalk8.gray("\nSubmitting to Vibe-Weaver..."));
|
|
1383
|
+
const deployResult = await submitDeploy({
|
|
1384
|
+
projectId: options.projectId,
|
|
1385
|
+
platform: options.platform
|
|
1386
|
+
});
|
|
1387
|
+
if (!deployResult.success) {
|
|
1388
|
+
return deployResult;
|
|
1389
|
+
}
|
|
1390
|
+
if (verify && deployResult.url) {
|
|
1391
|
+
const verifyResult = await verifyDeploy(deployResult.url);
|
|
1392
|
+
if (!verifyResult.success) {
|
|
1393
|
+
return {
|
|
1394
|
+
success: false,
|
|
1395
|
+
url: deployResult.url,
|
|
1396
|
+
error: verifyResult.error
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
return deployResult;
|
|
1401
|
+
}
|
|
1402
|
+
var deploy_default;
|
|
1403
|
+
var init_deploy = __esm({
|
|
1404
|
+
"src/agent/deploy.ts"() {
|
|
1405
|
+
init_auth();
|
|
1406
|
+
init_config();
|
|
1407
|
+
init_shell();
|
|
1408
|
+
deploy_default = {
|
|
1409
|
+
submitDeploy,
|
|
1410
|
+
verifyDeploy,
|
|
1411
|
+
deploy
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
|
|
1416
|
+
// src/index.ts
|
|
1417
|
+
init_auth();
|
|
1418
|
+
init_vibe_api();
|
|
1419
|
+
init_code_parser();
|
|
1420
|
+
|
|
1421
|
+
// src/tools/files.ts
|
|
1422
|
+
init_code_parser();
|
|
1423
|
+
async function readFile(filePath, baseDir = process.cwd()) {
|
|
1424
|
+
try {
|
|
1425
|
+
const fullPath = path2.isAbsolute(filePath) ? filePath : path2.join(baseDir, filePath);
|
|
1426
|
+
const content = await fs2.readFile(fullPath, "utf-8");
|
|
1427
|
+
return { success: true, path: filePath, content };
|
|
1428
|
+
} catch (error) {
|
|
1429
|
+
return {
|
|
1430
|
+
success: false,
|
|
1431
|
+
path: filePath,
|
|
1432
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
async function writeFile(filePath, content, baseDir = process.cwd(), options = {}) {
|
|
1437
|
+
try {
|
|
1438
|
+
const fullPath = path2.isAbsolute(filePath) ? filePath : path2.join(baseDir, filePath);
|
|
1439
|
+
const dir = path2.dirname(fullPath);
|
|
1440
|
+
let oldContent = "";
|
|
1441
|
+
try {
|
|
1442
|
+
oldContent = await fs2.readFile(fullPath, "utf-8");
|
|
1443
|
+
} catch {
|
|
1444
|
+
}
|
|
1445
|
+
const diff = options.showDiff && oldContent ? generateDiff(oldContent, content, filePath) : void 0;
|
|
1446
|
+
if (options.dryRun) {
|
|
1447
|
+
return { success: true, path: filePath, diff };
|
|
1448
|
+
}
|
|
1449
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1450
|
+
await fs2.writeFile(fullPath, content, "utf-8");
|
|
1451
|
+
return { success: true, path: filePath, diff };
|
|
1452
|
+
} catch (error) {
|
|
1453
|
+
return {
|
|
1454
|
+
success: false,
|
|
1455
|
+
path: filePath,
|
|
1456
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
async function listDir(dirPath = ".", baseDir = process.cwd()) {
|
|
1461
|
+
const fullPath = path2.isAbsolute(dirPath) ? dirPath : path2.join(baseDir, dirPath);
|
|
1462
|
+
try {
|
|
1463
|
+
const entries = await fs2.readdir(fullPath, { withFileTypes: true });
|
|
1464
|
+
return entries.map((entry) => ({
|
|
1465
|
+
path: entry.name,
|
|
1466
|
+
isDirectory: entry.isDirectory()
|
|
1467
|
+
}));
|
|
1468
|
+
} catch (error) {
|
|
1469
|
+
throw new Error(`Failed to list directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
async function grep(pattern, baseDir = process.cwd(), options = {}) {
|
|
1473
|
+
const results = [];
|
|
1474
|
+
const fs3 = await import('fs/promises');
|
|
1475
|
+
async function searchDir(dir) {
|
|
1476
|
+
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
1477
|
+
for (const entry of entries) {
|
|
1478
|
+
const fullPath = path2.join(dir, entry.name);
|
|
1479
|
+
if (entry.name === "node_modules" || entry.name === ".git" || entry.name.startsWith(".")) {
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
if (entry.isDirectory() && options.recursive !== false) {
|
|
1483
|
+
await searchDir(fullPath);
|
|
1484
|
+
} else if (entry.isFile()) {
|
|
1485
|
+
if (options.filePattern && !new RegExp(options.filePattern).test(entry.name)) {
|
|
1486
|
+
continue;
|
|
1487
|
+
}
|
|
1488
|
+
try {
|
|
1489
|
+
const content = await fs3.readFile(fullPath, "utf-8");
|
|
1490
|
+
const lines = content.split("\n");
|
|
1491
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1492
|
+
if (lines[i].includes(pattern)) {
|
|
1493
|
+
results.push({
|
|
1494
|
+
file: path2.relative(baseDir, fullPath),
|
|
1495
|
+
line: i + 1,
|
|
1496
|
+
content: lines[i].trim()
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
} catch {
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
await searchDir(baseDir);
|
|
1506
|
+
return results;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
// src/index.ts
|
|
1510
|
+
init_shell();
|
|
1511
|
+
init_git();
|
|
1512
|
+
var program = new Command();
|
|
1513
|
+
program.name("vibe-weaver").description("Vibe-Weaver CLI - Production-ready terminal agent that beats Claude Code").version("1.0.0");
|
|
1514
|
+
program.command("login").description("Log in with your Vibe-Weaver API key").option("-k, --api-key <key>", "API key (vw_...)").option("-o, --open", "Open browser to create API key").option("-g, --github", "Also configure GitHub token").action(async (options) => {
|
|
1515
|
+
try {
|
|
1516
|
+
await login({ apiKey: options.apiKey, openBrowser: options.open });
|
|
1517
|
+
if (options.github) {
|
|
1518
|
+
await loginGithub();
|
|
1519
|
+
}
|
|
1520
|
+
} catch (error) {
|
|
1521
|
+
console.error(chalk8.red("Login failed:"), error instanceof Error ? error.message : error);
|
|
1522
|
+
process.exit(1);
|
|
1523
|
+
}
|
|
1524
|
+
});
|
|
1525
|
+
program.command("logout").description("Log out and clear stored credentials").action(async () => {
|
|
1526
|
+
try {
|
|
1527
|
+
await logout();
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
console.error(chalk8.red("Logout failed:"), error instanceof Error ? error.message : error);
|
|
1530
|
+
process.exit(1);
|
|
1531
|
+
}
|
|
1532
|
+
});
|
|
1533
|
+
program.command("whoami").description("Show current user info and credits").action(async () => {
|
|
1534
|
+
try {
|
|
1535
|
+
await whoami();
|
|
1536
|
+
} catch (error) {
|
|
1537
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1538
|
+
process.exit(1);
|
|
1539
|
+
}
|
|
1540
|
+
});
|
|
1541
|
+
program.command("generate").description("Generate code using Vibe-Weaver AI").option("-g, --goal <text>", "Goal/prompt for code generation").option("-p, --platform <type>", "Platform: web, roblox, mobile, desktop, api", "web").option("-l, --language <lang>", "Language: typescript, javascript, python, lua, rust", "typescript").option("-m, --mode <mode>", "Model: fast, balanced, deep_reasoning, refactor", "balanced").option("-o, --out <dir>", "Output directory", ".").option("-y, --yes", "Auto-approve file writes").option("-d, --dry-run", "Show what would be generated without writing").action(async (options) => {
|
|
1542
|
+
if (!options.goal) {
|
|
1543
|
+
console.error(chalk8.red("Error: --goal is required"));
|
|
1544
|
+
process.exit(1);
|
|
1545
|
+
}
|
|
1546
|
+
try {
|
|
1547
|
+
const loggedIn = await isLoggedIn();
|
|
1548
|
+
if (!loggedIn) {
|
|
1549
|
+
console.error(chalk8.red('Not logged in. Run "vibe-weaver login" first.'));
|
|
1550
|
+
process.exit(1);
|
|
1551
|
+
}
|
|
1552
|
+
console.log(chalk8.cyan("\n\u{1F3A8} Vibe-Weaver Code Generation"));
|
|
1553
|
+
console.log(chalk8.gray(`Mode: ${options.mode} | Platform: ${options.platform} | Language: ${options.language}`));
|
|
1554
|
+
console.log(chalk8.gray(`Cost: ~${getCreditCost(options.mode)} credits
|
|
1555
|
+
`));
|
|
1556
|
+
const result = await generateCode({
|
|
1557
|
+
goal: options.goal,
|
|
1558
|
+
platform: options.platform,
|
|
1559
|
+
language: options.language,
|
|
1560
|
+
modelId: options.mode
|
|
1561
|
+
});
|
|
1562
|
+
console.log(chalk8.gray("Explanation:"));
|
|
1563
|
+
console.log(result.explanation);
|
|
1564
|
+
console.log(chalk8.gray("\nQuality Score:"), `${result.quality.score}/100`);
|
|
1565
|
+
if (result.parsed.blocks.length > 0) {
|
|
1566
|
+
console.log(chalk8.gray("\nGenerated Files:"));
|
|
1567
|
+
for (const block of result.parsed.blocks) {
|
|
1568
|
+
console.log(` - ${chalk8.green(block.path)} (${block.language})`);
|
|
1569
|
+
}
|
|
1570
|
+
if (!options.dryRun) {
|
|
1571
|
+
const writeResult = await writeCodeBlocks(result.parsed.blocks, path2.resolve(options.out));
|
|
1572
|
+
console.log(chalk8.gray("\nWritten:"));
|
|
1573
|
+
for (const file of writeResult.success) {
|
|
1574
|
+
console.log(` \u2713 ${file}`);
|
|
1575
|
+
}
|
|
1576
|
+
if (writeResult.failed.length > 0) {
|
|
1577
|
+
console.log(chalk8.red("\nFailed:"));
|
|
1578
|
+
for (const file of writeResult.failed) {
|
|
1579
|
+
console.log(` \u2717 ${file.path}: ${file.error}`);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
} else {
|
|
1583
|
+
console.log(chalk8.yellow("\n[DRY-RUN] Files not written"));
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
console.log(chalk8.green("\n\u2713 Generation complete"));
|
|
1587
|
+
} catch (error) {
|
|
1588
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1589
|
+
process.exit(1);
|
|
1590
|
+
}
|
|
1591
|
+
});
|
|
1592
|
+
program.command("run").description("Run the interactive agent loop (REPL)").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-y, --yes", "Auto-approve all operations").option("-d, --dry-run", "Preview changes without applying").action(async (options) => {
|
|
1593
|
+
const loggedIn = await isLoggedIn();
|
|
1594
|
+
if (!loggedIn) {
|
|
1595
|
+
console.error(chalk8.red('Not logged in. Run "vibe-weaver login" first.'));
|
|
1596
|
+
process.exit(1);
|
|
1597
|
+
}
|
|
1598
|
+
console.log(chalk8.cyan("\u{1F3AF} Vibe-Weaver Interactive Agent"));
|
|
1599
|
+
console.log(chalk8.gray("Type your goal or task. Press Ctrl+C to exit.\n"));
|
|
1600
|
+
const readline = await import('readline');
|
|
1601
|
+
const rl = readline.createInterface({
|
|
1602
|
+
input: process.stdin,
|
|
1603
|
+
output: process.stdout
|
|
1604
|
+
});
|
|
1605
|
+
const askQuestion = () => {
|
|
1606
|
+
rl.question(chalk8.green("\n> "), async (input) => {
|
|
1607
|
+
if (!input.trim()) {
|
|
1608
|
+
askQuestion();
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
if (input.toLowerCase() === "exit" || input.toLowerCase() === "quit") {
|
|
1612
|
+
rl.close();
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
try {
|
|
1616
|
+
console.log(chalk8.gray("\nGenerating code..."));
|
|
1617
|
+
const result = await generateCode({ goal: input });
|
|
1618
|
+
if (result.parsed.blocks.length > 0) {
|
|
1619
|
+
const writeResult = await writeCodeBlocks(result.parsed.blocks, options.cwd);
|
|
1620
|
+
console.log(chalk8.green("\n\u2713 Generated files:"));
|
|
1621
|
+
for (const file of writeResult.success) {
|
|
1622
|
+
console.log(` \u2713 ${file}`);
|
|
1623
|
+
}
|
|
1624
|
+
if (writeResult.failed.length > 0) {
|
|
1625
|
+
console.log(chalk8.red("\n\u2717 Failed:"));
|
|
1626
|
+
for (const file of writeResult.failed) {
|
|
1627
|
+
console.log(` \u2717 ${file.path}: ${file.error}`);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
} catch (error) {
|
|
1632
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1633
|
+
}
|
|
1634
|
+
askQuestion();
|
|
1635
|
+
});
|
|
1636
|
+
};
|
|
1637
|
+
askQuestion();
|
|
1638
|
+
});
|
|
1639
|
+
program.command("read").description("Read a file").argument("<file>", "File path to read").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (file, options) => {
|
|
1640
|
+
try {
|
|
1641
|
+
const result = await readFile(file, options.cwd);
|
|
1642
|
+
if (result.success && result.content) {
|
|
1643
|
+
console.log(result.content);
|
|
1644
|
+
} else {
|
|
1645
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1646
|
+
process.exit(1);
|
|
1647
|
+
}
|
|
1648
|
+
} catch (error) {
|
|
1649
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1650
|
+
process.exit(1);
|
|
1651
|
+
}
|
|
1652
|
+
});
|
|
1653
|
+
program.command("write").description("Write content to a file").argument("<file>", "File path to write").argument("<content>", "Content to write").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-d, --dry-run", "Preview without writing").action(async (file, content, options) => {
|
|
1654
|
+
try {
|
|
1655
|
+
const result = await writeFile(file, content, options.cwd, { dryRun: options.dryRun });
|
|
1656
|
+
if (result.success) {
|
|
1657
|
+
console.log(chalk8.green(`\u2713 Written to ${file}`));
|
|
1658
|
+
} else {
|
|
1659
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1660
|
+
process.exit(1);
|
|
1661
|
+
}
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1664
|
+
process.exit(1);
|
|
1665
|
+
}
|
|
1666
|
+
});
|
|
1667
|
+
program.command("ls").description("List files in a directory").argument("[dir]", "Directory to list", ".").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (dir, options) => {
|
|
1668
|
+
try {
|
|
1669
|
+
const entries = await listDir(dir, options.cwd);
|
|
1670
|
+
for (const entry of entries) {
|
|
1671
|
+
const prefix = entry.isDirectory ? chalk8.blue("\u{1F4C1}") : chalk8.gray("\u{1F4C4}");
|
|
1672
|
+
console.log(`${prefix} ${entry.path}`);
|
|
1673
|
+
}
|
|
1674
|
+
} catch (error) {
|
|
1675
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1676
|
+
process.exit(1);
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
program.command("grep").description("Search for a pattern in files").argument("<pattern>", "Pattern to search for").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-r, --recursive", "Search recursively", true).action(async (pattern, options) => {
|
|
1680
|
+
try {
|
|
1681
|
+
const results = await grep(pattern, options.cwd, { recursive: options.recursive });
|
|
1682
|
+
if (results.length === 0) {
|
|
1683
|
+
console.log(chalk8.yellow("No matches found"));
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1686
|
+
for (const result of results) {
|
|
1687
|
+
console.log(`${chalk8.gray(`${result.file}:${result.line}`)} ${result.content}`);
|
|
1688
|
+
}
|
|
1689
|
+
} catch (error) {
|
|
1690
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1691
|
+
process.exit(1);
|
|
1692
|
+
}
|
|
1693
|
+
});
|
|
1694
|
+
program.command("exec").description("Execute a shell command").argument("<command>", "Command to execute").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-d, --dry-run", "Preview without executing").action(async (command, options) => {
|
|
1695
|
+
try {
|
|
1696
|
+
if (options.dryRun) {
|
|
1697
|
+
console.log(chalk8.yellow(`[DRY-RUN] Would execute: ${command}`));
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
console.log(chalk8.gray(`$ ${command}`));
|
|
1701
|
+
const result = await runShell(command, { cwd: options.cwd });
|
|
1702
|
+
if (result.stdout) console.log(result.stdout);
|
|
1703
|
+
if (result.stderr) console.error(chalk8.red(result.stderr));
|
|
1704
|
+
process.exit(result.exitCode);
|
|
1705
|
+
} catch (error) {
|
|
1706
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1707
|
+
process.exit(1);
|
|
1708
|
+
}
|
|
1709
|
+
});
|
|
1710
|
+
program.command("status").description("Show git status").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (options) => {
|
|
1711
|
+
try {
|
|
1712
|
+
const status = await getStatus(options.cwd);
|
|
1713
|
+
console.log(chalk8.gray(`Branch: ${status.current || "(none)"}`));
|
|
1714
|
+
if (status.tracking) {
|
|
1715
|
+
console.log(chalk8.gray(`Tracking: ${status.tracking}`));
|
|
1716
|
+
}
|
|
1717
|
+
if (status.staged.length > 0) {
|
|
1718
|
+
console.log(chalk8.green("\nStaged:"));
|
|
1719
|
+
for (const file of status.staged) {
|
|
1720
|
+
console.log(` ${chalk8.green("+")} ${file}`);
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
if (status.modified.length > 0) {
|
|
1724
|
+
console.log(chalk8.yellow("\nModified:"));
|
|
1725
|
+
for (const file of status.modified) {
|
|
1726
|
+
console.log(` ${chalk8.yellow("M")} ${file}`);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
if (status.untracked.length > 0) {
|
|
1730
|
+
console.log(chalk8.gray("\nUntracked:"));
|
|
1731
|
+
for (const file of status.untracked) {
|
|
1732
|
+
console.log(` ${chalk8.gray("?")} ${file}`);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
} catch (error) {
|
|
1736
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1737
|
+
process.exit(1);
|
|
1738
|
+
}
|
|
1739
|
+
});
|
|
1740
|
+
program.command("commit").description("Commit changes with a message").argument("<message>", "Commit message").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-a, --all", "Stage all changes", false).action(async (message, options) => {
|
|
1741
|
+
try {
|
|
1742
|
+
if (options.all) {
|
|
1743
|
+
const result = await commitAll(message, options.cwd);
|
|
1744
|
+
if (result.success) {
|
|
1745
|
+
console.log(chalk8.green(`\u2713 Committed: ${result.message}`));
|
|
1746
|
+
} else {
|
|
1747
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1748
|
+
process.exit(1);
|
|
1749
|
+
}
|
|
1750
|
+
} else {
|
|
1751
|
+
const result = await commit(message, options.cwd);
|
|
1752
|
+
if (result.success) {
|
|
1753
|
+
console.log(chalk8.green(`\u2713 Committed: ${result.message}`));
|
|
1754
|
+
} else {
|
|
1755
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1756
|
+
process.exit(1);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
} catch (error) {
|
|
1760
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1761
|
+
process.exit(1);
|
|
1762
|
+
}
|
|
1763
|
+
});
|
|
1764
|
+
program.command("push").description("Push to remote").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-f, --force", "Force push", false).action(async (options) => {
|
|
1765
|
+
try {
|
|
1766
|
+
const result = await push({ force: options.force }, options.cwd);
|
|
1767
|
+
if (result.success) {
|
|
1768
|
+
console.log(chalk8.green("\u2713 Pushed successfully"));
|
|
1769
|
+
} else {
|
|
1770
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1771
|
+
process.exit(1);
|
|
1772
|
+
}
|
|
1773
|
+
} catch (error) {
|
|
1774
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1775
|
+
process.exit(1);
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
program.command("pull").description("Pull from remote").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (options) => {
|
|
1779
|
+
try {
|
|
1780
|
+
const result = await pull({}, options.cwd);
|
|
1781
|
+
if (result.success) {
|
|
1782
|
+
console.log(chalk8.green("\u2713 Pulled successfully"));
|
|
1783
|
+
} else {
|
|
1784
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1785
|
+
process.exit(1);
|
|
1786
|
+
}
|
|
1787
|
+
} catch (error) {
|
|
1788
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1789
|
+
process.exit(1);
|
|
1790
|
+
}
|
|
1791
|
+
});
|
|
1792
|
+
program.command("pr").description("Create a pull request with AI-generated summary").option("-t, --title <title>", "PR title").option("-b, --body <body>", "PR body").option("-o, --owner <owner>", "Repository owner").option("-r, --repo <repo>", "Repository name").option("-B, --base <branch>", "Base branch", "main").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (options) => {
|
|
1793
|
+
try {
|
|
1794
|
+
const isGitRepo = await isRepo(options.cwd);
|
|
1795
|
+
if (!isGitRepo) {
|
|
1796
|
+
console.error(chalk8.red("Not a git repository"));
|
|
1797
|
+
process.exit(1);
|
|
1798
|
+
}
|
|
1799
|
+
const currentBranch = await getBranch(options.cwd);
|
|
1800
|
+
let prTitle = options.title;
|
|
1801
|
+
let prBody = options.body;
|
|
1802
|
+
if (!prTitle || !prBody) {
|
|
1803
|
+
console.log(chalk8.gray("Generating PR description with AI..."));
|
|
1804
|
+
const result2 = await generateCode({
|
|
1805
|
+
goal: `Create a descriptive pull request title and body for the changes in branch ${currentBranch}. Focus on what changed and why.`,
|
|
1806
|
+
modelId: "balanced"
|
|
1807
|
+
});
|
|
1808
|
+
const lines = result2.explanation.split("\n").filter((l) => l.trim());
|
|
1809
|
+
if (!prTitle) prTitle = lines[0] || `Update ${currentBranch}`;
|
|
1810
|
+
if (!prBody) prBody = lines.slice(1).join("\n") || result2.explanation;
|
|
1811
|
+
}
|
|
1812
|
+
if (!options.owner || !options.repo) {
|
|
1813
|
+
const remote = await Promise.resolve().then(() => (init_git(), git_exports)).then((m) => m.getRemote(options.cwd));
|
|
1814
|
+
if (remote) {
|
|
1815
|
+
const match = remote.match(/github\.com[/:]([^/]+)\/([^/.]+)/);
|
|
1816
|
+
if (match) {
|
|
1817
|
+
options.owner = options.owner || match[1];
|
|
1818
|
+
options.repo = options.repo || match[2];
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (!options.owner || !options.repo) {
|
|
1823
|
+
const answers = await inquirer.prompt([
|
|
1824
|
+
{ type: "input", name: "owner", message: "Repository owner:", when: !options.owner },
|
|
1825
|
+
{ type: "input", name: "repo", message: "Repository name:", when: !options.repo }
|
|
1826
|
+
]);
|
|
1827
|
+
options.owner = options.owner || answers.owner;
|
|
1828
|
+
options.repo = options.repo || answers.repo;
|
|
1829
|
+
}
|
|
1830
|
+
const diff = await getDiff({ from: options.base, to: currentBranch }, options.cwd);
|
|
1831
|
+
console.log(chalk8.gray(`Diff: ${diff.length} characters`));
|
|
1832
|
+
const result = await fullPRWorkflow({
|
|
1833
|
+
owner: options.owner,
|
|
1834
|
+
repo: options.repo,
|
|
1835
|
+
branchName: currentBranch,
|
|
1836
|
+
baseBranch: options.base,
|
|
1837
|
+
files: [],
|
|
1838
|
+
// Would need to parse diff into files
|
|
1839
|
+
commitMessage: prTitle,
|
|
1840
|
+
prTitle,
|
|
1841
|
+
prBody
|
|
1842
|
+
});
|
|
1843
|
+
if (result.success) {
|
|
1844
|
+
console.log(chalk8.green(`
|
|
1845
|
+
\u2713 PR created: ${result.prUrl}`));
|
|
1846
|
+
} else {
|
|
1847
|
+
console.error(chalk8.red(`Error: ${result.error}`));
|
|
1848
|
+
process.exit(1);
|
|
1849
|
+
}
|
|
1850
|
+
} catch (error) {
|
|
1851
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1852
|
+
process.exit(1);
|
|
1853
|
+
}
|
|
1854
|
+
});
|
|
1855
|
+
program.command("build").description("Run build command").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-d, --dry-run", "Preview without executing").action(async (options) => {
|
|
1856
|
+
try {
|
|
1857
|
+
const buildCmd = getBuildCommand(options.cwd);
|
|
1858
|
+
if (options.dryRun) {
|
|
1859
|
+
console.log(chalk8.yellow(`[DRY-RUN] Would execute: ${buildCmd}`));
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
console.log(chalk8.gray(`$ ${buildCmd}`));
|
|
1863
|
+
const result = await runShell(buildCmd, { cwd: options.cwd });
|
|
1864
|
+
if (result.stdout) console.log(result.stdout);
|
|
1865
|
+
if (result.stderr) console.error(chalk8.red(result.stderr));
|
|
1866
|
+
if (result.success) {
|
|
1867
|
+
console.log(chalk8.green("\n\u2713 Build successful"));
|
|
1868
|
+
} else {
|
|
1869
|
+
console.log(chalk8.red(`
|
|
1870
|
+
\u2717 Build failed (exit code ${result.exitCode})`));
|
|
1871
|
+
process.exit(result.exitCode);
|
|
1872
|
+
}
|
|
1873
|
+
} catch (error) {
|
|
1874
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1875
|
+
process.exit(1);
|
|
1876
|
+
}
|
|
1877
|
+
});
|
|
1878
|
+
program.command("install").description("Run install command").option("-c, --cwd <dir>", "Working directory", process.cwd()).option("-d, --dry-run", "Preview without executing").action(async (options) => {
|
|
1879
|
+
try {
|
|
1880
|
+
const installCmd = getInstallCommand(options.cwd);
|
|
1881
|
+
if (options.dryRun) {
|
|
1882
|
+
console.log(chalk8.yellow(`[DRY-RUN] Would execute: ${installCmd}`));
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1885
|
+
console.log(chalk8.gray(`$ ${installCmd}`));
|
|
1886
|
+
const result = await runShell(installCmd, { cwd: options.cwd, timeout: 3e5 });
|
|
1887
|
+
if (result.stdout) console.log(result.stdout);
|
|
1888
|
+
if (result.stderr) console.error(chalk8.red(result.stderr));
|
|
1889
|
+
if (result.success) {
|
|
1890
|
+
console.log(chalk8.green("\n\u2713 Install successful"));
|
|
1891
|
+
} else {
|
|
1892
|
+
console.log(chalk8.red(`
|
|
1893
|
+
\u2717 Install failed (exit code ${result.exitCode})`));
|
|
1894
|
+
process.exit(result.exitCode);
|
|
1895
|
+
}
|
|
1896
|
+
} catch (error) {
|
|
1897
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1898
|
+
process.exit(1);
|
|
1899
|
+
}
|
|
1900
|
+
});
|
|
1901
|
+
program.command("mcp").description("Manage MCP server connections").option("-l, --list", "List available MCP servers").option("-c, --connect", "Connect to all enabled MCP servers").option("-s, --status", "Show MCP server status").action(async (options) => {
|
|
1902
|
+
const { MCPManager: MCPManager2, getDefaultMCPServers: getDefaultMCPServers2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
1903
|
+
if (options.list) {
|
|
1904
|
+
const servers = getDefaultMCPServers2();
|
|
1905
|
+
console.log(chalk8.cyan("\n\u{1F4E1} Available MCP Servers\n"));
|
|
1906
|
+
for (const server of servers) {
|
|
1907
|
+
const status = server.enabled ? chalk8.green("enabled") : chalk8.gray("disabled");
|
|
1908
|
+
console.log(` ${server.name.padEnd(20)} ${status}`);
|
|
1909
|
+
}
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1912
|
+
if (options.connect) {
|
|
1913
|
+
const manager = new MCPManager2();
|
|
1914
|
+
console.log(chalk8.cyan("\n\u{1F50C} Connecting to MCP servers...\n"));
|
|
1915
|
+
const result = await manager.initializeAll();
|
|
1916
|
+
console.log(chalk8.green(`
|
|
1917
|
+
\u2713 Connected to ${result.success.length} servers`));
|
|
1918
|
+
if (result.failed.length > 0) {
|
|
1919
|
+
console.log(chalk8.red(`\u2717 Failed to connect to ${result.failed.length} servers`));
|
|
1920
|
+
}
|
|
1921
|
+
return;
|
|
1922
|
+
}
|
|
1923
|
+
if (options.status) {
|
|
1924
|
+
const manager = new MCPManager2();
|
|
1925
|
+
await manager.initializeAll();
|
|
1926
|
+
const status = manager.getStatus();
|
|
1927
|
+
console.log(chalk8.cyan("\n\u{1F4E1} MCP Server Status\n"));
|
|
1928
|
+
for (const s of status) {
|
|
1929
|
+
const icon = s.connected ? chalk8.green("\u2713") : chalk8.red("\u2717");
|
|
1930
|
+
console.log(` ${icon} ${s.name}`);
|
|
1931
|
+
}
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
console.log(chalk8.gray("Use --list, --connect, or --status"));
|
|
1935
|
+
});
|
|
1936
|
+
program.command("swarm").description("Run multiple agents in parallel for complex tasks").option("-g, --goal <text>", "Goal for the swarm").option("-p, --parallel <num>", "Max parallel agents", "3").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (options) => {
|
|
1937
|
+
if (!options.goal) {
|
|
1938
|
+
console.error(chalk8.red("Error: --goal is required"));
|
|
1939
|
+
process.exit(1);
|
|
1940
|
+
}
|
|
1941
|
+
const loggedIn = await isLoggedIn();
|
|
1942
|
+
if (!loggedIn) {
|
|
1943
|
+
console.error(chalk8.red('Not logged in. Run "vibe-weaver login" first.'));
|
|
1944
|
+
process.exit(1);
|
|
1945
|
+
}
|
|
1946
|
+
const { runSwarm: runSwarm2 } = await Promise.resolve().then(() => (init_swarm(), swarm_exports));
|
|
1947
|
+
await runSwarm2(options.goal, {
|
|
1948
|
+
maxParallel: parseInt(options.parallel),
|
|
1949
|
+
baseDir: options.cwd
|
|
1950
|
+
});
|
|
1951
|
+
});
|
|
1952
|
+
var taskCmd = program.command("task").description("Manage background tasks");
|
|
1953
|
+
taskCmd.command("submit").description("Submit a background task").option("-g, --goal <text>", "Task goal").option("-p, --platform <type>", "Platform", "web").option("-m, --mode <mode>", "Model mode", "balanced").action(async (options) => {
|
|
1954
|
+
if (!options.goal) {
|
|
1955
|
+
console.error(chalk8.red("Error: --goal is required"));
|
|
1956
|
+
process.exit(1);
|
|
1957
|
+
}
|
|
1958
|
+
const { submitTask: submitTask2 } = await Promise.resolve().then(() => (init_tasks(), tasks_exports));
|
|
1959
|
+
await submitTask2({
|
|
1960
|
+
goal: options.goal,
|
|
1961
|
+
platform: options.platform,
|
|
1962
|
+
modelId: options.mode
|
|
1963
|
+
});
|
|
1964
|
+
});
|
|
1965
|
+
taskCmd.command("status").description("Check task status").argument("<id>", "Task ID").action(async (taskId) => {
|
|
1966
|
+
const { getTaskStatus: getTaskStatus2, displayTaskStatus: displayTaskStatus2 } = await Promise.resolve().then(() => (init_tasks(), tasks_exports));
|
|
1967
|
+
const status = await getTaskStatus2(taskId);
|
|
1968
|
+
displayTaskStatus2(status);
|
|
1969
|
+
});
|
|
1970
|
+
taskCmd.command("logs").description("Stream task logs").argument("<id>", "Task ID").action(async (taskId) => {
|
|
1971
|
+
const { streamTaskLogs: streamTaskLogs2 } = await Promise.resolve().then(() => (init_tasks(), tasks_exports));
|
|
1972
|
+
console.log(chalk8.gray(`Streaming logs for task ${taskId}...
|
|
1973
|
+
`));
|
|
1974
|
+
for await (const log of streamTaskLogs2(taskId)) {
|
|
1975
|
+
process.stdout.write(log);
|
|
1976
|
+
}
|
|
1977
|
+
});
|
|
1978
|
+
taskCmd.command("wait").description("Wait for task to complete").argument("<id>", "Task ID").option("-t, --timeout <seconds>", "Timeout in seconds", "300").action(async (taskId, options) => {
|
|
1979
|
+
const { waitForTask: waitForTask2, displayTaskStatus: displayTaskStatus2 } = await Promise.resolve().then(() => (init_tasks(), tasks_exports));
|
|
1980
|
+
try {
|
|
1981
|
+
const status = await waitForTask2(taskId, {
|
|
1982
|
+
pollInterval: 5e3,
|
|
1983
|
+
onProgress: (s) => {
|
|
1984
|
+
process.stdout.write(chalk8.gray(`\rStatus: ${s.status}`));
|
|
1985
|
+
}
|
|
1986
|
+
});
|
|
1987
|
+
console.log();
|
|
1988
|
+
displayTaskStatus2(status);
|
|
1989
|
+
} catch (error) {
|
|
1990
|
+
console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
|
|
1991
|
+
process.exit(1);
|
|
1992
|
+
}
|
|
1993
|
+
});
|
|
1994
|
+
program.command("deploy").description("Deploy project and verify").option("-i, --project-id <id>", "Project ID").option("-t, --platform <type>", "Platform", "web").option("-v, --verify", "Verify deployment", true).option("--no-verify", "Skip verification").option("-c, --cwd <dir>", "Working directory", process.cwd()).action(async (options) => {
|
|
1995
|
+
const loggedIn = await isLoggedIn();
|
|
1996
|
+
if (!loggedIn) {
|
|
1997
|
+
console.error(chalk8.red('Not logged in. Run "vibe-weaver login" first.'));
|
|
1998
|
+
process.exit(1);
|
|
1999
|
+
}
|
|
2000
|
+
const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), deploy_exports));
|
|
2001
|
+
const result = await deploy2({
|
|
2002
|
+
projectId: options.projectId,
|
|
2003
|
+
platform: options.platform,
|
|
2004
|
+
verify: options.verify,
|
|
2005
|
+
cwd: options.cwd
|
|
2006
|
+
});
|
|
2007
|
+
if (result.success) {
|
|
2008
|
+
console.log(chalk8.green(`
|
|
2009
|
+
\u2713 Deployed to ${result.url}`));
|
|
2010
|
+
} else {
|
|
2011
|
+
console.error(chalk8.red(`
|
|
2012
|
+
\u2717 Deployment failed: ${result.error}`));
|
|
2013
|
+
process.exit(1);
|
|
2014
|
+
}
|
|
2015
|
+
});
|
|
2016
|
+
program.parse();
|
|
2017
|
+
//# sourceMappingURL=index.js.map
|
|
2018
|
+
//# sourceMappingURL=index.js.map
|