@llamaventures/cli 1.2.3 → 1.2.4

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/bin/llama.mjs CHANGED
@@ -309,13 +309,19 @@ Upload a file (deck / pitch / one-pager):
309
309
  Interactive REPL (requires existing session):
310
310
  llama pitch
311
311
 
312
+ Wrap up the pitch (asks the agent to call finalize_intake immediately):
313
+ llama pitch finalize # use when you're done — agent stops asking
314
+
312
315
  Inspect / clean up:
313
316
  llama pitch status # session id, idle minutes, finalized?
314
317
  llama pitch end # clear local session state
315
318
 
316
319
  Caps (server-enforced):
317
- 5 sessions per IP per day, 3 per email per day, 30min idle timeout,
320
+ 5 sessions per IP per day, 3 per email per day, 60min idle timeout,
318
321
  100 messages per session, 1M tokens per session.
322
+
323
+ Environment:
324
+ LLAMA_API_URL override base URL (dev: http://localhost:3000)
319
325
  `);
320
326
  return;
321
327
  }
@@ -403,14 +409,49 @@ Caps (server-enforced):
403
409
  cleared: !!had,
404
410
  session_file: EXTERNAL_SESSION_FILE,
405
411
  note: had
406
- ? "Local session state cleared. Server-side session may still be active until idle timeout (30min)."
412
+ ? "Local session state cleared. Server-side session may still be active until idle timeout (60min)."
407
413
  : "No local session was active.",
408
414
  });
409
415
  return;
410
416
  }
411
417
 
418
+ if (action === "finalize") {
419
+ // Founder-initiated finalize: send a sentinel token in the chat
420
+ // stream that the system prompt recognizes as "wrap up now." The
421
+ // intake agent calls finalize_intake on this turn with whatever
422
+ // fields are recorded — no extra questions, no confirmation prompt.
423
+ // Local session is left as-is; on next read its `finalized=true`
424
+ // reflects the server's status.
425
+ const session = readExternalSession();
426
+ if (!session) {
427
+ throw new Error(
428
+ "No active pitch session. Run `llama pitch start --name \"...\" --email \"...\"` first."
429
+ );
430
+ }
431
+ if (session.finalized) {
432
+ throw new Error(
433
+ "This pitch session is already finalized. Run `llama pitch end` to clear local state."
434
+ );
435
+ }
436
+ process.stderr.write("Asking the agent to wrap up...\n");
437
+ const result = await sendExternalMessage("[FOUNDER_FINALIZE_REQUEST]");
438
+ process.stdout.write(result.text + "\n");
439
+ if (result.finalized) {
440
+ process.stderr.write("\n--- Pitch session finalized ---\n");
441
+ if (result.finalize_payload) {
442
+ process.stderr.write(JSON.stringify(result.finalize_payload, null, 2) + "\n");
443
+ }
444
+ } else {
445
+ process.stderr.write(
446
+ "\n⚠ Agent did not call finalize_intake on this turn. " +
447
+ "Try `llama pitch finalize` once more, or `llama pitch end` to abandon.\n"
448
+ );
449
+ }
450
+ return;
451
+ }
452
+
412
453
  // No action → REPL mode (requires existing session)
413
- if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end"].includes(action))) {
454
+ if (action === undefined || (rest.length === 0 && !["start", "say", "upload", "status", "end", "finalize"].includes(action))) {
414
455
  // Treat any unknown bare action as "join existing session in REPL mode"
415
456
  const session = readExternalSession();
416
457
  if (!session) {
package/lib/external.mjs CHANGED
@@ -100,6 +100,10 @@ export async function startExternalSession({ name, email }) {
100
100
  pow_nonce: powNonce,
101
101
  user_agent: "@llamaventures/cli",
102
102
  }),
103
+ // Cap at 60s — start-session is PoW + DB insert, never legitimate
104
+ // beyond a few seconds. Without this, a network hang freezes the CLI
105
+ // indefinitely.
106
+ signal: AbortSignal.timeout(60_000),
103
107
  });
104
108
 
105
109
  if (!res.ok) {
@@ -218,6 +222,11 @@ export async function sendExternalMessage(message, { attachments, onChunk } = {}
218
222
  message,
219
223
  ...(attachments ? { attachments } : {}),
220
224
  }),
225
+ // 180s ceiling — covers a legitimate slow agent turn (multi-tool
226
+ // call + deck read + Sonnet ~2k token reply ≈ 90-120s in practice)
227
+ // while still detecting a dead connection. Without this, a hung
228
+ // SSE stream freezes the CLI indefinitely.
229
+ signal: AbortSignal.timeout(180_000),
221
230
  });
222
231
 
223
232
  if (!res.ok) {
@@ -343,6 +352,10 @@ export async function uploadExternalFile(filePath) {
343
352
  method: "POST",
344
353
  headers: { Cookie: `external_session=${session.session_id}` },
345
354
  body: formData,
355
+ // 180s ceiling — covers a 50MB upload over a slow tether (~280KB/s).
356
+ // Faster networks return in seconds; this only kicks in on a dead
357
+ // connection so the CLI doesn't hang forever.
358
+ signal: AbortSignal.timeout(180_000),
346
359
  });
347
360
 
348
361
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llamaventures/cli",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "Llama Ventures CLI + MCP server. Internal team tool for command.llamaventures.vc.",
5
5
  "type": "module",
6
6
  "bin": {