@llamaventures/cli 1.22.0 → 1.23.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 CHANGED
@@ -66,6 +66,7 @@ A teammate says "I just met them and heard…" or pastes a chunk of notes. Your
66
66
  2. **Split what they gave you into two kinds** — this is the whole data model:
67
67
  - **A source packet with 2+ facts, or facts + a note → ingest once.** Build a JSON object with `source`, `facts`, and optional `note`, then run `llama deal ingest <dealId> --file <packet.json>`. This is the preferred agent path: one atomic, deduplicated, retry-safe commit. Reuse an explicit `idempotencyKey` when retrying the same material. The matching MCP tool is `deal_ingest` and uses the same packet shape.
68
68
  - **Verifiable claims → facts.** `llama deal fact add <dealId> --category <cat> --claim "…" --source "<where it came from>" --source-url <url>`. 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. In raw API terms, the fact text field is `claim` (`value` is only a compatibility alias), `source` is the human-readable provenance label, and `sourceUrl` is the canonical URL.
69
+ - **Trust and contest are separate axes.** A *contested* fact is excluded from what the Deal Agent treats as current, whatever its trust rung — so a fact can read as both `human-vouched` and suppressed. `fact verify --status confirmed` does **not** lift a contest; the response tells you when one is still standing. To lift one: `llama deal fact uncontest <dealId> <factId> --reason "…"`. The lifted contest is kept in the fact's history, not erased.
69
70
  - **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".
70
71
  - A pasted blob → pull the verifiable claims out as facts, capture their take as a note.
71
72
  3. **Read it back before you claim it's saved.** A generic tool call returning `{ok:true}` is NOT proof the content is where the user will look for it. `deal ingest` is the exception because its response is built from the rows and note block read back after commit: confirm `createdFacts`, `skippedFacts`, `note`, and `summary` in that receipt. For every other write, run `llama deal feed <dealId>` and confirm your fact/note actually appears. Never say "记好了 / saved" from a request acknowledgment 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 the authoritative ingest receipt or the feed read-back does not contain the material, fix it before reporting success.
@@ -217,6 +218,7 @@ llama deal create "Company" --description "..." --source-direction Outbound --st
217
218
  llama deal create "Company" --description "..." --source-direction Outbound --status Outreached --deal-owner "owner@llamaventures.vc"
218
219
  llama deal create "Company" --description "..." --source-direction Inbound --status Sourced --deal-owner "Exact Name"
219
220
  llama deal update <dealId> <field> <value>
221
+ llama deal fact uncontest <dealId> <factId> --reason "..." # lift a wrong contest; verify does NOT
220
222
  # writable: status theirStage stage notes dealOwner source sourceDirection description website
221
223
  # location founders proposedAmount roundSize valuation sector subsector
222
224
  # foundedYear leadInvestor investors (each write logs a deal_events row)
package/CHANGELOG.md CHANGED
@@ -6,6 +6,43 @@ this project adheres to [Semantic Versioning](https://semver.org).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.23.0] - 2026-08-05
10
+
11
+ ### Added
12
+ - `llama deal fact uncontest <dealId> <factId> --reason "..."` lifts a contest
13
+ that turned out to be wrong. Contesting a fact removes it from what the Deal
14
+ Agent treats as current, and until now nothing could put it back — so a true
15
+ claim contested on weak evidence stayed suppressed in every regenerated brief
16
+ and memo. The lifted contest is kept in the fact's history server-side, not
17
+ erased. Requires Llama Command >= 3.21.0.
18
+
19
+ ### Changed
20
+ - `--help` and `AGENT_BRIEFING.md` now state that **trust and contest are
21
+ separate axes**: `fact verify --status confirmed` does NOT lift a contest, and
22
+ a contested fact stays excluded from synthesis whatever its trust rung. The
23
+ server now returns a warning when a verify leaves a contest standing.
24
+ - `deal update` help says what `notes` is for — the one-line Summary headline at
25
+ the top of the deal page (~280 chars), not a place for meeting notes. It was
26
+ previously listed among 20 field names with no semantics, so the honest
27
+ reading was "notes" and long text landed in a headline slot.
28
+
29
+ ### Note
30
+ This release also carries the unpublished 1.22.2 fix below.
31
+
32
+ ## [1.22.2] - 2026-08-04
33
+
34
+ ### Fixed
35
+ - `llama claim` and `llama nominate` now require `--reason` and send it to
36
+ Llama Command's audited Owner-label endpoint. The CLI no longer emits a
37
+ request that Core must reject before recording the responsibility change.
38
+
39
+ ## [1.22.1] - 2026-08-04
40
+
41
+ ### Changed
42
+ - Refresh the transitive `ip-address` dependency from 10.2.0 to 10.4.0 and
43
+ retain the same CLI and MCP behavior across the supported Node 18/20/22
44
+ matrix.
45
+
9
46
  ## [1.22.0] - 2026-07-28
10
47
 
11
48
  ### Added
package/bin/llama-mcp.mjs CHANGED
@@ -457,8 +457,7 @@ server.registerTool(
457
457
  {
458
458
  description:
459
459
  "Create a new pipeline deal. Source defaults to the caller's user record. " +
460
- "Owner assignment goes through the partner-approval queue (status: pending) " +
461
- "until a partner approves it via /partner/approvals.",
460
+ "Owner is an audited responsibility label, not an operating-permission boundary.",
462
461
  inputSchema: {
463
462
  companyName: z.string(),
464
463
  description: z.string().optional().describe("one-liner: what they do"),
package/bin/llama.mjs CHANGED
@@ -395,6 +395,9 @@ Deals:
395
395
  description, website, location, founders, founderInfo, proposedAmount,
396
396
  roundSize, valuation, deckLink, folderUrl, sector, subsector,
397
397
  foundedYear, leadInvestor, investors, agentActive.
398
+ 'notes' is the ONE-LINE judgment shown as the Summary headline at the top of
399
+ the deal page (~280 chars). Meeting notes and narrative go in a comment
400
+ (llama post); verifiable claims go in facts (llama deal fact add).
398
401
  e.g. llama deal update <dealId> website https://acme.ai
399
402
  llama deal update <dealId> status Interested
400
403
  llama deal update <dealId> sector "Developer Tools"
@@ -446,12 +449,12 @@ Deal links (separate from brief link blocks — these live in deal_links):
446
449
  llama deal link restore <dealId> <linkId>
447
450
 
448
451
  Ownership:
449
- llama claim <dealId> # propose self as owner
450
- llama nominate <dealId> --user <userId> # partner nominates someone else
451
- llama nominations list # pending nominations for me
452
- llama nominations decide <approvalId> accepted|declined # accept/decline a nomination
452
+ llama claim <dealId> --reason "..." # set yourself as Owner
453
+ llama nominate <dealId> --user <userId> --reason "..." # set another teammate as Owner
454
+ Owner is an audited responsibility label, not a permission boundary. Any
455
+ internal teammate can change it after Partner Support; reason is mandatory.
453
456
 
454
- Approvals (partner queue — self-claim approvals):
457
+ Approvals (Partner queue — contribution decisions):
455
458
  llama approvals list
456
459
  llama approvals decide <approvalId> approved|rejected [--note "..."]
457
460
 
@@ -503,6 +506,9 @@ Deal facts (AI-extracted or human-asserted, with verification):
503
506
  llama deal fact list <dealId>
504
507
  llama deal fact add <dealId> --category <cat> --claim "<text>" [--source "..."] [--source-url <url>] [--confidence high|medium|low] [--attested]
505
508
  llama deal fact verify <dealId> <factId> --status confirmed|disputed [--corrected-value "..."]
509
+ llama deal fact uncontest <dealId> <factId> --reason "<why the contest was wrong>"
510
+ contest and trust are separate axes: 'verify --status confirmed' does NOT lift a contest,
511
+ and a contested fact stays excluded from what the Deal Agent treats as current.
506
512
 
507
513
  Mentions / Inbox:
508
514
  llama mentions # default: my unresolved cues
@@ -625,7 +631,7 @@ Command groups — run \`llama help <group>\` for that group's commands:
625
631
  deal create · show · feed · update · enrich · search · collaborators · links · delete
626
632
  activity new-deals · updated-deals · events for agent read models
627
633
  brief brief blocks: list · add · edit · history · refresh
628
- facts deal facts + skill corrections (the sourced, trust-rated layer)
634
+ facts deal facts the sourced, trust-rated layer
629
635
  timeline timeline · posts · mentions
630
636
  wiki cross-deal knowledge entries (markdown or HTML)
631
637
  pref standing agent preferences: list · add · retire · approve
@@ -645,10 +651,20 @@ the CLI auto-detects it — no token needed (\`llc_\` tokens are a fallback).`;
645
651
 
646
652
  // Area → which top-level sections of HELP_FULL belong to it.
647
653
  const HELP_AREA_MATCH = {
648
- deal: [/^Deals/, /^Collaborators/, /^Soft-delete/, /^Deal links/, /^Deal soft-delete/],
654
+ deal: [
655
+ /^Deals/,
656
+ /^Collaborators/,
657
+ /^Soft-delete/,
658
+ /^Deal links/,
659
+ /^Deal soft-delete/,
660
+ // `llama deal refresh-brief` / `revert-run` live under this heading. Without
661
+ // it here the section matched no area and was reachable only via `help all`,
662
+ // which read as "the command does not exist".
663
+ /^Brief refresh/,
664
+ ],
649
665
  activity: [/^Agent activity/],
650
- brief: [/^Brief blocks/],
651
- facts: [/^Deal facts/, /^Skill corrections/],
666
+ brief: [/^Brief blocks/, /^Brief refresh/],
667
+ facts: [/^Deal facts/],
652
668
  timeline: [/^Timeline/, /^Mentions/],
653
669
  wiki: [/^Wiki/, /^Where does this HTML/],
654
670
  memo: [/^Memo/],
@@ -1816,7 +1832,29 @@ async function main() {
1816
1832
  return;
1817
1833
  }
1818
1834
 
1819
- throw new Error(`Unknown fact sub-command "${sub}". Use list, add, or verify.`);
1835
+ // Lift a contest that turned out to be wrong. Contesting a claim removes
1836
+ // it from everything the Deal Agent treats as current; before this existed
1837
+ // there was no way back, so a TRUE claim contested on weak evidence stayed
1838
+ // suppressed in every regenerated brief and memo. `verify --status
1839
+ // confirmed` does NOT do this — trust and contest are separate axes.
1840
+ if (sub === "uncontest") {
1841
+ const factId = rest[2];
1842
+ const reason = flags.reason !== undefined && flags.reason !== true ? String(flags.reason).trim() : "";
1843
+ if (!factId || !reason) {
1844
+ throw new Error(
1845
+ `Usage: llama deal fact uncontest <dealId> <factId> --reason "<why the contest was wrong>"`
1846
+ );
1847
+ }
1848
+ // @core-api-operation POST /api/deals/{dealId}/facts/{factId}/uncontest
1849
+ print(await request(
1850
+ "POST",
1851
+ `/api/deals/${encodeURIComponent(dealId)}/facts/${encodeURIComponent(factId)}/uncontest`,
1852
+ { reason }
1853
+ ));
1854
+ return;
1855
+ }
1856
+
1857
+ throw new Error(`Unknown fact sub-command "${sub}". Use list, add, verify, or uncontest.`);
1820
1858
  }
1821
1859
 
1822
1860
  // ----- Brief refresh: trigger stale-section re-eval watcher run -----
@@ -1880,12 +1918,16 @@ async function main() {
1880
1918
  // ----- Ownership: self-claim -----
1881
1919
  if (area === "claim") {
1882
1920
  const dealId = action; // second positional
1883
- if (!dealId) throw new Error("Usage: llama claim <dealId>");
1921
+ const { flags } = parseFlags(rest, ["reason"]);
1922
+ const reason = typeof flags.reason === "string" ? flags.reason.trim() : "";
1923
+ if (!dealId || !reason) {
1924
+ throw new Error('Usage: llama claim <dealId> --reason "<why this person should own it>"');
1925
+ }
1884
1926
  const me = await request("GET", "/api/me");
1885
1927
  print(await request(
1886
1928
  "POST",
1887
1929
  `/api/deals/${encodeURIComponent(dealId)}/propose-owner`,
1888
- { userId: me.id }
1930
+ { userId: me.id, reason }
1889
1931
  ));
1890
1932
  return;
1891
1933
  }
@@ -1893,15 +1935,16 @@ async function main() {
1893
1935
  // ----- Ownership: partner nominates someone else -----
1894
1936
  if (area === "nominate") {
1895
1937
  const dealId = action;
1896
- const { flags } = parseFlags(rest);
1938
+ const { flags } = parseFlags(rest, ["user", "reason"]);
1897
1939
  const userId = Number(flags.user);
1898
- if (!dealId || !Number.isFinite(userId)) {
1899
- throw new Error("Usage: llama nominate <dealId> --user <userId>");
1940
+ const reason = typeof flags.reason === "string" ? flags.reason.trim() : "";
1941
+ if (!dealId || !Number.isFinite(userId) || !reason) {
1942
+ throw new Error('Usage: llama nominate <dealId> --user <userId> --reason "<why>"');
1900
1943
  }
1901
1944
  print(await request(
1902
1945
  "POST",
1903
1946
  `/api/deals/${encodeURIComponent(dealId)}/propose-owner`,
1904
- { userId }
1947
+ { userId, reason }
1905
1948
  ));
1906
1949
  return;
1907
1950
  }
@@ -186,6 +186,10 @@
186
186
  "method": "PATCH",
187
187
  "path": "/api/deals/{dealId}/facts/{factId}"
188
188
  },
189
+ {
190
+ "method": "POST",
191
+ "path": "/api/deals/{dealId}/facts/{factId}/uncontest"
192
+ },
189
193
  {
190
194
  "method": "GET",
191
195
  "path": "/api/deals/{dealId}/feed"
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "format": "llama.cli-build.v1",
3
3
  "packageName": "@llamaventures/cli",
4
- "packageVersion": "1.22.0",
5
- "sourceSha": "3e3ede496804de031650e23fc29e1a6763c41daf",
4
+ "packageVersion": "1.23.0",
5
+ "sourceSha": "3f3fb4ae90469e4c561bc8ad319c59d877d0fcf2",
6
6
  "sourceKind": "github",
7
7
  "sourceDirty": false,
8
8
  "coreApiContract": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llamaventures/cli",
3
- "version": "1.22.0",
3
+ "version": "1.23.0",
4
4
  "description": "CLI + MCP server for the Llama Ventures investment workbench (command.llamaventures.vc).",
5
5
  "type": "module",
6
6
  "scripts": {