@productbrain/mcp 0.0.1-beta.5543 → 0.0.1-beta.5561
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.
|
@@ -802,7 +802,8 @@ var FIELD_TYPE_DEFAULTS = {
|
|
|
802
802
|
"array": [],
|
|
803
803
|
"json": null,
|
|
804
804
|
"date": null,
|
|
805
|
-
"person": null
|
|
805
|
+
"person": null,
|
|
806
|
+
"role": null
|
|
806
807
|
};
|
|
807
808
|
|
|
808
809
|
// src/lib/formatFieldGuidance.ts
|
|
@@ -15334,6 +15335,9 @@ function stripControlChars(str) {
|
|
|
15334
15335
|
if (!str) return str;
|
|
15335
15336
|
return str.replace(ANSI_AND_CONTROL_RE2, "");
|
|
15336
15337
|
}
|
|
15338
|
+
function sanitizeSingleLineField(str) {
|
|
15339
|
+
return stripControlChars(str).replace(/\s+/g, " ").trim();
|
|
15340
|
+
}
|
|
15337
15341
|
|
|
15338
15342
|
// src/tools/question.ts
|
|
15339
15343
|
var QUESTION_ACTIONS = ["create", "adopt", "assign", "snooze", "decline", "answer", "force-close", "list"];
|
|
@@ -15598,6 +15602,93 @@ function registerQuestionTools(server) {
|
|
|
15598
15602
|
);
|
|
15599
15603
|
}
|
|
15600
15604
|
|
|
15605
|
+
// src/tools/role.ts
|
|
15606
|
+
import { z as z34 } from "zod/v3";
|
|
15607
|
+
var ROLE_ACTIONS = ["accountable"];
|
|
15608
|
+
var roleSchema = z34.object({
|
|
15609
|
+
action: z34.enum(ROLE_ACTIONS).describe("'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage."),
|
|
15610
|
+
roleId: z34.string().max(200).optional().describe("The role, by the human chain id `chain.getEntry` or `pb get` would print for it, or a raw entry id. Required for 'accountable'."),
|
|
15611
|
+
canonicalKey: z34.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
|
|
15612
|
+
limit: z34.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
|
|
15613
|
+
cursor: z34.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor.")
|
|
15614
|
+
});
|
|
15615
|
+
var accountableVariant = z34.object({
|
|
15616
|
+
action: z34.literal("accountable"),
|
|
15617
|
+
roleId: z34.string().max(200),
|
|
15618
|
+
canonicalKey: z34.string().max(200).optional(),
|
|
15619
|
+
limit: z34.number().int().positive().max(200).optional(),
|
|
15620
|
+
cursor: z34.number().optional()
|
|
15621
|
+
});
|
|
15622
|
+
var roleActionUnion = z34.discriminatedUnion("action", [accountableVariant]);
|
|
15623
|
+
var ROLE_ACTION_SPECS = {
|
|
15624
|
+
accountable: { params: ["roleId", "canonicalKey", "limit", "cursor"], description: "roleId is required; canonicalKey/limit/cursor are optional." }
|
|
15625
|
+
};
|
|
15626
|
+
function formatRow(row) {
|
|
15627
|
+
const id = row.entryId ?? row.id;
|
|
15628
|
+
return ` ${id} ${sanitizeSingleLineField(row.name)} [${row.canonicalKey ?? "?"}/${row.status}]`;
|
|
15629
|
+
}
|
|
15630
|
+
function formatSection(label, rows, truncated, cursorHint) {
|
|
15631
|
+
if (rows.length === 0) return [` ${label}: not recorded yet`];
|
|
15632
|
+
const lines = [` ${label}:`, ...rows.map(formatRow)];
|
|
15633
|
+
if (truncated) lines.push(` (more exist \u2014 ${cursorHint ?? "raise limit (capped at 200, no cursor for this list)"})`);
|
|
15634
|
+
return lines;
|
|
15635
|
+
}
|
|
15636
|
+
function formatRoleAccountable(result2) {
|
|
15637
|
+
const roleLabel = `${sanitizeSingleLineField(result2.role.name)} (${result2.role.entryId ?? result2.role.id})`;
|
|
15638
|
+
const explicitCursorHint = result2.nextCursor !== null ? `raise limit or continue with cursor ${result2.nextCursor}` : "raise limit";
|
|
15639
|
+
return [
|
|
15640
|
+
`${roleLabel} \u2014 accountability:`,
|
|
15641
|
+
...formatSection("explicit (owns)", result2.explicit, result2.explicitTruncated, explicitCursorHint),
|
|
15642
|
+
...formatSection("reporting (reports on)", result2.reporting, result2.reportingTruncated),
|
|
15643
|
+
` inherited: not-computed \u2014 ${result2.inheritedNotComputedReason}`
|
|
15644
|
+
].join("\n");
|
|
15645
|
+
}
|
|
15646
|
+
async function handleRoleAccountable(roleId, canonicalKey, limit, cursor) {
|
|
15647
|
+
try {
|
|
15648
|
+
const raw = await kernelQuery("chain.listByRole", { roleId, canonicalKey, limit, cursor });
|
|
15649
|
+
const result2 = raw;
|
|
15650
|
+
const message = formatRoleAccountable(result2);
|
|
15651
|
+
return successResult(message, message, result2);
|
|
15652
|
+
} catch (err) {
|
|
15653
|
+
return roleErrorResult(err, "accountable", { roleId, canonicalKey, limit, cursor });
|
|
15654
|
+
}
|
|
15655
|
+
}
|
|
15656
|
+
function roleErrorResult(err, action, params = {}) {
|
|
15657
|
+
const classified = classifyError(err);
|
|
15658
|
+
const definedParams = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== void 0));
|
|
15659
|
+
return failureResult(
|
|
15660
|
+
classified.message,
|
|
15661
|
+
classified.code,
|
|
15662
|
+
classified.message,
|
|
15663
|
+
classified.recovery ?? "Use action='accountable' with roleId set to a real role's chain id or entry id.",
|
|
15664
|
+
classified.availableActions ?? [{ tool: "role", description: `Retry ${action}`, parameters: { action, ...definedParams } }],
|
|
15665
|
+
classified.diagnostics
|
|
15666
|
+
);
|
|
15667
|
+
}
|
|
15668
|
+
function registerRoleTools(server) {
|
|
15669
|
+
const roleHandlers = {
|
|
15670
|
+
accountable: (data) => handleRoleAccountable(data.roleId, data.canonicalKey, data.limit, data.cursor)
|
|
15671
|
+
};
|
|
15672
|
+
server.registerTool(
|
|
15673
|
+
"role",
|
|
15674
|
+
{
|
|
15675
|
+
title: "Role",
|
|
15676
|
+
description: "Workspace roles \u2014 who is accountable for what. One action:\n\n- **accountable**: what this role owns (`explicit`, data.ownerRoleId), reports on (`reporting`, data.reporterRoleId \u2014 key results and tensions only, a separate fact from ownership), and \u2014 always `not-computed` today, never faked as empty \u2014 inherits via Team-Lead vacancy coverage.",
|
|
15677
|
+
inputSchema: roleSchema,
|
|
15678
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
15679
|
+
},
|
|
15680
|
+
thinWrapper(async (args) => {
|
|
15681
|
+
const parsed = parseOrFail(roleSchema, args);
|
|
15682
|
+
if (!parsed.ok) return parsed.result;
|
|
15683
|
+
const { action } = parsed.data;
|
|
15684
|
+
return runWithToolContext(
|
|
15685
|
+
{ tool: "role", action },
|
|
15686
|
+
() => dispatchDiscriminated("role", roleActionUnion, parsed.data, ROLE_ACTION_SPECS, roleHandlers)
|
|
15687
|
+
);
|
|
15688
|
+
})
|
|
15689
|
+
);
|
|
15690
|
+
}
|
|
15691
|
+
|
|
15601
15692
|
// src/resources/index.ts
|
|
15602
15693
|
import { existsSync as existsSync3 } from "fs";
|
|
15603
15694
|
import { dirname, join, resolve as resolve4 } from "path";
|
|
@@ -15607,7 +15698,7 @@ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
15607
15698
|
// src/resources/agentCheatsheet.ts
|
|
15608
15699
|
var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
|
|
15609
15700
|
|
|
15610
|
-
## Core Tools (Serves
|
|
15701
|
+
## Core Tools (Serves 14 default compound tools; 2 more (chain, chain-review) behind PB_MODULES=gitchain \u2014 map retired, L29)
|
|
15611
15702
|
| Tool | Purpose | Key params |
|
|
15612
15703
|
|---|---|---|
|
|
15613
15704
|
| \`orient\` | Workspace context, governance, active work packages, session start | \`action\`: start, task, record-activation |
|
|
@@ -15623,6 +15714,7 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
|
|
|
15623
15714
|
| \`feedback\` | Submit product feedback (any key, no session required); \`list\` reads back your own workspace's feedback (no gate); vendor triage: queue / note / group / status | \`action\`: submit, list, queue, note, group, status |
|
|
15624
15715
|
| \`shape\` | Review / disposition write-shape (single-concern split) advisories | \`action\`: list, show, agree, dismiss |
|
|
15625
15716
|
| \`question\` | Routed questions \u2014 create/adopt, own, snooze, decline, answer, force-close | \`action\`: create, adopt, assign, snooze, decline, answer, force-close |
|
|
15717
|
+
| \`role\` | What a role is accountable for \u2014 owns, reports on, and (not yet computed) inherits via Team-Lead vacancy coverage | \`action\`: accountable |
|
|
15626
15718
|
|
|
15627
15719
|
## Collection Prefixes
|
|
15628
15720
|
GLO (glossary), BR (business-rules), PRI (principles), STD (standards),
|
|
@@ -16109,12 +16201,12 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
|
|
|
16109
16201
|
}
|
|
16110
16202
|
|
|
16111
16203
|
// src/prompts/index.ts
|
|
16112
|
-
import { z as
|
|
16204
|
+
import { z as z35 } from "zod/v3";
|
|
16113
16205
|
function registerPrompts(server) {
|
|
16114
16206
|
server.prompt(
|
|
16115
16207
|
"review-against-rules",
|
|
16116
16208
|
"Review code or a design decision against all business rules for a given domain. Fetches the rules and asks you to do a structured compliance review.",
|
|
16117
|
-
{ domain:
|
|
16209
|
+
{ domain: z35.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
|
|
16118
16210
|
async ({ domain }) => {
|
|
16119
16211
|
const entries = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
16120
16212
|
const rules = entries.filter((e) => e.data?.domain === domain);
|
|
@@ -16167,7 +16259,7 @@ Provide a structured review with a compliance status for each rule (COMPLIANT /
|
|
|
16167
16259
|
server.prompt(
|
|
16168
16260
|
"name-check",
|
|
16169
16261
|
"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
|
|
16170
|
-
{ names:
|
|
16262
|
+
{ names: z35.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
|
|
16171
16263
|
async ({ names }) => {
|
|
16172
16264
|
const terms = await kernelQuery("chain.listEntries", { collectionSlug: "glossary" });
|
|
16173
16265
|
const glossaryContext = terms.map(
|
|
@@ -16203,7 +16295,7 @@ Format as a table: Name | Status | Canonical Form | Action Needed`
|
|
|
16203
16295
|
server.prompt(
|
|
16204
16296
|
"draft-decision-record",
|
|
16205
16297
|
"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
|
|
16206
|
-
{ context:
|
|
16298
|
+
{ context: z35.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
|
|
16207
16299
|
async ({ context }) => {
|
|
16208
16300
|
const recentDecisions = await kernelQuery("chain.listEntries", { collectionSlug: "decisions" });
|
|
16209
16301
|
const sorted = [...recentDecisions].sort((a, b) => (b.data?.date ?? "") > (a.data?.date ?? "") ? 1 : -1).slice(0, 5);
|
|
@@ -16241,8 +16333,8 @@ After drafting, I can log it using the capture tool with collection "decisions".
|
|
|
16241
16333
|
"draft-rule-from-context",
|
|
16242
16334
|
"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
|
|
16243
16335
|
{
|
|
16244
|
-
observation:
|
|
16245
|
-
domain:
|
|
16336
|
+
observation: z35.string().describe("What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')"),
|
|
16337
|
+
domain: z35.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
|
|
16246
16338
|
},
|
|
16247
16339
|
async ({ observation, domain }) => {
|
|
16248
16340
|
const allRules = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
@@ -16308,7 +16400,7 @@ var INSTRUCTIONS = [
|
|
|
16308
16400
|
"- **Self-documenting**: orient and server instructions teach agents how PB works. Cursor rules supplement but don't replace.",
|
|
16309
16401
|
"",
|
|
16310
16402
|
"### Tool Rename Notice (WP-484 S3, one release)",
|
|
16311
|
-
"Serves
|
|
16403
|
+
"Serves 14 default compound tools (WP-559 adds `shape` \u2014 review/disposition for write-shape advisories; WP-638 S3 adds `question` \u2014 routed-question routing/ownership/lifecycle; WP-730 S2 adds `role` \u2014 role accountability); 2 more (chain, chain-review) behind PB_MODULES=gitchain.",
|
|
16312
16404
|
"Old standalone names are gone \u2014 no alias window (ASM-43: zero external consumers). Map: `start_pb`\u2192`orient action=start`, `record_activation`\u2192`orient action=record-activation`, `session-wrapup`\u2192`session action=wrapup-review|wrapup-commit`, `facilitate`\u2192`session action=resume|commit-constellation`, `update-entry`\u2192`entries action=update`, `commit-entry`\u2192`entries action=commit`, `get-history`\u2192`entries action=history`, `move-entry`\u2192`entries action=move`, `verify-entry`\u2192`entries action=verify`, `graph`\u2192`relations action=find|suggest`, `documents`\u2192`context action=last-verified-brief`, `labels`\u2192`collections action=label-*`, `verify`\u2192`quality action=verify-chain`, `audit`\u2192`quality action=audit`, `health`\u2192`workspace action=check|whoami|status|self-test`, `get-usage-summary`\u2192`workspace action=usage`, `governance-proposals`\u2192`workspace action=proposals-*`, `skills`\u2192`workflows action=load-skill`, `chain-version`\u2192`chain action=version.*`, `chain-branch`\u2192`chain-review action=branch.*`.",
|
|
16313
16405
|
"",
|
|
16314
16406
|
"## Your Workspace Principles",
|
|
@@ -16380,6 +16472,7 @@ function createProductBrainServer() {
|
|
|
16380
16472
|
registerFeedbackTool(server);
|
|
16381
16473
|
registerShapeTools(server);
|
|
16382
16474
|
registerQuestionTools(server);
|
|
16475
|
+
registerRoleTools(server);
|
|
16383
16476
|
if (enabledModules.has("gitchain")) registerGitChainTools(server);
|
|
16384
16477
|
registerResources(server);
|
|
16385
16478
|
registerPrompts(server);
|
|
@@ -16519,4 +16612,4 @@ export {
|
|
|
16519
16612
|
createProductBrainServer,
|
|
16520
16613
|
initFeatureFlags
|
|
16521
16614
|
};
|
|
16522
|
-
//# sourceMappingURL=chunk-
|
|
16615
|
+
//# sourceMappingURL=chunk-Y2JXPTBG.js.map
|