@productbrain/mcp 0.0.1-beta.8633 → 0.0.1-beta.8643

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.
@@ -38,7 +38,7 @@ import {
38
38
  trackQualityVerdict,
39
39
  trackSessionCaptureRate,
40
40
  trackZeroCaptureAuditFired
41
- } from "./chunk-66OMK2AA.js";
41
+ } from "./chunk-FZWP45AU.js";
42
42
 
43
43
  // src/server.ts
44
44
  import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -7613,6 +7613,65 @@ function formatRuleListsLines(ruleLists) {
7613
7613
  if (lines.length === 0 && ruleLists.unassigned === 0 && !ruleLists.truncated) return [];
7614
7614
  return [...lines, ...formatRuleListTrailers(ruleLists)];
7615
7615
  }
7616
+ var BRIEFING_PULL_COMMANDS = {
7617
+ cli: 'pb orient --task "<what you are doing>" \xB7 pb get <ID> \xB7 pb search <query>',
7618
+ mcp: 'orient task="<what you are doing>" \xB7 entries action=get entryId=<ID> \xB7 entries action=search query=<query>'
7619
+ };
7620
+ var BRIEFING_ANSWER_COMMANDS = {
7621
+ cli: 'pb question answer <ID> "<answer>"',
7622
+ mcp: 'question action=answer entryId=<ID> text="<answer>"'
7623
+ };
7624
+ var BRIEFING_QUESTION_DETAIL_COMMANDS = {
7625
+ cli: "pb question list",
7626
+ mcp: "question action=list"
7627
+ };
7628
+ var BRIEFING_QUESTION_MAX_CHARS = 160;
7629
+ function briefingLine(value, max) {
7630
+ const line = sanitizeRuleListField(value);
7631
+ if (max === void 0 || Array.from(line).length <= max) return line;
7632
+ const cut = Array.from(line).slice(0, max).join("");
7633
+ return `${(cut.replace(/\s+\S*$/, "") || cut).trimEnd()}\u2026`;
7634
+ }
7635
+ function idTag(entryId) {
7636
+ return entryId ? ` (${sanitizeRuleListField(entryId)})` : "";
7637
+ }
7638
+ function formatBriefingLines(view) {
7639
+ const lines = [];
7640
+ const f = view.facts ?? {};
7641
+ if (view.workspaceName) lines.push(`Workspace: ${briefingLine(view.workspaceName)}${view.actingRole ? ` \u2014 acting as ${briefingLine(view.actingRole)}` : ""}`);
7642
+ if (f.purpose) lines.push(`Purpose: ${briefingLine(f.purpose)}`);
7643
+ if (f.vision) lines.push(`Vision: ${briefingLine(f.vision)}`);
7644
+ if (f.strategy) {
7645
+ lines.push(`Strategy${idTag(f.strategy.entryId)}: ${briefingLine(f.strategy.name)}`);
7646
+ if (f.strategy.notDo) lines.push(` Not doing: ${briefingLine(f.strategy.notDo)}`);
7647
+ }
7648
+ if (f.objective) {
7649
+ lines.push(`Objective${idTag(f.objective.entryId)}: ${briefingLine(f.objective.name)}`);
7650
+ for (const kr of f.objective.keyResults) {
7651
+ const current = kr.readingUnresolved ? "unresolved (too many corrections to read)" : kr.currentValue ?? "n/a";
7652
+ const value = `${current} / ${kr.targetValue ?? "n/a"}`;
7653
+ lines.push(` - ${briefingLine(kr.name)}: ${value}`);
7654
+ }
7655
+ }
7656
+ if (f.currentWorkPackage) lines.push(`Current work package${idTag(f.currentWorkPackage.entryId)}: ${briefingLine(f.currentWorkPackage.name)}`);
7657
+ if (f.briefingUnavailable) lines.push("Purpose, vision, strategy, objective and work package: unavailable \u2014 the briefing read failed; orient again to retry.");
7658
+ if (f.spineUnavailable) lines.push("Objective: unavailable \u2014 the objectives read failed; orient again to retry.");
7659
+ if (f.truncated) lines.push("(A bounded read hit its cap: a fact above may be missing or not the current one.)");
7660
+ const ruleLines = formatRuleListsLines(view.ruleLists);
7661
+ if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
7662
+ const questions = view.openQuestions ?? [];
7663
+ if (questions.length > 0) {
7664
+ lines.push("", `Open questions (${questions.length}) \u2014 they need you before you continue; answer with ${BRIEFING_ANSWER_COMMANDS[view.surface]}:`);
7665
+ for (const q of questions) {
7666
+ const age = q.ageDays !== void 0 ? ` (${q.ageDays}d)` : "";
7667
+ lines.push(` - ${sanitizeRuleListField(q.entryId)} \u2014 ${briefingLine(q.title, BRIEFING_QUESTION_MAX_CHARS)}${age}`);
7668
+ }
7669
+ if (view.openQuestionsTruncated) lines.push(" (This list may be incomplete: you may have more open questions than shown.)");
7670
+ lines.push(` Asker, why you, what waits on it and what you may do: ${BRIEFING_QUESTION_DETAIL_COMMANDS[view.surface]}`);
7671
+ }
7672
+ lines.push("", `Pull more: ${BRIEFING_PULL_COMMANDS[view.surface]}`);
7673
+ return lines;
7674
+ }
7616
7675
 
7617
7676
  // src/tools/orient-rituals.ts
7618
7677
  var RULE_LISTS_EVERYONE_ONLY_LABEL = "Rules (everyone list only; run `orient mode=full` for your team and role lists):";
@@ -12040,12 +12099,19 @@ async function handleStart2(data) {
12040
12099
  lines.push(`Acting as role: ${result2.roleName ?? result2.roleEntryId}.`);
12041
12100
  }
12042
12101
  lines.push(FEEDBACK_SUBMIT_HINT);
12043
- const noticeLines = formatNoticeLines(result2.notices);
12044
- if (noticeLines.length > 0) {
12045
- lines.push("", "Notices:", ...noticeLines);
12046
- }
12047
- const ruleLines = formatRuleListsLines(result2.ruleLists);
12048
- if (ruleLines.length > 0) lines.push("", "Rules:", ...ruleLines);
12102
+ const questionNotice = result2.notices?.find((n) => n.source === QUESTION_ACK_GATE_SOURCE_ID);
12103
+ const noticeLines = formatNoticeLines(result2.notices?.filter((n) => n !== questionNotice));
12104
+ if (noticeLines.length > 0) lines.push("", "Notices:", ...noticeLines);
12105
+ const openQuestions = (questionNotice?.payload?.questions ?? []).map((q) => ({ entryId: q.sourcePointer, title: q.name, ageDays: q.ageDays }));
12106
+ lines.push("", ...formatBriefingLines({
12107
+ workspaceName: result2.workspaceName,
12108
+ actingRole: result2.roleName,
12109
+ facts: result2.briefing,
12110
+ ruleLists: result2.ruleLists,
12111
+ openQuestions,
12112
+ openQuestionsTruncated: questionNotice?.payload?.truncated === true,
12113
+ surface: "mcp"
12114
+ }));
12049
12115
  const summary = `Session ${result2.sessionId} active. Workspace ${result2.workspaceName}. Orient with a task first; workflow checkpoints and organisation-structure writes still require it.`;
12050
12116
  return {
12051
12117
  content: [{ type: "text", text: lines.join("\n") }],
@@ -12059,8 +12125,10 @@ async function handleStart2(data) {
12059
12125
  feedbackQueueNew: result2.feedbackQueueNew,
12060
12126
  feedbackOldestNewAt: result2.feedbackOldestNewAt,
12061
12127
  notices: result2.notices ?? [],
12062
- ruleLists: result2.ruleLists
12128
+ ruleLists: result2.ruleLists,
12063
12129
  // TASK-436
12130
+ briefing: result2.briefing
12131
+ // TASK-552
12064
12132
  // Finding #16: bare `parameters: {}` lets orient's schema default kick in
12065
12133
  // (action defaults to "task", which requires a `task` string) — the suggested
12066
12134
  // next-action call failed validation instead of running. `action: "start"` is
@@ -13731,7 +13799,7 @@ var ALLOWED_RELATION_TYPES_LIST = [
13731
13799
  var ALLOWED_RELATION_TYPES = new Set(ALLOWED_RELATION_TYPES_LIST);
13732
13800
 
13733
13801
  // src/resources/agentCheatsheet.ts
13734
- var DATA_HANDLING_SECTION = "### How PB Handles Your Data\n- **The reply is the source of truth**: every reply carries `ok`; on failure it carries `code` and guidance. Read the reply, never an expectation.\n- **Empty-workspace safe**: the orientation resource and this cheatsheet render on a workspace with no entries and no collections.\n- **Workspace-agnostic**: PB is one product used by many teams. Nothing in these instructions is specific to your workspace; your own principles, standards and rules arrive through `productbrain://orientation`.\n- **Served, not installed**: these instructions, `productbrain://orientation` and `productbrain://agent-cheatsheet` are served over MCP.";
13802
+ var DATA_HANDLING_SECTION = "### How PB Handles Your Data\n- **The reply is the source of truth**: every reply carries `ok`; on failure it carries `code` and guidance. Read the reply, never an expectation.\n- **Empty-workspace safe**: the orientation resource and this cheatsheet render on a workspace with no entries and no collections.\n- **Workspace-agnostic**: PB is one product used by many teams. Nothing in these instructions is specific to your workspace; your own rules arrive as the rule lists that session start and orient serve you.\n- **Served, not installed**: these instructions, `productbrain://orientation` and `productbrain://agent-cheatsheet` are served over MCP.";
13735
13803
  var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
13736
13804
 
13737
13805
  ## Core Tools (Serves 15 compound tools, always)
@@ -13756,8 +13824,7 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
13756
13824
  This table lists actions only. See \`tools/list\` for each tool's input schema; a missing or invalid parameter is named in the call's own reply.
13757
13825
 
13758
13826
  ## Collection Prefixes
13759
- GLO (glossary), BR (business-rules), PRI (principles), STD (standards),
13760
- DEC (decisions), STR (strategy), TEN (tensions), FEAT (features),
13827
+ GLO (glossary), RULE (rules), DEC (decisions), STR (strategy), TEN (tensions), FEAT (features),
13761
13828
  BET (bets), INS (insights), ARCH (architecture), TEAM (teams),
13762
13829
  ROL (roles), MTRC (tracking-events), ST (semantic-types)
13763
13830
 
@@ -13771,7 +13838,11 @@ Write via \`update\`: \`draft\` | \`archived\` (\`accepted\` via \`commit\`, nev
13771
13838
  - **tensions:** open \u2192 processing \u2192 decided \u2192 closed
13772
13839
  - **decisions:** pending \u2192 decided
13773
13840
  - **bets:** shaped \u2192 bet \u2192 building \u2192 shipped
13774
- - **business-rules:** active | conflict | review
13841
+
13842
+ ## Rule Lists
13843
+ - Session start and \`orient action=task\` serve the rules that bind you, each as one sentence with its why.
13844
+ - A rule's \`applies\` and its one owner role place it on one list: everyone (cap 15), team (cap 5 per team) or role (cap 5 per role).
13845
+ - A rule on no list binds nobody; a full list refuses a new rule until one retires, and a list over its cap is served whole.
13775
13846
 
13776
13847
  ## Key Patterns
13777
13848
  - **Capture flow:** \`capture\` \u2192 \`relations action=suggest\` \u2192 \`relations action=batch-create\` \u2192 \`entries action=commit\`
@@ -14444,67 +14515,43 @@ Make sure the rule is consistent with existing rules and doesn't contradict them
14444
14515
  // src/server.ts
14445
14516
  var SERVER_VERSION = "0.7.2";
14446
14517
  var INSTRUCTIONS = [
14447
- "Product Brain \u2014 the single source of truth for product knowledge.",
14448
- "Terminology, standards, and core data all live here \u2014 no need to check external docs.",
14449
- "",
14450
- "## About Product Brain (PB)",
14518
+ "Product Brain (PB) is the single source of truth for your team's product knowledge: decisions, tensions, rules, work and the links between them.",
14451
14519
  "",
14452
- "PB is a knowledge management system used by many product teams.",
14453
- "These describe how PB works \u2014 not your product.",
14520
+ "## What session start hands you",
14454
14521
  "",
14455
- "### How PB Organizes Its Tools",
14456
- "- **Tools** are for actions with side-effects or dynamic computation (capture, accept, search).",
14457
- "- **Resources** are for stable, read-only data (orientation, terminology, collection schemas).",
14458
- "- **Prompts** are for multi-step choreography (workflows, guided capture, deep dives).",
14459
- "- Every tool, resource, and prompt works for ANY workspace \u2014 no bespoke logic.",
14460
- "- Resource templates (URI params) provide workspace-specific data through generic patterns.",
14461
- "- Tool count stays minimal: compound tools with `action` enums over many single-purpose tools.",
14522
+ "Call `session action=start` first. The reply names:",
14523
+ "- the workspace and the role you act as;",
14524
+ "- notices, including open questions routed to you;",
14525
+ "- the rule lists that bind you, each rule as one sentence with its why, its owner role and, when it has one, its date.",
14462
14526
  "",
14463
- DATA_HANDLING_SECTION,
14527
+ "Read those rules before you propose or build. If the work conflicts with one, stop, name the rule and ask the user before going on. Never design around a rule.",
14464
14528
  "",
14465
- "## Your Workspace Principles",
14529
+ "## What applies means",
14466
14530
  "",
14467
- "When you orient or start, PB surfaces active entries from your `principles`, `standards`,",
14468
- "and `business-rules` collections. These are YOUR team's guardrails \u2014 respect them during implementation.",
14469
- "If no principles exist yet, PB will tell you and suggest how to add them.",
14531
+ "Every rule (collection `rules`) declares whom it applies to, and its one owner role places it:",
14532
+ "- **everyone**: the whole workspace, owned by the root team's lead; capped at 15 rules;",
14533
+ "- **team**: its owner role's team; capped at 5 per team;",
14534
+ "- **role**: its owner role; capped at 5 per role.",
14470
14535
  "",
14471
- "The three governance collections:",
14472
- "- **Principles** (`principles`) \u2014 beliefs that guide decisions. 'We believe X.' You reason from a principle.",
14473
- "- **Standards** (`standards`) \u2014 conventions about how work is done. 'We do X this way.' You lint for a standard.",
14474
- "- **Business Rules** (`business-rules`) \u2014 system constraints. 'The system must do X.' You test for a rule.",
14536
+ "A rule on no list binds nobody. A full list refuses a new rule until one retires; a list already over its cap is served whole.",
14475
14537
  "",
14476
- "## Workflow",
14538
+ "## Pull the rest",
14477
14539
  "",
14478
- " 1. Start: call `session action=start` to open a tracked write session, then `orient action=start` \u2014 it returns a standup briefing for every workspace state, fresh or active. (`orient` orients the session; only `session action=start` creates one.)",
14479
- " 2. Re-orient: call `orient action=task` mid-session for task-scoped context or a compact status refresh.",
14480
- " 3. Discover: use `entries action=search` to find entries, or `entries action=list` to browse.",
14481
- ' 4. Drill in: use `entries action=get entryId="..."` for full details \u2014 data, labels, relations, history.',
14482
- " 5. Context: use `context action=gather` with an entryId or a task description.",
14483
- " 6. Capture: use `capture` to create entries \u2014 auto-links and scores in one call.",
14484
- " 7. Accept: use `entries action=commit` to send a draft for acceptance \u2014 read the reply's outcome/status field for what happened; read the capture reply first, since an entry that came back accepted needs no commit.",
14485
- " 8. Connect: use `relations action=suggest` then `relations action=create` to build the graph.",
14486
- " 9. Wrapup: call `session action=wrapup-review` before closing \u2014 reviews drafts, coaches quality, suggests links.",
14487
- " 10. Close: call `session action=close` when done \u2014 records session activity. Auto-nudges if wrapup was skipped.",
14540
+ '- `orient action=task task="<what you are doing>"`: context shaped to the task, with the rules for your team and role.',
14541
+ '- `entries action=get entryId="<ID>"`: one entry in full, with data, relations and history.',
14542
+ '- `entries action=search query="<noun>"`: find entries by what they are about.',
14488
14543
  "",
14489
- "Write tools (capture, entries action=update, relations, entries action=commit) require:",
14490
- " - An active agent session \u2014 call `session action=start` first, then `orient action=start` for context. Call `orient action=task` mid-session for a refresh.",
14491
- " - A readwrite API key scope",
14544
+ "## Writing",
14492
14545
  "",
14493
- "Alignment-first: before proposing or building anything, check orient's Workspace Governance",
14494
- "and Active work packages sections. These are constraints, not reference material.",
14495
- "If the proposal conflicts with a principle, standard, or business rule \u2014 stop, flag the conflict,",
14496
- "and get explicit user confirmation before proceeding. Do not design around governance.",
14497
- "If the work is outside the scope of active work packages \u2014 stop, name the gap, and ask the user",
14498
- "to confirm before designing. Do not propose implementation for out-of-scope work without a go-ahead.",
14546
+ "Write actions (capture, entries update and commit, relations create, batch-create, dismiss and delete) need an active session and a readwrite key.",
14547
+ "Use `capture` to create an entry and read its reply: an entry that came back accepted needs no `entries action=commit`.",
14548
+ "Link with `relations action=suggest`, then `relations action=create`.",
14549
+ "Finish with `session action=wrapup-review`, then `session action=close`.",
14550
+ "If the work falls outside the active work packages, name the gap and ask the user before designing it.",
14499
14551
  "",
14500
- "Workspace setup: use `collections action=update` to shape existing collections with the user.",
14501
- "Creating a brand-new collection is not self-serve \u2014 ask a platform admin to provision it, or",
14502
- "enable the module ontology pack that owns the drawer.",
14552
+ DATA_HANDLING_SECTION,
14503
14553
  "",
14504
- "Personalization: if you have context about the user from memory (prior work, recent",
14505
- "conversations, team context), use it to personalize recommendations. For example,",
14506
- "'Based on your recent pitch reviews, the gap most likely to matter is X.'",
14507
- "The orient/start output gives you the workspace state; your memory fills in the human context."
14554
+ "Every tool and action: `productbrain://agent-cheatsheet`."
14508
14555
  ].join("\n");
14509
14556
  function createProductBrainServer() {
14510
14557
  const server = new McpServer2(
@@ -14561,4 +14608,4 @@ export {
14561
14608
  createProductBrainServer,
14562
14609
  initFeatureFlags
14563
14610
  };
14564
- //# sourceMappingURL=chunk-LDWP3UNV.js.map
14611
+ //# sourceMappingURL=chunk-LJBOAIFJ.js.map