@productbrain/mcp 0.0.1-beta.6459 → 0.0.1-beta.6461
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.
|
@@ -847,6 +847,169 @@ async function resolveCollection(params) {
|
|
|
847
847
|
return result2 ?? null;
|
|
848
848
|
}
|
|
849
849
|
|
|
850
|
+
// src/tools/coherency-refusal.ts
|
|
851
|
+
function asDescription(value) {
|
|
852
|
+
if (typeof value !== "string") return void 0;
|
|
853
|
+
const trimmed = value.trim();
|
|
854
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
855
|
+
}
|
|
856
|
+
var GENERIC_RECOVERY_LINE = "Respond and retry: link the entry to the strategic spine, pass `coherencyAcknowledgement`, or supply a typed `steeringOverrideReason`.";
|
|
857
|
+
function coherencyRefusedResult(toolName, entryId, refusal, options) {
|
|
858
|
+
const headingLevel = options?.headingLevel ?? 1;
|
|
859
|
+
const heading = "#".repeat(headingLevel);
|
|
860
|
+
const lines = [
|
|
861
|
+
`${heading} Write refused by the coherency gate`,
|
|
862
|
+
"",
|
|
863
|
+
refusal.reason ?? `The coherency gate refused this write on ${entryId}.`
|
|
864
|
+
];
|
|
865
|
+
if (refusal.subject?.name) {
|
|
866
|
+
lines.push(`On: ${refusal.subject.name}`);
|
|
867
|
+
}
|
|
868
|
+
if (refusal.mode) {
|
|
869
|
+
lines.push("", `Mode: ${refusal.mode}`);
|
|
870
|
+
}
|
|
871
|
+
const routes = refusal.routes;
|
|
872
|
+
const routeKeys = routes ? Object.keys(routes) : [];
|
|
873
|
+
if (routeKeys.length > 0) {
|
|
874
|
+
lines.push("", `${"#".repeat(headingLevel + 1)} Recovery routes`);
|
|
875
|
+
const beforeRoutes = lines.length;
|
|
876
|
+
if (routes && typeof routes.link === "object" && routes.link !== null) {
|
|
877
|
+
const link = routes.link;
|
|
878
|
+
lines.push(`- **link:** ${asDescription(link.description) ?? "Link the entry to the strategic spine."}`);
|
|
879
|
+
}
|
|
880
|
+
if (routes && typeof routes.acknowledge === "object" && routes.acknowledge !== null) {
|
|
881
|
+
const ack = routes.acknowledge;
|
|
882
|
+
const responses = ack.responses?.join(" | ") ?? "linked | accepted-fix | diverged";
|
|
883
|
+
lines.push(
|
|
884
|
+
`- **acknowledge** (\`${ack.param ?? "coherencyAcknowledgement"}\`): ${responses}${ack.minReasonChars ? ` (\u2265${ack.minReasonChars} chars for diverged)` : ""}. ${asDescription(ack.description) ?? ""}`.trim()
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
if (routes && typeof routes.override === "object" && routes.override !== null) {
|
|
888
|
+
const ov = routes.override;
|
|
889
|
+
lines.push(
|
|
890
|
+
`- **override** (\`${ov.param ?? "steeringOverrideReason"}\`): \u2265${ov.minChars ?? 12} chars. ${asDescription(ov.description) ?? ""}`.trim()
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
if (lines.length === beforeRoutes) {
|
|
894
|
+
lines.push(GENERIC_RECOVERY_LINE);
|
|
895
|
+
}
|
|
896
|
+
} else {
|
|
897
|
+
lines.push("", GENERIC_RECOVERY_LINE);
|
|
898
|
+
}
|
|
899
|
+
return failureResult(
|
|
900
|
+
lines.join("\n"),
|
|
901
|
+
"COHERENCY_REFUSED",
|
|
902
|
+
`Coherency gate refused ${toolName} on ${entryId}.`,
|
|
903
|
+
"Use one of the refusal's routes (link / coherencyAcknowledgement / steeringOverrideReason), then retry.",
|
|
904
|
+
void 0,
|
|
905
|
+
{ entryId, refusal }
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// src/lib/collectionCache.ts
|
|
910
|
+
var collectionCache = new ScopedCache(COLLECTION_CACHE_TTL_MS);
|
|
911
|
+
async function getCollections() {
|
|
912
|
+
const scope = cacheScope();
|
|
913
|
+
const hit = collectionCache.get(scope);
|
|
914
|
+
if (hit) return hit.collections;
|
|
915
|
+
const result2 = await kernelQuery("chain.listCollections") ?? [];
|
|
916
|
+
const bySlug = new Map(result2.map((c) => [c.slug, c]));
|
|
917
|
+
collectionCache.set(scope, { collections: result2, bySlug });
|
|
918
|
+
return result2;
|
|
919
|
+
}
|
|
920
|
+
async function getCollectionBySlug(slug) {
|
|
921
|
+
await getCollections();
|
|
922
|
+
return collectionCache.get(cacheScope())?.bySlug.get(slug);
|
|
923
|
+
}
|
|
924
|
+
function invalidateCollectionCacheForScope() {
|
|
925
|
+
collectionCache.delete(cacheScope());
|
|
926
|
+
}
|
|
927
|
+
async function isGoverned(slug) {
|
|
928
|
+
const col = await getCollectionBySlug(slug);
|
|
929
|
+
return !!col?.governed;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// src/lib/versionWrite.ts
|
|
933
|
+
function buildVersionPatch(params) {
|
|
934
|
+
const { capture, targetProseKey } = params;
|
|
935
|
+
const data = { ...capture.fields ?? {} };
|
|
936
|
+
if (capture.prose.trim()) data[targetProseKey] = capture.prose;
|
|
937
|
+
return capture.name ? { name: capture.name, data } : { data };
|
|
938
|
+
}
|
|
939
|
+
function readVersionWriteOutcome(result2) {
|
|
940
|
+
if (result2 && typeof result2 === "object" && result2.outcome === "refused") {
|
|
941
|
+
const rawRefusal = result2.refusal;
|
|
942
|
+
const refusal = rawRefusal && typeof rawRefusal === "object" ? rawRefusal : { reason: "The workspace refused this update." };
|
|
943
|
+
return { ok: false, refusal };
|
|
944
|
+
}
|
|
945
|
+
if (result2 && typeof result2 === "object" && typeof result2.id === "string") {
|
|
946
|
+
return { ok: true, id: result2.id };
|
|
947
|
+
}
|
|
948
|
+
return { ok: false, refusal: { reason: "The workspace refused this update." } };
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// src/tools/captureVersion.ts
|
|
952
|
+
function buildVersionPreviewResult(groundingEntry, name) {
|
|
953
|
+
return successResult(
|
|
954
|
+
`# Would save as a new version of ${groundingEntry.entryId}
|
|
955
|
+
|
|
956
|
+
No DB writes \u2014 call without \`preview:true\` to version for real.`,
|
|
957
|
+
`Would save as a new version of ${groundingEntry.entryId}.`,
|
|
958
|
+
{ id: groundingEntry.entryId, kind: "version", preview: true, name }
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
async function resolveTargetProseKey(collectionSlug) {
|
|
962
|
+
const col = await getCollectionBySlug(collectionSlug).catch(() => void 0);
|
|
963
|
+
return col?.descriptionFieldKey || "description";
|
|
964
|
+
}
|
|
965
|
+
async function runVersionCapture(params) {
|
|
966
|
+
const { groundingEntry, name, description, data, sourceRef, sourceExcerpt, links, groundingElapsedMs } = params;
|
|
967
|
+
const versionAgentId = getAgentSessionId();
|
|
968
|
+
const targetProseKey = await resolveTargetProseKey(groundingEntry.collectionSlug);
|
|
969
|
+
const patch = buildVersionPatch({ capture: { prose: description ?? "", fields: data ?? void 0 }, targetProseKey });
|
|
970
|
+
try {
|
|
971
|
+
const rawResult = await kernelMutation("chain.updateEntry", {
|
|
972
|
+
entryId: groundingEntry.entryId,
|
|
973
|
+
...patch,
|
|
974
|
+
autoPublish: true,
|
|
975
|
+
changeNote: "Captured as a new version via MCP",
|
|
976
|
+
changedBy: versionAgentId ? `agent:${versionAgentId}` : "capture",
|
|
977
|
+
...sourceRef ? { sourceRef } : {},
|
|
978
|
+
...sourceExcerpt ? { sourceExcerpt } : {}
|
|
979
|
+
});
|
|
980
|
+
void kernelMutation("chain.recordGroundingOutcome", {
|
|
981
|
+
surface: "mcp",
|
|
982
|
+
promptShown: false,
|
|
983
|
+
highestRatio: groundingEntry.score,
|
|
984
|
+
hadGovernance: false,
|
|
985
|
+
grounding_ms: groundingElapsedMs
|
|
986
|
+
}).catch(() => void 0);
|
|
987
|
+
const outcome = readVersionWriteOutcome(rawResult);
|
|
988
|
+
if (!outcome.ok) {
|
|
989
|
+
return coherencyRefusedResult("capture", groundingEntry.entryId, outcome.refusal);
|
|
990
|
+
}
|
|
991
|
+
if (links && links.length > 0) {
|
|
992
|
+
await kernelMutation("chain.createEntryRelations", {
|
|
993
|
+
relations: links.slice(0, 25).map((l) => ({ fromEntryId: groundingEntry.entryId, toEntryId: l.to, type: l.type, proposedBy: "user" })),
|
|
994
|
+
sessionId: versionAgentId ?? void 0
|
|
995
|
+
}).catch(() => void 0);
|
|
996
|
+
}
|
|
997
|
+
return successResult(
|
|
998
|
+
`# Saved as a new version of ${groundingEntry.entryId}
|
|
999
|
+
|
|
1000
|
+
${name}`,
|
|
1001
|
+
`Saved as a new version of ${groundingEntry.entryId}.`,
|
|
1002
|
+
{ id: groundingEntry.entryId, kind: "version" }
|
|
1003
|
+
);
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
const classified = classifyError(error);
|
|
1006
|
+
return failureResult(classified.message, classified.code, classified.message, classified.recovery, classified.availableActions, classified.diagnostics);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
async function captureVersionOrPreview(preview, params) {
|
|
1010
|
+
return preview ? buildVersionPreviewResult(params.groundingEntry, params.name) : runVersionCapture(params);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
850
1013
|
// src/lib/fieldTypes.ts
|
|
851
1014
|
var FIELD_TYPE_DEFAULTS = {
|
|
852
1015
|
"string": "",
|
|
@@ -909,29 +1072,6 @@ function inferSourceDate(...values) {
|
|
|
909
1072
|
return `${inferredYear}-${month}-${day}`;
|
|
910
1073
|
}
|
|
911
1074
|
|
|
912
|
-
// src/lib/collectionCache.ts
|
|
913
|
-
var collectionCache = new ScopedCache(COLLECTION_CACHE_TTL_MS);
|
|
914
|
-
async function getCollections() {
|
|
915
|
-
const scope = cacheScope();
|
|
916
|
-
const hit = collectionCache.get(scope);
|
|
917
|
-
if (hit) return hit.collections;
|
|
918
|
-
const result2 = await kernelQuery("chain.listCollections") ?? [];
|
|
919
|
-
const bySlug = new Map(result2.map((c) => [c.slug, c]));
|
|
920
|
-
collectionCache.set(scope, { collections: result2, bySlug });
|
|
921
|
-
return result2;
|
|
922
|
-
}
|
|
923
|
-
async function getCollectionBySlug(slug) {
|
|
924
|
-
await getCollections();
|
|
925
|
-
return collectionCache.get(cacheScope())?.bySlug.get(slug);
|
|
926
|
-
}
|
|
927
|
-
function invalidateCollectionCacheForScope() {
|
|
928
|
-
collectionCache.delete(cacheScope());
|
|
929
|
-
}
|
|
930
|
-
async function isGoverned(slug) {
|
|
931
|
-
const col = await getCollectionBySlug(slug);
|
|
932
|
-
return !!col?.governed;
|
|
933
|
-
}
|
|
934
|
-
|
|
935
1075
|
// src/lib/textMatch.ts
|
|
936
1076
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
937
1077
|
"the",
|
|
@@ -2335,6 +2475,7 @@ ${groundingReport.duplicates.map((d) => `- **${d.entryId}** ${d.name} [${d.colle
|
|
|
2335
2475
|
}
|
|
2336
2476
|
};
|
|
2337
2477
|
}
|
|
2478
|
+
if (groundingEntry?.kind === "version") return captureVersionOrPreview(preview ?? false, { groundingEntry, name, description, data: userData, sourceRef, sourceExcerpt, links, groundingElapsedMs });
|
|
2338
2479
|
const data = buildDataFromFields(col.fields ?? [], profile.descriptionField, description);
|
|
2339
2480
|
for (const def of profile.defaults) {
|
|
2340
2481
|
if (def.value !== "infer" && def.value !== "today") {
|
|
@@ -2538,7 +2679,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
2538
2679
|
const tAfterCreate = Date.now();
|
|
2539
2680
|
void kernelMutation("chain.recordGroundingOutcome", {
|
|
2540
2681
|
surface: "mcp",
|
|
2541
|
-
promptShown: groundingEntry?.kind === "ask"
|
|
2682
|
+
promptShown: groundingEntry?.kind === "ask",
|
|
2542
2683
|
highestRatio: Math.max(
|
|
2543
2684
|
...groundingReport.duplicates.map((d) => d.overlapRatio),
|
|
2544
2685
|
...groundingReport.related.map((r) => r.overlapRatio),
|
|
@@ -3719,65 +3860,6 @@ async function runConflictPreflight(name, description, collectionHint) {
|
|
|
3719
3860
|
}
|
|
3720
3861
|
}
|
|
3721
3862
|
|
|
3722
|
-
// src/tools/coherency-refusal.ts
|
|
3723
|
-
function asDescription(value) {
|
|
3724
|
-
if (typeof value !== "string") return void 0;
|
|
3725
|
-
const trimmed = value.trim();
|
|
3726
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
3727
|
-
}
|
|
3728
|
-
var GENERIC_RECOVERY_LINE = "Respond and retry: link the entry to the strategic spine, pass `coherencyAcknowledgement`, or supply a typed `steeringOverrideReason`.";
|
|
3729
|
-
function coherencyRefusedResult(toolName, entryId, refusal, options) {
|
|
3730
|
-
const headingLevel = options?.headingLevel ?? 1;
|
|
3731
|
-
const heading = "#".repeat(headingLevel);
|
|
3732
|
-
const lines = [
|
|
3733
|
-
`${heading} Write refused by the coherency gate`,
|
|
3734
|
-
"",
|
|
3735
|
-
refusal.reason ?? `The coherency gate refused this write on ${entryId}.`
|
|
3736
|
-
];
|
|
3737
|
-
if (refusal.subject?.name) {
|
|
3738
|
-
lines.push(`On: ${refusal.subject.name}`);
|
|
3739
|
-
}
|
|
3740
|
-
if (refusal.mode) {
|
|
3741
|
-
lines.push("", `Mode: ${refusal.mode}`);
|
|
3742
|
-
}
|
|
3743
|
-
const routes = refusal.routes;
|
|
3744
|
-
const routeKeys = routes ? Object.keys(routes) : [];
|
|
3745
|
-
if (routeKeys.length > 0) {
|
|
3746
|
-
lines.push("", `${"#".repeat(headingLevel + 1)} Recovery routes`);
|
|
3747
|
-
const beforeRoutes = lines.length;
|
|
3748
|
-
if (routes && typeof routes.link === "object" && routes.link !== null) {
|
|
3749
|
-
const link = routes.link;
|
|
3750
|
-
lines.push(`- **link:** ${asDescription(link.description) ?? "Link the entry to the strategic spine."}`);
|
|
3751
|
-
}
|
|
3752
|
-
if (routes && typeof routes.acknowledge === "object" && routes.acknowledge !== null) {
|
|
3753
|
-
const ack = routes.acknowledge;
|
|
3754
|
-
const responses = ack.responses?.join(" | ") ?? "linked | accepted-fix | diverged";
|
|
3755
|
-
lines.push(
|
|
3756
|
-
`- **acknowledge** (\`${ack.param ?? "coherencyAcknowledgement"}\`): ${responses}${ack.minReasonChars ? ` (\u2265${ack.minReasonChars} chars for diverged)` : ""}. ${asDescription(ack.description) ?? ""}`.trim()
|
|
3757
|
-
);
|
|
3758
|
-
}
|
|
3759
|
-
if (routes && typeof routes.override === "object" && routes.override !== null) {
|
|
3760
|
-
const ov = routes.override;
|
|
3761
|
-
lines.push(
|
|
3762
|
-
`- **override** (\`${ov.param ?? "steeringOverrideReason"}\`): \u2265${ov.minChars ?? 12} chars. ${asDescription(ov.description) ?? ""}`.trim()
|
|
3763
|
-
);
|
|
3764
|
-
}
|
|
3765
|
-
if (lines.length === beforeRoutes) {
|
|
3766
|
-
lines.push(GENERIC_RECOVERY_LINE);
|
|
3767
|
-
}
|
|
3768
|
-
} else {
|
|
3769
|
-
lines.push("", GENERIC_RECOVERY_LINE);
|
|
3770
|
-
}
|
|
3771
|
-
return failureResult(
|
|
3772
|
-
lines.join("\n"),
|
|
3773
|
-
"COHERENCY_REFUSED",
|
|
3774
|
-
`Coherency gate refused ${toolName} on ${entryId}.`,
|
|
3775
|
-
"Use one of the refusal's routes (link / coherencyAcknowledgement / steeringOverrideReason), then retry.",
|
|
3776
|
-
void 0,
|
|
3777
|
-
{ entryId, refusal }
|
|
3778
|
-
);
|
|
3779
|
-
}
|
|
3780
|
-
|
|
3781
3863
|
// src/tools/knowledge/getHistory.ts
|
|
3782
3864
|
import { z as z7 } from "zod/v3";
|
|
3783
3865
|
var getHistorySchema = z7.object({
|
|
@@ -16671,4 +16753,4 @@ export {
|
|
|
16671
16753
|
createProductBrainServer,
|
|
16672
16754
|
initFeatureFlags
|
|
16673
16755
|
};
|
|
16674
|
-
//# sourceMappingURL=chunk-
|
|
16756
|
+
//# sourceMappingURL=chunk-PZDI2QMN.js.map
|