ventureos 1.0.6 → 1.0.7

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.
Files changed (2) hide show
  1. package/install.js +83 -13
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -15,6 +15,7 @@ import { stdin as input, stdout as output } from 'process';
15
15
  import fs from 'fs';
16
16
  import path from 'path';
17
17
  import { fileURLToPath } from 'url';
18
+ import { spawnSync } from 'child_process';
18
19
 
19
20
  const __filename = fileURLToPath(import.meta.url);
20
21
  const PACKAGE_ROOT = path.dirname(__filename);
@@ -40,6 +41,11 @@ const PROVIDERS = {
40
41
  },
41
42
  };
42
43
 
44
+ // CLI tools that can be used instead of an API key
45
+ const CLI_TOOLS = {
46
+ anthropic: { cmd: 'claude', label: 'Claude CLI' },
47
+ };
48
+
43
49
  const cmd = process.argv[2];
44
50
 
45
51
  if (cmd === 'start') {
@@ -283,17 +289,41 @@ async function startChat() {
283
289
  const providerKey = PROVIDERS[config.llm] ? config.llm : 'anthropic';
284
290
  const provider = PROVIDERS[providerKey];
285
291
 
286
- // ── Get API key ────────────────────────────────────────────────────────────
292
+ // ── Get API key or use CLI mode ────────────────────────────────────────────
287
293
  let apiKey = process.env[provider.envVar];
294
+ let useCLI = false;
295
+ let cliCmd = null;
296
+
288
297
  if (!apiKey) {
289
- console.log(`\n 🔑 ${provider.envVar} not set in environment.`);
290
- apiKey = (await rl.question(` Enter your ${provider.label} API key: `)).trim();
291
- if (!apiKey) {
292
- console.error('\n ❌ No API key provided.\n');
293
- rl.close();
294
- process.exit(1);
298
+ const cli = detectCLI(providerKey);
299
+ if (cli) {
300
+ console.log(`\n 🔑 ${provider.envVar} not set in environment.\n`);
301
+ console.log(` How would you like to connect?\n`);
302
+ console.log(` 1. Enter API key`);
303
+ console.log(` 2. Use ${cli.label} (detected on your system)\n`);
304
+ const choice = (await rl.question(' Select [1-2]: ')).trim();
305
+ if (choice === '2') {
306
+ useCLI = true;
307
+ cliCmd = cli.cmd;
308
+ } else {
309
+ apiKey = (await rl.question(`\n Enter your ${provider.label} API key: `)).trim();
310
+ if (!apiKey) {
311
+ console.error('\n ❌ No API key provided.\n');
312
+ rl.close();
313
+ process.exit(1);
314
+ }
315
+ console.log(`\n 💡 Tip: export ${provider.envVar}=your-key to skip this next time.\n`);
316
+ }
317
+ } else {
318
+ console.log(`\n 🔑 ${provider.envVar} not set in environment.`);
319
+ apiKey = (await rl.question(` Enter your ${provider.label} API key: `)).trim();
320
+ if (!apiKey) {
321
+ console.error('\n ❌ No API key provided.\n');
322
+ rl.close();
323
+ process.exit(1);
324
+ }
325
+ console.log(`\n 💡 Tip: export ${provider.envVar}=your-key to skip this next time.\n`);
295
326
  }
296
- console.log(`\n 💡 Tip: export ${provider.envVar}=your-key to skip this next time.\n`);
297
327
  }
298
328
 
299
329
  // ── Load system prompt ─────────────────────────────────────────────────────
@@ -320,7 +350,7 @@ async function startChat() {
320
350
  `--- ventureOS/_memory/venture-state.yaml ---\n${stateContent}`;
321
351
 
322
352
  console.log(line());
323
- console.log(` ✓ Connected to ${provider.label}`);
353
+ console.log(` ✓ Connected ${useCLI ? `via ${cliCmd} CLI` : `to ${provider.label}`}`);
324
354
  console.log(` ✓ Type your message and press Enter. Type "exit" or Ctrl+C to quit.`);
325
355
  console.log(line() + '\n');
326
356
 
@@ -330,9 +360,9 @@ async function startChat() {
330
360
  showSpinner(' Victor is thinking');
331
361
  let firstResponse;
332
362
  try {
333
- firstResponse = await callLLM(providerKey, apiKey, provider.defaultModel, systemPrompt, [
334
- { role: 'user', content: activationMsg },
335
- ]);
363
+ firstResponse = useCLI
364
+ ? await callViaCLI(cliCmd, systemPrompt, [{ role: 'user', content: activationMsg }])
365
+ : await callLLM(providerKey, apiKey, provider.defaultModel, systemPrompt, [{ role: 'user', content: activationMsg }]);
336
366
  } catch (err) {
337
367
  stopSpinner();
338
368
  console.error(`\n ❌ API error: ${err.message}`);
@@ -368,7 +398,9 @@ async function startChat() {
368
398
  showSpinner(' Victor is thinking');
369
399
  let response;
370
400
  try {
371
- response = await callLLM(providerKey, apiKey, provider.defaultModel, systemPrompt, messages);
401
+ response = useCLI
402
+ ? await callViaCLI(cliCmd, systemPrompt, messages)
403
+ : await callLLM(providerKey, apiKey, provider.defaultModel, systemPrompt, messages);
372
404
  } catch (err) {
373
405
  stopSpinner();
374
406
  console.error(`\n ❌ API error: ${err.message}\n`);
@@ -385,6 +417,19 @@ async function startChat() {
385
417
  rl.close();
386
418
  }
387
419
 
420
+ // ─── CLI Detection ─────────────────────────────────────────────────────────────
421
+
422
+ function detectCLI(providerKey) {
423
+ const tool = CLI_TOOLS[providerKey];
424
+ if (!tool) return null;
425
+ try {
426
+ const result = spawnSync('which', [tool.cmd], { encoding: 'utf8', stdio: 'pipe' });
427
+ return result.status === 0 && result.stdout.trim() ? tool : null;
428
+ } catch {
429
+ return null;
430
+ }
431
+ }
432
+
388
433
  // ─── Spinner ───────────────────────────────────────────────────────────────────
389
434
  function showSpinner(msg) {
390
435
  const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
@@ -442,6 +487,31 @@ async function callLLM(provider, apiKey, model, system, messages) {
442
487
  throw new Error(`Unknown provider: ${provider}`);
443
488
  }
444
489
 
490
+ async function callViaCLI(cliCmd, system, messages) {
491
+ // Build full context: system + conversation history + latest user message
492
+ let prompt = system + '\n\n';
493
+
494
+ for (const msg of messages.slice(0, -1)) {
495
+ const role = msg.role === 'user' ? 'Human' : 'Assistant';
496
+ prompt += `${role}: ${msg.content}\n\n`;
497
+ }
498
+
499
+ const lastMsg = messages[messages.length - 1];
500
+ prompt += `Human: ${lastMsg.content}`;
501
+
502
+ const result = spawnSync(cliCmd, ['-p', prompt], {
503
+ encoding: 'utf8',
504
+ maxBuffer: 10 * 1024 * 1024,
505
+ timeout: 120000,
506
+ });
507
+
508
+ if (result.error) throw result.error;
509
+ if (result.status !== 0) {
510
+ throw new Error(result.stderr?.trim() || `${cliCmd} CLI exited with code ${result.status}`);
511
+ }
512
+ return result.stdout.trim();
513
+ }
514
+
445
515
  async function callAnthropic(apiKey, model, system, messages) {
446
516
  const res = await fetch('https://api.anthropic.com/v1/messages', {
447
517
  method: 'POST',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ventureos",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "VentureOS — AI-powered venture building framework. From raw idea to investor-ready pitch in 12 structured weeks.",
5
5
  "type": "module",
6
6
  "bin": {