@llamaventures/cli 1.2.1 → 1.2.2
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 +18 -3
- package/lib/external.mjs +15 -7
- package/package.json +1 -1
package/bin/llama.mjs
CHANGED
|
@@ -296,7 +296,12 @@ Setup:
|
|
|
296
296
|
llama pitch start --name "Your Name" --email "you@company.com"
|
|
297
297
|
|
|
298
298
|
Single message (non-interactive):
|
|
299
|
-
llama pitch say
|
|
299
|
+
llama pitch say 'We have $8k MRR and 5 design partners'
|
|
300
|
+
|
|
301
|
+
⚠ Tip: wrap pitch text in SINGLE quotes ('...') if it contains
|
|
302
|
+
characters like $, \`, or !. Double quotes let the shell expand
|
|
303
|
+
variables — e.g. "$8k MRR" becomes "k MRR" because $8 is empty.
|
|
304
|
+
Interactive REPL (\`llama pitch\`) doesn't have this problem.
|
|
300
305
|
|
|
301
306
|
Upload a file (deck / pitch / one-pager):
|
|
302
307
|
llama pitch upload ./deck.pdf
|
|
@@ -365,13 +370,23 @@ Caps (server-enforced):
|
|
|
365
370
|
}
|
|
366
371
|
|
|
367
372
|
if (action === "upload") {
|
|
368
|
-
const
|
|
373
|
+
const { flags, positional } = parseFlags(rest);
|
|
374
|
+
const filePath = positional[0];
|
|
369
375
|
if (!filePath) {
|
|
370
376
|
throw new Error("pitch upload: file path required. Example: llama pitch upload ./deck.pdf");
|
|
371
377
|
}
|
|
372
378
|
process.stderr.write(`Uploading ${filePath}...\n`);
|
|
373
379
|
const result = await uploadExternalFile(filePath);
|
|
374
|
-
|
|
380
|
+
if (flags.json) {
|
|
381
|
+
print(result);
|
|
382
|
+
} else {
|
|
383
|
+
// Friendly default — drop server-internal fields (drive_file_id /
|
|
384
|
+
// sha256 / file_id). Founders just want "did it work + what does
|
|
385
|
+
// the agent do next." Pass --json for the full payload.
|
|
386
|
+
const sizeKb = (result.size / 1024).toFixed(1);
|
|
387
|
+
console.log(`✓ Uploaded ${result.filename} (${sizeKb} KB).`);
|
|
388
|
+
console.log(` The intake agent can now reference this file in your pitch.`);
|
|
389
|
+
}
|
|
375
390
|
return;
|
|
376
391
|
}
|
|
377
392
|
|
package/lib/external.mjs
CHANGED
|
@@ -104,13 +104,21 @@ export async function startExternalSession({ name, email }) {
|
|
|
104
104
|
|
|
105
105
|
if (!res.ok) {
|
|
106
106
|
const text = await res.text();
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
107
|
+
// Server returns a JSON envelope { error: "<message>" } — surface
|
|
108
|
+
// whatever message it picked. User-fault reasons (email_invalid /
|
|
109
|
+
// email_disposable / email_mx_unresolved / name_invalid) get a
|
|
110
|
+
// specific message; anti-abuse reasons collapse to a generic
|
|
111
|
+
// "try again later". Either way the server message is the one to
|
|
112
|
+
// show — don't bolt on a verbose "Common causes" trailer because
|
|
113
|
+
// it muddies the specific cases.
|
|
114
|
+
let serverMsg = text;
|
|
115
|
+
try {
|
|
116
|
+
const parsed = JSON.parse(text);
|
|
117
|
+
if (parsed?.error) serverMsg = String(parsed.error);
|
|
118
|
+
} catch {
|
|
119
|
+
// Non-JSON body — fall back to raw text.
|
|
120
|
+
}
|
|
121
|
+
throw new Error(`Could not start session (HTTP ${res.status}): ${serverMsg.slice(0, 300)}`);
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
const data = await res.json();
|