@llamaventures/cli 1.18.1 → 1.20.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
@@ -63,10 +63,11 @@ A teammate says "I just met them and heard…" or pastes a chunk of notes. Your
63
63
 
64
64
  1. **Find the deal** — `llama deal search "<name>"` (Pipeline First). New name → offer to create it.
65
65
  2. **Split what they gave you into two kinds** — this is the whole data model:
66
+ - **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.
66
67
  - **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.
67
68
  - **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".
68
69
  - A pasted blob → pull the verifiable claims out as facts, capture their take as a note.
69
- 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.
70
+ 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.
70
71
  - **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.
71
72
 
72
73
  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`.
@@ -130,6 +131,7 @@ These three look similar but land in different surfaces. Don't infer from the co
130
131
 
131
132
  | You want to… | Command | Lands in |
132
133
  |---|---|---|
134
+ | File a **source packet** with multiple facts and/or one note | `llama deal ingest <dealId> --file packet.json` | Facts + optional note → deal **Feed**, atomically and retry-safe |
133
135
  | Record a **sourced, verifiable fact** | `llama deal fact add <dealId> --category <cat> --claim "…" --source "deck p3" --source-url <url>` | Facts → deal **Feed** (FACT card) + citable in the **Memo** |
134
136
  | Leave a **comment / opinion / question / reaction** for the team | `llama post <dealId> "…"` (`@name` to notify) | Posts → deal **Feed** (POST card); `@mention` fires email + UI badge |
135
137
  | Write **narrative that belongs in the IC memo** | `llama brief add-text <dealId> --heading "…" --body "…"` | Brief blocks → **Memo tab only — NOT in the Feed** |
@@ -298,7 +300,7 @@ Run `llama --help` for the full surface (~40 commands).
298
300
 
299
301
  ## MCP-native agents
300
302
 
301
- If you support [MCP](https://modelcontextprotocol.io), **prefer the MCP server over parsing CLI output.** The same package ships `llama-mcp` (59 typed tools, identical auth chain).
303
+ If you support [MCP](https://modelcontextprotocol.io), **prefer the MCP server over parsing CLI output.** The same package ships `llama-mcp` (55 typed tools, identical auth chain).
302
304
 
303
305
  Add to your MCP client config (Claude Desktop / Claude Code / Cursor / OpenClaw / Codex / etc.):
304
306
 
package/CHANGELOG.md CHANGED
@@ -6,6 +6,42 @@ this project adheres to [Semantic Versioning](https://semver.org).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.20.0] - 2026-07-22
10
+
11
+ ### Added
12
+ - Add `llama deal ingest <dealId> --file <packet.json>` and the matching
13
+ `deal_ingest` MCP tool for atomic, retry-safe source packets containing up to
14
+ 50 facts and an optional Feed note.
15
+ - Add `llama pref list|add|retire|approve` and the `pref_list` / `pref_add` /
16
+ `pref_set_status` MCP tools for standing agent preferences (Core API 3.1.0).
17
+ Own user scope activates immediately; team scope requires system-admin
18
+ approval. Content is hard-capped at 280 chars.
19
+
20
+ ### Changed
21
+ - Prefer packet ingest for multi-fact agent writes; Core now canonicalizes fact
22
+ categories and skips exact source-aware duplicates before committing.
23
+ - Pin the Core API consumer contract to 3.1.0.
24
+
25
+ ### Removed
26
+ - Remove the retired generated-persona refresh and skill-correction commands
27
+ from the CLI, MCP tool registry, and required Core operation inventory.
28
+ Llama Command keeps authenticated historical reads and 410 compatibility
29
+ tombstones, but new clients can no longer invoke the retired workflow.
30
+ - Remove `llama eval` and the `record_eval_feedback` MCP tool; the server-side
31
+ Golden Query Eval candidate pipeline was retired with Core API 3.0.0.
32
+
33
+ ## [1.19.0] - 2026-07-16
34
+
35
+ ### Added
36
+ - Pin each CLI artifact to the exact versioned Llama Core OpenAPI contract,
37
+ source commit, and complete source-derived operation inventory.
38
+ - Verify the contract identity and required Core operations during tests,
39
+ packaging, clean tarball installation, and release-gate validation.
40
+
41
+ ### Changed
42
+ - Treat Core HTTP as the CLI's only backend boundary and expose contract/build
43
+ provenance through `llama version --json` for independent rollback audits.
44
+
9
45
  ## [1.18.1] - 2026-07-09
10
46
 
11
47
  ### Changed
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <p align="center">
8
8
  <strong>The Llama Ventures CLI &amp; MCP server.</strong><br/>
9
9
  One package, two binaries: <code>llama</code> — the CLI for humans and scripts —
10
- and <code>llama-mcp</code> — a stdio MCP server with 59 typed tools for any
10
+ and <code>llama-mcp</code> — a stdio MCP server with 55 typed tools for any
11
11
  MCP-native agent. Both share the same auth chain, HTTP client, and error
12
12
  format, and talk to <a href="https://command.llamaventures.vc">command.llamaventures.vc</a>.
13
13
  </p>
@@ -42,6 +42,7 @@
42
42
  ```bash
43
43
  npm i -g @llamaventures/cli # Node 18+; also puts `llama-mcp` on your PATH
44
44
  llama --version
45
+ llama version --json # package, source commit, and pinned Core API contract
45
46
  llama auth status # round-trips against /api/me
46
47
  ```
47
48
 
@@ -97,6 +98,7 @@ llama deal feed <dealId> # every contribution, newest first
97
98
  llama activity new-deals --since 24h # recent deal creations
98
99
  llama activity updated-deals --since 7d # meaningful updates grouped by deal
99
100
  llama deal create "Acme AI" --source alex --deal-owner owner@llamaventures.vc --source-direction Outbound --status Interested
101
+ llama deal ingest <dealId> --file packet.json # atomic multi-fact + optional Feed note; retry-safe
100
102
  llama deal fact add <dealId> --category funding --claim "Raised a seed round" --source "deck p3" --source-url https://...
101
103
  llama deal update <dealId> status Diligence
102
104
  llama post <dealId> "note body"
@@ -112,6 +114,13 @@ Status vocabulary — `Interested`: tracked before any contact ·
112
114
  signal exists. `sourceDirection` is separate: `Inbound` came to the firm,
113
115
  `Outbound` we reached out first.
114
116
 
117
+ For a deck, meeting note, email, or research packet, prefer `deal ingest` over a
118
+ loop of `deal fact add` calls. The JSON object accepts `source`, up to 50
119
+ `facts`, an optional `note`, and an optional `idempotencyKey`. The server commits
120
+ the packet atomically, maps common category aliases into the canonical taxonomy,
121
+ and skips exact source-aware duplicates. `deal fact add` remains the simple path
122
+ for one fact.
123
+
115
124
  Facts use `claim` for the fact text. `source` is a readable provenance label
116
125
  and `sourceUrl` is the canonical evidence URL; both round-trip from the API.
117
126
  For deal owners, use an exact `/api/field-options` `dealOwner` value, a user
@@ -128,12 +137,11 @@ reference (100+ commands). Deletes are soft and audit-logged everywhere.
128
137
  | `Error[UNAUTHORIZED]` | Server rejected the credentials | Token revoked / expired / wrong account |
129
138
 
130
139
  The MCP server returns the same prefixes inside `isError: true` content.
131
- Authenticated calls send bounded, content-redacted telemetry to Command;
132
- `llama eval good|bad --last` turns real searches into eval feedback.
140
+ Authenticated calls send bounded, content-redacted telemetry to Command.
133
141
 
134
142
  ## MCP server
135
143
 
136
- `llama-mcp` is a stdio Model Context Protocol server exposing 59 typed tools
144
+ `llama-mcp` is a stdio Model Context Protocol server exposing 55 typed tools
137
145
  that mirror the most-used CLI surface. Every tool is named and scoped — there
138
146
  is deliberately no generic API passthrough. Auth is identical to the CLI's
139
147
  chain. For the exact live list, pipe `tools/list` through it:
package/README.zh-CN.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <p align="center">
8
8
  <strong>Llama Ventures 的 CLI 与 MCP server。</strong><br/>
9
9
  一个包、两个可执行文件:<code>llama</code>——给人和脚本用的 CLI;
10
- <code>llama-mcp</code>——带 59 个类型化工具的 stdio MCP server,任何
10
+ <code>llama-mcp</code>——带 55 个类型化工具的 stdio MCP server,任何
11
11
  MCP 原生 agent 都能接。两者共享同一认证链、同一 HTTP 客户端、同一错误格式,
12
12
  连接 <a href="https://command.llamaventures.vc">command.llamaventures.vc</a>。
13
13
  </p>
@@ -67,6 +67,7 @@ Pitch 完成后档案自动进我们团队的 inbox,我们会主动联系你
67
67
  ```bash
68
68
  npm i -g @llamaventures/cli # Node 18+;llama-mcp 也会一起装上 PATH
69
69
  llama --version
70
+ llama version --json # 包版本、源码 commit 与固定的 Core API 契约
70
71
  llama auth status # 会跑一次 /api/me 验证
71
72
  ```
72
73
 
@@ -119,6 +120,7 @@ llama deal feed <dealId> # 该 deal 的全部贡献,最新在前
119
120
  llama activity new-deals --since 24h # 最近新建的 deal
120
121
  llama activity updated-deals --since 7d # 按 deal 聚合的实质更新
121
122
  llama deal create "Acme AI" --source alex --deal-owner owner@llamaventures.vc --source-direction Outbound --status Interested
123
+ llama deal ingest <dealId> --file packet.json # 多条 facts + 可选 Feed note,一次提交且可安全重试
122
124
  llama deal fact add <dealId> --category funding --claim "Raised a seed round" --source "deck p3" --source-url https://...
123
125
  llama deal update <dealId> status Diligence
124
126
  llama post <dealId> "备注内容"
@@ -133,6 +135,11 @@ Status 语义——`Interested`:接触前先记录关注 · `Outreached`:已
133
135
  尚无回应 · `Sourced`:已有真实关系信号。`sourceDirection` 是独立维度:
134
136
  `Inbound` 流入,`Outbound` 我们主动。
135
137
 
138
+ 处理 deck、会议笔记、邮件或研究材料时,优先使用 `deal ingest`,不要循环调用
139
+ `deal fact add`。JSON 对象支持 `source`、最多 50 条 `facts`、可选 `note` 和可选
140
+ `idempotencyKey`。服务端会原子提交整个材料包、把常见 category 别名归一到固定分类,
141
+ 并跳过来源一致的精确重复。只有真正的单条事实才用 `deal fact add`。
142
+
136
143
  Facts 的正文用 `claim`。`source` 是人可读来源标签,`sourceUrl` 是 canonical
137
144
  证据 URL;两者都会从 API 回显。`dealOwner` 请用 `/api/field-options`
138
145
  里的精确 `dealOwner` 值、用户邮箱,或数字 user id。
@@ -152,7 +159,7 @@ MCP server 在 `isError: true` 内容里返回相同前缀。认证请求会向
152
159
 
153
160
  ## MCP server
154
161
 
155
- `llama-mcp` 是 stdio MCP server,59 个类型化工具镜像 CLI 最常用的命令面。
162
+ `llama-mcp` 是 stdio MCP server,55 个类型化工具镜像 CLI 最常用的命令面。
156
163
  每个工具具名、有边界——**故意不提供**通用 API passthrough。认证链与 CLI
157
164
  完全一致。精确工具清单以 `tools/list` 为准:
158
165
 
package/bin/llama-mcp.mjs CHANGED
@@ -15,7 +15,6 @@ import { z } from "zod";
15
15
  import {
16
16
  getAuthHeaders,
17
17
  getBaseUrl,
18
- getLastAgentEvent,
19
18
  readBriefing,
20
19
  request,
21
20
  requestSse,
@@ -84,20 +83,6 @@ function splitSources(value) {
84
83
  .filter(Boolean);
85
84
  }
86
85
 
87
- function expectedIds(value) {
88
- const expected = { dealIds: [], wikiSlugs: [], raw: [] };
89
- if (!value) return expected;
90
- const items = Array.isArray(value) ? value : String(value).split(",");
91
- for (const item of items.map((s) => String(s).trim()).filter(Boolean)) {
92
- const [kind, ...rest] = item.split(":");
93
- const id = rest.join(":").trim();
94
- if (kind === "deal" && id) expected.dealIds.push(id);
95
- else if ((kind === "wiki" || kind === "slug") && id) expected.wikiSlugs.push(id);
96
- else expected.raw.push(item);
97
- }
98
- return expected;
99
- }
100
-
101
86
  function buildEnrichmentAgentMessage(args = {}) {
102
87
  if (args.message) return String(args.message);
103
88
  const sources = splitSources(args.sources) ?? [
@@ -257,41 +242,6 @@ server.registerTool(
257
242
  }
258
243
  );
259
244
 
260
- server.registerTool(
261
- "record_eval_feedback",
262
- {
263
- description:
264
- "Mark the latest llama CLI/MCP result as good/bad or add a real query " +
265
- "to the Golden Query Eval candidate pool. Use when the user says a " +
266
- "Llama Command search/result was right, wrong, missing a source, or should be regression-tested.",
267
- inputSchema: {
268
- action: z.enum(["good", "bad", "add"]).describe("feedback action"),
269
- eventId: z.number().optional().describe("agent_client_events id; defaults to latest local event"),
270
- query: z.string().optional().describe("required for manual add when no source event is available"),
271
- surface: z.string().optional().describe("deal, wiki, activity, people, or manual"),
272
- expect: z
273
- .union([z.string(), z.array(z.string())])
274
- .optional()
275
- .describe("expected ids like wiki:llamaos-weekly-2026-06-17 or deal:<uuid>"),
276
- reason: z.string().optional().describe("why this was good/bad or should be tracked"),
277
- privacyLevel: z.string().optional().describe("default internal"),
278
- },
279
- },
280
- async ({ action, eventId, query, surface, expect, reason, privacyLevel }) => {
281
- const last = getLastAgentEvent();
282
- const body = {
283
- action,
284
- eventId: eventId ?? last?.lastEventId,
285
- query,
286
- surface: surface ?? last?.lastSurface,
287
- expected: expectedIds(expect),
288
- reason,
289
- privacyLevel: privacyLevel ?? "internal",
290
- };
291
- return callApi("POST", "/api/agent/eval-feedback", body);
292
- }
293
- );
294
-
295
245
  server.registerTool(
296
246
  "skills_search",
297
247
  {
@@ -311,6 +261,60 @@ server.registerTool(
311
261
  }
312
262
  );
313
263
 
264
+ server.registerTool(
265
+ "pref_list",
266
+ {
267
+ description:
268
+ "List standing agent preferences (team scope + the caller's user scope). " +
269
+ "These are injected into every server-side agent turn. Use status=proposed " +
270
+ "to review pending proposals awaiting approval.",
271
+ inputSchema: {
272
+ status: z.enum(["active", "proposed", "retired", "all"]).optional()
273
+ .describe("filter; defaults to active"),
274
+ },
275
+ },
276
+ async ({ status }) => {
277
+ const params = new URLSearchParams();
278
+ if (status) params.set("status", status);
279
+ return callApi("GET", `/api/agent/preferences${params.toString() ? `?${params}` : ""}`);
280
+ }
281
+ );
282
+
283
+ server.registerTool(
284
+ "pref_add",
285
+ {
286
+ description:
287
+ "Save a standing preference so every Llama agent follows it from the next " +
288
+ "turn on. Use when the user states a durable way they want agents to work " +
289
+ "(style, workflow, defaults). Content is hard-capped at 280 chars — if it " +
290
+ "does not fit, it is a procedure and belongs in a skill. Team scope needs " +
291
+ "system-admin approval; own user scope activates immediately.",
292
+ inputSchema: {
293
+ key: z.string().describe("short slug, e.g. reply-style.conclusion-first"),
294
+ content: z.string().describe("the preference, max 280 chars"),
295
+ scope: z.enum(["user", "team"]).optional().describe("default user (the caller)"),
296
+ evidence: z.string().optional().describe("what prompted this (run, correction)"),
297
+ },
298
+ },
299
+ async ({ key, content, scope, evidence }) =>
300
+ callApi("POST", "/api/agent/preferences", { key, content, scope, evidence })
301
+ );
302
+
303
+ server.registerTool(
304
+ "pref_set_status",
305
+ {
306
+ description:
307
+ "Approve (activate) or retire a standing preference by id. Own user scope " +
308
+ "is self-service; team scope requires a system admin.",
309
+ inputSchema: {
310
+ id: z.number().describe("preference id from pref_list"),
311
+ status: z.enum(["active", "retired"]).describe("new status"),
312
+ },
313
+ },
314
+ async ({ id, status }) =>
315
+ callApi("PATCH", `/api/agent/preferences/${encodeURIComponent(String(id))}`, { status })
316
+ );
317
+
314
318
  server.registerTool(
315
319
  "skills_read",
316
320
  {
@@ -509,6 +513,50 @@ server.registerTool(
509
513
  // Deal facts (research substrate + trust ladder)
510
514
  // ============================================================
511
515
 
516
+ server.registerTool(
517
+ "deal_ingest",
518
+ {
519
+ description:
520
+ "Preferred write tool when one source yields multiple facts, or facts plus a Feed note. " +
521
+ "Commits the packet atomically, canonicalizes fact categories, skips exact source-aware " +
522
+ "duplicates, and is safe to retry with the same idempotencyKey. Use deal_fact_add only " +
523
+ "for a genuinely single fact. Canonical categories: company_basics, team, product, market, " +
524
+ "financials, fundraise, risk, milestone, meta.",
525
+ inputSchema: {
526
+ dealId: z.string(),
527
+ idempotencyKey: z
528
+ .string()
529
+ .optional()
530
+ .describe("Stable key for retries. If omitted, the server derives one from packet content."),
531
+ source: z
532
+ .object({
533
+ kind: z.enum(["deck", "web", "meeting_note", "email", "human", "agent_inference"]).optional(),
534
+ title: z.string().optional(),
535
+ url: z.string().optional(),
536
+ contentHash: z.string().optional(),
537
+ })
538
+ .optional(),
539
+ facts: z
540
+ .array(z.object({
541
+ category: z.string(),
542
+ claim: z.string(),
543
+ source: z.string().optional(),
544
+ sourceUrl: z.string().optional(),
545
+ sourceKind: z.enum(["deck", "web", "meeting_note", "email", "human", "agent_inference"]).optional(),
546
+ confidence: z.enum(["high", "medium", "low"]).optional(),
547
+ attested: z.boolean().optional(),
548
+ }))
549
+ .max(50)
550
+ .optional(),
551
+ note: z.string().optional().describe("Opinion, impression, or context to add to the deal Feed."),
552
+ },
553
+ },
554
+ async ({ dealId, ...packet }) => {
555
+ // @core-api-operation POST /api/deals/{dealId}/ingest
556
+ return callApi("POST", `/api/deals/${encodeURIComponent(dealId)}/ingest`, packet);
557
+ }
558
+ );
559
+
512
560
  server.registerTool(
513
561
  "deal_fact_list",
514
562
  {
@@ -613,7 +661,7 @@ server.registerTool(
613
661
  "accountable person, null only for principal-less system writes) and `agent` " +
614
662
  "(the assistant/system label when an AI did the writing, null when a human " +
615
663
  "typed it) so you can tell human-typed from assistant-drafted. The AI's " +
616
- "regenerable brief/persona synthesis is NOT here (that's the Memo) — only " +
664
+ "regenerable brief synthesis is NOT here (that's the Memo) — only " +
617
665
  "facts + discussion notes. Each item: kind (fact|note), ts, who, agent, " +
618
666
  "origin, text, and for facts: source + trust rung + category.",
619
667
  inputSchema: {
@@ -993,63 +1041,7 @@ server.registerTool(
993
1041
  );
994
1042
 
995
1043
  // ============================================================
996
- // Skill corrections (persona-owner pushback workflow)
997
- // ============================================================
998
-
999
- server.registerTool(
1000
- "skill_correction_list",
1001
- {
1002
- description:
1003
- "List the recorded corrections (long-term rules) for a persona/skill. These shape how " +
1004
- "that persona's analysis is generated.",
1005
- inputSchema: {
1006
- skillSlug: z.string(),
1007
- includeDeleted: z.boolean().optional(),
1008
- },
1009
- },
1010
- async ({ skillSlug, includeDeleted }) => {
1011
- const params = new URLSearchParams({ skill: skillSlug });
1012
- if (includeDeleted) params.set("include_deleted", "1");
1013
- return callApi("GET", `/api/skill-corrections?${params}`);
1014
- }
1015
- );
1016
-
1017
- server.registerTool(
1018
- "skill_correction_add",
1019
- {
1020
- description:
1021
- "Record a long-term correction rule for a persona/skill (e.g. 'always check burn multiple " +
1022
- "before commenting on efficiency'). ALWAYS reconfirm the distilled rule with the user before " +
1023
- "calling — this changes how the persona behaves going forward. Optionally tie it to the deal/" +
1024
- "block where it came up.",
1025
- inputSchema: {
1026
- skillSlug: z.string(),
1027
- correctionText: z.string(),
1028
- dealUuid: z.string().optional(),
1029
- blockId: z.string().optional(),
1030
- },
1031
- },
1032
- async ({ skillSlug, correctionText, dealUuid, blockId }) =>
1033
- callApi("POST", "/api/skill-corrections", {
1034
- skill_slug: skillSlug,
1035
- correction_text: correctionText,
1036
- triggered_in_deal_uuid: dealUuid ?? null,
1037
- triggered_in_block_id: blockId ?? null,
1038
- })
1039
- );
1040
-
1041
- server.registerTool(
1042
- "skill_correction_delete",
1043
- {
1044
- description: "Soft-delete a recorded skill correction by id.",
1045
- inputSchema: { id: z.union([z.string(), z.number()]) },
1046
- },
1047
- async ({ id }) =>
1048
- callApi("DELETE", `/api/skill-corrections/${encodeURIComponent(String(id))}`)
1049
- );
1050
-
1051
- // ============================================================
1052
- // Brief / persona refresh (signal-driven re-evaluation)
1044
+ // Brief refresh (signal-driven re-evaluation)
1053
1045
  // ============================================================
1054
1046
 
1055
1047
  server.registerTool(
@@ -1070,22 +1062,6 @@ server.registerTool(
1070
1062
  )
1071
1063
  );
1072
1064
 
1073
- server.registerTool(
1074
- "deal_refresh_persona",
1075
- {
1076
- description:
1077
- "Regenerate one persona's analysis section for a deal. persona = a server-configured " +
1078
- "persona key (unknown keys are rejected; discover the roster via agent_bootstrap). " +
1079
- "Returns a runId (or null if debounced).",
1080
- inputSchema: {
1081
- dealId: z.string(),
1082
- persona: z.string(),
1083
- },
1084
- },
1085
- async ({ dealId, persona }) =>
1086
- callApi("POST", `/api/deals/${encodeURIComponent(dealId)}/refresh-persona`, { persona })
1087
- );
1088
-
1089
1065
  server.registerTool(
1090
1066
  "deal_agent_run",
1091
1067
  {