@llamaventures/cli 1.18.1 → 1.19.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/CHANGELOG.md +12 -0
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/bin/llama.mjs +32 -0
- package/contracts/core-api.json +9 -0
- package/contracts/required-operations.json +91 -0
- package/lib/build-info.mjs +34 -0
- package/lib/build-manifest.json +15 -0
- package/lib/client.mjs +5 -0
- package/lib/oauth-flow.mjs +1 -0
- package/lib/version-check.mjs +1 -0
- package/package.json +8 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,18 @@ this project adheres to [Semantic Versioning](https://semver.org).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.19.0] - 2026-07-16
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Pin each CLI artifact to the exact versioned Llama Core OpenAPI contract,
|
|
13
|
+
source commit, and complete source-derived operation inventory.
|
|
14
|
+
- Verify the contract identity and required Core operations during tests,
|
|
15
|
+
packaging, clean tarball installation, and release-gate validation.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Treat Core HTTP as the CLI's only backend boundary and expose contract/build
|
|
19
|
+
provenance through `llama version --json` for independent rollback audits.
|
|
20
|
+
|
|
9
21
|
## [1.18.1] - 2026-07-09
|
|
10
22
|
|
|
11
23
|
### Changed
|
package/README.md
CHANGED
package/README.zh-CN.md
CHANGED
package/bin/llama.mjs
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
import { LLAMA_CLI_CLIENT_ID, pkceLoopbackFlow, revokeToken as revokeOAuthToken } from "../lib/oauth-flow.mjs";
|
|
36
36
|
import { deleteBundle, detectBackend, readBundle, writeBundle } from "../lib/oauth-storage.mjs";
|
|
37
37
|
import { maybeNudgeUpdate, getUpdateNudge } from "../lib/version-check.mjs";
|
|
38
|
+
import { getBuildInfo } from "../lib/build-info.mjs";
|
|
38
39
|
|
|
39
40
|
const requireFromHere = createRequire(import.meta.url);
|
|
40
41
|
const { version: PKG_VERSION } = requireFromHere("../package.json");
|
|
@@ -425,6 +426,7 @@ Manually-set \`llc_\` tokens are used as a fallback.
|
|
|
425
426
|
|
|
426
427
|
Deals:
|
|
427
428
|
llama deal create "Company" --source <name> --deal-owner <name|email|userId> --source-direction Inbound|Outbound --description "..." --status Interested|Outreached|Sourced --website https://...
|
|
429
|
+
llama deal founders set <dealId> --json '[{"name":"Ada","email":"ada@example.com","linkedin_url":"https://linkedin.com/in/ada"}]'
|
|
428
430
|
llama deal show <dealId>
|
|
429
431
|
llama deal feed <dealId> # every contribution (facts + notes), human-typed or assistant-drafted, newest first
|
|
430
432
|
llama deal update <dealId> <field> <value>
|
|
@@ -1005,6 +1007,10 @@ async function runPitchRepl() {
|
|
|
1005
1007
|
async function main() {
|
|
1006
1008
|
const [area, action, ...rest] = process.argv.slice(2);
|
|
1007
1009
|
if (area === "--version" || area === "-v" || area === "version") {
|
|
1010
|
+
if (action === "--json" || action === "json") {
|
|
1011
|
+
print(getBuildInfo());
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1008
1014
|
// `llama version --check` — explicitly check npm for a newer release and
|
|
1009
1015
|
// print the upgrade line (or "up to date"). Lets an agent surface the
|
|
1010
1016
|
// nudge on demand, separate from the throttled, TTY-gated auto-nudge.
|
|
@@ -1484,6 +1490,26 @@ async function main() {
|
|
|
1484
1490
|
return;
|
|
1485
1491
|
}
|
|
1486
1492
|
|
|
1493
|
+
if (area === "deal" && action === "founders") {
|
|
1494
|
+
const sub = rest[0];
|
|
1495
|
+
const dealId = rest[1];
|
|
1496
|
+
const { flags } = parseFlags(rest.slice(2), ["json"]);
|
|
1497
|
+
if (sub !== "set" || !dealId || typeof flags.json !== "string") {
|
|
1498
|
+
throw new Error(
|
|
1499
|
+
"Usage: llama deal founders set <dealId> --json '[{\"name\":\"Ada\",\"email\":\"ada@example.com\"}]'"
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
let founders;
|
|
1503
|
+
try {
|
|
1504
|
+
founders = JSON.parse(flags.json);
|
|
1505
|
+
} catch {
|
|
1506
|
+
throw new Error("--json must be a valid JSON array");
|
|
1507
|
+
}
|
|
1508
|
+
if (!Array.isArray(founders)) throw new Error("--json must be a JSON array");
|
|
1509
|
+
print(await request("PUT", `/api/deals/${encodeURIComponent(dealId)}/founders`, { founders }));
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1487
1513
|
// ----- deals.extra JSONB patches (system-admin only, server-gated) -----
|
|
1488
1514
|
// Same endpoint as `deal update`, but `extraKey` instead of `field`.
|
|
1489
1515
|
// Server patches one top-level key via jsonb_set and audits the change
|
|
@@ -1700,6 +1726,8 @@ async function main() {
|
|
|
1700
1726
|
const linkId = rest[2];
|
|
1701
1727
|
if (!linkId) throw new Error(`Usage: llama deal link ${sub} <dealId> <linkId>`);
|
|
1702
1728
|
const path = `/api/deals/${encodeURIComponent(dealId)}/links/${encodeURIComponent(linkId)}`;
|
|
1729
|
+
// @core-api-operation DELETE /api/deals/{dealId}/links/{linkId}
|
|
1730
|
+
// @core-api-operation POST /api/deals/{dealId}/links/{linkId}/restore
|
|
1703
1731
|
print(await request(
|
|
1704
1732
|
sub === "delete" ? "DELETE" : "POST",
|
|
1705
1733
|
sub === "delete" ? path : `${path}/restore`
|
|
@@ -1967,6 +1995,7 @@ async function main() {
|
|
|
1967
1995
|
if (!slug) throw new Error("Usage: llama wiki read <slug> [--lang en|zh]");
|
|
1968
1996
|
const lang = flags.lang === "zh" ? "zh" : "en";
|
|
1969
1997
|
const path = `/api/wiki/${encodeURIComponent(slug)}?lang=${lang}`;
|
|
1998
|
+
// @core-api-operation GET /api/wiki/{slug}
|
|
1970
1999
|
print(await request("GET", path));
|
|
1971
2000
|
return;
|
|
1972
2001
|
}
|
|
@@ -2298,6 +2327,9 @@ Routing — is this the right command?
|
|
|
2298
2327
|
if (flags["errors-only"]) params.set("errors_only", "1");
|
|
2299
2328
|
}
|
|
2300
2329
|
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
2330
|
+
// @core-api-operation GET /api/admin/auth-events
|
|
2331
|
+
// @core-api-operation GET /api/admin/deal-events
|
|
2332
|
+
// @core-api-operation GET /api/admin/agent-events
|
|
2301
2333
|
print(await request("GET", `/api/admin/${sub}${qs}`));
|
|
2302
2334
|
return;
|
|
2303
2335
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "llama.cli-core-api-operations.v1",
|
|
3
|
+
"coreApiContract": "contracts/core-api.json",
|
|
4
|
+
"requiredOperations": [
|
|
5
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}" },
|
|
6
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/blocks/{blockId}" },
|
|
7
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/collaborators/{userId}" },
|
|
8
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/documents/{slug}" },
|
|
9
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/documents/{slug}/html" },
|
|
10
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/links/{linkId}" },
|
|
11
|
+
{ "method": "DELETE", "path": "/api/deals/{dealId}/memo" },
|
|
12
|
+
{ "method": "DELETE", "path": "/api/skill-corrections/{id}" },
|
|
13
|
+
{ "method": "DELETE", "path": "/api/wiki/{slug}" },
|
|
14
|
+
{ "method": "GET", "path": "/api/admin/agent-events" },
|
|
15
|
+
{ "method": "GET", "path": "/api/admin/auth-events" },
|
|
16
|
+
{ "method": "GET", "path": "/api/admin/deal-events" },
|
|
17
|
+
{ "method": "GET", "path": "/api/agent/activity" },
|
|
18
|
+
{ "method": "GET", "path": "/api/agent/briefing" },
|
|
19
|
+
{ "method": "GET", "path": "/api/agent/explain" },
|
|
20
|
+
{ "method": "GET", "path": "/api/agent/manifest" },
|
|
21
|
+
{ "method": "GET", "path": "/api/agent/skills" },
|
|
22
|
+
{ "method": "GET", "path": "/api/agent/skills/{slug}" },
|
|
23
|
+
{ "method": "GET", "path": "/api/deals" },
|
|
24
|
+
{ "method": "GET", "path": "/api/deals/{dealId}" },
|
|
25
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/blocks" },
|
|
26
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/blocks/{blockId}" },
|
|
27
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/blocks/{blockId}/history" },
|
|
28
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/collaborators" },
|
|
29
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/command-center" },
|
|
30
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/documents" },
|
|
31
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/documents/{slug}/html" },
|
|
32
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/documents/{slug}/html/history" },
|
|
33
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/facts" },
|
|
34
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/feed" },
|
|
35
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/links" },
|
|
36
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/memo" },
|
|
37
|
+
{ "method": "GET", "path": "/api/deals/{dealId}/timeline" },
|
|
38
|
+
{ "method": "GET", "path": "/api/deals/deleted" },
|
|
39
|
+
{ "method": "GET", "path": "/api/me" },
|
|
40
|
+
{ "method": "GET", "path": "/api/me/nominations" },
|
|
41
|
+
{ "method": "GET", "path": "/api/mentions" },
|
|
42
|
+
{ "method": "GET", "path": "/api/mentions/unread-count" },
|
|
43
|
+
{ "method": "GET", "path": "/api/oauth/authorize" },
|
|
44
|
+
{ "method": "GET", "path": "/api/partner/approvals" },
|
|
45
|
+
{ "method": "GET", "path": "/api/skill-corrections" },
|
|
46
|
+
{ "method": "GET", "path": "/api/users" },
|
|
47
|
+
{ "method": "GET", "path": "/api/wiki/{slug}" },
|
|
48
|
+
{ "method": "GET", "path": "/api/wiki/search" },
|
|
49
|
+
{ "method": "PATCH", "path": "/api/deals/{dealId}/blocks/{blockId}" },
|
|
50
|
+
{ "method": "PATCH", "path": "/api/deals/{dealId}/documents/{slug}" },
|
|
51
|
+
{ "method": "PATCH", "path": "/api/deals/{dealId}/facts/{factId}" },
|
|
52
|
+
{ "method": "POST", "path": "/api/agent/client-events" },
|
|
53
|
+
{ "method": "POST", "path": "/api/agent/eval-feedback" },
|
|
54
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/agent-runs/{runId}/revert" },
|
|
55
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/blocks/{blockId}/history" },
|
|
56
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/blocks/{blockId}/restore" },
|
|
57
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/collaborators" },
|
|
58
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/collaborators/{userId}/restore" },
|
|
59
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/documents" },
|
|
60
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/documents/{slug}/html/restore/{version}" },
|
|
61
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/enrich" },
|
|
62
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/facts" },
|
|
63
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/links" },
|
|
64
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/links/{linkId}/restore" },
|
|
65
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/memo" },
|
|
66
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/posts" },
|
|
67
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/propose-owner" },
|
|
68
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/refresh-brief" },
|
|
69
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/refresh-persona" },
|
|
70
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/restore" },
|
|
71
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/threads" },
|
|
72
|
+
{ "method": "POST", "path": "/api/deals/{dealId}/threads/{threadId}" },
|
|
73
|
+
{ "method": "POST", "path": "/api/deals/create" },
|
|
74
|
+
{ "method": "POST", "path": "/api/deals/update" },
|
|
75
|
+
{ "method": "POST", "path": "/api/external/chat" },
|
|
76
|
+
{ "method": "POST", "path": "/api/external/start-session" },
|
|
77
|
+
{ "method": "POST", "path": "/api/external/upload" },
|
|
78
|
+
{ "method": "POST", "path": "/api/mentions/{id}/resolve" },
|
|
79
|
+
{ "method": "POST", "path": "/api/nominations/{approvalId}" },
|
|
80
|
+
{ "method": "POST", "path": "/api/oauth/revoke" },
|
|
81
|
+
{ "method": "POST", "path": "/api/oauth/token" },
|
|
82
|
+
{ "method": "POST", "path": "/api/partner/approvals" },
|
|
83
|
+
{ "method": "POST", "path": "/api/skill-corrections" },
|
|
84
|
+
{ "method": "POST", "path": "/api/wiki/{slug}/restore" },
|
|
85
|
+
{ "method": "POST", "path": "/api/wiki/save" },
|
|
86
|
+
{ "method": "PUT", "path": "/api/deals/{dealId}/blocks" },
|
|
87
|
+
{ "method": "PUT", "path": "/api/deals/{dealId}/documents/{slug}/html" },
|
|
88
|
+
{ "method": "PUT", "path": "/api/deals/{dealId}/founders" },
|
|
89
|
+
{ "method": "PUT", "path": "/api/deals/{dealId}/memo" }
|
|
90
|
+
]
|
|
91
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
function readJson(relativePath) {
|
|
6
|
+
try {
|
|
7
|
+
return requireFromHere(relativePath);
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getBuildInfo() {
|
|
14
|
+
const built = readJson("./build-manifest.json");
|
|
15
|
+
if (built) return built;
|
|
16
|
+
|
|
17
|
+
const packageJson = readJson("../package.json") || {};
|
|
18
|
+
const contract = readJson("../contracts/core-api.json") || {};
|
|
19
|
+
return {
|
|
20
|
+
format: "llama.cli-build.v1",
|
|
21
|
+
packageName: packageJson.name || "@llamaventures/cli",
|
|
22
|
+
packageVersion: packageJson.version || "unknown",
|
|
23
|
+
sourceSha: "local/unknown",
|
|
24
|
+
sourceKind: "local",
|
|
25
|
+
sourceDirty: null,
|
|
26
|
+
coreApiContract: {
|
|
27
|
+
format: contract.format || "unknown",
|
|
28
|
+
name: contract.name || "llama-core-api",
|
|
29
|
+
apiVersion: contract.apiVersion || "unknown",
|
|
30
|
+
openapiVersion: contract.openapiVersion || "unknown",
|
|
31
|
+
sha256: contract.sha256 || "unknown",
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "llama.cli-build.v1",
|
|
3
|
+
"packageName": "@llamaventures/cli",
|
|
4
|
+
"packageVersion": "1.19.0",
|
|
5
|
+
"sourceSha": "5f615ca16d607fc0da09887952afdf42301a43f8",
|
|
6
|
+
"sourceKind": "github",
|
|
7
|
+
"sourceDirty": false,
|
|
8
|
+
"coreApiContract": {
|
|
9
|
+
"format": "llama.core-api-contract.v1",
|
|
10
|
+
"name": "llama-core-api",
|
|
11
|
+
"apiVersion": "1.0.1",
|
|
12
|
+
"openapiVersion": "3.0.3",
|
|
13
|
+
"sha256": "95ce3639aeee15b0fed09830116838f2a11fd2e40e4f35bf80d785664ecf8d96"
|
|
14
|
+
}
|
|
15
|
+
}
|
package/lib/client.mjs
CHANGED
|
@@ -14,6 +14,7 @@ import { fileURLToPath } from "url";
|
|
|
14
14
|
import { execFile as _execFile } from "child_process";
|
|
15
15
|
import { promisify } from "util";
|
|
16
16
|
import { createHash, randomUUID } from "crypto";
|
|
17
|
+
import { getBuildInfo } from "./build-info.mjs";
|
|
17
18
|
|
|
18
19
|
const execFile = promisify(_execFile);
|
|
19
20
|
|
|
@@ -207,9 +208,13 @@ function rememberAgentEvent(event) {
|
|
|
207
208
|
}
|
|
208
209
|
|
|
209
210
|
function agentClientHeaders(command) {
|
|
211
|
+
const build = getBuildInfo();
|
|
210
212
|
return {
|
|
211
213
|
"X-Llama-Client": runtimeClient,
|
|
212
214
|
"X-Llama-Client-Version": getPackageVersion(),
|
|
215
|
+
"X-Llama-Client-Source-Sha": build.sourceSha,
|
|
216
|
+
"X-Llama-API-Contract-Version": build.coreApiContract.apiVersion,
|
|
217
|
+
"X-Llama-API-Contract-Digest": build.coreApiContract.sha256,
|
|
213
218
|
"X-Llama-Agent-Client": detectAgentClient(),
|
|
214
219
|
"X-Llama-Agent-Session": currentAgentSessionId(),
|
|
215
220
|
"X-Llama-Command": command || "unknown",
|
package/lib/oauth-flow.mjs
CHANGED
|
@@ -173,6 +173,7 @@ export async function pkceLoopbackFlow({ baseUrl, scope, resource }) {
|
|
|
173
173
|
});
|
|
174
174
|
|
|
175
175
|
// Build authorize URL and open browser.
|
|
176
|
+
// @core-api-operation GET /api/oauth/authorize
|
|
176
177
|
const authorizeUrl = new URL(`${baseUrl}/api/oauth/authorize`);
|
|
177
178
|
authorizeUrl.searchParams.set("response_type", "code");
|
|
178
179
|
authorizeUrl.searchParams.set("client_id", CLIENT_ID);
|
package/lib/version-check.mjs
CHANGED
|
@@ -73,6 +73,7 @@ async function fetchLatest() {
|
|
|
73
73
|
// The /latest convenience endpoint returns full JSON under the default
|
|
74
74
|
// Accept. (The abbreviated "vnd.npm.install-v1+json" metadata type is only
|
|
75
75
|
// valid on the full packument endpoint — it 406s here.)
|
|
76
|
+
// @core-api-ignore external npm registry version check
|
|
76
77
|
const res = await fetch(REGISTRY_URL, { signal: controller.signal });
|
|
77
78
|
if (!res.ok) return null;
|
|
78
79
|
const data = await res.json();
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llamaventures/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "CLI + MCP server for the Llama Ventures investment workbench (command.llamaventures.vc).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "npm run test:agent-routing",
|
|
7
|
+
"test": "npm run test:agent-routing && npm run test:contract",
|
|
8
8
|
"test:agent-routing": "node scripts/verify-agent-routing.mjs",
|
|
9
|
-
"
|
|
9
|
+
"test:contract": "node --test scripts/build-manifest.test.mjs scripts/core-api-call-sites.test.mjs scripts/verify-core-api-contract.test.mjs && node scripts/verify-core-api-contract.mjs",
|
|
10
|
+
"verify:artifact": "node scripts/verify-release-artifact.mjs",
|
|
11
|
+
"verify:release": "npm test && npm run verify:artifact && node scripts/verify-tarball-clean.mjs",
|
|
12
|
+
"prepack": "node scripts/prepare-build-manifest.mjs",
|
|
13
|
+
"postpack": "node scripts/cleanup-build-manifest.mjs"
|
|
10
14
|
},
|
|
11
15
|
"bin": {
|
|
12
16
|
"llama": "bin/llama.mjs",
|
|
@@ -14,6 +18,7 @@
|
|
|
14
18
|
},
|
|
15
19
|
"files": [
|
|
16
20
|
"bin/",
|
|
21
|
+
"contracts/",
|
|
17
22
|
"lib/",
|
|
18
23
|
"AGENT_BRIEFING.md",
|
|
19
24
|
"CHANGELOG.md",
|