@productbrain/mcp 0.0.1-beta.149 → 0.0.1-beta.150
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-H7XBZ4H3.js → chunk-ML7BPLBX.js} +101 -9
- package/dist/chunk-ML7BPLBX.js.map +1 -0
- package/dist/{chunk-MOPOQUJP.js → chunk-X3S5UTTZ.js} +52 -1
- package/dist/chunk-X3S5UTTZ.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +154 -7
- package/dist/http.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{setup-YYADLH22.js → setup-HSMGR5HL.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-H7XBZ4H3.js.map +0 -1
- package/dist/chunk-MOPOQUJP.js.map +0 -1
- /package/dist/{setup-YYADLH22.js.map → setup-HSMGR5HL.js.map} +0 -0
|
@@ -6,14 +6,21 @@ import {
|
|
|
6
6
|
trackCaptureQualityHints,
|
|
7
7
|
trackCaptureRelationSuggestions,
|
|
8
8
|
trackChainEntryCommitted,
|
|
9
|
+
trackCollectionClassified,
|
|
10
|
+
trackFieldGuidanceApplied,
|
|
11
|
+
trackFieldQualityWarning,
|
|
9
12
|
trackKnowledgeGap,
|
|
10
13
|
trackQualityCheck,
|
|
11
14
|
trackQualityVerdict,
|
|
12
15
|
trackToolCall
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-X3S5UTTZ.js";
|
|
14
17
|
|
|
15
18
|
// src/auth.ts
|
|
16
19
|
import { AsyncLocalStorage } from "async_hooks";
|
|
20
|
+
import { createHash } from "crypto";
|
|
21
|
+
function hashKey(key) {
|
|
22
|
+
return createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
23
|
+
}
|
|
17
24
|
var requestStore = new AsyncLocalStorage();
|
|
18
25
|
function runWithAuth(auth, fn) {
|
|
19
26
|
return requestStore.run(auth, fn);
|
|
@@ -996,6 +1003,21 @@ var FIELD_TYPE_DEFAULTS = {
|
|
|
996
1003
|
"date": null
|
|
997
1004
|
};
|
|
998
1005
|
|
|
1006
|
+
// src/lib/formatFieldGuidance.ts
|
|
1007
|
+
function formatFieldGuidance(fields) {
|
|
1008
|
+
const guidedFields = fields.filter((f) => f.writingGuidance);
|
|
1009
|
+
if (guidedFields.length === 0) return "";
|
|
1010
|
+
const lines = ["## Writing Guidance"];
|
|
1011
|
+
for (const field of guidedFields) {
|
|
1012
|
+
const displayName = field.label || field.key;
|
|
1013
|
+
lines.push(`- ${displayName}: ${field.writingGuidance}`);
|
|
1014
|
+
if (field.writingExamples && field.writingExamples.length > 0) {
|
|
1015
|
+
lines.push(` Examples: ${field.writingExamples.join(" | ")}`);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
return lines.join("\n");
|
|
1019
|
+
}
|
|
1020
|
+
|
|
999
1021
|
// src/lib/collectionCache.ts
|
|
1000
1022
|
var cachedCollections = null;
|
|
1001
1023
|
var cachedBySlug = null;
|
|
@@ -1908,6 +1930,20 @@ function buildClassifierMeta(resolved, overrides = {}) {
|
|
|
1908
1930
|
...overrides
|
|
1909
1931
|
};
|
|
1910
1932
|
}
|
|
1933
|
+
function emitClassificationTelemetry(resolved, workspaceId, opts) {
|
|
1934
|
+
const topAlt = resolved.alternatives?.[0] ?? null;
|
|
1935
|
+
trackCollectionClassified(workspaceId, {
|
|
1936
|
+
collection_slug: resolved.collection,
|
|
1937
|
+
thinking_layer: resolved.thinkingLayer ?? null,
|
|
1938
|
+
confidence: resolved.confidence,
|
|
1939
|
+
classified_by: resolved.classifiedBy,
|
|
1940
|
+
confidence_tier: resolved.tier,
|
|
1941
|
+
alternative_slug: topAlt?.collection ?? null,
|
|
1942
|
+
alternative_confidence: topAlt?.confidence ?? null,
|
|
1943
|
+
explicit_collection_provided: opts.explicitCollectionProvided,
|
|
1944
|
+
auto_routed: opts.autoRouted
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1911
1947
|
async function resolveCaptureCollection(params) {
|
|
1912
1948
|
const {
|
|
1913
1949
|
collection,
|
|
@@ -1929,6 +1965,10 @@ async function resolveCaptureCollection(params) {
|
|
|
1929
1965
|
overrideCommand: `capture collection="${resolved2.collection}"`
|
|
1930
1966
|
}
|
|
1931
1967
|
});
|
|
1968
|
+
emitClassificationTelemetry(resolved2, workspaceId, {
|
|
1969
|
+
explicitCollectionProvided: true,
|
|
1970
|
+
autoRouted: false
|
|
1971
|
+
});
|
|
1932
1972
|
if (!agrees) {
|
|
1933
1973
|
trackClassifierTelemetry({
|
|
1934
1974
|
workspaceId,
|
|
@@ -1975,6 +2015,10 @@ async function resolveCaptureCollection(params) {
|
|
|
1975
2015
|
}
|
|
1976
2016
|
const autoRoute = resolved.tier !== "low";
|
|
1977
2017
|
const classifierMeta = buildClassifierMeta(resolved, { autoRouted: autoRoute });
|
|
2018
|
+
emitClassificationTelemetry(resolved, workspaceId, {
|
|
2019
|
+
explicitCollectionProvided,
|
|
2020
|
+
autoRouted: autoRoute
|
|
2021
|
+
});
|
|
1978
2022
|
if (!autoRoute) {
|
|
1979
2023
|
trackClassifierTelemetry({
|
|
1980
2024
|
workspaceId,
|
|
@@ -2260,7 +2304,8 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
2260
2304
|
const colMeta = await getCollectionBySlug(resolvedCollection);
|
|
2261
2305
|
const isBetCapture = canonicalKey === "work_package" || colMeta?.defaultCanonicalKey === "work_package";
|
|
2262
2306
|
let entryWarnings = [];
|
|
2263
|
-
const
|
|
2307
|
+
const isStrategyCapture = colMeta?.thinkingLayer === "strategy";
|
|
2308
|
+
const shouldDecompose = (isStrategyCapture || isBetCapture) && description.trim().length > 0;
|
|
2264
2309
|
if (shouldDecompose) {
|
|
2265
2310
|
try {
|
|
2266
2311
|
const decomposed = await mcpCall(
|
|
@@ -2270,7 +2315,8 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
2270
2315
|
entryName: name,
|
|
2271
2316
|
description,
|
|
2272
2317
|
existingData: data,
|
|
2273
|
-
...isBetCapture ? { canonicalKey: "work_package" } : {}
|
|
2318
|
+
...isBetCapture ? { canonicalKey: "work_package" } : {},
|
|
2319
|
+
...colMeta?.thinkingLayer ? { thinkingLayer: colMeta.thinkingLayer } : {}
|
|
2274
2320
|
}
|
|
2275
2321
|
);
|
|
2276
2322
|
if (decomposed?.decomposed) {
|
|
@@ -2630,6 +2676,16 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2630
2676
|
lines.push("");
|
|
2631
2677
|
lines.push(`_To improve: \`update-entry entryId="${finalEntryId}"\` to fill missing fields._`);
|
|
2632
2678
|
}
|
|
2679
|
+
const fieldGuidanceSection = formatFieldGuidance(col.fields ?? []);
|
|
2680
|
+
if (fieldGuidanceSection) {
|
|
2681
|
+
lines.push("");
|
|
2682
|
+
lines.push(fieldGuidanceSection);
|
|
2683
|
+
const guidedFieldCount = (col.fields ?? []).filter((f) => f.writingGuidance).length;
|
|
2684
|
+
trackFieldGuidanceApplied(wsCtx.workspaceId, {
|
|
2685
|
+
collection: resolvedCollection,
|
|
2686
|
+
guided_field_count: guidedFieldCount
|
|
2687
|
+
});
|
|
2688
|
+
}
|
|
2633
2689
|
if (formativeHints.length > 0) {
|
|
2634
2690
|
lines.push("");
|
|
2635
2691
|
lines.push("## Quality Hints (advisory)");
|
|
@@ -2852,6 +2908,12 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2852
2908
|
classifiedBy = "explicit";
|
|
2853
2909
|
} else {
|
|
2854
2910
|
const resolved = classificationMap.get(entryIdx);
|
|
2911
|
+
if (resolved) {
|
|
2912
|
+
emitClassificationTelemetry(resolved, wsCtx.workspaceId, {
|
|
2913
|
+
explicitCollectionProvided: false,
|
|
2914
|
+
autoRouted: resolved.tier !== "low"
|
|
2915
|
+
});
|
|
2916
|
+
}
|
|
2855
2917
|
if (!resolved || resolved.tier === "low") {
|
|
2856
2918
|
skippedLowConfidence.push({
|
|
2857
2919
|
index: entryIdx,
|
|
@@ -2933,7 +2995,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2933
2995
|
}
|
|
2934
2996
|
}
|
|
2935
2997
|
const batchIsBet = resolvedSlug === "work-packages" || entry.canonicalKey === "work_package";
|
|
2936
|
-
const
|
|
2998
|
+
const batchIsStrategy = col?.thinkingLayer === "strategy";
|
|
2999
|
+
const shouldDecomposeBatch = (batchIsStrategy || batchIsBet) && entry.description?.trim();
|
|
2937
3000
|
let batchDecomposeWarning;
|
|
2938
3001
|
if (shouldDecomposeBatch) {
|
|
2939
3002
|
try {
|
|
@@ -2944,7 +3007,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2944
3007
|
entryName: entry.name,
|
|
2945
3008
|
description: entry.description,
|
|
2946
3009
|
existingData: data,
|
|
2947
|
-
...batchIsBet ? { canonicalKey: "work_package" } : {}
|
|
3010
|
+
...batchIsBet ? { canonicalKey: "work_package" } : {},
|
|
3011
|
+
...col?.thinkingLayer ? { thinkingLayer: col.thinkingLayer } : {}
|
|
2948
3012
|
}
|
|
2949
3013
|
);
|
|
2950
3014
|
if (decomposed?.decomposed) {
|
|
@@ -3855,6 +3919,20 @@ ${formatted}` }],
|
|
|
3855
3919
|
}
|
|
3856
3920
|
}
|
|
3857
3921
|
}
|
|
3922
|
+
const guidanceWarnings = result?.guidanceWarnings;
|
|
3923
|
+
if (guidanceWarnings && guidanceWarnings.length > 0) {
|
|
3924
|
+
lines.push("");
|
|
3925
|
+
lines.push("## Field Guidance Warnings (advisory)");
|
|
3926
|
+
for (const w of guidanceWarnings) {
|
|
3927
|
+
lines.push(`- **${w.field}:** ${w.message}`);
|
|
3928
|
+
}
|
|
3929
|
+
lines.push(`_These are advisory \u2014 the entry was committed. Use \`update-entry entryId="${entryId}"\` to address them._`);
|
|
3930
|
+
const uniqueTypes = [...new Set(guidanceWarnings.map((w) => w.warningType))];
|
|
3931
|
+
trackFieldQualityWarning(wsCtx.workspaceId, {
|
|
3932
|
+
warning_count: guidanceWarnings.length,
|
|
3933
|
+
warning_types: uniqueTypes
|
|
3934
|
+
});
|
|
3935
|
+
}
|
|
3858
3936
|
const epistemic = deriveEpistemicStatus(toEpistemicInput(entry));
|
|
3859
3937
|
if (epistemic && (epistemic.level === "hypothesis" || epistemic.level === "untested")) {
|
|
3860
3938
|
lines.push("");
|
|
@@ -5930,7 +6008,7 @@ function formatTimeAgo(ms) {
|
|
|
5930
6008
|
|
|
5931
6009
|
// src/tools/collections.ts
|
|
5932
6010
|
import { z as z8 } from "zod";
|
|
5933
|
-
var COLLECTIONS_ACTIONS = ["list", "create", "update", "describe", "audit"];
|
|
6011
|
+
var COLLECTIONS_ACTIONS = ["list", "create", "update", "describe", "audit", "export"];
|
|
5934
6012
|
var qualityCriterionSchema = z8.object({
|
|
5935
6013
|
field: z8.string().describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
|
|
5936
6014
|
rule: z8.enum(["required", "min_length", "pattern"]).describe("'required': field must be non-empty (blocks commit). 'min_length': minimum string length (warns). 'pattern': regex match (warns)."),
|
|
@@ -5956,7 +6034,7 @@ var fieldSchema = z8.object({
|
|
|
5956
6034
|
});
|
|
5957
6035
|
var collectionsSchema = z8.object({
|
|
5958
6036
|
action: z8.enum(COLLECTIONS_ACTIONS).describe(
|
|
5959
|
-
"'list': browse all collections. 'create': create a new collection. 'update': update an existing collection. 'describe': full documentation for one collection \u2014 fields, option guides, usage guidance, examples. 'audit': health report for all collections \u2014 missing classification, icon, displayHint coverage, and field schema gaps."
|
|
6037
|
+
"'list': browse all collections. 'create': create a new collection. 'update': update an existing collection. 'describe': full documentation for one collection \u2014 fields, option guides, usage guidance, examples. 'audit': health report for all collections \u2014 missing classification, icon, displayHint coverage, and field schema gaps. 'export': full system_collection_definitions export with classification metadata (thinkingLayer, classificationPriority, classificationCheck, classificationSignals, governanceRole, timelineRole, canBeElementOf, descriptionFieldKey). Admin only."
|
|
5960
6038
|
),
|
|
5961
6039
|
slug: z8.string().optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'"),
|
|
5962
6040
|
name: z8.string().optional().describe("Display name for create, or new name for update"),
|
|
@@ -5979,7 +6057,7 @@ function registerCollectionsTools(server) {
|
|
|
5979
6057
|
"collections",
|
|
5980
6058
|
{
|
|
5981
6059
|
title: "Collections",
|
|
5982
|
-
description: "Manage knowledge collections. Four actions:\n\n- **list**: Browse all collections \u2014 glossary, business rules, tracking events, etc. Returns slug, name, description, and field schema. Use before capture to see what exists.\n- **describe**: Full documentation for a single collection. Returns field help text, option decision guides, usage guidance, examples, and cross-references. Use when you need to understand a collection's purpose, field semantics, or option values.\n- **create**: Create a new collection. Provide slug, name, and field schema. Use when setting up a workspace or tracking a new type of knowledge.\n- **update**: Update an existing collection's name, description, purpose, icon, navGroup, or fields. Only provide the fields you want to change.\n- **audit**: Health report for all workspace collections. Checks classification metadata, icon presence, displayHint coverage per field, and field schema gaps vs system definitions. Returns total collections, count with issues, and per-collection issue list.",
|
|
6060
|
+
description: "Manage knowledge collections. Four actions:\n\n- **list**: Browse all collections \u2014 glossary, business rules, tracking events, etc. Returns slug, name, description, and field schema. Use before capture to see what exists.\n- **describe**: Full documentation for a single collection. Returns field help text, option decision guides, usage guidance, examples, and cross-references. Use when you need to understand a collection's purpose, field semantics, or option values.\n- **create**: Create a new collection. Provide slug, name, and field schema. Use when setting up a workspace or tracking a new type of knowledge.\n- **update**: Update an existing collection's name, description, purpose, icon, navGroup, or fields. Only provide the fields you want to change.\n- **audit**: Health report for all workspace collections. Checks classification metadata, icon presence, displayHint coverage per field, and field schema gaps vs system definitions. Returns total collections, count with issues, and per-collection issue list.\n- **export**: Full system_collection_definitions export as JSON. Includes all classification metadata (thinkingLayer, classificationPriority, classificationCheck, timelineRole, governanceRole, etc.). Admin only.",
|
|
5983
6061
|
inputSchema: collectionsSchema,
|
|
5984
6062
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
|
|
5985
6063
|
},
|
|
@@ -6016,6 +6094,9 @@ function registerCollectionsTools(server) {
|
|
|
6016
6094
|
if (action === "audit") {
|
|
6017
6095
|
return handleAudit();
|
|
6018
6096
|
}
|
|
6097
|
+
if (action === "export") {
|
|
6098
|
+
return handleExport();
|
|
6099
|
+
}
|
|
6019
6100
|
return unknownAction(action, COLLECTIONS_ACTIONS);
|
|
6020
6101
|
});
|
|
6021
6102
|
})
|
|
@@ -6282,6 +6363,16 @@ All collections are healthy.`);
|
|
|
6282
6363
|
)
|
|
6283
6364
|
};
|
|
6284
6365
|
}
|
|
6366
|
+
async function handleExport() {
|
|
6367
|
+
const definitions = await mcpQuery("chain.exportDefinitions");
|
|
6368
|
+
return {
|
|
6369
|
+
content: [{ type: "text", text: JSON.stringify(definitions, null, 2) }],
|
|
6370
|
+
structuredContent: success(
|
|
6371
|
+
`Exported ${definitions.length} system collection definitions with full classification metadata.`,
|
|
6372
|
+
{ definitions, total: definitions.length }
|
|
6373
|
+
)
|
|
6374
|
+
};
|
|
6375
|
+
}
|
|
6285
6376
|
|
|
6286
6377
|
// src/tools/labels.ts
|
|
6287
6378
|
import { z as z9 } from "zod";
|
|
@@ -15214,6 +15305,7 @@ function createProductBrainServer() {
|
|
|
15214
15305
|
}
|
|
15215
15306
|
|
|
15216
15307
|
export {
|
|
15308
|
+
hashKey,
|
|
15217
15309
|
runWithAuth,
|
|
15218
15310
|
getAgentSessionId,
|
|
15219
15311
|
startAgentSession,
|
|
@@ -15226,4 +15318,4 @@ export {
|
|
|
15226
15318
|
SERVER_VERSION,
|
|
15227
15319
|
createProductBrainServer
|
|
15228
15320
|
};
|
|
15229
|
-
//# sourceMappingURL=chunk-
|
|
15321
|
+
//# sourceMappingURL=chunk-ML7BPLBX.js.map
|