@clien-ai/mcp 0.4.0 → 0.5.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/CHANGELOG.md +133 -0
- package/README.md +1 -1
- package/dist/tools/collections.js +255 -22
- package/dist/tools/collections.js.map +1 -1
- package/dist/tools/interview.js +45 -5
- package/dist/tools/interview.js.map +1 -1
- package/dist/tools/personas.js +70 -9
- package/dist/tools/personas.js.map +1 -1
- package/dist/tools/projects.js +41 -4
- package/dist/tools/projects.js.map +1 -1
- package/dist/tools/registry.js +18 -9
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/render-safety.js +264 -0
- package/dist/tools/render-safety.js.map +1 -0
- package/dist/tools/report-digest.js +149 -40
- package/dist/tools/report-digest.js.map +1 -1
- package/dist/tools/reports.js +68 -5
- package/dist/tools/reports.js.map +1 -1
- package/dist/tools/research.js +1 -3
- package/dist/tools/research.js.map +1 -1
- package/dist/tools/scoped-research.js +87 -22
- package/dist/tools/scoped-research.js.map +1 -1
- package/dist/tools/status.js +30 -4
- package/dist/tools/status.js.map +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@clien-ai/mcp`.
|
|
4
|
+
|
|
5
|
+
This file starts at 0.5.0. The 0.3.0 and 0.4.0 entries below were reconstructed
|
|
6
|
+
from merge history after the fact and are deliberately terse — they record what
|
|
7
|
+
changed, not the reasoning, which lives in the linked PRs. Versions before 0.3.0
|
|
8
|
+
have no entry; nothing was written down at the time and inventing one now would
|
|
9
|
+
be worse than the gap.
|
|
10
|
+
|
|
11
|
+
The client and the Clien.ai app ship on **independent release cycles**. An
|
|
12
|
+
upgrade here does not imply the deployed app speaks the same shape, and the
|
|
13
|
+
client strips unknown fields by construction — so a field described below only
|
|
14
|
+
reaches you once both sides have shipped.
|
|
15
|
+
|
|
16
|
+
## 0.5.1
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **`list_interviews` rows now show when each interview started** (#497). The
|
|
21
|
+
list is ordered by `started_at DESC`, and until now printed no date at all —
|
|
22
|
+
so the sort key itself was the one thing an agent could not see. Two rows for
|
|
23
|
+
the same persona in the same status read identically while being months apart,
|
|
24
|
+
and an agent resuming work could not tell today's run from last month's.
|
|
25
|
+
|
|
26
|
+
The closing line reads **"Newest started first"**, not a generic "newest
|
|
27
|
+
first": the app's collection endpoints do not share a sort key, and a copied
|
|
28
|
+
ordering claim is a lie about a specific column. It is stated only now that
|
|
29
|
+
the dates make it checkable.
|
|
30
|
+
|
|
31
|
+
### Internal
|
|
32
|
+
|
|
33
|
+
- The render-coverage guard's "no unfixed findings" claim now enforces itself by
|
|
34
|
+
**parsing** its own source rather than grepping it (#497). Comments are
|
|
35
|
+
excluded by the language grammar, so the prose documenting the convention
|
|
36
|
+
cannot self-match — which means there is no exclusion list a later change can
|
|
37
|
+
add itself to. Parking an unfixed finding in that file now turns the suite red.
|
|
38
|
+
|
|
39
|
+
- Render-safety helpers moved out of `research.ts` into their own module (#496).
|
|
40
|
+
Internal only — this package publishes no type declarations, so no consumer
|
|
41
|
+
can observe the move. Incidentally removed an import cycle between the
|
|
42
|
+
research tool and the report digest.
|
|
43
|
+
|
|
44
|
+
## 0.5.0
|
|
45
|
+
|
|
46
|
+
The release where **agent-visible output stops being forgeable**.
|
|
47
|
+
|
|
48
|
+
0.4.0 made the trust spine reach the agent. This one makes what reaches the
|
|
49
|
+
agent trustworthy: every renderer in this package builds line-structured text
|
|
50
|
+
(`- Name (id: uuid)`, `Funding: X [GROUNDED]`) that an agent parses as the
|
|
51
|
+
server's own statements, and until now several of them interpolated untrusted
|
|
52
|
+
values into those lines raw.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- **Line-structured forgery, closed across nine renderers** (FUL-253, #493).
|
|
57
|
+
A newline inside an interpolated value ended the line early, and everything
|
|
58
|
+
after it became a line the agent read as the server's own. Untrusted values
|
|
59
|
+
are now whitespace-flattened before rendering, so a crafted forum post cannot
|
|
60
|
+
forge a line that reads as this server's output. The value is still shown in
|
|
61
|
+
full-width — flattening bounds where it can appear, not whether it appears.
|
|
62
|
+
|
|
63
|
+
Covered: `list_community_signals`, `search_forums` (`renderThreads` and
|
|
64
|
+
`renderCompetitors`), `clien_research_status`, `list_personas`,
|
|
65
|
+
`list_interviews`, and the `get_report` trust digest's claim spines, receipt
|
|
66
|
+
lines and robustness rows.
|
|
67
|
+
|
|
68
|
+
The sharpest case was the claim spine, where a newline in a claim's text could
|
|
69
|
+
forge `- [GROUNDED] … ← RRCP-s0` — a receipt for a claim nothing had checked,
|
|
70
|
+
which is the exact invariant the digest exists to hold.
|
|
71
|
+
|
|
72
|
+
⚠️ The GROUNDED gates deliberately read the **raw** state while the row renders
|
|
73
|
+
the flattened one. Flattening trims, so gating on the flattened value would
|
|
74
|
+
newly admit a padded `" GROUNDED "` as grounded and put a row's badge at odds
|
|
75
|
+
with the tallies, which read raw. Flattening is for the render; it must never
|
|
76
|
+
widen what counts as a receipt. There is a test per spine holding this — the
|
|
77
|
+
two variables are load-bearing, not redundant.
|
|
78
|
+
|
|
79
|
+
- **Receipt quotes are windowed around the verified span** (FUL-252, #492).
|
|
80
|
+
A quote longer than the excerpt cap was clipped from the head, so the span the
|
|
81
|
+
verifier actually grounded could fall outside the text a reader sees — a
|
|
82
|
+
receipt that did not show its own evidence. The excerpt is now centred on the
|
|
83
|
+
span.
|
|
84
|
+
|
|
85
|
+
⚠️ The span lookup matches the **verifier's** comparison (NFC, case-folded,
|
|
86
|
+
whitespace-collapsed, fuzzy at 0.95), not a case-sensitive `indexOf`. A
|
|
87
|
+
language-default lookup silently re-creates the bug for exactly the claims the
|
|
88
|
+
verifier was most generous about.
|
|
89
|
+
|
|
90
|
+
- `clien_research_status` renders its disambiguators, and `list_competitors`
|
|
91
|
+
bounds its payload (FUL-252, #492). Measured: 20.7 → 15.4 KB at `limit=20`,
|
|
92
|
+
99.9 → 72.8 KB at `limit=100`.
|
|
93
|
+
|
|
94
|
+
- **`null` is preserved where it means "we asked, the answer is nothing"**
|
|
95
|
+
(FUL-246, #490). Identity-prior fields are now `string | null` rather than
|
|
96
|
+
collapsing to absent. The two are not interchangeable across independent
|
|
97
|
+
release cycles: absent reads as "this deploy never computed it", `null` reads
|
|
98
|
+
as "it computed it and there was nothing." Dropping the distinction made a
|
|
99
|
+
real answer indistinguishable from an old deployment.
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **Fields that previously reached no agent-visible channel are now rendered**
|
|
104
|
+
(FUL-247, #491), with a test guarding that every declared entity field either
|
|
105
|
+
renders or carries a written reason for not doing so.
|
|
106
|
+
|
|
107
|
+
## 0.4.0
|
|
108
|
+
|
|
109
|
+
The trust spine reaches the agent.
|
|
110
|
+
|
|
111
|
+
- **`_meta` is not a delivery channel** (FUL-243, #482). Hosts are not obliged
|
|
112
|
+
to surface a tool result's `_meta`, and Claude Code drops it outright — so the
|
|
113
|
+
entire Trust Engine was being sent and never read. Trust state is now rendered
|
|
114
|
+
into result **text**. Anything an agent must act on has to appear there.
|
|
115
|
+
- Render-coverage guard: every declared entity field is rendered or allowlisted
|
|
116
|
+
with a reason (FUL-245, #484).
|
|
117
|
+
- Persona identity priors on the read path (FUL-208, #483).
|
|
118
|
+
- Dropped the phantom `Persona.includeInInsights` (FUL-242, #481).
|
|
119
|
+
- In-process single-flight token refresh (FUL-236, #474).
|
|
120
|
+
- Transcript-free interview list via `fields=summary` (FUL-237, #470, #472).
|
|
121
|
+
|
|
122
|
+
## 0.3.0
|
|
123
|
+
|
|
124
|
+
The agent-first read + update surface — **12 → 20 tools**.
|
|
125
|
+
|
|
126
|
+
- Read tools: `list_interviews`, `get_interview`, `list_personas`, `get_persona`,
|
|
127
|
+
`list_competitors`, `list_community_signals`, `get_project` (#457, #459, #465,
|
|
128
|
+
#466).
|
|
129
|
+
- `update_persona` (#457).
|
|
130
|
+
- `snake_case` parameters with `camelCase` aliases accepted on both spellings
|
|
131
|
+
(#467, #468).
|
|
132
|
+
- Persona and market/competitor trust spine typed into the report schema (#456).
|
|
133
|
+
- Per-tool-call usage telemetry (#455).
|
package/README.md
CHANGED
|
@@ -113,7 +113,7 @@ a finding is, rather than taking the prose at face value:
|
|
|
113
113
|
| Field | What it tells you |
|
|
114
114
|
|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
|
|
115
115
|
| `claims[]` | Every persona/interview claim with a `state`: `GROUNDED` (span-verified against a cached source quote), `SPECULATION`, or `NO_RECEIPT` (evidence-shaped but unsourced). A `GROUNDED` claim carries a `sourceId` receipt and the `quoteSpan` that grounds it. |
|
|
116
|
-
| `personas[].sources[]` | The cached forum posts (`url`, `platform`, `quote`, `retrievedAt`) a claim's `sourceId` (`RCP-p{i}-s{j}`) points at — the receipts.
|
|
116
|
+
| `personas[].sources[]` | The cached forum posts (`url`, `platform`, `quote`, `retrievedAt`) a claim's `sourceId` (`RCP-p{i}-s{j}`) points at — the receipts. In the digest text each quote is shown as a 200-character excerpt **windowed around the span that grounded the claim**, with a leading `…` when the window starts mid-quote; the untruncated `quote` is in the structured payload. |
|
|
117
117
|
| `personas[].qaFlagged` / `insufficientEvidence` / `sourcesFound` | Per-persona quality flags: `qaFlagged` means the persona failed a QA check; `insufficientEvidence` / `sourcesFound` tell you whether a `NO_RECEIPT` reflects a weak claim or just a thin evidence base. |
|
|
118
118
|
| `hypothesisResults[].robustness` | How many reworded re-asks a verdict survived (`survived`/`total`); when `flipped` is true, `downgradedStatus` is the verdict to trust, not the top-level `status`. |
|
|
119
119
|
| `sycophancySignals` | Anti-sycophancy readout: broken-persona flags (`lowDiscrimination`), per-hypothesis disagreement splits, and explicit `totalRejections`. |
|
|
@@ -55,7 +55,8 @@
|
|
|
55
55
|
*/
|
|
56
56
|
import { z } from 'zod';
|
|
57
57
|
import { ToolError } from './errors.js';
|
|
58
|
-
import { apiCall, categorizeFetchError,
|
|
58
|
+
import { apiCall, categorizeFetchError, } from './research.js';
|
|
59
|
+
import { truncate, collapseWhitespace, safeInline } from './render-safety.js';
|
|
59
60
|
const COLLECTIONS_FETCH_TIMEOUT_MS = 30_000;
|
|
60
61
|
// Mirrors `CollectionListQuerySchema` in app/lib/api/collection-list-query.ts.
|
|
61
62
|
// The MCP package is published separately and cannot import from the Next.js
|
|
@@ -323,6 +324,107 @@ function resolvePagination(serverPagination, limit, offset, total) {
|
|
|
323
324
|
total,
|
|
324
325
|
};
|
|
325
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* The trust state of one FUL-201 per-fact grounding blob, as a bracket suffix.
|
|
329
|
+
*
|
|
330
|
+
* ⚠️ THE RULE THIS ENFORCES (FUL-247): a company fact must NEVER reach
|
|
331
|
+
* agent-visible text without its state beside it. `list_competitors` used to print
|
|
332
|
+
* `Funding: $12M Series A` and, separately, one blanket sentence telling the reader
|
|
333
|
+
* to go consult `<fact>Grounding.state` — on `_meta`, the channel Claude Code
|
|
334
|
+
* drops. So the number arrived and its trust state did not, and a bare number next
|
|
335
|
+
* to a competitor's name reads as verified. Pairing them is the whole point: the
|
|
336
|
+
* value and its grounding are advanced in lockstep at merge time (`toCompetitorSummary`),
|
|
337
|
+
* so they are one fact, and splitting them across channels split a fact from its warrant.
|
|
338
|
+
*
|
|
339
|
+
* Three outcomes, kept distinct because they are genuinely different answers:
|
|
340
|
+
* - a RECOGNISED state string → printed verbatim (`GROUNDED` / `SPECULATION` / `NO_RECEIPT`)
|
|
341
|
+
* - anything else in `state`, or no readable `state` → `state?` — we have a
|
|
342
|
+
* grounding blob but cannot read a state we understand
|
|
343
|
+
* - no blob at all → `no grounding`
|
|
344
|
+
*
|
|
345
|
+
* The last two are NOT "checked and unsupported" (see `FactGrounding`), and the
|
|
346
|
+
* caveat below says so — an agent that reads `no grounding` as a refutation is as
|
|
347
|
+
* wrong as one that reads a bare number as a fact.
|
|
348
|
+
*
|
|
349
|
+
* ⚠️ The state is checked against an ALLOWLIST, not merely for non-emptiness.
|
|
350
|
+
* `FactGrounding`'s own contract says a consumer "MUST key on `state` and treat
|
|
351
|
+
* anything unrecognised as ungrounded — the presence of a grounding object never
|
|
352
|
+
* by itself means the fact is verified." A bare `length > 0` test would print an
|
|
353
|
+
* unrecognised value verbatim, so a blob carrying `state: 'verified'` — from a
|
|
354
|
+
* future writer, a reshaped column, or a bad migration — would render
|
|
355
|
+
* `Funding: $4M [verified]` and read to an agent as stronger than `[GROUNDED]`.
|
|
356
|
+
* The renderer must not be the place a new trust vocabulary silently debuts.
|
|
357
|
+
*/
|
|
358
|
+
const RECOGNISED_GROUNDING_STATES = new Set(['GROUNDED', 'SPECULATION', 'NO_RECEIPT']);
|
|
359
|
+
function groundingSuffix(grounding) {
|
|
360
|
+
if (grounding === null)
|
|
361
|
+
return ' [no grounding]';
|
|
362
|
+
const state = grounding.state;
|
|
363
|
+
return typeof state === 'string' && RECOGNISED_GROUNDING_STATES.has(state)
|
|
364
|
+
? ` [${state}]`
|
|
365
|
+
: ' [state?]';
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* One company fact, rendered only when it HAS a value, always carrying its state.
|
|
369
|
+
*
|
|
370
|
+
* Returns `null` for an absent value rather than printing the state alone: a trust
|
|
371
|
+
* state for a fact nobody asserted is noise, and `Funding: [no grounding]` invites
|
|
372
|
+
* a reader to think a funding figure was checked and rejected.
|
|
373
|
+
*/
|
|
374
|
+
function factLine(label, value, grounding, max) {
|
|
375
|
+
// `collapseWhitespace` is load-bearing for THE INVARIANT, not cosmetic. These
|
|
376
|
+
// facts are agent-written free text. A `funding` of `'Series B\nHQ: London'`
|
|
377
|
+
// would render `Funding: Series B` on one line — with no state beside it — and
|
|
378
|
+
// move the `[NO_RECEIPT]` suffix onto what now reads as an HQ line. That is
|
|
379
|
+
// both halves of the failure this function exists to prevent, from one newline.
|
|
380
|
+
// Null-check FIRST: `value` is `string | null`, and a whitespace-only value
|
|
381
|
+
// collapses to '' — both mean "no fact was asserted" and must render nothing,
|
|
382
|
+
// never a bare `Funding: [no grounding]` that reads as checked-and-rejected.
|
|
383
|
+
if (!value)
|
|
384
|
+
return null;
|
|
385
|
+
const flat = collapseWhitespace(value);
|
|
386
|
+
if (!flat)
|
|
387
|
+
return null;
|
|
388
|
+
return `${label}: ${truncate(flat, max)}${groundingSuffix(grounding)}`;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* How much FREE-TEXT PROSE one competitor spends in the LIST view (FUL-252).
|
|
392
|
+
*
|
|
393
|
+
* ⚠️ PROSE ONLY. `description`, `strengths`, `weaknesses` — never a fact value,
|
|
394
|
+
* never a grounding bracket, never the trust caveat. Those are the load-bearing
|
|
395
|
+
* parts: a funding figure whose `[SPECULATION]` fell off the end of a clip reads
|
|
396
|
+
* as a plain number, and a plain number beside a competitor's name reads as
|
|
397
|
+
* checked. Shrinking a payload by eating a trust state makes the tool worse, not
|
|
398
|
+
* smaller. `factLine`'s own 80/40/40/80 limits are separate and stay put.
|
|
399
|
+
*
|
|
400
|
+
* WHY 120, measured on a deliberately saturated fixture (every prose field long
|
|
401
|
+
* enough to clip, every fact populated) — the numbers are pinned as executable
|
|
402
|
+
* budgets in `collections.test.ts`, not left in this comment to rot:
|
|
403
|
+
*
|
|
404
|
+
* cap limit=20 limit=100
|
|
405
|
+
* 240 20.7 KB 99.9 KB ← FUL-247's value
|
|
406
|
+
* 160 17.6 KB 84.4 KB
|
|
407
|
+
* 120 15.4 KB 72.8 KB ← here (−26% / −27%)
|
|
408
|
+
* 100 14.1 KB 66.9 KB
|
|
409
|
+
* 80 12.9 KB 61.0 KB
|
|
410
|
+
*
|
|
411
|
+
* 120 is the knee. Below it the curve flattens hard, because what remains is not
|
|
412
|
+
* prose: roughly 38 KB of a 100-row page is the header, url, id and the FOUR
|
|
413
|
+
* bracketed company facts, none of which may be cut. Paying a third of the visible
|
|
414
|
+
* analysis for the next 12 KB is a bad trade — the row stops being able to say why
|
|
415
|
+
* a competitor matters, which is the only reason the analysis was rendered at all.
|
|
416
|
+
* One sentence per field survives, which is what a triage list needs; the full text
|
|
417
|
+
* is one `structuredContent.competitors` read away.
|
|
418
|
+
*
|
|
419
|
+
* ONE constant for all three fields, not three tuned numbers: FUL-247's own note
|
|
420
|
+
* on this line is that three different clip lengths in one row read as three
|
|
421
|
+
* different KINDS of field. That reasoning did not change when the number did.
|
|
422
|
+
*
|
|
423
|
+
* NOT LOWERED INSTEAD: the default limit (20) and the max (100). Hitting the same
|
|
424
|
+
* byte count by refusing to answer the question asked is not a payload fix — a
|
|
425
|
+
* caller who asks for 100 competitors is asking about 100 competitors.
|
|
426
|
+
*/
|
|
427
|
+
const LIST_PROSE_MAX = 120;
|
|
326
428
|
/** Shared "N more not shown" tail so both lists page identically. */
|
|
327
429
|
function moreLine(offset, shown, total) {
|
|
328
430
|
const seen = offset + shown;
|
|
@@ -346,20 +448,85 @@ export async function listCompetitors(input, deps) {
|
|
|
346
448
|
'clien_research) to populate the project\'s competitor set.';
|
|
347
449
|
}
|
|
348
450
|
else {
|
|
451
|
+
// Whether any prose was actually clipped on THIS page, so the closing note can
|
|
452
|
+
// say so only when it is true. This file's stated degradation property is that
|
|
453
|
+
// a cut is always STATED — `capNote` does it for dropped rows, and a clipped
|
|
454
|
+
// field deserves the same. The trailing `…` marks the individual field, but it
|
|
455
|
+
// does not tell a reader that the untruncated text exists and where; an agent
|
|
456
|
+
// that needs a competitor's full strengths should not have to guess that
|
|
457
|
+
// `structuredContent` has more than the screen does.
|
|
458
|
+
let proseClipped = false;
|
|
459
|
+
const clip = (value) => {
|
|
460
|
+
if (value.length > LIST_PROSE_MAX)
|
|
461
|
+
proseClipped = true;
|
|
462
|
+
return truncate(value, LIST_PROSE_MAX);
|
|
463
|
+
};
|
|
349
464
|
// Numbering is offset-aware so a second page reads as 21., 22., … rather
|
|
350
465
|
// than restarting at 1 and looking like a different result set.
|
|
351
466
|
const lines = competitors.map((c, i) => {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
467
|
+
// FUL-252: `name`, `pricing` and `description` go through `safeInline` /
|
|
468
|
+
// `collapseWhitespace` like every other value on this row. FUL-247 gave the
|
|
469
|
+
// facts and the strengths/weaknesses that guard and left these three raw —
|
|
470
|
+
// a gap four independent reviewers found here, and the sharpest one in the
|
|
471
|
+
// file: EVERY line of this row shares the same `\n ` indent, so a
|
|
472
|
+
// `description` containing `\n Funding: $999M [GROUNDED]` forges a company
|
|
473
|
+
// fact carrying a trust state nothing ever checked. That defeats precisely
|
|
474
|
+
// the invariant this renderer exists to hold — a fact never appears without
|
|
475
|
+
// its state — using the state itself as the payload.
|
|
476
|
+
const name = safeInline(c.name, 120) ?? 'Unnamed competitor';
|
|
477
|
+
const pricing = safeInline(c.pricing, 80);
|
|
478
|
+
const header = `${offset + i + 1}. **${name}**${pricing ? ` — ${pricing}` : ''}`;
|
|
479
|
+
// `collapseWhitespace` before `clip`, not `safeInline`, so the clip still runs
|
|
480
|
+
// through the `clip()` closure that sets `proseClipped` — routing it through
|
|
481
|
+
// `safeInline`'s own `truncate` would silently stop the page announcing its cut.
|
|
482
|
+
const flatDesc = collapseWhitespace(c.description ?? '');
|
|
483
|
+
const desc = flatDesc ? `\n ${clip(flatDesc)}` : '';
|
|
484
|
+
const url = c.url ? `\n ${safeInline(c.url, 200) ?? ''}` : '';
|
|
485
|
+
// FUL-247: each M1b company fact travels WITH its FUL-201 grounding state.
|
|
486
|
+
// Never render one of these values without `groundingSuffix` beside it.
|
|
355
487
|
const meta = [
|
|
356
|
-
c.funding
|
|
357
|
-
c.employeeCount
|
|
358
|
-
c.founded
|
|
359
|
-
c.hqLocation
|
|
488
|
+
factLine('Funding', c.funding, c.fundingGrounding, 80),
|
|
489
|
+
factLine('Employees', c.employeeCount, c.employeeCountGrounding, 40),
|
|
490
|
+
factLine('Founded', c.founded, c.foundedGrounding, 40),
|
|
491
|
+
factLine('HQ', c.hqLocation, c.hqLocationGrounding, 80),
|
|
360
492
|
].filter(Boolean);
|
|
361
493
|
const metaLine = meta.length ? `\n ${meta.join(' · ')}` : '';
|
|
362
|
-
|
|
494
|
+
// FUL-247: the analytical substance. Before this, an agent asked to position
|
|
495
|
+
// against a competitor got a name, a price and a blurb — the actual analysis
|
|
496
|
+
// reached only `_meta`. Joined and capped rather than bulleted per item: this
|
|
497
|
+
// is a paginated list of up to 100 rows, and a competitor with a dozen
|
|
498
|
+
// strengths must not turn one row into a page.
|
|
499
|
+
//
|
|
500
|
+
// ⚠️ SIZE, measured rather than estimated, because this is the biggest lever
|
|
501
|
+
// in the file: rendering the analysis roughly DOUBLED this tool's output —
|
|
502
|
+
// 8.4 KB → 17.2 KB at the default `limit=20`, 41 KB → 83 KB at `limit=100`,
|
|
503
|
+
// on rows with realistic 3-4 item lists. FUL-247 shipped that and wrote "if
|
|
504
|
+
// this ever has to shrink, cut here and re-measure; do not guess".
|
|
505
|
+
//
|
|
506
|
+
// FUL-252 is that cut. The three prose caps moved 240 → `LIST_PROSE_MAX`
|
|
507
|
+
// (120), which is a ~27% reduction on a saturated page — see that constant
|
|
508
|
+
// for the measurement table and why 120 rather than lower. What did NOT move:
|
|
509
|
+
// the default limit, the max limit, and every fact/grounding/caveat on the
|
|
510
|
+
// row. The numbers are now pinned as executable budgets in
|
|
511
|
+
// `collections.test.ts`, so the next person to touch a cap re-measures by
|
|
512
|
+
// running the suite instead of by trusting this paragraph.
|
|
513
|
+
//
|
|
514
|
+
// `collapseWhitespace` for the same forgery reason as the facts above: a
|
|
515
|
+
// strength containing a newline would end this line early and let the
|
|
516
|
+
// remainder pose as the row's own trailing ` id: <uuid>` line.
|
|
517
|
+
const strengthsText = collapseWhitespace(c.strengths.join('; '));
|
|
518
|
+
const weaknessesText = collapseWhitespace(c.weaknesses.join('; '));
|
|
519
|
+
const strengths = strengthsText
|
|
520
|
+
? `\n Strengths: ${clip(strengthsText)}`
|
|
521
|
+
: '';
|
|
522
|
+
const weaknesses = weaknessesText
|
|
523
|
+
? `\n Weaknesses: ${clip(weaknessesText)}`
|
|
524
|
+
: '';
|
|
525
|
+
// FUL-253: the one raw interpolation FUL-252 left on this row. An `id` is a
|
|
526
|
+
// uuid today, but "the endpoint only ever sends clean ids" is the assumption
|
|
527
|
+
// this guard exists to stop relying on — and this is the field an agent acts
|
|
528
|
+
// on. Guarded here so the row has no exceptions left to reason about.
|
|
529
|
+
return `${header}${desc}${url}${metaLine}${strengths}${weaknesses}\n id: ${safeInline(c.id, 60) ?? 'unknown'}`;
|
|
363
530
|
});
|
|
364
531
|
// The trust caveat is only worth its length when there is actually a company
|
|
365
532
|
// fact on this page to be careful about — a set with no M1b facts would just
|
|
@@ -368,11 +535,60 @@ export async function listCompetitors(input, deps) {
|
|
|
368
535
|
// above that decide whether each fact RENDERS. With `??`, a competitor whose
|
|
369
536
|
// funding is '' short-circuits on the empty string and the caveat disappears
|
|
370
537
|
// even though a later fact is populated and on screen.
|
|
371
|
-
|
|
538
|
+
// Asks the RENDERER, not the raw fields. The `||`-not-`??` note above is the
|
|
539
|
+
// first version of this trap; `collapseWhitespace` added a second (a
|
|
540
|
+
// whitespace-only `funding` is truthy but prints nothing). Routing the
|
|
541
|
+
// predicate through `factLine` itself makes the two impossible to disagree —
|
|
542
|
+
// whatever future guard `factLine` grows, the caveat follows it for free.
|
|
543
|
+
const hasCompanyFacts = competitors.some((c) => Boolean(factLine('Funding', c.funding, c.fundingGrounding, 80) ??
|
|
544
|
+
factLine('Employees', c.employeeCount, c.employeeCountGrounding, 40) ??
|
|
545
|
+
factLine('Founded', c.founded, c.foundedGrounding, 40) ??
|
|
546
|
+
factLine('HQ', c.hqLocation, c.hqLocationGrounding, 80)));
|
|
547
|
+
// FUL-247: the caveat now EXPLAINS THE BRACKET each fact carries, instead of
|
|
548
|
+
// pointing the reader at `<fact>Grounding.state` on a channel Claude Code
|
|
549
|
+
// drops. A caveat that names a field the reader cannot see is not a caveat.
|
|
372
550
|
const trustLine = hasCompanyFacts
|
|
373
|
-
? '
|
|
374
|
-
'
|
|
375
|
-
'
|
|
551
|
+
? ' Each company fact (funding/employees/founded/HQ) is followed by its own trust state ' +
|
|
552
|
+
'in brackets — read the bracket, not the number: only `[GROUNDED]` means a source was ' +
|
|
553
|
+
'checked. `[SPECULATION]` and `[NO_RECEIPT]` are the agent\'s inference, and ' +
|
|
554
|
+
'`[no grounding]` / `[state?]` mean no state was recorded — which is NOT the same as ' +
|
|
555
|
+
'checked-and-refuted. Cite only `[GROUNDED]` figures; state the rest as unverified.'
|
|
556
|
+
: '';
|
|
557
|
+
// Strengths/weaknesses have no per-fact grounding column at all, so they get
|
|
558
|
+
// their own sentence rather than riding on the bracket caveat above — an agent
|
|
559
|
+
// must not read "the facts are bracketed" as covering the analysis too.
|
|
560
|
+
// The predicate must agree with the RENDERER, not with the raw array — the
|
|
561
|
+
// same trap the `||`-vs-`??` note above records. `strengths: ['']` has
|
|
562
|
+
// `.length === 1` but collapses to '' and prints nothing, so a length test
|
|
563
|
+
// would attach "strengths and weaknesses carry NO grounding" to a page with
|
|
564
|
+
// no analysis on it. Test the rendered text.
|
|
565
|
+
const hasAnalysis = competitors.some((c) => collapseWhitespace(c.strengths.join('; ')).length > 0 ||
|
|
566
|
+
collapseWhitespace(c.weaknesses.join('; ')).length > 0);
|
|
567
|
+
const analysisLine = hasAnalysis
|
|
568
|
+
? ' Strengths and weaknesses carry NO grounding of any kind: they are the research ' +
|
|
569
|
+
'agent\'s reading of the competitor, not receipted claims. Attribute them, never cite them.'
|
|
570
|
+
: '';
|
|
571
|
+
// FUL-252: state the clip, and state ONLY the prose was clipped. `capNote`
|
|
572
|
+
// already refuses to drop rows silently; a clipped field is the same promise at
|
|
573
|
+
// a smaller scale. Naming exactly which fields were shortened is the load-bearing
|
|
574
|
+
// part — without it a reader has no way to know that the bracketed company facts
|
|
575
|
+
// beside them are complete, and a reader who suspects a `[GROUNDED]` might be a
|
|
576
|
+
// truncated `[GROUNDED-ish]` gets nothing from the trust surface at all.
|
|
577
|
+
//
|
|
578
|
+
// Set inside `clip`, so it can only be true when a `truncate` actually fired.
|
|
579
|
+
// A predicate re-derived here from the raw fields would be a second place to be
|
|
580
|
+
// wrong — the trap this file's `||`-vs-`??` and `hasAnalysis` notes both record.
|
|
581
|
+
// ⚠️ The claim is scoped to the STATES, not to the fact values, and that
|
|
582
|
+
// narrowing is a correction: `factLine` has always truncated a long fact value
|
|
583
|
+
// at its own 80/40/40/80 cap, so a blanket "the company facts are complete"
|
|
584
|
+
// was itself a false statement on the trust surface — the failure mode this
|
|
585
|
+
// whole ticket is about. What is guaranteed is the part an agent must key on:
|
|
586
|
+
// the bracket. A clipped value still carries its own visible `…`.
|
|
587
|
+
const clipNote = proseClipped
|
|
588
|
+
? ' Descriptions and strengths/weaknesses are CLIPPED here (trailing `…`) to keep this ' +
|
|
589
|
+
'list readable. The bracketed trust states above are never clipped — a fact value may ' +
|
|
590
|
+
'itself end in `…` when it is long, but its `[STATE]` is always complete and always ' +
|
|
591
|
+
'present. Read the full prose in `structuredContent.competitors`.'
|
|
376
592
|
: '';
|
|
377
593
|
text =
|
|
378
594
|
`Found ${total} competitor${total === 1 ? '' : 's'} in project ${projectId}:\n\n` +
|
|
@@ -381,7 +597,7 @@ export async function listCompetitors(input, deps) {
|
|
|
381
597
|
// channel (Claude Code drops it), so pointing an agent there ALONE
|
|
382
598
|
// describes data it cannot reach. Everything a caller must act on is
|
|
383
599
|
// already rendered above; these are the fuller records.
|
|
384
|
-
`Full records are in \`structuredContent.competitors\` (also mirrored in \`_meta.competitors\`).${trustLine}`;
|
|
600
|
+
`Full records are in \`structuredContent.competitors\` (also mirrored in \`_meta.competitors\`).${trustLine}${analysisLine}${clipNote}`;
|
|
385
601
|
}
|
|
386
602
|
return {
|
|
387
603
|
content: [{ type: 'text', text }],
|
|
@@ -407,19 +623,36 @@ export async function listCommunitySignals(input, deps) {
|
|
|
407
623
|
}
|
|
408
624
|
else {
|
|
409
625
|
const lines = signals.map((s, i) => {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
626
|
+
// FUL-253: every field on this row goes through `safeInline`, the same guard
|
|
627
|
+
// `list_competitors` above got in FUL-252. This renderer is the sharpest case
|
|
628
|
+
// in the package: `title`, `sentimentSummary` and above all `relevantQuotes[0]`
|
|
629
|
+
// are VERBATIM FORUM TEXT — third-party attacker-controlled by definition, and
|
|
630
|
+
// the exact input class FUL-247's original forgery finding used. `renderThreads`
|
|
631
|
+
// in `scoped-research.ts` renders the SAME rows from the SAME endpoint on the
|
|
632
|
+
// way in, and is guarded alongside this one — a fix to either belongs in both.
|
|
633
|
+
// Every line of this row shares
|
|
634
|
+
// the `\n ` indent, so one newline in a cached quote forges a sibling
|
|
635
|
+
// ` id: <uuid>` line, or an entire `2. **Thread**` row with an id an agent
|
|
636
|
+
// may then pass to another tool. `platform` and `url` were fully raw — not
|
|
637
|
+
// even truncated — so they could forge without needing to survive a clip.
|
|
638
|
+
const platformText = safeInline(s.platform, 40);
|
|
639
|
+
const platform = platformText ? ` [${platformText}]` : '';
|
|
640
|
+
const header = `${offset + i + 1}. **${safeInline(s.title, 160) ?? 'Untitled thread'}**${platform}`;
|
|
641
|
+
const sentimentText = safeInline(s.sentimentSummary, 240);
|
|
642
|
+
const sentiment = sentimentText ? `\n ${sentimentText}` : '';
|
|
643
|
+
const urlText = safeInline(s.url, 200);
|
|
644
|
+
const url = urlText ? `\n ${urlText}` : '';
|
|
645
|
+
// Branch on the rendered value, not on `.length`: a quote of '' or ' '
|
|
646
|
+
// collapses to nothing, and `""` on its own line reads as "this thread was
|
|
647
|
+
// quoted and the quote was empty" rather than "no quote was cached".
|
|
648
|
+
const quoteText = safeInline(s.relevantQuotes[0], 200);
|
|
649
|
+
const quote = quoteText ? `\n "${quoteText}"` : '';
|
|
417
650
|
const engagement = [
|
|
418
651
|
s.upvotes !== null && `${s.upvotes} upvotes`,
|
|
419
652
|
s.commentCount !== null && `${s.commentCount} comments`,
|
|
420
653
|
].filter(Boolean);
|
|
421
654
|
const engagementLine = engagement.length ? `\n ${engagement.join(' · ')}` : '';
|
|
422
|
-
return `${header}${sentiment}${url}${quote}${engagementLine}\n id: ${s.id ?? 'unknown'}`;
|
|
655
|
+
return `${header}${sentiment}${url}${quote}${engagementLine}\n id: ${safeInline(s.id, 60) ?? 'unknown'}`;
|
|
423
656
|
});
|
|
424
657
|
text =
|
|
425
658
|
`Found ${total} community signal${total === 1 ? '' : 's'} in project ${projectId}:\n\n` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/tools/collections.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/tools/collections.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/interview.js
CHANGED
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
import { z } from 'zod';
|
|
41
41
|
import { ToolError } from './errors.js';
|
|
42
42
|
import { deprecatedAlias } from './param-aliases.js';
|
|
43
|
-
import { apiCall, categorizeFetchError,
|
|
43
|
+
import { apiCall, categorizeFetchError, } from './research.js';
|
|
44
|
+
import { safeInline, truncate } from './render-safety.js';
|
|
44
45
|
const INTERVIEW_FETCH_TIMEOUT_MS = 60_000;
|
|
45
46
|
/** Upper bound on a turn's question — matches the server's `MESSAGE_CONTENT_MAX`. */
|
|
46
47
|
const CONTENT_MAX = 10_000;
|
|
@@ -163,8 +164,14 @@ function formatTranscript(interview) {
|
|
|
163
164
|
const speaker = m.role === 'assistant' ? 'Persona' : 'Interviewer';
|
|
164
165
|
return `${speaker}: ${m.content ?? ''}`;
|
|
165
166
|
});
|
|
167
|
+
// FUL-247: the `Persona:` speaker label names a ROLE, not a record — an agent
|
|
168
|
+
// reading a transcript could see who was speaking in prose but had no way to
|
|
169
|
+
// follow through to `get_persona` and read who that actually is. This is the
|
|
170
|
+
// surface where knowing which persona is speaking matters most, and
|
|
171
|
+
// `list_interviews` already renders the id, so its absence here was pure skew.
|
|
172
|
+
const persona = interview.personaId ? `\npersona_id: ${interview.personaId}` : '';
|
|
166
173
|
const header = `Interview ${interview.id ?? '?'} — status: ${interview.status ?? 'unknown'}, ` +
|
|
167
|
-
`${messages.length} message${messages.length === 1 ? '' : 's'}
|
|
174
|
+
`${messages.length} message${messages.length === 1 ? '' : 's'}.${persona}`;
|
|
168
175
|
return lines.length > 0 ? `${header}\n\n${lines.join('\n\n')}` : header;
|
|
169
176
|
}
|
|
170
177
|
async function startInterview(input, ctx, deps) {
|
|
@@ -435,14 +442,47 @@ export async function listInterviews(input, deps) {
|
|
|
435
442
|
// the gap.
|
|
436
443
|
const count = iv.messageCount;
|
|
437
444
|
const messages = count === null ? 'message count unknown' : `${count} message${count === 1 ? '' : 's'}`;
|
|
438
|
-
|
|
439
|
-
|
|
445
|
+
// FUL-253: ids and a status only, so this is the mildest case in the class —
|
|
446
|
+
// but it is a `- ` row whose whole purpose is to hand an agent an `id` for
|
|
447
|
+
// `get_interview`, and "the endpoint only ever sends clean uuids" is exactly
|
|
448
|
+
// the assumption this guard exists so nothing has to rely on.
|
|
449
|
+
const personaId = iv.personaId ? (safeInline(iv.personaId, 60) ?? 'unknown') : null;
|
|
450
|
+
const persona = personaId ? ` with persona ${personaId}` : '';
|
|
451
|
+
const status = safeInline(iv.status, 40) ?? 'unknown';
|
|
452
|
+
// This list is ordered by `started_at DESC` (`interviews-api.ts`:
|
|
453
|
+
// `LIST_ORDER_COLUMN`), and until now it printed no date at all — so the
|
|
454
|
+
// SORT KEY ITSELF was the one thing an agent could not see. Two rows for
|
|
455
|
+
// the same persona in the same status read identically here while being
|
|
456
|
+
// months apart, and an agent resuming work could not tell today's run from
|
|
457
|
+
// last month's. Same argument FUL-247 accepted for `ReportSummary.createdAt`
|
|
458
|
+
// and FUL-252 for `Project.createdAt`; this row is the same shape.
|
|
459
|
+
//
|
|
460
|
+
// `safeInline`, not raw, like every other interpolated field on this row:
|
|
461
|
+
// a newline in a timestamp would end the row early and let the remainder
|
|
462
|
+
// pose as a sibling `- ` entry (FUL-253). Placed immediately before the
|
|
463
|
+
// `(id: …)` tail so the assertion on it can be anchored ROW-LOCALLY —
|
|
464
|
+
// whole-text search cannot tell which of 20 rows a date landed on.
|
|
465
|
+
//
|
|
466
|
+
// ⚠️ The `(id: …)` tail must stay LAST: `interview.test.ts` asserts a row
|
|
467
|
+
// terminates on the real id, which is what stops a forged id being lifted
|
|
468
|
+
// off the end of a row.
|
|
469
|
+
const startedAt = safeInline(iv.startedAt, 40);
|
|
470
|
+
const started = startedAt ? ` — started ${startedAt}` : '';
|
|
471
|
+
return `- ${status} interview${persona} — ${messages}${started} (id: ${safeInline(iv.id, 60) ?? 'unknown'})`;
|
|
440
472
|
});
|
|
441
473
|
const shown = offset + interviews.length;
|
|
442
474
|
const more = shown < total ? `\n\n${total - shown} more not shown — page with offset=${shown}.` : '';
|
|
475
|
+
// "Newest started first", NOT a generic "newest first". The app's five
|
|
476
|
+
// collection endpoints do NOT share a sort key, and `get_project` already
|
|
477
|
+
// carries this exact phrase for interviews for that reason — see the ORDERING
|
|
478
|
+
// warning in `projects.ts`, where a copied ordering claim (U7) once told
|
|
479
|
+
// agents the wrong thing. Verified against `interviews-api.ts`:
|
|
480
|
+
// `LIST_ORDER_COLUMN = 'started_at'`, `LIST_ORDER_ASCENDING = false`. Stated
|
|
481
|
+
// only now that the rows print `started` dates, so the claim is CHECKABLE by
|
|
482
|
+
// the reader against the list rather than being taken on trust.
|
|
443
483
|
text =
|
|
444
484
|
`Found ${total} interview${total === 1 ? '' : 's'} in project ${projectId}:\n${lines.join('\n')}${more}\n\n` +
|
|
445
|
-
'Use get_interview with an id to re-read a full transcript.';
|
|
485
|
+
'Newest started first. Use get_interview with an id to re-read a full transcript.';
|
|
446
486
|
}
|
|
447
487
|
return {
|
|
448
488
|
content: [{ type: 'text', text }],
|