@productbrain/mcp 0.0.1-beta.77 → 0.0.1-beta.78

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.
@@ -5074,64 +5074,6 @@ function parseListOutput(output) {
5074
5074
 
5075
5075
  // src/tools/facilitate.ts
5076
5076
  import { z as z12 } from "zod";
5077
-
5078
- // src/tools/facilitate-validation.ts
5079
- function computeCommitBlockers(opts) {
5080
- const { betEntryId, betDocId, relations, hasStrategyLink, betData, sessionDrafts } = opts;
5081
- const blockers = [];
5082
- const links = betData.links ?? {};
5083
- const str = (key) => (links[key] ?? "").trim();
5084
- if (!hasStrategyLink) {
5085
- blockers.push({
5086
- entryId: betEntryId,
5087
- blocker: "Missing strategy link",
5088
- fix: `relations action=create from=${betEntryId} to=<strategy> type=related_to`
5089
- });
5090
- }
5091
- const MIN_FIELD_LENGTH = 20;
5092
- if (str("problem").length < MIN_FIELD_LENGTH) {
5093
- blockers.push({
5094
- entryId: betEntryId,
5095
- blocker: str("problem") ? "Problem statement too short (< 20 chars)" : "Missing problem statement",
5096
- fix: `update-entry entryId="${betEntryId}" data.problem="<problem description>"`
5097
- });
5098
- }
5099
- if (!str("appetite")) {
5100
- blockers.push({
5101
- entryId: betEntryId,
5102
- blocker: "Missing appetite",
5103
- fix: `update-entry entryId="${betEntryId}" data.appetite="<appetite declaration>"`
5104
- });
5105
- }
5106
- if (str("elements").length < MIN_FIELD_LENGTH) {
5107
- blockers.push({
5108
- entryId: betEntryId,
5109
- blocker: str("elements") ? "Solution elements too short (< 20 chars)" : "Missing solution elements",
5110
- fix: `update-entry entryId="${betEntryId}" data.links.elements="<solution elements>"`
5111
- });
5112
- }
5113
- const hasFeatures = sessionDrafts.some((d) => d.collection === "features");
5114
- if (!hasFeatures && str("elements").length >= MIN_FIELD_LENGTH) {
5115
- blockers.push({
5116
- entryId: betEntryId,
5117
- blocker: "Elements described but no feature entries linked in constellation",
5118
- fix: `capture name="<element name>" description="<description>" then relations action=create from=${betEntryId} to=<entryId> type=part_of`
5119
- });
5120
- }
5121
- for (const draft of sessionDrafts) {
5122
- if (!draft.name || draft.name.trim().length === 0) {
5123
- const draftRef = draft.entryId && draft.entryId.trim().length > 0 ? draft.entryId : "<draftId>";
5124
- blockers.push({
5125
- entryId: betEntryId,
5126
- blocker: `Draft constellation entry is missing a name`,
5127
- fix: `update-entry entryId="${draftRef}" name="<name>"`
5128
- });
5129
- }
5130
- }
5131
- return blockers;
5132
- }
5133
-
5134
- // src/tools/facilitate.ts
5135
5077
  var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
5136
5078
  var facilitateSchema = z12.object({
5137
5079
  action: z12.enum(FACILITATE_ACTIONS).describe(
@@ -5140,21 +5082,6 @@ var facilitateSchema = z12.object({
5140
5082
  betEntryId: z12.string().optional().describe("Bet entry ID. Required for both actions."),
5141
5083
  operationId: z12.string().optional().describe("Optional idempotency key for commit-constellation retries.")
5142
5084
  });
5143
- async function hasStrategyLinkForEntry(entryDocId, relations) {
5144
- const relatedDocIds = /* @__PURE__ */ new Set();
5145
- for (const rel of relations) {
5146
- if (rel.fromId === entryDocId && rel.toId) relatedDocIds.add(rel.toId);
5147
- if (rel.toId === entryDocId && rel.fromId) relatedDocIds.add(rel.fromId);
5148
- }
5149
- for (const docId of relatedDocIds) {
5150
- try {
5151
- const related = await mcpQuery("chain.getEntry", { id: docId });
5152
- if (related?.collectionSlug === "strategy") return true;
5153
- } catch {
5154
- }
5155
- }
5156
- return false;
5157
- }
5158
5085
  function buildStudioUrl(workspaceSlug, entryId) {
5159
5086
  const appUrl = process.env.PRODUCTBRAIN_APP_URL ?? "https://productbrain.io";
5160
5087
  return `${appUrl}/${workspaceSlug}/studio/entries/${entryId}`;
@@ -5334,19 +5261,7 @@ async function handleCommitConstellation(args) {
5334
5261
  }
5335
5262
  const betData = betEntry.data ?? {};
5336
5263
  const operationId = args.operationId ?? `${betId}:${getAgentSessionId() ?? "sessionless"}:${betEntry.status}:${betEntry.currentVersion ?? 0}`;
5337
- const relations = await mcpQuery("chain.listEntryRelations", {
5338
- entryId: betId
5339
- });
5340
- const hasStrategyLink = await hasStrategyLinkForEntry(betEntry._id, relations);
5341
- const sessionDrafts = await loadSessionDrafts(betId, betEntry._id);
5342
- const commitBlockerItems = computeCommitBlockers({
5343
- betEntryId: betId,
5344
- betDocId: betEntry._id,
5345
- relations,
5346
- hasStrategyLink,
5347
- betData,
5348
- sessionDrafts
5349
- });
5264
+ const { blockers: commitBlockerItems, totalRelations } = await mcpQuery("chain.validateCommitConstellation", { betEntryId: betId });
5350
5265
  if (commitBlockerItems.length > 0) {
5351
5266
  return {
5352
5267
  content: [{
@@ -5369,7 +5284,7 @@ async function handleCommitConstellation(args) {
5369
5284
  operationId,
5370
5285
  blockers: commitBlockerItems,
5371
5286
  committedIds: [],
5372
- totalRelations: relations.length
5287
+ totalRelations
5373
5288
  }
5374
5289
  )
5375
5290
  };
@@ -9580,7 +9495,7 @@ Browse: \`entries action=list collection=tracking-events\`.`
9580
9495
  "## Knowledge Graph\nEntries are connected via typed relations (`entryRelations` table). Relations are bidirectional and collection-agnostic \u2014 any entry can link to any other entry.\n\n**Recommended relation types** (extensible \u2014 any string accepted):\n- `governs` \u2014 a rule constrains behavior of a feature\n- `defines_term_for` \u2014 a glossary term is canonical vocabulary for a feature/area\n- `belongs_to` \u2014 a feature belongs to a product area or parent concept\n- `informs` \u2014 a decision or insight informs a feature\n- `fills_slot` \u2014 an ingredient entry fills a slot in a map\n- `surfaces_tension_in` \u2014 a tension exists within a feature area\n- `related_to`, `depends_on`, `replaces`, `conflicts_with`, `references`, `confused_with`\n\nEach relation type is defined as a glossary entry (prefix `GT-REL-*`) to prevent terminology drift.\n\n**Tools:**\n- `context action=gather` \u2014 get the full context around any entry (multi-hop graph traversal)\n- `graph action=suggest` \u2014 discover potential connections for an entry\n- `relations action=create` \u2014 create a typed link between two entries\n- `graph action=find` \u2014 list direct relations for an entry\n\n**Convention:** When creating or updating entries in governed collections, always use `graph action=suggest` to discover and create relevant relations."
9581
9496
  );
9582
9497
  sections.push(
9583
- "## Creating Knowledge\n**Entries:** Use `capture` as the primary tool for creating new entries. It handles the full workflow in one call:\n1. Creates the entry with collection-aware defaults (auto-fills dates, infers domains, sets priority)\n2. Auto-links related entries from across the chain (up to 5 confident matches)\n3. Returns a quality scorecard (X/10) with actionable improvement suggestions\n\n**Smart profiles** exist for: `tensions`, `business-rules`, `glossary`, `decisions`, `features`, `audiences`, `strategy`, `standards`, `maps`, `chains`, `tracking-events`.\nAll other collections use the `ENT-{random}` fallback profile.\n\n**Processes:** Use `chain action=create` with a template (e.g., `strategy-coherence`, `idm-proposal`). Fill links with `chain action=edit`.\n\n**Maps:** Use `map action=create` with a template (e.g., `lean-canvas`). Fill slots with `map-slot action=add`. Commit with `map-version action=commit`.\nNote: committing a map version creates a snapshot but does NOT change the entry status. To activate: `update-entry entryId=MAP-xxx status=active autoPublish=true`.\nUse `map-suggest` to discover ingredients for empty slots.\n\n**Prompts** (invoke via MCP prompt protocol):\n- `name-check` \u2014 verify a name against glossary conventions\n- `draft-decision-record` \u2014 scaffold a decision entry\n- `review-against-rules` \u2014 check work against business rules for a domain\n- `draft-rule-from-context` \u2014 create a new business rule from context\n- `run-workflow` \u2014 run a structured ceremony (e.g., retrospective)\n\nUse `quality action=check` to score existing entries retroactively.\nUse `update-entry` for post-creation adjustments (status changes, field updates, deprecation)."
9498
+ "## Creating Knowledge\n**Entries:** Use `capture` as the primary tool for creating new entries. It handles the full workflow in one call:\n1. Creates the entry with collection-aware defaults (auto-fills dates, infers domains, sets priority)\n2. Auto-links related entries from across the chain (up to 5 confident matches)\n3. Returns a quality scorecard (X/10) with actionable improvement suggestions\n\n**Smart profiles** exist for: `tensions`, `business-rules`, `glossary`, `decisions`, `features`, `audiences`, `strategy`, `standards`, `maps`, `chains`, `tracking-events`.\nAll other collections use the `ENT-{random}` fallback profile.\n\n**Processes:** Use `chain action=create` with a template (e.g., `strategy-coherence`, `idm-proposal`). Fill links with `chain action=edit`.\n\n**Maps:** Use `map action=create` with a template (e.g., `lean-canvas`). Fill slots with `map-slot action=add`. Commit with `map-version action=commit`.\nNote: committing a map version creates a snapshot but does NOT change the entry status. To activate: `update-entry entryId=MAP-xxx status=active autoPublish=true`.\nUse `map-suggest` to discover ingredients for empty slots.\n\n**Prompts** (invoke via MCP prompt protocol):\n- `name-check` \u2014 verify a name against glossary conventions\n- `draft-decision-record` \u2014 scaffold a decision entry\n- `review-against-rules` \u2014 check work against business rules for a domain\n- `draft-rule-from-context` \u2014 create a new business rule from context\n\nUse `quality action=check` to score existing entries retroactively.\nUse `update-entry` for post-creation adjustments (status changes, field updates, deprecation)."
9584
9499
  );
9585
9500
  sections.push(
9586
9501
  "## Where to Go Next\n- **Create entry** \u2192 `capture` tool (auto-links + quality score in one call)\n- **Full context** \u2192 `context action=gather` (by entry ID or task description)\n- **Discover links** \u2192 `graph action=suggest`\n- **Quality audit** \u2192 `quality action=check`\n- **Terminology** \u2192 `name-check` prompt or `productbrain://terminology` resource\n- **Schema details** \u2192 `productbrain://collections` resource or `collections action=list`\n- **Labels** \u2192 `productbrain://labels` resource or `labels` tool\n- **Any collection** \u2192 `productbrain://{slug}/entries` resource\n- **Log a decision** \u2192 `draft-decision-record` prompt\n- **Build a map** \u2192 `map action=create` + `map-slot action=add` + `map-version action=commit`\n- **Architecture map** \u2192 `architecture action=show` tool (layered system visualization)\n- **Explore a layer** \u2192 `architecture action=explore` tool (drill into Auth, Core, Features, etc.)\n- **Growth funnel** \u2192 `productbrain://growth-funnel` resource or `entries action=list collection=strategy status=draft`\n- **Audiences** \u2192 `productbrain://audiences/entries` resource or `entries action=list collection=audiences`\n- **Session identity** \u2192 `health action=whoami`\n- **Health check** \u2192 `health action=check`\n- **Debug MCP calls** \u2192 `health action=audit`"
@@ -10962,4 +10877,4 @@ export {
10962
10877
  SERVER_VERSION,
10963
10878
  createProductBrainServer
10964
10879
  };
10965
- //# sourceMappingURL=chunk-YIVFK6VL.js.map
10880
+ //# sourceMappingURL=chunk-2TAMQOP7.js.map