@llamaventures/cli 2.0.3 → 2.1.1
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 +10 -1
- package/CHANGELOG.md +32 -14
- package/README.md +24 -1
- package/README.zh-CN.md +23 -1
- package/bin/llama-mcp.mjs +31 -0
- package/bin/llama.mjs +58 -4
- package/contracts/core-api.json +4 -4
- package/contracts/required-operations.json +3 -1
- package/lib/build-manifest.json +4 -4
- package/lib/client.mjs +3 -0
- package/lib/deal-memory-actions.mjs +31 -0
- package/package.json +2 -2
package/AGENT_BRIEFING.md
CHANGED
|
@@ -44,6 +44,14 @@ working memory; it never becomes Page automatically. Page is the bounded,
|
|
|
44
44
|
human-visible current projection, so patch the exact semantic fields described
|
|
45
45
|
by the live contract instead of hiding structured analysis in `notes`.
|
|
46
46
|
|
|
47
|
+
The Markdown Deal Story is a separate sidecar domain, not a sixth Occam
|
|
48
|
+
resource. Use `get_deal_memory` / `llama memory read` for accumulated narrative
|
|
49
|
+
understanding, and `update_deal_memory` / `llama memory write` to replace its
|
|
50
|
+
complete Markdown. Read first and pass the returned opaque version on every
|
|
51
|
+
update; a conflict means read again and reconcile. These calls still go only
|
|
52
|
+
through authenticated Core. Never request AWS credentials or call S3 or the
|
|
53
|
+
sidecar directly.
|
|
54
|
+
|
|
47
55
|
Every Page content field is Agent-writable. A field's `author` or
|
|
48
56
|
`semanticOwner` describes attribution, not permission. Preserve a real human
|
|
49
57
|
judgment with its author; otherwise label the value as an Agent proposal / 待人确认.
|
|
@@ -207,4 +215,5 @@ artifact, then decide whether its content deserves Information or a Page patch.
|
|
|
207
215
|
`DEAL_COMMAND_RETIRED`. Upgrade the CLI and retry the intended four-action
|
|
208
216
|
command.
|
|
209
217
|
- Wiki, admin audit, external pitch, authentication, and skill discovery are
|
|
210
|
-
separate domains.
|
|
218
|
+
separate domains. Deal Memory is also separate. None expands the four-action
|
|
219
|
+
Occam Deal space.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
All notable changes to `@llamaventures/cli` are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
5
|
+
this project adheres to [Semantic Versioning](https://semver.org).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [2.1.1] - 2026-09-03
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- `llama help deal` no longer hardcodes the Page field count; the count is
|
|
13
|
+
live in `llama agent bootstrap`.
|
|
14
|
+
- Show `contentBase64` as the primary `artifact.put` example. Core stores the
|
|
15
|
+
bytes in the Deal's Drive folder and derives `byteSize` / `sha256` itself;
|
|
16
|
+
`storageKey` remains only for artifacts that already live elsewhere.
|
|
17
|
+
|
|
18
|
+
## [2.1.0] - 2026-09-03
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- Add `llama memory read|write` and matching `get_deal_memory` /
|
|
22
|
+
`update_deal_memory` MCP tools for one canonical Markdown Deal Story, using
|
|
23
|
+
the existing Llama login through Core's authenticated sidecar adapter.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- Make the authenticated live bootstrap mandatory before Deal work and clarify
|
|
27
|
+
that it loads the server-owned two-part private Brain plus the separate Live
|
|
28
|
+
Deal Page field contract. CLI remains only the tool/transport layer.
|
|
29
|
+
- Teach CLI and MCP Agents that Information never updates Page automatically,
|
|
30
|
+
every Page content field is Agent-writable, and field authorship controls
|
|
31
|
+
attribution rather than permission.
|
|
32
|
+
- Pin the additive Deal Memory operations to Core API 5.1.0 while preserving
|
|
33
|
+
exactly four Occam Deal actions and five Occam resources.
|
|
34
|
+
|
|
3
35
|
## [2.0.3] - 2026-08-31
|
|
4
36
|
|
|
5
37
|
- Show Core validation codes and field paths instead of collapsing malformed
|
|
@@ -49,20 +81,6 @@
|
|
|
49
81
|
- Keep Wiki, admin audit, external pitch, authentication, preferences, and
|
|
50
82
|
progressive skill discovery as separate non-Deal domains.
|
|
51
83
|
|
|
52
|
-
All notable changes to `@llamaventures/cli` are documented here.
|
|
53
|
-
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
54
|
-
this project adheres to [Semantic Versioning](https://semver.org).
|
|
55
|
-
|
|
56
|
-
## [Unreleased]
|
|
57
|
-
|
|
58
|
-
### Changed
|
|
59
|
-
- Make the authenticated live bootstrap mandatory before Deal work and clarify
|
|
60
|
-
that it loads the server-owned two-part private Brain plus the separate Live
|
|
61
|
-
Deal Page field contract. CLI remains only the tool/transport layer.
|
|
62
|
-
- Teach CLI and MCP Agents that Information never updates Page automatically,
|
|
63
|
-
every Page content field is Agent-writable, and field authorship controls
|
|
64
|
-
attribution rather than permission.
|
|
65
|
-
|
|
66
84
|
## [1.26.0] - 2026-08-11
|
|
67
85
|
|
|
68
86
|
### Added
|
package/README.md
CHANGED
|
@@ -122,6 +122,27 @@ For user-originated work, preserve the exact words in
|
|
|
122
122
|
Chat and Event are system-owned. There is no caller-controlled Event append or
|
|
123
123
|
general Chat-forging operation.
|
|
124
124
|
|
|
125
|
+
## Deal Memory sidecar
|
|
126
|
+
|
|
127
|
+
Deal Memory is a separate domain alongside the five-resource Deal model. Each
|
|
128
|
+
deal can have one canonical, human-readable Markdown Deal Story:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
llama memory read <dealId>
|
|
132
|
+
llama memory read <dealId> --raw
|
|
133
|
+
llama memory write <dealId> --markdown deal-story.md
|
|
134
|
+
llama memory write <dealId> --markdown deal-story.md --expected-version '"etag-from-read"'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The first write omits `--expected-version`. Updating an existing story requires
|
|
138
|
+
the opaque `version` returned by `read`; a stale value fails instead of losing a
|
|
139
|
+
concurrent edit. This uses the same `llama auth login` identity. CLI calls the
|
|
140
|
+
authenticated Command Core adapter only—it has no sidecar URL, service token,
|
|
141
|
+
S3 credentials, or direct database access.
|
|
142
|
+
|
|
143
|
+
`llama deal read --detail memory` still means structured Deal Information.
|
|
144
|
+
`llama memory read` means the separate accumulated Markdown Deal Story.
|
|
145
|
+
|
|
125
146
|
## Five Deal resources
|
|
126
147
|
|
|
127
148
|
1. Live Deal Page — current human-visible state.
|
|
@@ -149,7 +170,9 @@ Its Deal surface is also exactly four tools:
|
|
|
149
170
|
- `write_deal`
|
|
150
171
|
|
|
151
172
|
Authentication, skill discovery, Wiki, admin audit, preferences, and external
|
|
152
|
-
pitch remain separate non-Deal domains.
|
|
173
|
+
pitch remain separate non-Deal domains. Deal Memory likewise has two separate
|
|
174
|
+
MCP tools, `get_deal_memory` and `update_deal_memory`; it does not add a fifth
|
|
175
|
+
Occam Deal tool.
|
|
153
176
|
|
|
154
177
|
## Agent bootstrap
|
|
155
178
|
|
package/README.zh-CN.md
CHANGED
|
@@ -116,6 +116,26 @@ llama deal write --json write.json
|
|
|
116
116
|
Chat 和 Event 由系统拥有。Agent 不能自行伪造 Event 类型、顺序、作者、
|
|
117
117
|
时间,也没有通用的 Chat 写入工具。
|
|
118
118
|
|
|
119
|
+
## Deal Memory sidecar
|
|
120
|
+
|
|
121
|
+
Deal Memory 是与五资源 Deal 模型并行、完全解耦的领域。每个 Deal 可以有一个
|
|
122
|
+
人和 Agent 都能直接阅读的 Markdown Deal Story:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
llama memory read <dealId>
|
|
126
|
+
llama memory read <dealId> --raw
|
|
127
|
+
llama memory write <dealId> --markdown deal-story.md
|
|
128
|
+
llama memory write <dealId> --markdown deal-story.md --expected-version '"read 返回的 etag"'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
第一次创建时不传 `--expected-version`;以后更新必须使用前一次 `read` 返回的
|
|
132
|
+
不透明 `version`,旧版本会安全失败,不会覆盖他人的新内容。它复用同一个
|
|
133
|
+
`llama auth login` 身份。CLI 只调用经过认证的 Command Core adapter,不持有
|
|
134
|
+
sidecar URL、service token、S3 凭证,也不直接访问数据库。
|
|
135
|
+
|
|
136
|
+
`llama deal read --detail memory` 仍表示结构化 Deal Information;
|
|
137
|
+
`llama memory read` 表示独立的 Markdown Deal Story。
|
|
138
|
+
|
|
119
139
|
## Deal 只有五种业务资源
|
|
120
140
|
|
|
121
141
|
1. Live Deal Page:人类看到的当前状态;
|
|
@@ -141,7 +161,9 @@ MCP 的 Deal 工具同样恰好四个:
|
|
|
141
161
|
- `write_deal`
|
|
142
162
|
|
|
143
163
|
认证、skill discovery、Wiki、admin audit、preferences 和 external pitch
|
|
144
|
-
属于其他独立领域,不会扩大 Deal action space。
|
|
164
|
+
属于其他独立领域,不会扩大 Deal action space。Deal Memory 同样是独立领域,
|
|
165
|
+
对应 `get_deal_memory` 和 `update_deal_memory` 两个 MCP 工具,并不增加第五个
|
|
166
|
+
Occam Deal 工具。
|
|
145
167
|
|
|
146
168
|
## Agent 启动
|
|
147
169
|
|
package/bin/llama-mcp.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
compactDealWriteResult,
|
|
26
26
|
prepareDealCommand,
|
|
27
27
|
} from "../lib/deal-actions.mjs";
|
|
28
|
+
import { buildDealMemoryPath } from "../lib/deal-memory-actions.mjs";
|
|
28
29
|
|
|
29
30
|
const requireFromHere = createRequire(import.meta.url);
|
|
30
31
|
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
@@ -164,6 +165,36 @@ server.registerTool(
|
|
|
164
165
|
),
|
|
165
166
|
);
|
|
166
167
|
|
|
168
|
+
// Deal Memory is a separate sidecar domain. These do not add an Occam Deal
|
|
169
|
+
// business resource or widen the deliberately closed four-tool Deal surface.
|
|
170
|
+
server.registerTool(
|
|
171
|
+
"get_deal_memory",
|
|
172
|
+
{
|
|
173
|
+
description: "Read the complete canonical Markdown Deal Story and its opaque concurrency version.",
|
|
174
|
+
inputSchema: { dealId: z.string().uuid() },
|
|
175
|
+
},
|
|
176
|
+
// @core-api-operation GET /api/deal-memory/{dealId}/story
|
|
177
|
+
async ({ dealId }) => callApi("GET", buildDealMemoryPath(dealId)),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
server.registerTool(
|
|
181
|
+
"update_deal_memory",
|
|
182
|
+
{
|
|
183
|
+
description: "Create or replace the complete Markdown Deal Story. Existing stories require the version returned by get_deal_memory; stale writes fail safely.",
|
|
184
|
+
inputSchema: {
|
|
185
|
+
dealId: z.string().uuid(),
|
|
186
|
+
markdown: z.string().min(1).max(1_048_576),
|
|
187
|
+
expected_version: z.string().min(1).optional(),
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
// @core-api-operation PUT /api/deal-memory/{dealId}/story
|
|
191
|
+
async ({ dealId, markdown, expected_version }) => callApi(
|
|
192
|
+
"PUT",
|
|
193
|
+
buildDealMemoryPath(dealId),
|
|
194
|
+
{ markdown, ...(expected_version ? { expected_version } : {}) },
|
|
195
|
+
),
|
|
196
|
+
);
|
|
197
|
+
|
|
167
198
|
server.registerTool(
|
|
168
199
|
"auth_status",
|
|
169
200
|
{
|
package/bin/llama.mjs
CHANGED
|
@@ -39,6 +39,10 @@ import {
|
|
|
39
39
|
prepareDealCommand,
|
|
40
40
|
readJsonInput,
|
|
41
41
|
} from "../lib/deal-actions.mjs";
|
|
42
|
+
import {
|
|
43
|
+
buildDealMemoryPath,
|
|
44
|
+
readMarkdownInput,
|
|
45
|
+
} from "../lib/deal-memory-actions.mjs";
|
|
42
46
|
|
|
43
47
|
const requireFromHere = createRequire(import.meta.url);
|
|
44
48
|
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
@@ -51,6 +55,10 @@ Deal has exactly four actions:
|
|
|
51
55
|
llama deal create --json <file|->
|
|
52
56
|
llama deal write --json <file|->
|
|
53
57
|
|
|
58
|
+
Deal Memory is a separate sidecar domain through the same login:
|
|
59
|
+
llama memory read <dealId> [--raw]
|
|
60
|
+
llama memory write <dealId> --markdown <file|-> [--expected-version <version>]
|
|
61
|
+
|
|
54
62
|
Separate preserved domains:
|
|
55
63
|
llama auth status|login|logout
|
|
56
64
|
llama token set|show
|
|
@@ -77,8 +85,9 @@ Before any Page write:
|
|
|
77
85
|
|
|
78
86
|
The authenticated bootstrap contains the two-part private Llama Brain:
|
|
79
87
|
Investment Framework V3 plus the Llama Command operating skill. It also
|
|
80
|
-
contains the separate current
|
|
81
|
-
|
|
88
|
+
contains the separate current Page field contract; its field count is live,
|
|
89
|
+
so read it there. CLI is the tool, not Brain. Information never updates
|
|
90
|
+
Page automatically. page.patch is JSON
|
|
82
91
|
Merge Patch: objects merge, null deletes, and arrays replace whole arrays, so
|
|
83
92
|
read-modify-write complete Page arrays and preserve sibling slots.
|
|
84
93
|
|
|
@@ -89,7 +98,13 @@ write JSON (CLI derives idempotencyKey when omitted):
|
|
|
89
98
|
input.submit: {"operation":"input.submit","dealId":"<uuid>","content":"<original input>","format":"text","source":{},"origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
90
99
|
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":"..."}}
|
|
91
100
|
page.patch: {"operation":"page.patch","dealId":"<uuid>","patch":{"description":{"en":"...","zh":"..."}},"origin":{"kind":"agent"}}
|
|
92
|
-
artifact.put: {"operation":"artifact.put","dealId":"<uuid>","kind":"deck","title":"deck.pdf","mimeType":"application/pdf","
|
|
101
|
+
artifact.put: {"operation":"artifact.put","dealId":"<uuid>","kind":"deck","title":"deck.pdf","mimeType":"application/pdf","contentBase64":"<file bytes, base64>","origin":{"kind":"user","originalUserUtterance":"..."}}
|
|
102
|
+
|
|
103
|
+
artifact.put sends the bytes as contentBase64; Core stores them in the Deal's
|
|
104
|
+
own Drive folder and derives byteSize and sha256 itself. Do not supply a
|
|
105
|
+
folder, storage key or URL for a file you hold. Write the JSON to a file and
|
|
106
|
+
pass its path. Only an artifact that already lives elsewhere is referenced
|
|
107
|
+
with storageKey (+ optional storageUrl) plus byteSize and sha256 instead.
|
|
93
108
|
|
|
94
109
|
For Information, origin records who caused the write and preserves user words;
|
|
95
110
|
value.source records where the evidence came from.
|
|
@@ -98,6 +113,19 @@ Core owns Chat Records, append-only Deal Events, Drive provisioning, audit,
|
|
|
98
113
|
and idempotency. User-originated work must preserve exact wording in
|
|
99
114
|
origin.originalUserUtterance or reference origin.originatingChatRecordId.`;
|
|
100
115
|
|
|
116
|
+
const HELP_MEMORY = `Llama Deal Memory — one canonical Markdown Deal Story
|
|
117
|
+
|
|
118
|
+
llama memory read <dealId> [--raw]
|
|
119
|
+
llama memory write <dealId> --markdown <file|-> [--expected-version <version>]
|
|
120
|
+
|
|
121
|
+
Read returns the full JSON record, including its opaque version. --raw prints
|
|
122
|
+
only the exact Markdown. A first write creates the story without a version.
|
|
123
|
+
Every later write must pass the version from the preceding read; stale writes
|
|
124
|
+
fail instead of overwriting newer understanding.
|
|
125
|
+
|
|
126
|
+
This uses your existing Llama authentication. The CLI talks only to Command
|
|
127
|
+
Core and never receives Deal Memory service credentials or AWS access.`;
|
|
128
|
+
|
|
101
129
|
function parseFlags(args, allowed = null) {
|
|
102
130
|
const flags = {};
|
|
103
131
|
const positional = [];
|
|
@@ -124,7 +152,7 @@ function parseFlags(args, allowed = null) {
|
|
|
124
152
|
}
|
|
125
153
|
|
|
126
154
|
function usage(area) {
|
|
127
|
-
console.log(area === "deal" ? HELP_DEAL : HELP_ROOT);
|
|
155
|
+
console.log(area === "deal" ? HELP_DEAL : area === "memory" ? HELP_MEMORY : HELP_ROOT);
|
|
128
156
|
}
|
|
129
157
|
|
|
130
158
|
function assertDealAction(area, action) {
|
|
@@ -576,6 +604,32 @@ async function main() {
|
|
|
576
604
|
return;
|
|
577
605
|
}
|
|
578
606
|
|
|
607
|
+
if (area === "memory" && action === "read") {
|
|
608
|
+
const { flags, positional } = parseFlags(rest, ["raw"]);
|
|
609
|
+
const path = buildDealMemoryPath(positional[0]);
|
|
610
|
+
// @core-api-operation GET /api/deal-memory/{dealId}/story
|
|
611
|
+
const result = await request("GET", path);
|
|
612
|
+
if (flags.raw) process.stdout.write(result.markdown);
|
|
613
|
+
else print(result);
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
if (area === "memory" && action === "write") {
|
|
617
|
+
const { flags, positional } = parseFlags(rest, ["markdown", "expected-version"]);
|
|
618
|
+
const path = buildDealMemoryPath(positional[0]);
|
|
619
|
+
const markdown = await readMarkdownInput(flags.markdown);
|
|
620
|
+
// @core-api-operation PUT /api/deal-memory/{dealId}/story
|
|
621
|
+
print(await request("PUT", path, {
|
|
622
|
+
markdown,
|
|
623
|
+
...(typeof flags["expected-version"] === "string"
|
|
624
|
+
? { expected_version: flags["expected-version"] }
|
|
625
|
+
: {}),
|
|
626
|
+
}));
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
if (area === "memory") {
|
|
630
|
+
throw new Error("Memory actions: read, write.");
|
|
631
|
+
}
|
|
632
|
+
|
|
579
633
|
if (area === "wiki") {
|
|
580
634
|
await handleWiki(action, rest);
|
|
581
635
|
return;
|
package/contracts/core-api.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "llama.core-api-contract.v1",
|
|
3
3
|
"name": "llama-core-api",
|
|
4
|
-
"apiVersion": "5.
|
|
4
|
+
"apiVersion": "5.1.0",
|
|
5
5
|
"openapiVersion": "3.0.3",
|
|
6
|
-
"sha256": "
|
|
7
|
-
"pathCount":
|
|
8
|
-
"operationCount":
|
|
6
|
+
"sha256": "948a8d02ae833e8cfa2302bc3c615fc1d3c792ae774ebc25b16be81fd1b85fee",
|
|
7
|
+
"pathCount": 111,
|
|
8
|
+
"operationCount": 138
|
|
9
9
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
{ "method": "GET", "path": "/api/agent/preferences" },
|
|
13
13
|
{ "method": "GET", "path": "/api/agent/skills" },
|
|
14
14
|
{ "method": "GET", "path": "/api/agent/skills/{slug}" },
|
|
15
|
+
{ "method": "GET", "path": "/api/deal-memory/{dealId}/story" },
|
|
15
16
|
{ "method": "GET", "path": "/api/me" },
|
|
16
17
|
{ "method": "GET", "path": "/api/oauth/authorize" },
|
|
17
18
|
{ "method": "GET", "path": "/api/occam/deals" },
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
{ "method": "POST", "path": "/api/oauth/token" },
|
|
29
30
|
{ "method": "POST", "path": "/api/occam/deals/commands" },
|
|
30
31
|
{ "method": "POST", "path": "/api/wiki/{slug}/restore" },
|
|
31
|
-
{ "method": "POST", "path": "/api/wiki/save" }
|
|
32
|
+
{ "method": "POST", "path": "/api/wiki/save" },
|
|
33
|
+
{ "method": "PUT", "path": "/api/deal-memory/{dealId}/story" }
|
|
32
34
|
]
|
|
33
35
|
}
|
package/lib/build-manifest.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "llama.cli-build.v1",
|
|
3
3
|
"packageName": "@llamaventures/cli",
|
|
4
|
-
"packageVersion": "2.
|
|
5
|
-
"sourceSha": "
|
|
4
|
+
"packageVersion": "2.1.1",
|
|
5
|
+
"sourceSha": "335bf5d6c510d38616754100568a64f385d62607",
|
|
6
6
|
"sourceKind": "github",
|
|
7
7
|
"sourceDirty": false,
|
|
8
8
|
"coreApiContract": {
|
|
9
9
|
"format": "llama.core-api-contract.v1",
|
|
10
10
|
"name": "llama-core-api",
|
|
11
|
-
"apiVersion": "5.
|
|
11
|
+
"apiVersion": "5.1.0",
|
|
12
12
|
"openapiVersion": "3.0.3",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "948a8d02ae833e8cfa2302bc3c615fc1d3c792ae774ebc25b16be81fd1b85fee"
|
|
14
14
|
}
|
|
15
15
|
}
|
package/lib/client.mjs
CHANGED
|
@@ -294,6 +294,9 @@ function inferCommand(method, endpoint) {
|
|
|
294
294
|
if (pathname === "/api/occam/deals") return "deal.search";
|
|
295
295
|
if (pathname === "/api/occam/deals/commands") return "deal.write";
|
|
296
296
|
if (/^\/api\/occam\/deals\/[^/]+$/.test(pathname)) return "deal.read";
|
|
297
|
+
if (/^\/api\/deal-memory\/[^/]+\/story$/.test(pathname)) {
|
|
298
|
+
return verb === "GET" ? "memory.read" : "memory.write";
|
|
299
|
+
}
|
|
297
300
|
if (pathname === "/api/me") return "auth.status";
|
|
298
301
|
if (pathname.startsWith("/api/agent/skills")) return "skills.read";
|
|
299
302
|
if (pathname === "/api/agent/manifest") return "agent.bootstrap";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
export const MAX_DEAL_STORY_BYTES = 1_048_576;
|
|
4
|
+
|
|
5
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
6
|
+
|
|
7
|
+
export function buildDealMemoryPath(dealId) {
|
|
8
|
+
if (!UUID.test(String(dealId || ""))) {
|
|
9
|
+
throw new Error("Deal Memory requires a valid deal UUID");
|
|
10
|
+
}
|
|
11
|
+
return `/api/deal-memory/${encodeURIComponent(dealId)}/story`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function readMarkdownInput(path, stdin = process.stdin) {
|
|
15
|
+
if (!path || path === true) throw new Error("--markdown <file|-> is required");
|
|
16
|
+
const markdown = path === "-"
|
|
17
|
+
? await new Promise((resolve, reject) => {
|
|
18
|
+
let value = "";
|
|
19
|
+
stdin.setEncoding("utf8");
|
|
20
|
+
stdin.on("data", (chunk) => { value += chunk; });
|
|
21
|
+
stdin.on("end", () => resolve(value));
|
|
22
|
+
stdin.on("error", reject);
|
|
23
|
+
})
|
|
24
|
+
: await readFile(path, "utf8");
|
|
25
|
+
if (!markdown) throw new Error("Deal Story Markdown cannot be empty");
|
|
26
|
+
const bytes = Buffer.byteLength(markdown, "utf8");
|
|
27
|
+
if (bytes > MAX_DEAL_STORY_BYTES) {
|
|
28
|
+
throw new Error(`Deal Story is ${bytes} bytes; maximum is ${MAX_DEAL_STORY_BYTES}`);
|
|
29
|
+
}
|
|
30
|
+
return markdown;
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llamaventures/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "CLI + MCP server for the Llama Ventures investment workbench (command.llamaventures.vc).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "npm run test:agent-routing && npm run test:contract",
|
|
8
8
|
"test:agent-routing": "node scripts/verify-agent-routing.mjs",
|
|
9
|
-
"test:contract": "node --test scripts/build-manifest.test.mjs scripts/core-api-call-sites.test.mjs scripts/deal-actions-cli.test.mjs scripts/deal-actions.test.mjs scripts/mcp-four-action-surface.test.mjs scripts/server-compatibility.test.mjs scripts/verify-core-api-contract.test.mjs && node scripts/verify-core-api-contract.mjs",
|
|
9
|
+
"test:contract": "node --test scripts/build-manifest.test.mjs scripts/core-api-call-sites.test.mjs scripts/deal-actions-cli.test.mjs scripts/deal-actions.test.mjs scripts/deal-memory-actions-cli.test.mjs scripts/deal-memory-actions.test.mjs scripts/mcp-four-action-surface.test.mjs scripts/server-compatibility.test.mjs scripts/verify-core-api-contract.test.mjs && node scripts/verify-core-api-contract.mjs",
|
|
10
10
|
"verify:artifact": "node scripts/verify-release-artifact.mjs",
|
|
11
11
|
"verify:release": "npm test && npm run verify:artifact && node scripts/verify-tarball-clean.mjs",
|
|
12
12
|
"prepack": "node scripts/prepare-build-manifest.mjs",
|