@productbrain/mcp 0.0.1-beta.135 → 0.0.1-beta.137
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.
|
@@ -996,326 +996,6 @@ var FIELD_TYPE_DEFAULTS = {
|
|
|
996
996
|
"date": null
|
|
997
997
|
};
|
|
998
998
|
|
|
999
|
-
// src/lib/collectionRoutingClassifier.ts
|
|
1000
|
-
var CLASSIFIABLE_COLLECTIONS = [
|
|
1001
|
-
"decisions",
|
|
1002
|
-
"tensions",
|
|
1003
|
-
"glossary",
|
|
1004
|
-
"insights",
|
|
1005
|
-
"features",
|
|
1006
|
-
"architecture",
|
|
1007
|
-
"business-rules",
|
|
1008
|
-
// tracking-events: removed (Tier 1 Hierarchy — 0 entries, collection deprecated)
|
|
1009
|
-
"landscape",
|
|
1010
|
-
"standards",
|
|
1011
|
-
"principles",
|
|
1012
|
-
"assumptions",
|
|
1013
|
-
"work-packages",
|
|
1014
|
-
"patterns",
|
|
1015
|
-
// BET-274: Capabilities collection
|
|
1016
|
-
"capabilities"
|
|
1017
|
-
];
|
|
1018
|
-
var SIGNAL_WEIGHT = 10;
|
|
1019
|
-
var MIN_SCORE_FLOOR = 10;
|
|
1020
|
-
var MAX_MATCHES_PER_SIGNAL = 2;
|
|
1021
|
-
var MAX_REASON_COUNT = 3;
|
|
1022
|
-
var ENTRY_ID_PATTERN = /\b[A-Z]{2,}-\d+\b/g;
|
|
1023
|
-
var COLLECTION_SIGNALS = {
|
|
1024
|
-
decisions: [
|
|
1025
|
-
"decide",
|
|
1026
|
-
"decision",
|
|
1027
|
-
"chose",
|
|
1028
|
-
"chosen",
|
|
1029
|
-
"choice",
|
|
1030
|
-
"resolved",
|
|
1031
|
-
"we will",
|
|
1032
|
-
"we should",
|
|
1033
|
-
"approved",
|
|
1034
|
-
"replaces",
|
|
1035
|
-
"instead of",
|
|
1036
|
-
"go with",
|
|
1037
|
-
"criteria",
|
|
1038
|
-
"adopted",
|
|
1039
|
-
"reposition",
|
|
1040
|
-
"scoring framework",
|
|
1041
|
-
"review",
|
|
1042
|
-
// BET-124: tune recall 35%→≥50% — match abstained/misclassified fixture entries
|
|
1043
|
-
"guard level",
|
|
1044
|
-
"mcp-native",
|
|
1045
|
-
"pure functions",
|
|
1046
|
-
"intentional debt",
|
|
1047
|
-
"read allowlist",
|
|
1048
|
-
"safe-by-default",
|
|
1049
|
-
"map ingredients",
|
|
1050
|
-
"never per-seat",
|
|
1051
|
-
"neighborhood-first",
|
|
1052
|
-
"locked at",
|
|
1053
|
-
"ssot"
|
|
1054
|
-
],
|
|
1055
|
-
tensions: [
|
|
1056
|
-
"problem",
|
|
1057
|
-
"issue",
|
|
1058
|
-
"blocked",
|
|
1059
|
-
"blocker",
|
|
1060
|
-
"friction",
|
|
1061
|
-
"pain",
|
|
1062
|
-
"bottleneck",
|
|
1063
|
-
"struggle",
|
|
1064
|
-
"missing",
|
|
1065
|
-
"breaks",
|
|
1066
|
-
"regression",
|
|
1067
|
-
"unclear",
|
|
1068
|
-
"no way to",
|
|
1069
|
-
"scope creep",
|
|
1070
|
-
"coupled",
|
|
1071
|
-
"trapped",
|
|
1072
|
-
"ambiguous",
|
|
1073
|
-
"no batch",
|
|
1074
|
-
"undetectable",
|
|
1075
|
-
"coordination gap",
|
|
1076
|
-
// BET-124: tune recall 40%→≥50% — match abstained/misclassified fixture entries
|
|
1077
|
-
"methodology wall",
|
|
1078
|
-
"feature flag gap",
|
|
1079
|
-
"doesn't bridge",
|
|
1080
|
-
"cap limits",
|
|
1081
|
-
"trapped in",
|
|
1082
|
-
"no pan",
|
|
1083
|
-
"no zoom",
|
|
1084
|
-
"no interaction",
|
|
1085
|
-
"accuracy regression",
|
|
1086
|
-
"response bloat"
|
|
1087
|
-
],
|
|
1088
|
-
glossary: [
|
|
1089
|
-
"definition",
|
|
1090
|
-
"define",
|
|
1091
|
-
"term",
|
|
1092
|
-
"means",
|
|
1093
|
-
"refers to",
|
|
1094
|
-
"defined as",
|
|
1095
|
-
"is a term for",
|
|
1096
|
-
"is called",
|
|
1097
|
-
"vocabulary",
|
|
1098
|
-
"terminology",
|
|
1099
|
-
"a governance mechanism",
|
|
1100
|
-
"a workspace",
|
|
1101
|
-
"a tracked",
|
|
1102
|
-
"the atom",
|
|
1103
|
-
"the action of",
|
|
1104
|
-
"the versioned",
|
|
1105
|
-
"a field on",
|
|
1106
|
-
"one of the",
|
|
1107
|
-
"a constraint on",
|
|
1108
|
-
"a hard data",
|
|
1109
|
-
"a single",
|
|
1110
|
-
// BET-124: tune recall 46.7%→≥50% — definitional language, name-is-term pattern
|
|
1111
|
-
"constraint"
|
|
1112
|
-
],
|
|
1113
|
-
insights: [
|
|
1114
|
-
"insight",
|
|
1115
|
-
"learned",
|
|
1116
|
-
"observed",
|
|
1117
|
-
"trend",
|
|
1118
|
-
"found that",
|
|
1119
|
-
"discovery",
|
|
1120
|
-
"validates",
|
|
1121
|
-
"validated",
|
|
1122
|
-
"saturates",
|
|
1123
|
-
"convergence",
|
|
1124
|
-
"signals from",
|
|
1125
|
-
"signals",
|
|
1126
|
-
"converge",
|
|
1127
|
-
"tam",
|
|
1128
|
-
// BET-124: tune recall 26.7%→≥40% — research/data/learning language
|
|
1129
|
-
"thesis",
|
|
1130
|
-
"decay",
|
|
1131
|
-
"learnings",
|
|
1132
|
-
"aha moment",
|
|
1133
|
-
"data informs"
|
|
1134
|
-
],
|
|
1135
|
-
features: [
|
|
1136
|
-
"feature",
|
|
1137
|
-
"capability",
|
|
1138
|
-
"user can",
|
|
1139
|
-
"navigation",
|
|
1140
|
-
"palette",
|
|
1141
|
-
"modal",
|
|
1142
|
-
"smart capture",
|
|
1143
|
-
"suggest-links",
|
|
1144
|
-
"command palette",
|
|
1145
|
-
"auto-commit",
|
|
1146
|
-
"collection-optional",
|
|
1147
|
-
"organisation intelligence",
|
|
1148
|
-
"consolidation"
|
|
1149
|
-
],
|
|
1150
|
-
architecture: [
|
|
1151
|
-
"architecture",
|
|
1152
|
-
"layer",
|
|
1153
|
-
"data model",
|
|
1154
|
-
"infrastructure",
|
|
1155
|
-
"system design",
|
|
1156
|
-
"l1",
|
|
1157
|
-
"l2",
|
|
1158
|
-
"l3",
|
|
1159
|
-
"l4",
|
|
1160
|
-
"l5",
|
|
1161
|
-
"l6",
|
|
1162
|
-
"l7",
|
|
1163
|
-
"guard infrastructure",
|
|
1164
|
-
"data layer",
|
|
1165
|
-
"intelligence layer",
|
|
1166
|
-
"mcp layer",
|
|
1167
|
-
"core layer"
|
|
1168
|
-
],
|
|
1169
|
-
"business-rules": [
|
|
1170
|
-
"guard",
|
|
1171
|
-
"enforce",
|
|
1172
|
-
"integrity",
|
|
1173
|
-
"prevents",
|
|
1174
|
-
"excludes",
|
|
1175
|
-
"permitted",
|
|
1176
|
-
"policy",
|
|
1177
|
-
"feature gate",
|
|
1178
|
-
"must not",
|
|
1179
|
-
"only permitted",
|
|
1180
|
-
"closed enum",
|
|
1181
|
-
"write guard",
|
|
1182
|
-
"never imports",
|
|
1183
|
-
"requires active session",
|
|
1184
|
-
"readiness excludes"
|
|
1185
|
-
],
|
|
1186
|
-
// tracking-events: removed (Tier 1 Hierarchy — 0 entries, collection deprecated)
|
|
1187
|
-
landscape: [
|
|
1188
|
-
"competitor",
|
|
1189
|
-
"alternative tool",
|
|
1190
|
-
"alternative platform",
|
|
1191
|
-
"competing product",
|
|
1192
|
-
"landscape",
|
|
1193
|
-
"comparison"
|
|
1194
|
-
],
|
|
1195
|
-
standards: [
|
|
1196
|
-
"standard",
|
|
1197
|
-
"convention",
|
|
1198
|
-
"trunk-based",
|
|
1199
|
-
"alignment-first",
|
|
1200
|
-
"structured bet",
|
|
1201
|
-
"system fixes",
|
|
1202
|
-
"patches"
|
|
1203
|
-
],
|
|
1204
|
-
principles: [
|
|
1205
|
-
"we believe",
|
|
1206
|
-
"principle",
|
|
1207
|
-
"compounds",
|
|
1208
|
-
"philosophy",
|
|
1209
|
-
"simplicity compounds",
|
|
1210
|
-
"trust through",
|
|
1211
|
-
"evidence over",
|
|
1212
|
-
"compensate for",
|
|
1213
|
-
"honest by default"
|
|
1214
|
-
],
|
|
1215
|
-
assumptions: [
|
|
1216
|
-
"assume",
|
|
1217
|
-
"assumption",
|
|
1218
|
-
"hypothesis",
|
|
1219
|
-
"untested",
|
|
1220
|
-
"we think",
|
|
1221
|
-
"we assume",
|
|
1222
|
-
"needs validation"
|
|
1223
|
-
],
|
|
1224
|
-
patterns: [
|
|
1225
|
-
"pattern",
|
|
1226
|
-
"anti-pattern",
|
|
1227
|
-
"best practice",
|
|
1228
|
-
"reusable solution",
|
|
1229
|
-
"design pattern",
|
|
1230
|
-
"recurring solution",
|
|
1231
|
-
"template",
|
|
1232
|
-
"proven approach"
|
|
1233
|
-
],
|
|
1234
|
-
capabilities: [
|
|
1235
|
-
"capability",
|
|
1236
|
-
"capabilities",
|
|
1237
|
-
"can do",
|
|
1238
|
-
"supply-side",
|
|
1239
|
-
"product capability",
|
|
1240
|
-
"what the product does",
|
|
1241
|
-
"mature",
|
|
1242
|
-
"emerging",
|
|
1243
|
-
"declining",
|
|
1244
|
-
"platform capability",
|
|
1245
|
-
"infrastructure capability"
|
|
1246
|
-
],
|
|
1247
|
-
"work-packages": [
|
|
1248
|
-
"appetite",
|
|
1249
|
-
"elements",
|
|
1250
|
-
"no-gos",
|
|
1251
|
-
"no gos",
|
|
1252
|
-
"problem",
|
|
1253
|
-
"solution",
|
|
1254
|
-
"done when",
|
|
1255
|
-
"doneWhen",
|
|
1256
|
-
"rabbit hole",
|
|
1257
|
-
"rabbit holes",
|
|
1258
|
-
"build sequence",
|
|
1259
|
-
"build contract",
|
|
1260
|
-
"slice",
|
|
1261
|
-
"bet",
|
|
1262
|
-
"shaping",
|
|
1263
|
-
"shape up"
|
|
1264
|
-
]
|
|
1265
|
-
};
|
|
1266
|
-
function escapeRegExp(text) {
|
|
1267
|
-
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1268
|
-
}
|
|
1269
|
-
function countSignalMatches(text, signal) {
|
|
1270
|
-
const trimmed = signal.trim().toLowerCase();
|
|
1271
|
-
if (!trimmed) return 0;
|
|
1272
|
-
const words = trimmed.split(/\s+/).map(escapeRegExp);
|
|
1273
|
-
const pattern = `\\b${words.join("\\s+")}\\b`;
|
|
1274
|
-
const regex = new RegExp(pattern, "g");
|
|
1275
|
-
const matches = text.match(regex);
|
|
1276
|
-
return matches?.length ?? 0;
|
|
1277
|
-
}
|
|
1278
|
-
function classifyCollection(name, description) {
|
|
1279
|
-
const text = `${name} ${description}`.replace(ENTRY_ID_PATTERN, "").toLowerCase();
|
|
1280
|
-
const rawScores = [];
|
|
1281
|
-
for (const collection of CLASSIFIABLE_COLLECTIONS) {
|
|
1282
|
-
const signals = COLLECTION_SIGNALS[collection];
|
|
1283
|
-
const reasons = [];
|
|
1284
|
-
let score = 0;
|
|
1285
|
-
for (const signal of signals) {
|
|
1286
|
-
const matches = countSignalMatches(text, signal);
|
|
1287
|
-
if (matches <= 0) continue;
|
|
1288
|
-
const cappedMatches = Math.min(matches, MAX_MATCHES_PER_SIGNAL);
|
|
1289
|
-
score += cappedMatches * SIGNAL_WEIGHT;
|
|
1290
|
-
if (reasons.length < MAX_REASON_COUNT) {
|
|
1291
|
-
const capNote = matches > cappedMatches ? ` (capped at ${cappedMatches})` : "";
|
|
1292
|
-
reasons.push(`matched "${signal}" x${matches}${capNote}`);
|
|
1293
|
-
}
|
|
1294
|
-
}
|
|
1295
|
-
rawScores.push({ collection, score, reasons });
|
|
1296
|
-
}
|
|
1297
|
-
rawScores.sort((left, right) => right.score - left.score);
|
|
1298
|
-
const top = rawScores[0];
|
|
1299
|
-
const second = rawScores[1];
|
|
1300
|
-
if (!top || top.score < MIN_SCORE_FLOOR) return null;
|
|
1301
|
-
const margin = Math.max(0, top.score - (second?.score ?? 0));
|
|
1302
|
-
if (margin === 0 && top.score <= MIN_SCORE_FLOOR) return null;
|
|
1303
|
-
const baseConfidence = Math.min(90, top.score);
|
|
1304
|
-
const confidence = Math.min(99, baseConfidence + Math.min(20, margin));
|
|
1305
|
-
return {
|
|
1306
|
-
collection: top.collection,
|
|
1307
|
-
topConfidence: confidence,
|
|
1308
|
-
confidence,
|
|
1309
|
-
reasons: top.reasons,
|
|
1310
|
-
scoreMargin: margin,
|
|
1311
|
-
candidates: rawScores.filter((candidate) => candidate.score > 0).slice(0, 3).map((candidate) => ({
|
|
1312
|
-
collection: candidate.collection,
|
|
1313
|
-
signalScore: Math.min(99, candidate.score),
|
|
1314
|
-
confidence: Math.min(99, candidate.score)
|
|
1315
|
-
}))
|
|
1316
|
-
};
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1319
999
|
// src/tools/smart-capture.ts
|
|
1320
1000
|
function normalizeMatchText(value) {
|
|
1321
1001
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -13323,9 +13003,23 @@ function extractSessionEntryIds(priorSessions) {
|
|
|
13323
13003
|
}
|
|
13324
13004
|
return { all, lastSessionOnly };
|
|
13325
13005
|
}
|
|
13006
|
+
var VALID_TASK_DOMAINS = [
|
|
13007
|
+
"auth",
|
|
13008
|
+
"governance",
|
|
13009
|
+
"architecture",
|
|
13010
|
+
"product",
|
|
13011
|
+
"data-foundation",
|
|
13012
|
+
"chainwork",
|
|
13013
|
+
"capture-pipeline",
|
|
13014
|
+
"ingestion",
|
|
13015
|
+
"intelligence-and-operations",
|
|
13016
|
+
"review-and-learning",
|
|
13017
|
+
"general"
|
|
13018
|
+
];
|
|
13326
13019
|
var orientSchema = z22.object({
|
|
13327
13020
|
mode: z22.enum(["full", "brief"]).optional().default("full").describe("full = full context (default). brief = compact summary for mid-session re-orientation."),
|
|
13328
|
-
task: z22.string().optional().describe("Natural-language task description for task-scoped context. When provided, orient returns scored, relevant entries for the task.")
|
|
13021
|
+
task: z22.string().optional().describe("Natural-language task description for task-scoped context. When provided, orient returns scored, relevant entries for the task."),
|
|
13022
|
+
scope: z22.enum(VALID_TASK_DOMAINS).optional().describe(`Optional domain scope to filter governance to entries relevant for this domain. Valid values: ${VALID_TASK_DOMAINS.join(", ")}.`)
|
|
13329
13023
|
});
|
|
13330
13024
|
function taskGroundingWarningLines(task, hasTaskGrounding = false) {
|
|
13331
13025
|
if (hasTaskGrounding) return [];
|
|
@@ -13351,12 +13045,15 @@ function registerOrientTool(server) {
|
|
|
13351
13045
|
"orient",
|
|
13352
13046
|
{
|
|
13353
13047
|
title: "Orient \u2014 Start Here",
|
|
13354
|
-
description: "The single entry point for starting a session. Returns workspace context with a single recommended next action for low-readiness workspaces, or a standup-style briefing for established workspaces.\n\nUse this FIRST. One call to orient replaces 3\u20135 individual tool calls.\n\nCompleting orientation unlocks write tools for the active session.\n\n**mode:** `full` (default) returns full context. `brief` returns only vision, bet/tension counts, readiness, active bet names, and last-session summary \u2014 use for mid-session re-orientation.\n\n**task:** Optional natural-language task description. When provided, returns task-scoped context (scored, relevant entries) in addition to standard orient sections.",
|
|
13048
|
+
description: "The single entry point for starting a session. Returns workspace context with a single recommended next action for low-readiness workspaces, or a standup-style briefing for established workspaces.\n\nUse this FIRST. One call to orient replaces 3\u20135 individual tool calls.\n\nCompleting orientation unlocks write tools for the active session.\n\n**mode:** `full` (default) returns full context. `brief` returns only vision, bet/tension counts, readiness, active bet names, and last-session summary \u2014 use for mid-session re-orientation.\n\n**task:** Optional natural-language task description. When provided, returns task-scoped context (scored, relevant entries) in addition to standard orient sections.\n\n**scope:** Optional domain scope. Filters governance entries to those relevant for the specified domain. Valid values: auth, governance, architecture, product, data-foundation, chainwork, capture-pipeline, ingestion, intelligence-and-operations, review-and-learning, general.",
|
|
13355
13049
|
inputSchema: orientSchema,
|
|
13356
13050
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
13357
13051
|
},
|
|
13358
|
-
withEnvelope(async ({ mode = "full", task
|
|
13052
|
+
withEnvelope(async ({ mode = "full", task, scope }) => {
|
|
13359
13053
|
const errors = [];
|
|
13054
|
+
if (scope && !task) {
|
|
13055
|
+
errors.push("--scope requires --task to filter governance. Scope was ignored.");
|
|
13056
|
+
}
|
|
13360
13057
|
const agentSessionId = getAgentSessionId();
|
|
13361
13058
|
if (isSessionOriented() && mode === "brief" && !task) {
|
|
13362
13059
|
return {
|
|
@@ -13397,6 +13094,7 @@ function registerOrientTool(server) {
|
|
|
13397
13094
|
try {
|
|
13398
13095
|
const orientArgs = {};
|
|
13399
13096
|
if (task) orientArgs.task = task;
|
|
13097
|
+
if (scope) orientArgs.scope = scope;
|
|
13400
13098
|
if (sessionEntryIds.length > 0) orientArgs.sessionEntryIds = sessionEntryIds;
|
|
13401
13099
|
if (lastSessionOnly.length > 0) orientArgs.lastSessionEntryIds = lastSessionOnly;
|
|
13402
13100
|
orientEntries = await mcpQuery("chain.getOrientEntries", orientArgs);
|
|
@@ -14043,16 +13741,15 @@ function buildSessionSummary(log) {
|
|
|
14043
13741
|
}
|
|
14044
13742
|
return lines.join("\n");
|
|
14045
13743
|
}
|
|
14046
|
-
function computeOrganisationHealth(entries) {
|
|
13744
|
+
function computeOrganisationHealth(entries, classifications) {
|
|
14047
13745
|
let agreements = 0;
|
|
14048
13746
|
let disagreements = 0;
|
|
14049
13747
|
let abstentions = 0;
|
|
14050
13748
|
const flagMap = /* @__PURE__ */ new Map();
|
|
14051
|
-
for (
|
|
14052
|
-
const slug =
|
|
14053
|
-
const
|
|
14054
|
-
|
|
14055
|
-
if (!result) {
|
|
13749
|
+
for (let i = 0; i < entries.length; i++) {
|
|
13750
|
+
const slug = entries[i].collectionSlug ?? entries[i].collection ?? "unknown";
|
|
13751
|
+
const result = classifications[i];
|
|
13752
|
+
if (!result?.collection) {
|
|
14056
13753
|
abstentions++;
|
|
14057
13754
|
continue;
|
|
14058
13755
|
}
|
|
@@ -14092,7 +13789,15 @@ async function fetchOrganisationHealth() {
|
|
|
14092
13789
|
try {
|
|
14093
13790
|
const allEntries = await mcpQuery("chain.listEntries", { status: "active" });
|
|
14094
13791
|
if (!allEntries || allEntries.length === 0) return null;
|
|
14095
|
-
|
|
13792
|
+
const classifyInput = allEntries.map((e) => ({
|
|
13793
|
+
name: e.name ?? "",
|
|
13794
|
+
description: typeof e.data?.description === "string" ? e.data.description : ""
|
|
13795
|
+
}));
|
|
13796
|
+
const classifications = await mcpQuery(
|
|
13797
|
+
"chain.batchClassifyHeuristic",
|
|
13798
|
+
{ entries: classifyInput }
|
|
13799
|
+
);
|
|
13800
|
+
return computeOrganisationHealth(allEntries, classifications);
|
|
14096
13801
|
} catch (err) {
|
|
14097
13802
|
process.stderr.write(`[MCP] fetchOrganisationHealth failed: ${err.message}
|
|
14098
13803
|
`);
|
|
@@ -15464,4 +15169,4 @@ export {
|
|
|
15464
15169
|
SERVER_VERSION,
|
|
15465
15170
|
createProductBrainServer
|
|
15466
15171
|
};
|
|
15467
|
-
//# sourceMappingURL=chunk-
|
|
15172
|
+
//# sourceMappingURL=chunk-YKDHYK3Q.js.map
|