@productbrain/mcp 0.0.1-beta.3298 → 0.0.1-beta.3314
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/dist/{chunk-WXBZFMDB.js → chunk-AWDYYGKN.js} +174 -10
- package/dist/chunk-AWDYYGKN.js.map +1 -0
- package/dist/{chunk-6XYRKXER.js → chunk-ZZVUTH6P.js} +2 -2
- package/dist/chunk-ZZVUTH6P.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-KNS6CN4K.js → setup-7J7MSQCV.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6XYRKXER.js.map +0 -1
- package/dist/chunk-WXBZFMDB.js.map +0 -1
- /package/dist/{setup-KNS6CN4K.js.map → setup-7J7MSQCV.js.map} +0 -0
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
trackSessionCaptureRate,
|
|
41
41
|
trackWriteBackHintServed,
|
|
42
42
|
trackZeroCaptureAuditFired
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-ZZVUTH6P.js";
|
|
44
44
|
|
|
45
45
|
// src/server.ts
|
|
46
46
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -14706,6 +14706,168 @@ function registerFeedbackTool(server) {
|
|
|
14706
14706
|
}));
|
|
14707
14707
|
}
|
|
14708
14708
|
|
|
14709
|
+
// src/tools/shape.ts
|
|
14710
|
+
import { z as z29 } from "zod/v3";
|
|
14711
|
+
var SHAPE_ACTIONS = ["list", "show", "agree", "dismiss"];
|
|
14712
|
+
var LIST_DISPOSITIONS = ["pending", "agreed", "dismissed", "expired"];
|
|
14713
|
+
var LIST_OUTCOMES = ["not_candidate", "atomic", "compound", "unavailable"];
|
|
14714
|
+
var shapeSchema = z29.object({
|
|
14715
|
+
action: z29.enum(SHAPE_ACTIONS).describe(
|
|
14716
|
+
"'list': list shape advisories for this workspace, latest per subject. 'show': show one shape advisory by id. 'agree': agree with a compound advisory's split verdict. 'dismiss': dismiss a compound advisory's split verdict."
|
|
14717
|
+
),
|
|
14718
|
+
disposition: z29.enum(LIST_DISPOSITIONS).optional().describe(
|
|
14719
|
+
"For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
14720
|
+
),
|
|
14721
|
+
outcome: z29.enum(LIST_OUTCOMES).optional().describe(
|
|
14722
|
+
"For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
14723
|
+
),
|
|
14724
|
+
limit: z29.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
|
|
14725
|
+
rowId: z29.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
|
|
14726
|
+
reason: z29.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
|
|
14727
|
+
});
|
|
14728
|
+
var shapeListVariant = z29.object({
|
|
14729
|
+
action: z29.literal("list"),
|
|
14730
|
+
disposition: z29.enum(LIST_DISPOSITIONS).optional(),
|
|
14731
|
+
outcome: z29.enum(LIST_OUTCOMES).optional(),
|
|
14732
|
+
limit: z29.number().min(1).max(200).optional()
|
|
14733
|
+
});
|
|
14734
|
+
var shapeShowVariant = z29.object({ action: z29.literal("show"), rowId: z29.string().max(200) });
|
|
14735
|
+
var shapeAgreeVariant = z29.object({ action: z29.literal("agree"), rowId: z29.string().max(200), reason: z29.string().max(1e3).optional() });
|
|
14736
|
+
var shapeDismissVariant = z29.object({ action: z29.literal("dismiss"), rowId: z29.string().max(200), reason: z29.string().max(1e3).optional() });
|
|
14737
|
+
var shapeActionUnion = z29.discriminatedUnion("action", [
|
|
14738
|
+
shapeListVariant,
|
|
14739
|
+
shapeShowVariant,
|
|
14740
|
+
shapeAgreeVariant,
|
|
14741
|
+
shapeDismissVariant
|
|
14742
|
+
]);
|
|
14743
|
+
var SHAPE_ACTION_SPECS = {
|
|
14744
|
+
list: { params: ["disposition", "outcome", "limit"], description: "All params optional; no filters defaults to disposition:pending + outcome:compound." },
|
|
14745
|
+
show: { params: ["rowId"], description: "rowId is required." },
|
|
14746
|
+
agree: { params: ["rowId", "reason"], description: "rowId is required; reason is optional." },
|
|
14747
|
+
dismiss: { params: ["rowId", "reason"], description: "rowId is required; reason is optional." }
|
|
14748
|
+
};
|
|
14749
|
+
async function handleShapeList(disposition, outcome, limit) {
|
|
14750
|
+
const noFiltersGiven = disposition === void 0 && outcome === void 0;
|
|
14751
|
+
const effectiveDisposition = disposition ?? (noFiltersGiven ? "pending" : void 0);
|
|
14752
|
+
const effectiveOutcome = outcome ?? (noFiltersGiven ? "compound" : void 0);
|
|
14753
|
+
const items = await kernelQuery("chain.shapeAdvisories", {
|
|
14754
|
+
...effectiveDisposition ? { disposition: effectiveDisposition } : {},
|
|
14755
|
+
...effectiveOutcome ? { outcome: effectiveOutcome } : {},
|
|
14756
|
+
...limit ? { limit } : {}
|
|
14757
|
+
});
|
|
14758
|
+
if (items.length === 0) {
|
|
14759
|
+
return successResult("No shape advisories match.", "No shape advisories found.", { items: [], count: 0 });
|
|
14760
|
+
}
|
|
14761
|
+
const lines = ["# Shape Advisories", ""];
|
|
14762
|
+
for (const item of items) {
|
|
14763
|
+
const verdict = item.outcome === "unavailable" && item.unavailableReason ? `unavailable(${item.unavailableReason})` : item.outcome;
|
|
14764
|
+
lines.push(`- \`${item.id}\` \u2014 ${item.subjectEntryId} \xB7 ${verdict} \xB7 disposition:${item.disposition} \xB7 ${item.source}`);
|
|
14765
|
+
}
|
|
14766
|
+
return successResult(
|
|
14767
|
+
lines.join("\n"),
|
|
14768
|
+
`Found ${items.length} shape advisor${items.length === 1 ? "y" : "ies"}.`,
|
|
14769
|
+
{ items, count: items.length },
|
|
14770
|
+
[{ tool: "shape", description: "Show one advisory in full", parameters: { action: "show", rowId: items[0].id } }]
|
|
14771
|
+
);
|
|
14772
|
+
}
|
|
14773
|
+
function renderShapeAdvisoryText(item) {
|
|
14774
|
+
const lines = [
|
|
14775
|
+
`# ${item.id}`,
|
|
14776
|
+
`- Subject: ${item.subjectEntryId} (${item.collectionSlug})`,
|
|
14777
|
+
`- Outcome: ${item.outcome}`,
|
|
14778
|
+
`- Disposition: ${item.disposition}`,
|
|
14779
|
+
`- Source: ${item.source}`
|
|
14780
|
+
];
|
|
14781
|
+
if (item.proposedAtoms?.length) {
|
|
14782
|
+
lines.push("", `Proposed split (${item.proposedAtoms.length} atom(s)):`);
|
|
14783
|
+
item.proposedAtoms.forEach((atom, idx) => {
|
|
14784
|
+
lines.push(` [${idx}] ${atom.title} \u2014 ${atom.concern}`);
|
|
14785
|
+
lines.push(` "${atom.bodyExcerpt}"`);
|
|
14786
|
+
if (atom.suggestedCollection) lines.push(` suggested collection: ${atom.suggestedCollection}`);
|
|
14787
|
+
});
|
|
14788
|
+
}
|
|
14789
|
+
if (item.proposedLinks?.length) {
|
|
14790
|
+
lines.push("", "Proposed links:");
|
|
14791
|
+
for (const link of item.proposedLinks) {
|
|
14792
|
+
const from = link.fromIdx === -1 ? "original" : `[${link.fromIdx}]`;
|
|
14793
|
+
lines.push(` ${from} --${link.relation}--> [${link.toIdx}]`);
|
|
14794
|
+
}
|
|
14795
|
+
}
|
|
14796
|
+
if (item.dispositionReason) lines.push("", `- Disposition reason: ${item.dispositionReason}`);
|
|
14797
|
+
return lines.join("\n");
|
|
14798
|
+
}
|
|
14799
|
+
async function handleShapeShow(rowId) {
|
|
14800
|
+
const item = await kernelQuery("chain.showShapeAdvisory", { rowId });
|
|
14801
|
+
if (!item) {
|
|
14802
|
+
return failureResult(
|
|
14803
|
+
`Advisory '${rowId}' not found (missing, or belongs to a different workspace).`,
|
|
14804
|
+
"NOT_FOUND",
|
|
14805
|
+
`Advisory '${rowId}' not found.`,
|
|
14806
|
+
"Use action=list to find valid ids.",
|
|
14807
|
+
[{ tool: "shape", description: "List advisories", parameters: { action: "list" } }]
|
|
14808
|
+
);
|
|
14809
|
+
}
|
|
14810
|
+
return successResult(
|
|
14811
|
+
renderShapeAdvisoryText(item),
|
|
14812
|
+
`Advisory ${item.id}: ${item.outcome}, disposition:${item.disposition}.`,
|
|
14813
|
+
item
|
|
14814
|
+
);
|
|
14815
|
+
}
|
|
14816
|
+
async function handleShapeDisposition(disposition, rowId, reason) {
|
|
14817
|
+
requireWriteAccess();
|
|
14818
|
+
try {
|
|
14819
|
+
const result2 = await kernelMutation("chain.dispositionShapeAdvisory", {
|
|
14820
|
+
rowId,
|
|
14821
|
+
disposition,
|
|
14822
|
+
...reason ? { dispositionReason: reason } : {}
|
|
14823
|
+
});
|
|
14824
|
+
return successResult(
|
|
14825
|
+
`Advisory ${result2.rowId} dispositioned: ${result2.disposition}.`,
|
|
14826
|
+
`Advisory dispositioned: ${result2.disposition}.`,
|
|
14827
|
+
result2
|
|
14828
|
+
);
|
|
14829
|
+
} catch (err) {
|
|
14830
|
+
const classified = classifyError(err);
|
|
14831
|
+
const isNotFound = classified.code === "NOT_FOUND";
|
|
14832
|
+
return failureResult(
|
|
14833
|
+
classified.message,
|
|
14834
|
+
classified.code,
|
|
14835
|
+
classified.message,
|
|
14836
|
+
isNotFound ? "Use action=list to find valid ids." : classified.recovery ?? "Use action=show to check the advisory's current outcome/disposition.",
|
|
14837
|
+
isNotFound ? [{ tool: "shape", description: "List advisories", parameters: { action: "list" } }] : classified.availableActions ?? [{ tool: "shape", description: "Show the advisory", parameters: { action: "show", rowId } }],
|
|
14838
|
+
classified.diagnostics
|
|
14839
|
+
);
|
|
14840
|
+
}
|
|
14841
|
+
}
|
|
14842
|
+
function registerShapeTools(server) {
|
|
14843
|
+
const shapeHandlers = {
|
|
14844
|
+
list: (data) => handleShapeList(data.disposition, data.outcome, data.limit),
|
|
14845
|
+
show: (data) => handleShapeShow(data.rowId),
|
|
14846
|
+
agree: (data) => handleShapeDisposition("agreed", data.rowId, data.reason),
|
|
14847
|
+
dismiss: (data) => handleShapeDisposition("dismissed", data.rowId, data.reason)
|
|
14848
|
+
};
|
|
14849
|
+
server.registerTool(
|
|
14850
|
+
"shape",
|
|
14851
|
+
{
|
|
14852
|
+
title: "Shape",
|
|
14853
|
+
description: "Review and disposition shape-advisory (single-concern split) suggestions for this workspace. Four actions:\n\n- **list**: List shape advisories, latest per subject (filter by disposition/outcome).\n- **show**: Show one shape advisory in full by id.\n- **agree**: Agree with a compound advisory's split verdict.\n- **dismiss**: Dismiss a compound advisory's split verdict.",
|
|
14854
|
+
inputSchema: shapeSchema,
|
|
14855
|
+
// Mixed read/write noun (§3 R3, same as workspace's proposals-respond): agree/dismiss write;
|
|
14856
|
+
// list/show read.
|
|
14857
|
+
annotations: { readOnlyHint: false, idempotentHint: false, openWorldHint: false }
|
|
14858
|
+
},
|
|
14859
|
+
thinWrapper(async (args) => {
|
|
14860
|
+
const parsed = parseOrFail(shapeSchema, args);
|
|
14861
|
+
if (!parsed.ok) return parsed.result;
|
|
14862
|
+
const { action } = parsed.data;
|
|
14863
|
+
return runWithToolContext(
|
|
14864
|
+
{ tool: "shape", action },
|
|
14865
|
+
() => dispatchDiscriminated("shape", shapeActionUnion, parsed.data, SHAPE_ACTION_SPECS, shapeHandlers)
|
|
14866
|
+
);
|
|
14867
|
+
})
|
|
14868
|
+
);
|
|
14869
|
+
}
|
|
14870
|
+
|
|
14709
14871
|
// src/resources/index.ts
|
|
14710
14872
|
import { existsSync as existsSync3 } from "fs";
|
|
14711
14873
|
import { dirname, join, resolve as resolve4 } from "path";
|
|
@@ -14715,7 +14877,7 @@ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
14715
14877
|
// src/resources/agentCheatsheet.ts
|
|
14716
14878
|
var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
|
|
14717
14879
|
|
|
14718
|
-
## Core Tools (Serves
|
|
14880
|
+
## Core Tools (Serves 12 default compound tools; 3 more (chain, chain-review, map) behind PB_MODULES=gitchain)
|
|
14719
14881
|
| Tool | Purpose | Key params |
|
|
14720
14882
|
|---|---|---|
|
|
14721
14883
|
| \`orient\` | Workspace context, governance, active bets, session start | \`action\`: start, task, record-activation |
|
|
@@ -14729,6 +14891,7 @@ var AGENT_CHEATSHEET = `# Product Brain \u2014 Agent Cheatsheet
|
|
|
14729
14891
|
| \`workflows\` | Run workflows, checkpoint, load a skill | \`action\`: list, start, checkpoint, get-run, load-skill |
|
|
14730
14892
|
| \`workspace\` | Check / whoami / status / self-test, usage, governance proposals | \`action\`: check, whoami, status, audit, self-test, usage, proposals-* |
|
|
14731
14893
|
| \`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 |
|
|
14894
|
+
| \`shape\` | Review / disposition write-shape (single-concern split) advisories | \`action\`: list, show, agree, dismiss |
|
|
14732
14895
|
|
|
14733
14896
|
## Collection Prefixes
|
|
14734
14897
|
GLO (glossary), BR (business-rules), PRI (principles), STD (standards),
|
|
@@ -15226,12 +15389,12 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
|
|
|
15226
15389
|
}
|
|
15227
15390
|
|
|
15228
15391
|
// src/prompts/index.ts
|
|
15229
|
-
import { z as
|
|
15392
|
+
import { z as z30 } from "zod/v3";
|
|
15230
15393
|
function registerPrompts(server) {
|
|
15231
15394
|
server.prompt(
|
|
15232
15395
|
"review-against-rules",
|
|
15233
15396
|
"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.",
|
|
15234
|
-
{ domain:
|
|
15397
|
+
{ domain: z30.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
|
|
15235
15398
|
async ({ domain }) => {
|
|
15236
15399
|
const entries = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
15237
15400
|
const rules = entries.filter((e) => e.data?.domain === domain);
|
|
@@ -15284,7 +15447,7 @@ Provide a structured review with a compliance status for each rule (COMPLIANT /
|
|
|
15284
15447
|
server.prompt(
|
|
15285
15448
|
"name-check",
|
|
15286
15449
|
"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
|
|
15287
|
-
{ names:
|
|
15450
|
+
{ names: z30.string().describe("Comma-separated list of names to check (e.g. 'vendor_id, compliance_level, formulator_type')") },
|
|
15288
15451
|
async ({ names }) => {
|
|
15289
15452
|
const terms = await kernelQuery("chain.listEntries", { collectionSlug: "glossary" });
|
|
15290
15453
|
const glossaryContext = terms.map(
|
|
@@ -15320,7 +15483,7 @@ Format as a table: Name | Status | Canonical Form | Action Needed`
|
|
|
15320
15483
|
server.prompt(
|
|
15321
15484
|
"draft-decision-record",
|
|
15322
15485
|
"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
|
|
15323
|
-
{ context:
|
|
15486
|
+
{ context: z30.string().describe("Description of the decision (e.g. 'We decided to use MRSL v3.1 as the conformance baseline because...')") },
|
|
15324
15487
|
async ({ context }) => {
|
|
15325
15488
|
const recentDecisions = await kernelQuery("chain.listEntries", { collectionSlug: "decisions" });
|
|
15326
15489
|
const sorted = [...recentDecisions].sort((a, b) => (b.data?.date ?? "") > (a.data?.date ?? "") ? 1 : -1).slice(0, 5);
|
|
@@ -15358,8 +15521,8 @@ After drafting, I can log it using the capture tool with collection "decisions".
|
|
|
15358
15521
|
"draft-rule-from-context",
|
|
15359
15522
|
"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
|
|
15360
15523
|
{
|
|
15361
|
-
observation:
|
|
15362
|
-
domain:
|
|
15524
|
+
observation: z30.string().describe("What you observed or discovered (e.g. 'Suppliers can have multiple org types in Gateway')"),
|
|
15525
|
+
domain: z30.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
|
|
15363
15526
|
},
|
|
15364
15527
|
async ({ observation, domain }) => {
|
|
15365
15528
|
const allRules = await kernelQuery("chain.listEntries", { collectionSlug: "business-rules" });
|
|
@@ -15425,7 +15588,7 @@ var INSTRUCTIONS = [
|
|
|
15425
15588
|
"- **Self-documenting**: orient and server instructions teach agents how PB works. Cursor rules supplement but don't replace.",
|
|
15426
15589
|
"",
|
|
15427
15590
|
"### Tool Rename Notice (WP-484 S3, one release)",
|
|
15428
|
-
"Serves
|
|
15591
|
+
"Serves 12 default compound tools (WP-559 adds `shape` \u2014 review/disposition for write-shape advisories); 3 more (chain, chain-review, map) behind PB_MODULES=gitchain.",
|
|
15429
15592
|
"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.*`, `create-audience-map-set`/`map-slot`/`map-version`/`map-suggest`\u2192`map action=create-audience-set|slot.*|version.*|suggest`.",
|
|
15430
15593
|
"",
|
|
15431
15594
|
"## Your Workspace Principles",
|
|
@@ -15494,6 +15657,7 @@ function createProductBrainServer() {
|
|
|
15494
15657
|
registerWorkflowTools(server);
|
|
15495
15658
|
registerWorkspaceTools(server);
|
|
15496
15659
|
registerFeedbackTool(server);
|
|
15660
|
+
registerShapeTools(server);
|
|
15497
15661
|
if (enabledModules.has("gitchain")) registerGitChainTools(server);
|
|
15498
15662
|
if (enabledModules.has("gitchain")) registerMapTools(server);
|
|
15499
15663
|
registerResources(server);
|
|
@@ -15634,4 +15798,4 @@ export {
|
|
|
15634
15798
|
createProductBrainServer,
|
|
15635
15799
|
initFeatureFlags
|
|
15636
15800
|
};
|
|
15637
|
-
//# sourceMappingURL=chunk-
|
|
15801
|
+
//# sourceMappingURL=chunk-AWDYYGKN.js.map
|