@llamaventures/cli 1.10.0 → 1.12.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/AGENT_BRIEFING.md +2 -1
- package/bin/llama-mcp.mjs +9 -3
- package/bin/llama.mjs +107 -5
- package/package.json +1 -1
package/AGENT_BRIEFING.md
CHANGED
|
@@ -47,7 +47,8 @@ A teammate says "I just met them and heard…" or pastes a chunk of notes. Your
|
|
|
47
47
|
- **Verifiable claims → facts.** `llama deal fact add <dealId> --category <cat> --claim "…" --source "<where it came from>"`. A claim someone *relayed* ("their ARR is $3M", "raised from a16z") is a fact at **unverified** trust — it's hearsay until checked. Pass `--attested` ONLY if you actually verified it against a source yourself.
|
|
48
48
|
- **Their judgment / impression → a note.** `llama post <dealId> "…"`. "Founder seemed evasive", "I'd lean pass", "worth a second meeting" — opinion, not fact. Attributed, never "verified".
|
|
49
49
|
- A pasted blob → pull the verifiable claims out as facts, capture their take as a note.
|
|
50
|
-
3. **
|
|
50
|
+
3. **Read it back before you claim it's saved.** A tool call returning `{ok:true}` is NOT proof the content is where the user will look for it. After filing, run `llama deal feed <dealId>` and confirm your fact/note actually appears, THEN tell the user in plain language what you recorded and where. Never say "记好了 / saved" from the return value alone — the #1 failure is an agent writing to the wrong surface (e.g. the brief, which is the Memo and does NOT appear in the feed) and reporting success anyway. If it's not in the feed, you routed it wrong — fix it.
|
|
51
|
+
- **Authorship is automatic, don't fake it.** Everything you write via CLI/MCP is recorded as "via assistant" (you're the accountable human's assistant). You can't and shouldn't make it read as human-typed — that honesty is the feature. Facts you add stay **unverified** until a human confirms them; if you pass `--attested` (only when you actually checked the source) your ceiling is **agent-verified**, never human-vouched. Only a person, signed in at the browser, can vouch. The confirmation IS the trust step — never silently mark something verified.
|
|
51
52
|
|
|
52
53
|
Why split it: facts and opinions live in different layers so the deal keeps one clean **source of truth** (facts, sourced + trust-rated) separate from people's **takes** (notes). The four layers — facts / notes / brief (AI's synthesis) / timeline — are documented in Llama Command's `docs/SCHEMA.md`.
|
|
53
54
|
|
package/bin/llama-mcp.mjs
CHANGED
|
@@ -307,10 +307,16 @@ server.registerTool(
|
|
|
307
307
|
"deal_feed",
|
|
308
308
|
{
|
|
309
309
|
description:
|
|
310
|
-
"The unified, time-sorted stream of
|
|
310
|
+
"The unified, time-sorted stream of every contribution to a deal — " +
|
|
311
311
|
"facts + notes/discussion + legacy posts, merged at query time, newest first. " +
|
|
312
|
-
"
|
|
313
|
-
"
|
|
312
|
+
"Shows contributions from ANYONE — a teammate, their AI assistant, or an " +
|
|
313
|
+
"autonomous system agent; nothing is hidden. Each item carries `who` (the " +
|
|
314
|
+
"accountable person, null only for principal-less system writes) and `agent` " +
|
|
315
|
+
"(the assistant/system label when an AI did the writing, null when a human " +
|
|
316
|
+
"typed it) so you can tell human-typed from assistant-drafted. The AI's " +
|
|
317
|
+
"regenerable brief/persona synthesis is NOT here (that's the Memo) — only " +
|
|
318
|
+
"facts + discussion notes. Each item: kind (fact|note), ts, who, agent, " +
|
|
319
|
+
"origin, text, and for facts: source + trust rung + category.",
|
|
314
320
|
inputSchema: {
|
|
315
321
|
dealId: z.string(),
|
|
316
322
|
},
|
package/bin/llama.mjs
CHANGED
|
@@ -225,7 +225,7 @@ Manually-set \`llc_\` tokens are used as a fallback.
|
|
|
225
225
|
Deals:
|
|
226
226
|
llama deal create "Company" --source <name> --description "..." --website https://...
|
|
227
227
|
llama deal show <dealId>
|
|
228
|
-
llama deal feed <dealId> #
|
|
228
|
+
llama deal feed <dealId> # every contribution (facts + notes), human-typed or assistant-drafted, newest first
|
|
229
229
|
llama deal update <dealId> <field> <value>
|
|
230
230
|
Writable fields: status, theirStage, stage, notes, dealOwner, source,
|
|
231
231
|
description, website, location, founders, proposedAmount, roundSize,
|
|
@@ -375,6 +375,11 @@ Deal page HTML (hand-authored sandboxed pages on /deals/<id>/browse/<slug>):
|
|
|
375
375
|
llama html docs create <dealId> <slug> [--title "..."] # pre-create a slot
|
|
376
376
|
llama html docs archive <dealId> <slug> # soft-archive (browse hides)
|
|
377
377
|
|
|
378
|
+
Link a card to a wiki article (one file, multiple entrances — the wiki
|
|
379
|
+
stays canonical, the deal card is a live, read-only pointer):
|
|
380
|
+
llama html link <dealId> --wiki <slug> [--lang en|zh] [--title "..."]
|
|
381
|
+
llama html unlink <dealId> <slug> # revert to a normal self-hosted doc
|
|
382
|
+
|
|
378
383
|
Update an EXISTING artifact (slug must exist):
|
|
379
384
|
llama html upload <dealId> --doc <slug> --file <path> [--assets DIR]
|
|
380
385
|
|
|
@@ -423,7 +428,7 @@ const HELP_ROOT = `Llama Command CLI — the \`llama\` command for the Llama Ven
|
|
|
423
428
|
Common:
|
|
424
429
|
llama deal search "<name>" find a deal in the pipeline
|
|
425
430
|
llama deal show <dealId> full deal record
|
|
426
|
-
llama deal feed <dealId>
|
|
431
|
+
llama deal feed <dealId> every contribution (facts + notes), newest first
|
|
427
432
|
llama post <dealId> "..." add a note to a deal
|
|
428
433
|
llama agent-onboard print the AI-agent workflow contract
|
|
429
434
|
|
|
@@ -2132,6 +2137,27 @@ Routing — is this the right command?
|
|
|
2132
2137
|
return `/api/deals/${encodeURIComponent(dealId)}/documents/${encodeURIComponent(slug)}/html`;
|
|
2133
2138
|
}
|
|
2134
2139
|
|
|
2140
|
+
// Surface a clean `linked_wiki` field on linked docs so the listing
|
|
2141
|
+
// reads as "this card points at wiki/<slug>" rather than exposing the
|
|
2142
|
+
// raw source_wiki_* columns. Non-linked docs are returned unchanged.
|
|
2143
|
+
function withLinkedWiki(data) {
|
|
2144
|
+
if (!data || !Array.isArray(data.documents)) return data;
|
|
2145
|
+
return {
|
|
2146
|
+
...data,
|
|
2147
|
+
documents: data.documents.map((d) =>
|
|
2148
|
+
d && d.source_wiki_slug
|
|
2149
|
+
? {
|
|
2150
|
+
...d,
|
|
2151
|
+
linked_wiki: {
|
|
2152
|
+
slug: d.source_wiki_slug,
|
|
2153
|
+
lang: d.source_wiki_lang || "en",
|
|
2154
|
+
},
|
|
2155
|
+
}
|
|
2156
|
+
: d,
|
|
2157
|
+
),
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2135
2161
|
// docs — list / create / archive documents on a deal.
|
|
2136
2162
|
//
|
|
2137
2163
|
// Forms:
|
|
@@ -2159,7 +2185,7 @@ Routing — is this the right command?
|
|
|
2159
2185
|
"GET",
|
|
2160
2186
|
`/api/deals/${encodeURIComponent(dealId)}/documents`,
|
|
2161
2187
|
);
|
|
2162
|
-
print(data);
|
|
2188
|
+
print(withLinkedWiki(data));
|
|
2163
2189
|
return;
|
|
2164
2190
|
}
|
|
2165
2191
|
if (docSub === "list") {
|
|
@@ -2171,7 +2197,7 @@ Routing — is this the right command?
|
|
|
2171
2197
|
"GET",
|
|
2172
2198
|
`/api/deals/${encodeURIComponent(dealId)}/documents`,
|
|
2173
2199
|
);
|
|
2174
|
-
print(data);
|
|
2200
|
+
print(withLinkedWiki(data));
|
|
2175
2201
|
return;
|
|
2176
2202
|
}
|
|
2177
2203
|
if (docSub === "create") {
|
|
@@ -2210,6 +2236,82 @@ Routing — is this the right command?
|
|
|
2210
2236
|
);
|
|
2211
2237
|
}
|
|
2212
2238
|
|
|
2239
|
+
// link — turn a deal doc card into a live, read-only pointer to a wiki
|
|
2240
|
+
// HTML article. "One file, multiple entrances": the wiki stays the
|
|
2241
|
+
// canonical home, the card just renders the wiki's HTML. Edits go to
|
|
2242
|
+
// the wiki source; uploads to a linked slug are refused server-side.
|
|
2243
|
+
//
|
|
2244
|
+
// llama html link <dealId> --wiki <slug> [--lang en|zh] [--title "..."]
|
|
2245
|
+
//
|
|
2246
|
+
// Default deal-side slug = the wiki slug. Default title = the wiki
|
|
2247
|
+
// article's title (fetched from `llama wiki read`).
|
|
2248
|
+
if (sub === "link") {
|
|
2249
|
+
const dealId = rest[0];
|
|
2250
|
+
const { flags } = parseFlags(rest.slice(1), ["wiki", "lang", "title", "slug"]);
|
|
2251
|
+
const wikiSlug =
|
|
2252
|
+
typeof flags.wiki === "string" && flags.wiki.trim()
|
|
2253
|
+
? flags.wiki.trim()
|
|
2254
|
+
: null;
|
|
2255
|
+
if (!dealId || !wikiSlug) {
|
|
2256
|
+
throw new Error(
|
|
2257
|
+
"Usage: llama html link <dealId> --wiki <slug> [--lang en|zh] [--title \"...\"]",
|
|
2258
|
+
);
|
|
2259
|
+
}
|
|
2260
|
+
const lang = flags.lang === "zh" ? "zh" : "en";
|
|
2261
|
+
// Deal-side slug defaults to the wiki slug; --slug overrides.
|
|
2262
|
+
const dealSlug =
|
|
2263
|
+
typeof flags.slug === "string" && flags.slug.trim()
|
|
2264
|
+
? flags.slug.trim()
|
|
2265
|
+
: wikiSlug;
|
|
2266
|
+
// Title defaults to the wiki article's title.
|
|
2267
|
+
let title =
|
|
2268
|
+
typeof flags.title === "string" && flags.title.trim()
|
|
2269
|
+
? flags.title.trim()
|
|
2270
|
+
: null;
|
|
2271
|
+
if (!title) {
|
|
2272
|
+
try {
|
|
2273
|
+
const article = await request(
|
|
2274
|
+
"GET",
|
|
2275
|
+
`/api/wiki/${encodeURIComponent(wikiSlug)}?lang=${lang}`,
|
|
2276
|
+
);
|
|
2277
|
+
title = article?.frontmatter?.title || wikiSlug;
|
|
2278
|
+
} catch {
|
|
2279
|
+
// Fall back to the slug as the title; the server still validates
|
|
2280
|
+
// that the wiki article exists + is HTML on the POST below.
|
|
2281
|
+
title = wikiSlug;
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
const data = await request(
|
|
2285
|
+
"POST",
|
|
2286
|
+
`/api/deals/${encodeURIComponent(dealId)}/documents`,
|
|
2287
|
+
{
|
|
2288
|
+
slug: dealSlug,
|
|
2289
|
+
title,
|
|
2290
|
+
source_wiki_slug: wikiSlug,
|
|
2291
|
+
source_wiki_lang: lang,
|
|
2292
|
+
},
|
|
2293
|
+
);
|
|
2294
|
+
print(data);
|
|
2295
|
+
return;
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// unlink — revert a linked card back to a normal self-hosted doc.
|
|
2299
|
+
// llama html unlink <dealId> <slug>
|
|
2300
|
+
if (sub === "unlink") {
|
|
2301
|
+
const dealId = rest[0];
|
|
2302
|
+
const slug = rest[1];
|
|
2303
|
+
if (!dealId || !slug) {
|
|
2304
|
+
throw new Error("Usage: llama html unlink <dealId> <slug>");
|
|
2305
|
+
}
|
|
2306
|
+
const data = await request(
|
|
2307
|
+
"PATCH",
|
|
2308
|
+
`/api/deals/${encodeURIComponent(dealId)}/documents/${encodeURIComponent(slug)}`,
|
|
2309
|
+
{ source_wiki_slug: null },
|
|
2310
|
+
);
|
|
2311
|
+
print(data);
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2213
2315
|
// show — fetch the current HTML. Default: print to stdout (pipeable).
|
|
2214
2316
|
if (sub === "show") {
|
|
2215
2317
|
const dealId = rest[0];
|
|
@@ -2648,7 +2750,7 @@ Routing — is this the right command?
|
|
|
2648
2750
|
}
|
|
2649
2751
|
|
|
2650
2752
|
throw new Error(
|
|
2651
|
-
`Unknown html subcommand "${sub || ""}". Use: docs / show / upload / versions / restore / reset.`,
|
|
2753
|
+
`Unknown html subcommand "${sub || ""}". Use: docs / link / unlink / show / upload / versions / restore / reset.`,
|
|
2652
2754
|
);
|
|
2653
2755
|
}
|
|
2654
2756
|
|