@productbrain/mcp 0.0.1-beta.134 → 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,311 +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
|
-
];
|
|
1016
|
-
var SIGNAL_WEIGHT = 10;
|
|
1017
|
-
var MIN_SCORE_FLOOR = 10;
|
|
1018
|
-
var MAX_MATCHES_PER_SIGNAL = 2;
|
|
1019
|
-
var MAX_REASON_COUNT = 3;
|
|
1020
|
-
var ENTRY_ID_PATTERN = /\b[A-Z]{2,}-\d+\b/g;
|
|
1021
|
-
var COLLECTION_SIGNALS = {
|
|
1022
|
-
decisions: [
|
|
1023
|
-
"decide",
|
|
1024
|
-
"decision",
|
|
1025
|
-
"chose",
|
|
1026
|
-
"chosen",
|
|
1027
|
-
"choice",
|
|
1028
|
-
"resolved",
|
|
1029
|
-
"we will",
|
|
1030
|
-
"we should",
|
|
1031
|
-
"approved",
|
|
1032
|
-
"replaces",
|
|
1033
|
-
"instead of",
|
|
1034
|
-
"go with",
|
|
1035
|
-
"criteria",
|
|
1036
|
-
"adopted",
|
|
1037
|
-
"reposition",
|
|
1038
|
-
"scoring framework",
|
|
1039
|
-
"review",
|
|
1040
|
-
// BET-124: tune recall 35%→≥50% — match abstained/misclassified fixture entries
|
|
1041
|
-
"guard level",
|
|
1042
|
-
"mcp-native",
|
|
1043
|
-
"pure functions",
|
|
1044
|
-
"intentional debt",
|
|
1045
|
-
"read allowlist",
|
|
1046
|
-
"safe-by-default",
|
|
1047
|
-
"map ingredients",
|
|
1048
|
-
"never per-seat",
|
|
1049
|
-
"neighborhood-first",
|
|
1050
|
-
"locked at",
|
|
1051
|
-
"ssot"
|
|
1052
|
-
],
|
|
1053
|
-
tensions: [
|
|
1054
|
-
"problem",
|
|
1055
|
-
"issue",
|
|
1056
|
-
"blocked",
|
|
1057
|
-
"blocker",
|
|
1058
|
-
"friction",
|
|
1059
|
-
"pain",
|
|
1060
|
-
"bottleneck",
|
|
1061
|
-
"struggle",
|
|
1062
|
-
"missing",
|
|
1063
|
-
"breaks",
|
|
1064
|
-
"regression",
|
|
1065
|
-
"unclear",
|
|
1066
|
-
"no way to",
|
|
1067
|
-
"scope creep",
|
|
1068
|
-
"coupled",
|
|
1069
|
-
"trapped",
|
|
1070
|
-
"ambiguous",
|
|
1071
|
-
"no batch",
|
|
1072
|
-
"undetectable",
|
|
1073
|
-
"coordination gap",
|
|
1074
|
-
// BET-124: tune recall 40%→≥50% — match abstained/misclassified fixture entries
|
|
1075
|
-
"methodology wall",
|
|
1076
|
-
"feature flag gap",
|
|
1077
|
-
"doesn't bridge",
|
|
1078
|
-
"cap limits",
|
|
1079
|
-
"trapped in",
|
|
1080
|
-
"no pan",
|
|
1081
|
-
"no zoom",
|
|
1082
|
-
"no interaction",
|
|
1083
|
-
"accuracy regression",
|
|
1084
|
-
"response bloat"
|
|
1085
|
-
],
|
|
1086
|
-
glossary: [
|
|
1087
|
-
"definition",
|
|
1088
|
-
"define",
|
|
1089
|
-
"term",
|
|
1090
|
-
"means",
|
|
1091
|
-
"refers to",
|
|
1092
|
-
"defined as",
|
|
1093
|
-
"is a term for",
|
|
1094
|
-
"is called",
|
|
1095
|
-
"vocabulary",
|
|
1096
|
-
"terminology",
|
|
1097
|
-
"a governance mechanism",
|
|
1098
|
-
"a workspace",
|
|
1099
|
-
"a tracked",
|
|
1100
|
-
"the atom",
|
|
1101
|
-
"the action of",
|
|
1102
|
-
"the versioned",
|
|
1103
|
-
"a field on",
|
|
1104
|
-
"one of the",
|
|
1105
|
-
"a constraint on",
|
|
1106
|
-
"a hard data",
|
|
1107
|
-
"a single",
|
|
1108
|
-
// BET-124: tune recall 46.7%→≥50% — definitional language, name-is-term pattern
|
|
1109
|
-
"constraint"
|
|
1110
|
-
],
|
|
1111
|
-
insights: [
|
|
1112
|
-
"insight",
|
|
1113
|
-
"learned",
|
|
1114
|
-
"observed",
|
|
1115
|
-
"trend",
|
|
1116
|
-
"found that",
|
|
1117
|
-
"discovery",
|
|
1118
|
-
"validates",
|
|
1119
|
-
"validated",
|
|
1120
|
-
"saturates",
|
|
1121
|
-
"convergence",
|
|
1122
|
-
"signals from",
|
|
1123
|
-
"signals",
|
|
1124
|
-
"converge",
|
|
1125
|
-
"tam",
|
|
1126
|
-
// BET-124: tune recall 26.7%→≥40% — research/data/learning language
|
|
1127
|
-
"thesis",
|
|
1128
|
-
"decay",
|
|
1129
|
-
"learnings",
|
|
1130
|
-
"aha moment",
|
|
1131
|
-
"data informs"
|
|
1132
|
-
],
|
|
1133
|
-
features: [
|
|
1134
|
-
"feature",
|
|
1135
|
-
"capability",
|
|
1136
|
-
"user can",
|
|
1137
|
-
"navigation",
|
|
1138
|
-
"palette",
|
|
1139
|
-
"modal",
|
|
1140
|
-
"smart capture",
|
|
1141
|
-
"suggest-links",
|
|
1142
|
-
"command palette",
|
|
1143
|
-
"auto-commit",
|
|
1144
|
-
"collection-optional",
|
|
1145
|
-
"organisation intelligence",
|
|
1146
|
-
"consolidation"
|
|
1147
|
-
],
|
|
1148
|
-
architecture: [
|
|
1149
|
-
"architecture",
|
|
1150
|
-
"layer",
|
|
1151
|
-
"data model",
|
|
1152
|
-
"infrastructure",
|
|
1153
|
-
"system design",
|
|
1154
|
-
"l1",
|
|
1155
|
-
"l2",
|
|
1156
|
-
"l3",
|
|
1157
|
-
"l4",
|
|
1158
|
-
"l5",
|
|
1159
|
-
"l6",
|
|
1160
|
-
"l7",
|
|
1161
|
-
"guard infrastructure",
|
|
1162
|
-
"data layer",
|
|
1163
|
-
"intelligence layer",
|
|
1164
|
-
"mcp layer",
|
|
1165
|
-
"core layer"
|
|
1166
|
-
],
|
|
1167
|
-
"business-rules": [
|
|
1168
|
-
"guard",
|
|
1169
|
-
"enforce",
|
|
1170
|
-
"integrity",
|
|
1171
|
-
"prevents",
|
|
1172
|
-
"excludes",
|
|
1173
|
-
"permitted",
|
|
1174
|
-
"policy",
|
|
1175
|
-
"feature gate",
|
|
1176
|
-
"must not",
|
|
1177
|
-
"only permitted",
|
|
1178
|
-
"closed enum",
|
|
1179
|
-
"write guard",
|
|
1180
|
-
"never imports",
|
|
1181
|
-
"requires active session",
|
|
1182
|
-
"readiness excludes"
|
|
1183
|
-
],
|
|
1184
|
-
// tracking-events: removed (Tier 1 Hierarchy — 0 entries, collection deprecated)
|
|
1185
|
-
landscape: [
|
|
1186
|
-
"competitor",
|
|
1187
|
-
"alternative tool",
|
|
1188
|
-
"alternative platform",
|
|
1189
|
-
"competing product",
|
|
1190
|
-
"landscape",
|
|
1191
|
-
"comparison"
|
|
1192
|
-
],
|
|
1193
|
-
standards: [
|
|
1194
|
-
"standard",
|
|
1195
|
-
"convention",
|
|
1196
|
-
"trunk-based",
|
|
1197
|
-
"alignment-first",
|
|
1198
|
-
"structured bet",
|
|
1199
|
-
"system fixes",
|
|
1200
|
-
"patches"
|
|
1201
|
-
],
|
|
1202
|
-
principles: [
|
|
1203
|
-
"we believe",
|
|
1204
|
-
"principle",
|
|
1205
|
-
"compounds",
|
|
1206
|
-
"philosophy",
|
|
1207
|
-
"simplicity compounds",
|
|
1208
|
-
"trust through",
|
|
1209
|
-
"evidence over",
|
|
1210
|
-
"compensate for",
|
|
1211
|
-
"honest by default"
|
|
1212
|
-
],
|
|
1213
|
-
assumptions: [
|
|
1214
|
-
"assume",
|
|
1215
|
-
"assumption",
|
|
1216
|
-
"hypothesis",
|
|
1217
|
-
"untested",
|
|
1218
|
-
"we think",
|
|
1219
|
-
"we assume",
|
|
1220
|
-
"needs validation"
|
|
1221
|
-
],
|
|
1222
|
-
patterns: [
|
|
1223
|
-
"pattern",
|
|
1224
|
-
"anti-pattern",
|
|
1225
|
-
"best practice",
|
|
1226
|
-
"reusable solution",
|
|
1227
|
-
"design pattern",
|
|
1228
|
-
"recurring solution",
|
|
1229
|
-
"template",
|
|
1230
|
-
"proven approach"
|
|
1231
|
-
],
|
|
1232
|
-
"work-packages": [
|
|
1233
|
-
"appetite",
|
|
1234
|
-
"elements",
|
|
1235
|
-
"no-gos",
|
|
1236
|
-
"no gos",
|
|
1237
|
-
"problem",
|
|
1238
|
-
"solution",
|
|
1239
|
-
"done when",
|
|
1240
|
-
"doneWhen",
|
|
1241
|
-
"rabbit hole",
|
|
1242
|
-
"rabbit holes",
|
|
1243
|
-
"build sequence",
|
|
1244
|
-
"build contract",
|
|
1245
|
-
"slice",
|
|
1246
|
-
"bet",
|
|
1247
|
-
"shaping",
|
|
1248
|
-
"shape up"
|
|
1249
|
-
]
|
|
1250
|
-
};
|
|
1251
|
-
function escapeRegExp(text) {
|
|
1252
|
-
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1253
|
-
}
|
|
1254
|
-
function countSignalMatches(text, signal) {
|
|
1255
|
-
const trimmed = signal.trim().toLowerCase();
|
|
1256
|
-
if (!trimmed) return 0;
|
|
1257
|
-
const words = trimmed.split(/\s+/).map(escapeRegExp);
|
|
1258
|
-
const pattern = `\\b${words.join("\\s+")}\\b`;
|
|
1259
|
-
const regex = new RegExp(pattern, "g");
|
|
1260
|
-
const matches = text.match(regex);
|
|
1261
|
-
return matches?.length ?? 0;
|
|
1262
|
-
}
|
|
1263
|
-
function classifyCollection(name, description) {
|
|
1264
|
-
const text = `${name} ${description}`.replace(ENTRY_ID_PATTERN, "").toLowerCase();
|
|
1265
|
-
const rawScores = [];
|
|
1266
|
-
for (const collection of CLASSIFIABLE_COLLECTIONS) {
|
|
1267
|
-
const signals = COLLECTION_SIGNALS[collection];
|
|
1268
|
-
const reasons = [];
|
|
1269
|
-
let score = 0;
|
|
1270
|
-
for (const signal of signals) {
|
|
1271
|
-
const matches = countSignalMatches(text, signal);
|
|
1272
|
-
if (matches <= 0) continue;
|
|
1273
|
-
const cappedMatches = Math.min(matches, MAX_MATCHES_PER_SIGNAL);
|
|
1274
|
-
score += cappedMatches * SIGNAL_WEIGHT;
|
|
1275
|
-
if (reasons.length < MAX_REASON_COUNT) {
|
|
1276
|
-
const capNote = matches > cappedMatches ? ` (capped at ${cappedMatches})` : "";
|
|
1277
|
-
reasons.push(`matched "${signal}" x${matches}${capNote}`);
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
|
-
rawScores.push({ collection, score, reasons });
|
|
1281
|
-
}
|
|
1282
|
-
rawScores.sort((left, right) => right.score - left.score);
|
|
1283
|
-
const top = rawScores[0];
|
|
1284
|
-
const second = rawScores[1];
|
|
1285
|
-
if (!top || top.score < MIN_SCORE_FLOOR) return null;
|
|
1286
|
-
const margin = Math.max(0, top.score - (second?.score ?? 0));
|
|
1287
|
-
if (margin === 0 && top.score <= MIN_SCORE_FLOOR) return null;
|
|
1288
|
-
const baseConfidence = Math.min(90, top.score);
|
|
1289
|
-
const confidence = Math.min(99, baseConfidence + Math.min(20, margin));
|
|
1290
|
-
return {
|
|
1291
|
-
collection: top.collection,
|
|
1292
|
-
topConfidence: confidence,
|
|
1293
|
-
confidence,
|
|
1294
|
-
reasons: top.reasons,
|
|
1295
|
-
scoreMargin: margin,
|
|
1296
|
-
candidates: rawScores.filter((candidate) => candidate.score > 0).slice(0, 3).map((candidate) => ({
|
|
1297
|
-
collection: candidate.collection,
|
|
1298
|
-
signalScore: Math.min(99, candidate.score),
|
|
1299
|
-
confidence: Math.min(99, candidate.score)
|
|
1300
|
-
}))
|
|
1301
|
-
};
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
999
|
// src/tools/smart-capture.ts
|
|
1305
1000
|
function normalizeMatchText(value) {
|
|
1306
1001
|
return value.toLowerCase().replace(/[^a-z0-9]+/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -13308,9 +13003,23 @@ function extractSessionEntryIds(priorSessions) {
|
|
|
13308
13003
|
}
|
|
13309
13004
|
return { all, lastSessionOnly };
|
|
13310
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
|
+
];
|
|
13311
13019
|
var orientSchema = z22.object({
|
|
13312
13020
|
mode: z22.enum(["full", "brief"]).optional().default("full").describe("full = full context (default). brief = compact summary for mid-session re-orientation."),
|
|
13313
|
-
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(", ")}.`)
|
|
13314
13023
|
});
|
|
13315
13024
|
function taskGroundingWarningLines(task, hasTaskGrounding = false) {
|
|
13316
13025
|
if (hasTaskGrounding) return [];
|
|
@@ -13336,12 +13045,15 @@ function registerOrientTool(server) {
|
|
|
13336
13045
|
"orient",
|
|
13337
13046
|
{
|
|
13338
13047
|
title: "Orient \u2014 Start Here",
|
|
13339
|
-
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.",
|
|
13340
13049
|
inputSchema: orientSchema,
|
|
13341
13050
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
13342
13051
|
},
|
|
13343
|
-
withEnvelope(async ({ mode = "full", task
|
|
13052
|
+
withEnvelope(async ({ mode = "full", task, scope }) => {
|
|
13344
13053
|
const errors = [];
|
|
13054
|
+
if (scope && !task) {
|
|
13055
|
+
errors.push("--scope requires --task to filter governance. Scope was ignored.");
|
|
13056
|
+
}
|
|
13345
13057
|
const agentSessionId = getAgentSessionId();
|
|
13346
13058
|
if (isSessionOriented() && mode === "brief" && !task) {
|
|
13347
13059
|
return {
|
|
@@ -13382,6 +13094,7 @@ function registerOrientTool(server) {
|
|
|
13382
13094
|
try {
|
|
13383
13095
|
const orientArgs = {};
|
|
13384
13096
|
if (task) orientArgs.task = task;
|
|
13097
|
+
if (scope) orientArgs.scope = scope;
|
|
13385
13098
|
if (sessionEntryIds.length > 0) orientArgs.sessionEntryIds = sessionEntryIds;
|
|
13386
13099
|
if (lastSessionOnly.length > 0) orientArgs.lastSessionEntryIds = lastSessionOnly;
|
|
13387
13100
|
orientEntries = await mcpQuery("chain.getOrientEntries", orientArgs);
|
|
@@ -14028,16 +13741,15 @@ function buildSessionSummary(log) {
|
|
|
14028
13741
|
}
|
|
14029
13742
|
return lines.join("\n");
|
|
14030
13743
|
}
|
|
14031
|
-
function computeOrganisationHealth(entries) {
|
|
13744
|
+
function computeOrganisationHealth(entries, classifications) {
|
|
14032
13745
|
let agreements = 0;
|
|
14033
13746
|
let disagreements = 0;
|
|
14034
13747
|
let abstentions = 0;
|
|
14035
13748
|
const flagMap = /* @__PURE__ */ new Map();
|
|
14036
|
-
for (
|
|
14037
|
-
const slug =
|
|
14038
|
-
const
|
|
14039
|
-
|
|
14040
|
-
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) {
|
|
14041
13753
|
abstentions++;
|
|
14042
13754
|
continue;
|
|
14043
13755
|
}
|
|
@@ -14077,7 +13789,15 @@ async function fetchOrganisationHealth() {
|
|
|
14077
13789
|
try {
|
|
14078
13790
|
const allEntries = await mcpQuery("chain.listEntries", { status: "active" });
|
|
14079
13791
|
if (!allEntries || allEntries.length === 0) return null;
|
|
14080
|
-
|
|
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);
|
|
14081
13801
|
} catch (err) {
|
|
14082
13802
|
process.stderr.write(`[MCP] fetchOrganisationHealth failed: ${err.message}
|
|
14083
13803
|
`);
|
|
@@ -15449,4 +15169,4 @@ export {
|
|
|
15449
15169
|
SERVER_VERSION,
|
|
15450
15170
|
createProductBrainServer
|
|
15451
15171
|
};
|
|
15452
|
-
//# sourceMappingURL=chunk-
|
|
15172
|
+
//# sourceMappingURL=chunk-YKDHYK3Q.js.map
|