@productbrain/mcp 0.0.1-beta.8928 → 0.0.1-beta.8937

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.
@@ -1277,31 +1277,16 @@ function formatRubricVerdictSection(verdict) {
1277
1277
 
1278
1278
  // src/lib/captureSinglePreviewOutput.ts
1279
1279
  import { z as z3 } from "zod/v3";
1280
- var groundingRelatedEntrySchema = z3.object({
1281
- entryId: z3.string(),
1282
- name: z3.string(),
1283
- collectionSlug: z3.string(),
1284
- overlapRatio: z3.number(),
1285
- reasoning: z3.string()
1286
- });
1287
1280
  var groundingDuplicateEntrySchema = z3.object({
1288
1281
  entryId: z3.string(),
1289
1282
  name: z3.string(),
1290
1283
  collectionSlug: z3.string(),
1291
- matchType: z3.enum(["related", "possible_duplicate"]),
1292
1284
  overlapRatio: z3.number()
1293
1285
  });
1294
- var groundingGovernanceEntrySchema = z3.object({
1295
- entryId: z3.string(),
1296
- name: z3.string(),
1297
- collectionSlug: z3.string()
1298
- });
1299
1286
  var groundingReportSchema = z3.object({
1300
1287
  // TASK-156: null preserves uncertainty for unavailable checks or an older server response.
1301
1288
  scanTruncated: z3.boolean().nullable(),
1302
- related: z3.array(groundingRelatedEntrySchema),
1303
- duplicates: z3.array(groundingDuplicateEntrySchema),
1304
- governance: z3.array(groundingGovernanceEntrySchema)
1289
+ duplicates: z3.array(groundingDuplicateEntrySchema)
1305
1290
  });
1306
1291
  var taskAlignmentSchema = z3.record(z3.unknown());
1307
1292
  var captureSinglePreviewOutputSchema = z3.object({
@@ -1385,10 +1370,6 @@ var captureSchema = z4.object({
1385
1370
  sourceExcerpt: z4.string().optional().describe("Verbatim excerpt from the source that backs this entry's claims. Stored as top-level entry field, not in data."),
1386
1371
  // WP-316 S3: Preview gate — dry-run mode. Returns what would happen, no DB writes.
1387
1372
  preview: z4.boolean().optional().describe("If true, validates the capture without writing. Returns what would happen. Default false."),
1388
- // WP-318 S2: Pre-write grounding — run link suggestion before creating entry.
1389
- suggestOnly: z4.boolean().optional().describe("If true, runs pre-write grounding (chain.capture) and returns a groundingReport WITHOUT creating any entry. Use to preview graph participation before accepting. Default false."),
1390
- // WP-318 S2: Format for groundingReport in response.
1391
- format: z4.enum(["agent", "human"]).optional().describe("Response format for grounding data. 'agent' (default): full JSON groundingReport. 'human': compressed summary string appended to the capture summary."),
1392
1373
  // WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b (DEC-1715):
1393
1374
  // ownerTeamEntryId is deleted — the server takes the team you hold the role in (root first, else the shallowest),
1394
1375
  // and an unnamed create resolves a default owner itself instead of landing ownerless.
@@ -1683,6 +1664,7 @@ var captureOutputSchema = z4.union([
1683
1664
  captureClassifierOnlyOutputSchema
1684
1665
  ]);
1685
1666
  var CAPTURE_ACTIONS = ["capture"];
1667
+ var SUGGEST_ONLY_REMOVED = "suggestOnly was removed: call capture with preview: true to check a capture without writing.";
1686
1668
  var captureCompoundSchema = z4.object({
1687
1669
  action: z4.enum(CAPTURE_ACTIONS).optional().default("capture").describe("Create a single knowledge entry."),
1688
1670
  collection: z4.string().max(200).optional().describe("Collection slug, e.g. 'tensions', 'business-rules', 'glossary', 'decisions'. Optional \u2014 classifier auto-routes when omitted."),
@@ -1700,8 +1682,8 @@ var captureCompoundSchema = z4.object({
1700
1682
  sourceRef: z4.string().max(2e3).optional().describe("URI or path of the source document backing this entry."),
1701
1683
  sourceExcerpt: z4.string().max(SOURCE_EXCERPT_MAX_CHARS).optional().describe("Verbatim excerpt from the source backing this entry's claims."),
1702
1684
  preview: z4.boolean().optional().describe("If true, validates without writing."),
1703
- suggestOnly: z4.boolean().optional().describe("If true, runs pre-write grounding and returns a groundingReport WITHOUT creating any entry."),
1704
- format: z4.enum(["agent", "human"]).optional().describe("Response format for grounding data."),
1685
+ suggestOnly: z4.never({ invalid_type_error: SUGGEST_ONLY_REMOVED }).optional().describe(SUGGEST_ONLY_REMOVED),
1686
+ // TASK-608: refused, never stripped into a write.
1705
1687
  // WP-513: explicit role to create AS OWNER of (rung 2 only). WP-753 O1b: ownerTeamEntryId
1706
1688
  // deleted — team is the one you hold the role in (root first, else the shallowest).
1707
1689
  ownerRoleEntryId: z4.string().max(200).optional().describe("Owning role (rung-2); you must hold it; its team is the one you hold it in (root first, else the shallowest).")
@@ -1712,7 +1694,7 @@ var captureActionUnion = z4.discriminatedUnion("action", [
1712
1694
  ]);
1713
1695
  var CAPTURE_ACTION_SPECS = {
1714
1696
  capture: {
1715
- params: ["collection", "name", "description", "context", "entryId", "canonicalKey", "data", "why", "links", "sourceRef", "sourceExcerpt", "preview", "suggestOnly", "format"],
1697
+ params: ["collection", "name", "description", "context", "entryId", "canonicalKey", "data", "why", "links", "sourceRef", "sourceExcerpt", "preview"],
1716
1698
  description: "name and description are required."
1717
1699
  }
1718
1700
  };
@@ -1746,7 +1728,7 @@ All other collections get an ENT-{random} ID and sensible defaults.
1746
1728
  })
1747
1729
  );
1748
1730
  }
1749
- async function handleCapture(server, { collection, name, description, context, entryId, canonicalKey, data: userData, why, links, sourceRef, sourceExcerpt, preview, suggestOnly, format, ownerRoleEntryId }) {
1731
+ async function handleCapture(server, { collection, name, description, context, entryId, canonicalKey, data: userData, why, links, sourceRef, sourceExcerpt, preview, ownerRoleEntryId }) {
1750
1732
  requireWriteAccess();
1751
1733
  const timingStart = Date.now();
1752
1734
  const wsCtx = await getWorkspaceContext();
@@ -1824,73 +1806,12 @@ async function handleCapture(server, { collection, name, description, context, e
1824
1806
  const groundingRaw = await Promise.race([groundingPromise, new Promise((r) => setTimeout(() => r(null), 500))]);
1825
1807
  const groundingElapsedMs = Date.now() - groundingStart;
1826
1808
  const groundingEntry = groundingRaw ?? null;
1827
- const groundingRelated = groundingEntry?.kind === "create_and_link" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, overlapRatio: c.score, reasoning: `${Math.round(c.score * 100)}% match` })) : [];
1828
- const groundingDuplicates = groundingEntry?.kind === "ask" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, matchType: "related", overlapRatio: c.score })) : groundingEntry?.kind === "version" ? [{ entryId: groundingEntry.entryId, name: groundingEntry.name, collectionSlug: groundingEntry.collectionSlug, matchType: "possible_duplicate", overlapRatio: groundingEntry.score }] : [];
1829
- const groundingGovernance = [];
1830
1809
  const groundingReport = {
1831
1810
  // null preserves uncertainty for unavailable checks or an older server response.
1832
1811
  scanTruncated: typeof groundingEntry?.scanTruncated === "boolean" ? groundingEntry.scanTruncated : null,
1833
- related: groundingRelated.map((r) => ({
1834
- entryId: r.entryId,
1835
- name: r.name,
1836
- collectionSlug: r.collectionSlug,
1837
- overlapRatio: r.overlapRatio,
1838
- reasoning: r.reasoning
1839
- })),
1840
- duplicates: groundingDuplicates.map((d) => ({
1841
- entryId: d.entryId,
1842
- name: d.name,
1843
- collectionSlug: d.collectionSlug,
1844
- matchType: d.matchType,
1845
- overlapRatio: d.overlapRatio
1846
- })),
1847
- governance: groundingGovernance
1812
+ duplicates: groundingEntry?.kind === "ask" ? groundingEntry.candidates.map((c) => ({ entryId: c.entryId, name: c.name, collectionSlug: c.collectionSlug, overlapRatio: c.score })) : []
1848
1813
  };
1849
1814
  const groundingCaveat = !groundingEntry ? "Grounding could not be completed; duplicate presence is unknown. Review existing entries before creating another." : groundingReport.scanTruncated !== false ? "Grounding covered a bounded sample; completeness is unverified and additional matching entries may exist. Review existing entries before creating another." : "";
1850
- if (suggestOnly) {
1851
- const hasSuggestions = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0;
1852
- const summaryText = hasSuggestions ? `Grounding preview for "${name}": ${groundingReport.related.length} related, ${groundingReport.duplicates.length} possible duplicates. No entry created.` : groundingEntry ? `Grounding preview for "${name}": no similar entries found in this check. No entry created.` : `Grounding preview for "${name}": duplicate check unavailable. No entry created.`;
1853
- return {
1854
- content: [{
1855
- type: "text",
1856
- text: `# Grounding Preview \u2014 No Entry Created
1857
-
1858
- ${summaryText}
1859
-
1860
- ` + (groundingCaveat ? `${groundingCaveat}
1861
-
1862
- ` : "") + (groundingReport.related.length > 0 ? `## Related entries
1863
- ${groundingReport.related.map((r) => `- **${r.entryId}** ${r.name} [${r.collectionSlug}] \u2014 ${r.reasoning}`).join("\n")}
1864
-
1865
- ` : "") + (groundingReport.duplicates.length > 0 ? `## Possible duplicates
1866
- ${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.collectionSlug}] (${d.matchType}, overlap: ${d.overlapRatio})`).join("\n")}
1867
-
1868
- ` : "") + // "## Governance entries to review" ternary removed (item 5d, dead — see line ~1051).
1869
- `_Call \`capture\` without \`suggestOnly\` to proceed with entry creation._`
1870
- }],
1871
- structuredContent: {
1872
- ...success(
1873
- summaryText,
1874
- { groundingReport, outcome: "suggest_only" },
1875
- // Fix 3 sibling (TEN-2918 follow-up): thread the caller's full original payload —
1876
- // see lib/captureForRealAction.ts's doc comment.
1877
- buildCaptureForRealNextAction({
1878
- collection: resolvedCollection,
1879
- name,
1880
- description,
1881
- context,
1882
- entryId,
1883
- canonicalKey,
1884
- data: userData,
1885
- links,
1886
- sourceRef,
1887
- sourceExcerpt,
1888
- ownerRoleEntryId
1889
- })
1890
- )
1891
- }
1892
- };
1893
- }
1894
1815
  if (groundingEntry?.kind === "version") return captureVersionOrPreview(preview ?? false, { groundingEntry, name, description, data: userData, sourceRef, sourceExcerpt, links, groundingElapsedMs });
1895
1816
  const built = buildDataFromFieldsOrRefuse(col.fields ?? [], profile.descriptionField, description, resolvedCollection);
1896
1817
  if ("refusal" in built) return built.refusal;
@@ -1989,13 +1910,10 @@ ${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.colle
1989
1910
  });
1990
1911
  if (result2 && isPreviewCreateEntryResult(result2)) {
1991
1912
  const preflight = await resolvePreviewPreflight(result2, links);
1992
- const hasGrounding = groundingReport.related.length > 0 || groundingReport.duplicates.length > 0;
1993
- const groundingSummary = hasGrounding ? `
1913
+ const dupCount = groundingReport.duplicates.length;
1914
+ const groundingSummary = dupCount > 0 ? `
1994
1915
 
1995
- **Grounding:** ${[
1996
- groundingReport.duplicates.length > 0 && `${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? "s" : ""}`,
1997
- groundingReport.related.length > 0 && `${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? "ies" : "y"}`
1998
- ].filter(Boolean).join(", ")}.` : "";
1916
+ **Possible duplicates:** ${dupCount}.` : "";
1999
1917
  const wouldBlock = result2.wouldBlock === true;
2000
1918
  const headline = wouldBlock ? `Preview: would be BLOCKED \u2014 "${name}" [${resolvedCollection}]` : `Preview: would capture "${name}" [${resolvedCollection}]`;
2001
1919
  const previewEnvelope = success(
@@ -2092,11 +2010,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
2092
2010
  void kernelMutation("chain.recordGroundingOutcome", {
2093
2011
  surface: "mcp",
2094
2012
  promptShown: groundingEntry?.kind === "ask",
2095
- highestRatio: Math.max(
2096
- ...groundingReport.duplicates.map((d) => d.overlapRatio),
2097
- ...groundingReport.related.map((r) => r.overlapRatio),
2098
- 0
2099
- ),
2013
+ highestRatio: Math.max(...groundingReport.duplicates.map((d) => d.overlapRatio), 0),
2100
2014
  hadGovernance: false,
2101
2015
  grounding_ms: groundingElapsedMs
2102
2016
  }).catch(() => void 0);
@@ -2267,17 +2181,6 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
2267
2181
  lines.push(`Next: \`entries action=commit entryId="${finalEntryId}"\`.`);
2268
2182
  }
2269
2183
  if (groundingCaveat) lines.push("", groundingCaveat);
2270
- if (format === "human") {
2271
- const hasDuplicates = groundingReport.duplicates.length > 0;
2272
- const hasRelated = groundingReport.related.length > 0;
2273
- if (hasDuplicates || hasRelated) {
2274
- lines.push("");
2275
- const parts = [];
2276
- if (hasDuplicates) parts.push(`${groundingReport.duplicates.length} possible duplicate${groundingReport.duplicates.length > 1 ? "s" : ""}`);
2277
- if (hasRelated) parts.push(`${groundingReport.related.length} related entr${groundingReport.related.length > 1 ? "ies" : "y"}`);
2278
- lines.push(`_Grounding: ${parts.join(", ")}. Review and link if relevant._`);
2279
- }
2280
- }
2281
2184
  if (formativeHints.length > 0) {
2282
2185
  lines.push("");
2283
2186
  lines.push("## Quality Hints (advisory)");
@@ -2416,7 +2319,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
2416
2319
  qualityHints: formativeHints,
2417
2320
  // WP-745 TASK-160 (PR #901 review): the machine-readable projection — was reaching the human text only.
2418
2321
  ...spineFloor && { spineFloor },
2419
- // WP-318 S2: Pre-write grounding report — always included (empty arrays when no suggestions)
2322
+ // WP-318 S2: the possible-duplicate report — always included (empty when no ask match)
2420
2323
  groundingReport
2421
2324
  },
2422
2325
  next
@@ -13681,4 +13584,4 @@ export {
13681
13584
  createProductBrainServer,
13682
13585
  initFeatureFlags
13683
13586
  };
13684
- //# sourceMappingURL=chunk-PYA7M43F.js.map
13587
+ //# sourceMappingURL=chunk-C6EYMV77.js.map