@llamaventures/cli 2.1.3 → 2.3.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
@@ -162,16 +162,29 @@ Always submit raw user information first when losing it would be unacceptable:
162
162
  }
163
163
  ```
164
164
 
165
- Then, when useful, write a structured Information unit:
165
+ Then, when useful, write a structured Information unit. Before each one, ask a
166
+ single question: is this a Llama user's own subjective judgment? Subjective
167
+ means the truth depends on who judges: a value or comparative word with no
168
+ stated benchmark, or a claim about someone's future behavior or inner state. If
169
+ yes, the type is `human_subjective_view.people` (founders or team) or
170
+ `human_subjective_view.business` (company, product, market or deal),
171
+ `value.speaker` names that user, `value.rawText` quotes the user verbatim
172
+ from `origin.originalUserUtterance`, and `value.summary` is your own
173
+ restatement of those words (never a substitute for them). CLI and Core reject
174
+ anything else. If no, choose any type that fits; founder words are
175
+ `founder_claim`.
166
176
 
167
177
  ```json
168
178
  {
169
179
  "operation": "information.put",
170
180
  "dealId": "<uuid>",
171
- "type": "founder.opinion",
172
- "labels": ["human_view"],
181
+ "type": "human_subjective_view.people",
173
182
  "subject": {"person": "Founder name"},
174
- "value": {"speaker": "user", "view": "strong product taste"},
183
+ "value": {
184
+ "speaker": "<Llama user>",
185
+ "rawText": "I think the founder has strong product taste.",
186
+ "summary": "Strong product taste, per the user."
187
+ },
175
188
  "origin": {
176
189
  "kind": "user",
177
190
  "originalUserUtterance": "I think the founder has strong product taste."
package/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@ this project adheres to [Semantic Versioning](https://semver.org).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.3.0] - 2026-09-04
10
+
11
+ ### Changed
12
+ - `human_subjective_view.people|business` now also requires `value.summary`,
13
+ the agent's own restatement of the user's words, and rejects a summary that
14
+ merely repeats `value.rawText`. Core enforces the same rule; the Deal Page
15
+ shows both the summary and the verbatim text.
16
+
17
+ ## [2.2.0] - 2026-09-04
18
+
19
+ ### Added
20
+ - Define `human_subjective_view.people` and `human_subjective_view.business`
21
+ as the only Information types for a Llama user's own judgment. CLI and MCP
22
+ reject them locally unless `value.speaker` is set and `value.rawText`
23
+ appears verbatim inside `origin.originalUserUtterance`; retired aliases
24
+ (`human_view`, `human_statement`, `human_opinion`, `human_judgment`,
25
+ `partner_view`) are refused with the replacement named. Core enforces the
26
+ same rule server-side.
27
+
9
28
  ## [2.1.3] - 2026-09-03
10
29
 
11
30
  ### Added
package/bin/llama-mcp.mjs CHANGED
@@ -152,7 +152,7 @@ server.registerTool(
152
152
  server.registerTool(
153
153
  "write_deal",
154
154
  {
155
- description: "The only Deal mutation tool. Pass one command: input.submit, information.put, page.patch, or artifact.put. All Page content fields are Agent-writable; author controls attribution, not permission. Before page.patch, use get_live_deal_page_schema for the exact fields being changed and write bilingual Page prose. page.patch is JSON Merge Patch: arrays replace whole arrays, so read-modify-write and preserve sibling slots.",
155
+ description: "The only Deal mutation tool. Pass one command: input.submit, information.put, page.patch, or artifact.put. All Page content fields are Agent-writable; author controls attribution, not permission. Before page.patch, use get_live_deal_page_schema for the exact fields being changed and write bilingual Page prose. page.patch is JSON Merge Patch: arrays replace whole arrays, so read-modify-write and preserve sibling slots. A Llama user's own judgment is human_subjective_view.people or human_subjective_view.business and must carry value.speaker, value.rawText quoted verbatim from origin.originalUserUtterance, and value.summary (the agent's restatement); it is rejected otherwise.",
156
156
  // MCP SDK 1.30 only publishes object schemas at the tool root. Nesting one
157
157
  // command preserves the real discriminated union instead of flattening four
158
158
  // incompatible operations into false affordances.
package/bin/llama.mjs CHANGED
@@ -103,6 +103,7 @@ create JSON:
103
103
  write JSON (CLI derives idempotencyKey when omitted):
104
104
  input.submit: {"operation":"input.submit","dealId":"<uuid>","content":"<original input>","format":"text","source":{},"origin":{"kind":"user","originalUserUtterance":"..."}}
105
105
  information.put:{"operation":"information.put","dealId":"<uuid>","type":"founder_claim","labels":["founder-stated"],"subject":{"topic":"traction"},"value":{"content":"...","source":{"kind":"first_meeting_transcript"}},"origin":{"kind":"user","originalUserUtterance":"..."}}
106
+ human judgment: {"operation":"information.put","dealId":"<uuid>","type":"human_subjective_view.people","subject":{"topic":"founder_execution"},"value":{"speaker":"<Llama user>","rawText":"<the user's verbatim words>","summary":"<the agent's restatement>"},"origin":{"kind":"user","originalUserUtterance":"<complete user input; must contain rawText>"}}
106
107
  page.patch: {"operation":"page.patch","dealId":"<uuid>","patch":{"description":{"en":"...","zh":"..."}},"origin":{"kind":"agent"}}
107
108
  artifact.put: {"operation":"artifact.put","dealId":"<uuid>","kind":"deck","title":"deck.pdf","mimeType":"application/pdf","contentBase64":"<file bytes, base64>","origin":{"kind":"user","originalUserUtterance":"..."}}
108
109
 
@@ -115,6 +116,13 @@ with storageKey (+ optional storageUrl) plus byteSize and sha256 instead.
115
116
  For Information, origin records who caused the write and preserves user words;
116
117
  value.source records where the evidence came from.
117
118
 
119
+ human_subjective_view.people|business is a Llama user's own judgment about the
120
+ team or the deal. Subjective = the truth depends on who judges: a value or
121
+ comparative word with no benchmark, or a claim about someone's future behavior
122
+ or inner state. It requires value.speaker, value.rawText quoted verbatim from
123
+ origin.originalUserUtterance, and value.summary, the agent's own restatement of
124
+ those words; CLI and Core reject anything else. Other types are free.
125
+
118
126
  Core owns Chat Records, append-only Deal Events, Drive provisioning, audit,
119
127
  and idempotency. User-originated work must preserve exact wording in
120
128
  origin.originalUserUtterance or reference origin.originatingChatRecordId.`;
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "format": "llama.cli-build.v1",
3
3
  "packageName": "@llamaventures/cli",
4
- "packageVersion": "2.1.3",
5
- "sourceSha": "e349368d3de4fd4dcf181399b0c1f93c9f38dbf3",
4
+ "packageVersion": "2.3.0",
5
+ "sourceSha": "c68a1849a4c43edbcc340a8f47f21cf16ca615ef",
6
6
  "sourceKind": "github",
7
7
  "sourceDirty": false,
8
8
  "coreApiContract": {
@@ -9,6 +9,80 @@ export const DEAL_WRITE_OPERATIONS = Object.freeze([
9
9
  "artifact.put",
10
10
  ]);
11
11
 
12
+ /**
13
+ * A Llama user's own subjective judgment about the team (.people) or the deal
14
+ * (.business). An agent may record it, but the record must name the user and
15
+ * quote them verbatim from their own input, plus the agent's own restatement in
16
+ * value.summary, so the type alone stays a reliable filter and every record
17
+ * reads the same way. Core enforces the same rule; this check only fails faster.
18
+ */
19
+ export const HUMAN_SUBJECTIVE_VIEW_TYPES = Object.freeze([
20
+ "human_subjective_view.people",
21
+ "human_subjective_view.business",
22
+ ]);
23
+
24
+ const RETIRED_HUMAN_VIEW_TYPES = Object.freeze([
25
+ "human_view",
26
+ "human_statement",
27
+ "human_opinion",
28
+ "human_judgment",
29
+ "partner_view",
30
+ ]);
31
+
32
+ function normalizeWhitespace(text) {
33
+ return String(text).replace(/\s+/g, " ").trim();
34
+ }
35
+
36
+ function stringField(object, key) {
37
+ const value = object && typeof object === "object" && !Array.isArray(object) ? object[key] : undefined;
38
+ return typeof value === "string" ? value.trim() : "";
39
+ }
40
+
41
+ export function validateHumanSubjectiveView(information, origin) {
42
+ const type = stringField(information, "type");
43
+ const lower = type.toLowerCase();
44
+ if (RETIRED_HUMAN_VIEW_TYPES.includes(lower) || lower.startsWith("human_view.")) {
45
+ throw new Error(
46
+ `Information type "${type}" is retired: a Llama user's own judgment is human_subjective_view.people or human_subjective_view.business`,
47
+ );
48
+ }
49
+ if (lower !== "human_subjective_view" && !lower.startsWith("human_subjective_view.")) {
50
+ return information;
51
+ }
52
+ if (!HUMAN_SUBJECTIVE_VIEW_TYPES.includes(type)) {
53
+ throw new Error(
54
+ "human_subjective_view must be exactly human_subjective_view.people (team) or human_subjective_view.business (deal)",
55
+ );
56
+ }
57
+ const utterance = origin?.kind === "user" ? stringField(origin, "originalUserUtterance") : "";
58
+ if (!utterance) {
59
+ throw new Error(
60
+ "human_subjective_view.* must originate from a user and carry the user's words in origin.originalUserUtterance",
61
+ );
62
+ }
63
+ const speaker = stringField(information.value, "speaker");
64
+ const rawText = stringField(information.value, "rawText");
65
+ if (!speaker) {
66
+ throw new Error("human_subjective_view.* requires value.speaker: the Llama user whose judgment this is");
67
+ }
68
+ if (!rawText) {
69
+ throw new Error("human_subjective_view.* requires value.rawText: the user's verbatim words");
70
+ }
71
+ if (!normalizeWhitespace(utterance).includes(normalizeWhitespace(rawText))) {
72
+ throw new Error(
73
+ "human_subjective_view.* value.rawText must appear verbatim inside origin.originalUserUtterance; do not paraphrase",
74
+ );
75
+ }
76
+ const summary = stringField(information.value, "summary");
77
+ if (!summary) {
78
+ throw new Error("human_subjective_view.* requires value.summary: the agent's restatement of the user's words");
79
+ }
80
+ if (normalizeWhitespace(summary) === normalizeWhitespace(rawText)) {
81
+ throw new Error("human_subjective_view.* value.summary must restate value.rawText, not repeat it");
82
+ }
83
+ return information;
84
+ }
85
+
12
86
  function canonicalJson(value) {
13
87
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
14
88
  if (value && typeof value === "object") {
@@ -153,9 +227,14 @@ export function prepareDealCommand(action, input) {
153
227
  }
154
228
  if (action === "create") {
155
229
  validateLocalizedTextPairs(command.page ?? {});
230
+ const information = Array.isArray(command.information) ? command.information : [];
231
+ for (const item of information) validateHumanSubjectiveView(item, command.origin);
156
232
  }
157
233
  if (action === "write" && command.operation === "page.patch") {
158
234
  validateLocalizedTextPairs(command.patch ?? {});
159
235
  }
236
+ if (action === "write" && command.operation === "information.put") {
237
+ validateHumanSubjectiveView(command, command.origin);
238
+ }
160
239
  return ensureIdempotencyKey(validateCommandOrigin(command));
161
240
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llamaventures/cli",
3
- "version": "2.1.3",
3
+ "version": "2.3.0",
4
4
  "description": "CLI + MCP server for the Llama Ventures investment workbench (command.llamaventures.vc).",
5
5
  "type": "module",
6
6
  "scripts": {