@productbrain/mcp 0.0.1-beta.48 → 0.0.1-beta.49
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-4ZJEIAA6.js → chunk-ED3KCWZE.js} +393 -69
- package/dist/chunk-ED3KCWZE.js.map +1 -0
- package/dist/{chunk-RPESSNTC.js → chunk-IGQLZI32.js} +2232 -1941
- package/dist/chunk-IGQLZI32.js.map +1 -0
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{smart-capture-YIBXUP2H.js → smart-capture-2IM2565I.js} +8 -2
- package/dist/views/src/entry-cards/index.html +227 -0
- package/dist/views/src/graph-constellation/index.html +254 -0
- package/package.json +3 -2
- package/dist/chunk-4ZJEIAA6.js.map +0 -1
- package/dist/chunk-RPESSNTC.js.map +0 -1
- /package/dist/{smart-capture-YIBXUP2H.js.map → smart-capture-2IM2565I.js.map} +0 -0
|
@@ -159,22 +159,27 @@ async function startAgentSession() {
|
|
|
159
159
|
workspaceId,
|
|
160
160
|
apiKeyId: s.apiKeyId
|
|
161
161
|
});
|
|
162
|
+
if (s.agentSessionId) {
|
|
163
|
+
resetTouchThrottle(s.agentSessionId);
|
|
164
|
+
}
|
|
162
165
|
s.agentSessionId = result.sessionId;
|
|
163
166
|
s.apiKeyScope = result.toolsScope;
|
|
164
167
|
s.sessionOriented = false;
|
|
165
168
|
s.sessionClosed = false;
|
|
166
|
-
resetTouchThrottle();
|
|
169
|
+
resetTouchThrottle(result.sessionId);
|
|
167
170
|
return result;
|
|
168
171
|
}
|
|
169
172
|
async function closeAgentSession() {
|
|
170
173
|
const s = state();
|
|
171
174
|
if (!s.agentSessionId) return;
|
|
175
|
+
const sessionId = s.agentSessionId;
|
|
172
176
|
try {
|
|
173
177
|
await mcpCall("agent.closeSession", {
|
|
174
|
-
sessionId
|
|
178
|
+
sessionId,
|
|
175
179
|
status: "closed"
|
|
176
180
|
});
|
|
177
181
|
} finally {
|
|
182
|
+
resetTouchThrottle(sessionId);
|
|
178
183
|
s.sessionClosed = true;
|
|
179
184
|
s.agentSessionId = null;
|
|
180
185
|
s.sessionOriented = false;
|
|
@@ -183,32 +188,40 @@ async function closeAgentSession() {
|
|
|
183
188
|
async function orphanAgentSession() {
|
|
184
189
|
const s = state();
|
|
185
190
|
if (!s.agentSessionId) return;
|
|
191
|
+
const sessionId = s.agentSessionId;
|
|
186
192
|
try {
|
|
187
193
|
await mcpCall("agent.closeSession", {
|
|
188
|
-
sessionId
|
|
194
|
+
sessionId,
|
|
189
195
|
status: "orphaned"
|
|
190
196
|
});
|
|
191
197
|
} catch {
|
|
192
198
|
} finally {
|
|
199
|
+
resetTouchThrottle(sessionId);
|
|
193
200
|
s.agentSessionId = null;
|
|
194
201
|
s.sessionOriented = false;
|
|
195
202
|
}
|
|
196
203
|
}
|
|
197
|
-
var
|
|
204
|
+
var _lastTouchAtBySession = /* @__PURE__ */ new Map();
|
|
198
205
|
var TOUCH_THROTTLE_MS = 5e3;
|
|
199
206
|
function touchSessionActivity() {
|
|
200
207
|
const s = state();
|
|
201
|
-
|
|
208
|
+
const sessionId = s.agentSessionId;
|
|
209
|
+
if (!sessionId) return;
|
|
202
210
|
const now = Date.now();
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
const lastTouchAt = _lastTouchAtBySession.get(sessionId) ?? 0;
|
|
212
|
+
if (now - lastTouchAt < TOUCH_THROTTLE_MS) return;
|
|
213
|
+
_lastTouchAtBySession.set(sessionId, now);
|
|
205
214
|
mcpCall("agent.touchSession", {
|
|
206
|
-
sessionId
|
|
215
|
+
sessionId
|
|
207
216
|
}).catch(() => {
|
|
208
217
|
});
|
|
209
218
|
}
|
|
210
|
-
function resetTouchThrottle() {
|
|
211
|
-
|
|
219
|
+
function resetTouchThrottle(sessionId) {
|
|
220
|
+
if (sessionId) {
|
|
221
|
+
_lastTouchAtBySession.delete(sessionId);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
_lastTouchAtBySession.clear();
|
|
212
225
|
}
|
|
213
226
|
async function recordSessionActivity(activity) {
|
|
214
227
|
const s = state();
|
|
@@ -302,7 +315,14 @@ async function mcpCall(fn, args = {}) {
|
|
|
302
315
|
setCached(fn, args, data);
|
|
303
316
|
}
|
|
304
317
|
const s = state();
|
|
305
|
-
const TOUCH_EXCLUDED = /* @__PURE__ */ new Set([
|
|
318
|
+
const TOUCH_EXCLUDED = /* @__PURE__ */ new Set([
|
|
319
|
+
"agent.touchSession",
|
|
320
|
+
"agent.startSession",
|
|
321
|
+
"agent.markOriented",
|
|
322
|
+
"agent.recordActivity",
|
|
323
|
+
"agent.recordWrapup",
|
|
324
|
+
"agent.closeSession"
|
|
325
|
+
]);
|
|
306
326
|
if (s.agentSessionId && !TOUCH_EXCLUDED.has(fn)) {
|
|
307
327
|
touchSessionActivity();
|
|
308
328
|
}
|
|
@@ -428,6 +448,58 @@ async function recoverSessionState() {
|
|
|
428
448
|
}
|
|
429
449
|
|
|
430
450
|
// src/tools/knowledge-helpers.ts
|
|
451
|
+
var EPISTEMIC_COLLECTIONS = /* @__PURE__ */ new Set(["insights", "assumptions"]);
|
|
452
|
+
function deriveEpistemicStatus(entry) {
|
|
453
|
+
const coll = entry.collectionName?.toLowerCase();
|
|
454
|
+
if (!coll || !EPISTEMIC_COLLECTIONS.has(coll)) return null;
|
|
455
|
+
const relations = entry.relations ?? [];
|
|
456
|
+
const hasValidates = relations.some(
|
|
457
|
+
(r) => r.type === "validates" && r.direction === "incoming"
|
|
458
|
+
);
|
|
459
|
+
const hasInvalidates = relations.some(
|
|
460
|
+
(r) => r.type === "invalidates" && r.direction === "incoming"
|
|
461
|
+
);
|
|
462
|
+
const evidenceCount = relations.filter(
|
|
463
|
+
(r) => (r.type === "validates" || r.type === "invalidates") && r.direction === "incoming"
|
|
464
|
+
).length;
|
|
465
|
+
if (coll === "assumptions") {
|
|
466
|
+
const ws2 = entry.workflowStatus;
|
|
467
|
+
if (ws2 === "invalidated" || hasInvalidates) {
|
|
468
|
+
return { level: "invalidated", reason: "Disproved by linked counter-evidence" };
|
|
469
|
+
}
|
|
470
|
+
if (ws2 === "validated" || hasValidates && ws2 !== "untested") {
|
|
471
|
+
return { level: "validated", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? "s" : ""}` };
|
|
472
|
+
}
|
|
473
|
+
if (ws2 === "testing") {
|
|
474
|
+
return { level: "testing", reason: "Experiment in progress" };
|
|
475
|
+
}
|
|
476
|
+
return { level: "untested", reason: "No evidence linked", action: 'Link evidence via `relations action=create type="validates"`' };
|
|
477
|
+
}
|
|
478
|
+
const ws = entry.workflowStatus;
|
|
479
|
+
if (ws === "validated" && hasValidates) {
|
|
480
|
+
return { level: "validated", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? "s" : ""}` };
|
|
481
|
+
}
|
|
482
|
+
if (ws === "evidenced" || hasValidates) {
|
|
483
|
+
return { level: "evidenced", reason: `${evidenceCount} evidence link${evidenceCount !== 1 ? "s" : ""}` };
|
|
484
|
+
}
|
|
485
|
+
return {
|
|
486
|
+
level: "hypothesis",
|
|
487
|
+
reason: "No linked evidence",
|
|
488
|
+
action: 'Link proof via `relations action=create type="validates"`'
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
function formatEpistemicLine(es) {
|
|
492
|
+
const icon = es.level === "validated" ? "\u2713" : es.level === "evidenced" ? "\u25CE" : es.level === "hypothesis" ? "\u25B3" : es.level === "untested" ? "?" : es.level === "testing" ? "\u25CE" : "\u2715";
|
|
493
|
+
const suffix = es.action ? ` ${es.action}` : "";
|
|
494
|
+
return `**Confidence:** ${icon} ${es.level} \u2014 ${es.reason}.${suffix}`;
|
|
495
|
+
}
|
|
496
|
+
function toEpistemicInput(entry) {
|
|
497
|
+
return {
|
|
498
|
+
collectionName: typeof entry.collectionName === "string" ? entry.collectionName : void 0,
|
|
499
|
+
workflowStatus: typeof entry.workflowStatus === "string" ? entry.workflowStatus : void 0,
|
|
500
|
+
relations: Array.isArray(entry.relations) ? entry.relations.map((r) => ({ type: r.type, direction: r.direction })) : void 0
|
|
501
|
+
};
|
|
502
|
+
}
|
|
431
503
|
function extractPreview(data, maxLen) {
|
|
432
504
|
if (!data || typeof data !== "object") return "";
|
|
433
505
|
const d = data;
|
|
@@ -546,11 +618,27 @@ async function isFeatureEnabled(flag, workspaceId, workspaceSlug) {
|
|
|
546
618
|
// src/tools/smart-capture-routing.ts
|
|
547
619
|
var CLASSIFIER_AUTO_ROUTE_THRESHOLD = 70;
|
|
548
620
|
var CLASSIFIER_AMBIGUITY_MARGIN = 15;
|
|
549
|
-
var
|
|
621
|
+
var CLASSIFIABLE_COLLECTIONS = [
|
|
622
|
+
"decisions",
|
|
623
|
+
"tensions",
|
|
624
|
+
"glossary",
|
|
625
|
+
"insights",
|
|
626
|
+
"bets",
|
|
627
|
+
"features",
|
|
628
|
+
"architecture",
|
|
629
|
+
"business-rules",
|
|
630
|
+
"tracking-events",
|
|
631
|
+
"landscape",
|
|
632
|
+
"standards",
|
|
633
|
+
"principles",
|
|
634
|
+
"assumptions"
|
|
635
|
+
];
|
|
636
|
+
var STARTER_COLLECTIONS = CLASSIFIABLE_COLLECTIONS;
|
|
550
637
|
var SIGNAL_WEIGHT = 10;
|
|
638
|
+
var MIN_SCORE_FLOOR = 10;
|
|
551
639
|
var MAX_MATCHES_PER_SIGNAL = 2;
|
|
552
640
|
var MAX_REASON_COUNT = 3;
|
|
553
|
-
var
|
|
641
|
+
var COLLECTION_SIGNALS = {
|
|
554
642
|
decisions: [
|
|
555
643
|
"decide",
|
|
556
644
|
"decision",
|
|
@@ -560,7 +648,15 @@ var STARTER_COLLECTION_SIGNALS = {
|
|
|
560
648
|
"resolved",
|
|
561
649
|
"we will",
|
|
562
650
|
"we should",
|
|
563
|
-
"approved"
|
|
651
|
+
"approved",
|
|
652
|
+
"replaces",
|
|
653
|
+
"instead of",
|
|
654
|
+
"go with",
|
|
655
|
+
"criteria",
|
|
656
|
+
"adopted",
|
|
657
|
+
"reposition",
|
|
658
|
+
"scoring framework",
|
|
659
|
+
"review"
|
|
564
660
|
],
|
|
565
661
|
tensions: [
|
|
566
662
|
"problem",
|
|
@@ -569,10 +665,20 @@ var STARTER_COLLECTION_SIGNALS = {
|
|
|
569
665
|
"blocker",
|
|
570
666
|
"friction",
|
|
571
667
|
"pain",
|
|
572
|
-
"risk",
|
|
573
|
-
"constraint",
|
|
574
668
|
"bottleneck",
|
|
575
|
-
"struggle"
|
|
669
|
+
"struggle",
|
|
670
|
+
"missing",
|
|
671
|
+
"breaks",
|
|
672
|
+
"regression",
|
|
673
|
+
"unclear",
|
|
674
|
+
"no way to",
|
|
675
|
+
"scope creep",
|
|
676
|
+
"coupled",
|
|
677
|
+
"trapped",
|
|
678
|
+
"ambiguous",
|
|
679
|
+
"no batch",
|
|
680
|
+
"undetectable",
|
|
681
|
+
"coordination gap"
|
|
576
682
|
],
|
|
577
683
|
glossary: [
|
|
578
684
|
"definition",
|
|
@@ -582,28 +688,151 @@ var STARTER_COLLECTION_SIGNALS = {
|
|
|
582
688
|
"refers to",
|
|
583
689
|
"is called",
|
|
584
690
|
"vocabulary",
|
|
585
|
-
"terminology"
|
|
691
|
+
"terminology",
|
|
692
|
+
"a governance mechanism",
|
|
693
|
+
"a workspace",
|
|
694
|
+
"a tracked",
|
|
695
|
+
"the atom",
|
|
696
|
+
"the action of",
|
|
697
|
+
"the versioned",
|
|
698
|
+
"a field on",
|
|
699
|
+
"one of the",
|
|
700
|
+
"a constraint on",
|
|
701
|
+
"a hard data",
|
|
702
|
+
"a single"
|
|
586
703
|
],
|
|
587
704
|
insights: [
|
|
588
705
|
"insight",
|
|
589
706
|
"learned",
|
|
590
707
|
"observed",
|
|
591
|
-
"pattern",
|
|
592
708
|
"trend",
|
|
593
|
-
"signal",
|
|
594
709
|
"found that",
|
|
595
|
-
"
|
|
710
|
+
"discovery",
|
|
711
|
+
"validates",
|
|
712
|
+
"saturates",
|
|
713
|
+
"convergence",
|
|
714
|
+
"signals from",
|
|
715
|
+
"converge",
|
|
716
|
+
"TAM"
|
|
596
717
|
],
|
|
597
718
|
bets: [
|
|
598
|
-
"bet",
|
|
599
719
|
"appetite",
|
|
600
|
-
"scope",
|
|
601
|
-
"elements",
|
|
602
720
|
"rabbit hole",
|
|
603
721
|
"no-go",
|
|
604
|
-
"shape",
|
|
605
|
-
"
|
|
606
|
-
"
|
|
722
|
+
"shape up",
|
|
723
|
+
"done when",
|
|
724
|
+
"shaping session",
|
|
725
|
+
"from static",
|
|
726
|
+
"from storage",
|
|
727
|
+
"from passive",
|
|
728
|
+
"the chain learns",
|
|
729
|
+
"stage-aware",
|
|
730
|
+
"commit friction",
|
|
731
|
+
"interactive knowledge",
|
|
732
|
+
"capture without",
|
|
733
|
+
"front door",
|
|
734
|
+
"response envelope",
|
|
735
|
+
"knowledge organisation",
|
|
736
|
+
"graveyard",
|
|
737
|
+
"remote MCP",
|
|
738
|
+
"coaching service"
|
|
739
|
+
],
|
|
740
|
+
features: [
|
|
741
|
+
"feature",
|
|
742
|
+
"capability",
|
|
743
|
+
"user can",
|
|
744
|
+
"navigation",
|
|
745
|
+
"palette",
|
|
746
|
+
"modal",
|
|
747
|
+
"smart capture",
|
|
748
|
+
"suggest-links",
|
|
749
|
+
"command palette",
|
|
750
|
+
"auto-commit",
|
|
751
|
+
"collection-optional",
|
|
752
|
+
"organisation intelligence",
|
|
753
|
+
"consolidation"
|
|
754
|
+
],
|
|
755
|
+
architecture: [
|
|
756
|
+
"architecture",
|
|
757
|
+
"layer",
|
|
758
|
+
"data model",
|
|
759
|
+
"infrastructure",
|
|
760
|
+
"system design",
|
|
761
|
+
"L1",
|
|
762
|
+
"L2",
|
|
763
|
+
"L3",
|
|
764
|
+
"L4",
|
|
765
|
+
"L5",
|
|
766
|
+
"L6",
|
|
767
|
+
"L7",
|
|
768
|
+
"guard infrastructure",
|
|
769
|
+
"data layer",
|
|
770
|
+
"intelligence layer",
|
|
771
|
+
"MCP layer",
|
|
772
|
+
"core layer"
|
|
773
|
+
],
|
|
774
|
+
"business-rules": [
|
|
775
|
+
"guard",
|
|
776
|
+
"enforce",
|
|
777
|
+
"integrity",
|
|
778
|
+
"prevents",
|
|
779
|
+
"excludes",
|
|
780
|
+
"permitted",
|
|
781
|
+
"policy",
|
|
782
|
+
"feature gate",
|
|
783
|
+
"must not",
|
|
784
|
+
"only permitted",
|
|
785
|
+
"closed enum",
|
|
786
|
+
"write guard",
|
|
787
|
+
"never imports",
|
|
788
|
+
"requires active session",
|
|
789
|
+
"readiness excludes"
|
|
790
|
+
],
|
|
791
|
+
"tracking-events": [
|
|
792
|
+
"track",
|
|
793
|
+
"tracking",
|
|
794
|
+
"analytics",
|
|
795
|
+
"trigger",
|
|
796
|
+
"posthog",
|
|
797
|
+
"instrument",
|
|
798
|
+
"fires when"
|
|
799
|
+
],
|
|
800
|
+
landscape: [
|
|
801
|
+
"competitor",
|
|
802
|
+
"alternative tool",
|
|
803
|
+
"alternative platform",
|
|
804
|
+
"competing product",
|
|
805
|
+
"landscape",
|
|
806
|
+
"comparison"
|
|
807
|
+
],
|
|
808
|
+
standards: [
|
|
809
|
+
"standard",
|
|
810
|
+
"convention",
|
|
811
|
+
"trunk-based",
|
|
812
|
+
"alignment-first",
|
|
813
|
+
"structured bet",
|
|
814
|
+
"system fixes",
|
|
815
|
+
"patches"
|
|
816
|
+
],
|
|
817
|
+
principles: [
|
|
818
|
+
"we believe",
|
|
819
|
+
"principle",
|
|
820
|
+
"compounds",
|
|
821
|
+
"philosophy",
|
|
822
|
+
"simplicity compounds",
|
|
823
|
+
"trust through",
|
|
824
|
+
"evidence over",
|
|
825
|
+
"compensate for",
|
|
826
|
+
"honest by default"
|
|
827
|
+
],
|
|
828
|
+
assumptions: [
|
|
829
|
+
"assume",
|
|
830
|
+
"assumption",
|
|
831
|
+
"hypothesis",
|
|
832
|
+
"untested",
|
|
833
|
+
"we think",
|
|
834
|
+
"we assume",
|
|
835
|
+
"needs validation"
|
|
607
836
|
]
|
|
608
837
|
};
|
|
609
838
|
function escapeRegExp(text) {
|
|
@@ -618,11 +847,12 @@ function countSignalMatches(text, signal) {
|
|
|
618
847
|
const matches = text.match(regex);
|
|
619
848
|
return matches?.length ?? 0;
|
|
620
849
|
}
|
|
621
|
-
|
|
622
|
-
|
|
850
|
+
var ENTRY_ID_PATTERN = /\b[A-Z]{2,}-\d+\b/g;
|
|
851
|
+
function classifyCollection(name, description) {
|
|
852
|
+
const text = `${name} ${description}`.replace(ENTRY_ID_PATTERN, "").toLowerCase();
|
|
623
853
|
const rawScores = [];
|
|
624
|
-
for (const collection of
|
|
625
|
-
const signals =
|
|
854
|
+
for (const collection of CLASSIFIABLE_COLLECTIONS) {
|
|
855
|
+
const signals = COLLECTION_SIGNALS[collection];
|
|
626
856
|
const reasons = [];
|
|
627
857
|
let score = 0;
|
|
628
858
|
for (const signal of signals) {
|
|
@@ -640,8 +870,9 @@ function classifyStarterCollection(name, description) {
|
|
|
640
870
|
rawScores.sort((a, b) => b.score - a.score);
|
|
641
871
|
const top = rawScores[0];
|
|
642
872
|
const second = rawScores[1];
|
|
643
|
-
if (!top || top.score
|
|
873
|
+
if (!top || top.score < MIN_SCORE_FLOOR) return null;
|
|
644
874
|
const margin = Math.max(0, top.score - (second?.score ?? 0));
|
|
875
|
+
if (margin === 0 && top.score <= MIN_SCORE_FLOOR) return null;
|
|
645
876
|
const baseConfidence = Math.min(90, top.score);
|
|
646
877
|
const confidence = Math.min(99, baseConfidence + Math.min(20, margin));
|
|
647
878
|
return {
|
|
@@ -665,6 +896,7 @@ function shouldAutoRouteClassification(result) {
|
|
|
665
896
|
function isClassificationAmbiguous(result) {
|
|
666
897
|
return result.scoreMargin < CLASSIFIER_AMBIGUITY_MARGIN;
|
|
667
898
|
}
|
|
899
|
+
var classifyStarterCollection = classifyCollection;
|
|
668
900
|
|
|
669
901
|
// src/envelope.ts
|
|
670
902
|
import { z } from "zod";
|
|
@@ -935,6 +1167,33 @@ var COMMON_CHECKS = {
|
|
|
935
1167
|
suggestion: () => "Classify this entry with a canonical type for better context assembly. Use update-entry to set canonicalKey."
|
|
936
1168
|
}
|
|
937
1169
|
};
|
|
1170
|
+
var STRATEGY_CATEGORY_INFERENCE_THRESHOLD = 2;
|
|
1171
|
+
var STRATEGY_CATEGORY_SIGNALS = [
|
|
1172
|
+
["business-model", [/pricing/, /revenue/, /unit economics/, /cost structure/, /monetiz/, /margin/, /per.?seat/, /subscription/, /freemium/]],
|
|
1173
|
+
["vision", [/vision/, /aspirational/, /future state/, /world where/]],
|
|
1174
|
+
["purpose", [/purpose/, /why we exist/, /mission/, /reason for being/]],
|
|
1175
|
+
["goal", [/goal/, /metric/, /target/, /kpi/, /okr/, /critical number/, /measur/]],
|
|
1176
|
+
["principle", [/we believe/, /guiding principle/, /core belief/, /philosophy/]],
|
|
1177
|
+
["product-area", [/product area/, /module/, /surface/, /capability area/]],
|
|
1178
|
+
["audience", [/audience/, /persona/, /user segment/, /icp/, /target market/]],
|
|
1179
|
+
["insight", [/insight/, /we learned/, /we observed/, /pattern/]],
|
|
1180
|
+
["opportunity", [/opportunity/, /whitespace/, /gap/, /underserved/]]
|
|
1181
|
+
];
|
|
1182
|
+
function inferStrategyCategory(name, description) {
|
|
1183
|
+
const text = `${name} ${description}`.toLowerCase();
|
|
1184
|
+
let bestCategory = null;
|
|
1185
|
+
let bestScore = 0;
|
|
1186
|
+
for (const [cat, signals] of STRATEGY_CATEGORY_SIGNALS) {
|
|
1187
|
+
const score = signals.reduce((s, rx) => s + (rx.test(text) ? 1 : 0), 0);
|
|
1188
|
+
if (score > bestScore) {
|
|
1189
|
+
bestScore = score;
|
|
1190
|
+
bestCategory = cat;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
if (bestCategory && bestScore >= STRATEGY_CATEGORY_INFERENCE_THRESHOLD) return bestCategory;
|
|
1194
|
+
if (bestScore === 0) return "strategy";
|
|
1195
|
+
return null;
|
|
1196
|
+
}
|
|
938
1197
|
var PROFILES = /* @__PURE__ */ new Map([
|
|
939
1198
|
["tensions", {
|
|
940
1199
|
governedDraft: false,
|
|
@@ -1150,6 +1409,11 @@ var PROFILES = /* @__PURE__ */ new Map([
|
|
|
1150
1409
|
descriptionField: "description",
|
|
1151
1410
|
defaults: [],
|
|
1152
1411
|
recommendedRelationTypes: ["informs", "governs", "belongs_to", "related_to"],
|
|
1412
|
+
inferField: (ctx) => {
|
|
1413
|
+
if (ctx.data?.category) return {};
|
|
1414
|
+
const category = inferStrategyCategory(ctx.name, ctx.description);
|
|
1415
|
+
return category ? { category } : {};
|
|
1416
|
+
},
|
|
1153
1417
|
qualityChecks: [
|
|
1154
1418
|
COMMON_CHECKS.clearName,
|
|
1155
1419
|
COMMON_CHECKS.hasDescription,
|
|
@@ -1302,6 +1566,36 @@ var PROFILES = /* @__PURE__ */ new Map([
|
|
|
1302
1566
|
suggestion: () => "Describe how this assumption could be tested or validated."
|
|
1303
1567
|
}
|
|
1304
1568
|
]
|
|
1569
|
+
}],
|
|
1570
|
+
["architecture", {
|
|
1571
|
+
governedDraft: true,
|
|
1572
|
+
descriptionField: "description",
|
|
1573
|
+
defaults: [],
|
|
1574
|
+
recommendedRelationTypes: ["belongs_to", "depends_on", "governs", "references", "related_to"],
|
|
1575
|
+
qualityChecks: [
|
|
1576
|
+
COMMON_CHECKS.clearName,
|
|
1577
|
+
COMMON_CHECKS.hasDescription,
|
|
1578
|
+
COMMON_CHECKS.hasRelations,
|
|
1579
|
+
COMMON_CHECKS.hasType,
|
|
1580
|
+
{
|
|
1581
|
+
id: "has-layer",
|
|
1582
|
+
label: "Architecture layer identified",
|
|
1583
|
+
check: (ctx) => !!ctx.data?.layer && String(ctx.data.layer).length > 0,
|
|
1584
|
+
suggestion: () => "Specify which architecture layer this belongs to (L1-L7)."
|
|
1585
|
+
}
|
|
1586
|
+
]
|
|
1587
|
+
}],
|
|
1588
|
+
["landscape", {
|
|
1589
|
+
governedDraft: false,
|
|
1590
|
+
descriptionField: "description",
|
|
1591
|
+
defaults: [],
|
|
1592
|
+
recommendedRelationTypes: ["references", "related_to", "fills_slot"],
|
|
1593
|
+
qualityChecks: [
|
|
1594
|
+
COMMON_CHECKS.clearName,
|
|
1595
|
+
COMMON_CHECKS.hasDescription,
|
|
1596
|
+
COMMON_CHECKS.hasRelations,
|
|
1597
|
+
COMMON_CHECKS.hasType
|
|
1598
|
+
]
|
|
1305
1599
|
}]
|
|
1306
1600
|
]);
|
|
1307
1601
|
var FALLBACK_PROFILE = {
|
|
@@ -1466,7 +1760,8 @@ var GOVERNED_COLLECTIONS = /* @__PURE__ */ new Set([
|
|
|
1466
1760
|
"principles",
|
|
1467
1761
|
"standards",
|
|
1468
1762
|
"strategy",
|
|
1469
|
-
"features"
|
|
1763
|
+
"features",
|
|
1764
|
+
"architecture"
|
|
1470
1765
|
]);
|
|
1471
1766
|
var AUTO_LINK_CONFIDENCE_THRESHOLD = 35;
|
|
1472
1767
|
var MAX_AUTO_LINKS = 5;
|
|
@@ -1498,15 +1793,14 @@ var captureClassifierSchema = z2.object({
|
|
|
1498
1793
|
enabled: z2.boolean(),
|
|
1499
1794
|
autoRouted: z2.boolean(),
|
|
1500
1795
|
agrees: z2.boolean(),
|
|
1796
|
+
abstained: z2.boolean(),
|
|
1501
1797
|
topConfidence: z2.number(),
|
|
1502
|
-
// Backward-compatible alias for topConfidence.
|
|
1503
1798
|
confidence: z2.number(),
|
|
1504
1799
|
reasons: z2.array(z2.string()),
|
|
1505
1800
|
candidates: z2.array(
|
|
1506
1801
|
z2.object({
|
|
1507
|
-
collection: z2.enum(
|
|
1802
|
+
collection: z2.enum(CLASSIFIABLE_COLLECTIONS),
|
|
1508
1803
|
signalScore: z2.number(),
|
|
1509
|
-
// Backward-compatible alias for signalScore.
|
|
1510
1804
|
confidence: z2.number()
|
|
1511
1805
|
})
|
|
1512
1806
|
),
|
|
@@ -1553,12 +1847,12 @@ function buildClassifierUnknownResult() {
|
|
|
1553
1847
|
"Could not infer collection from input.",
|
|
1554
1848
|
"Provide collection explicitly, or rewrite with clearer intent.",
|
|
1555
1849
|
[{ tool: "collections", description: "List available collections", parameters: { action: "list" } }],
|
|
1556
|
-
{ classifier: { enabled: true, autoRouted: false, agrees: true, topConfidence: 0, confidence: 0, reasons: [], candidates: [] } }
|
|
1850
|
+
{ classifier: { enabled: true, autoRouted: false, agrees: false, abstained: true, topConfidence: 0, confidence: 0, reasons: [], candidates: [] } }
|
|
1557
1851
|
)
|
|
1558
1852
|
};
|
|
1559
1853
|
}
|
|
1560
1854
|
function buildProvisionedCollectionSuggestions(candidates) {
|
|
1561
|
-
return candidates.length ? candidates.map((c) => `- \`${c.collection}\` (${c.signalScore}% signal score)`).join("\n") : "- No provisioned
|
|
1855
|
+
return candidates.length ? candidates.map((c) => `- \`${c.collection}\` (${c.signalScore}% signal score)`).join("\n") : "- No provisioned collection candidates were inferred confidently.";
|
|
1562
1856
|
}
|
|
1563
1857
|
function buildUnsupportedProvisioningResult(classified, provisionedCandidates) {
|
|
1564
1858
|
const suggestions = buildProvisionedCollectionSuggestions(provisionedCandidates);
|
|
@@ -1583,6 +1877,7 @@ Correction path: rerun with explicit \`collection\`.`;
|
|
|
1583
1877
|
enabled: true,
|
|
1584
1878
|
autoRouted: false,
|
|
1585
1879
|
agrees: false,
|
|
1880
|
+
abstained: false,
|
|
1586
1881
|
topConfidence: classified.topConfidence,
|
|
1587
1882
|
confidence: classified.confidence,
|
|
1588
1883
|
reasons: classified.reasons,
|
|
@@ -1616,17 +1911,17 @@ Correction path: if this was close, rerun with your chosen \`collection\`.`;
|
|
|
1616
1911
|
)
|
|
1617
1912
|
};
|
|
1618
1913
|
}
|
|
1619
|
-
async function
|
|
1914
|
+
async function getProvisionedCollectionCandidates(classified, supportedCollections) {
|
|
1620
1915
|
const allCollections = await mcpQuery("chain.listCollections");
|
|
1621
|
-
const
|
|
1916
|
+
const provisionedCollections = new Set(
|
|
1622
1917
|
(allCollections ?? []).map((collection) => collection.slug).filter(
|
|
1623
|
-
(slug) =>
|
|
1918
|
+
(slug) => supportedCollections.has(slug)
|
|
1624
1919
|
)
|
|
1625
1920
|
);
|
|
1626
1921
|
const provisionedCandidates = classified.candidates.filter(
|
|
1627
|
-
(candidate) =>
|
|
1922
|
+
(candidate) => provisionedCollections.has(candidate.collection)
|
|
1628
1923
|
);
|
|
1629
|
-
return {
|
|
1924
|
+
return { provisionedCollections, provisionedCandidates };
|
|
1630
1925
|
}
|
|
1631
1926
|
async function resolveCaptureCollection(params) {
|
|
1632
1927
|
const {
|
|
@@ -1634,18 +1929,19 @@ async function resolveCaptureCollection(params) {
|
|
|
1634
1929
|
name,
|
|
1635
1930
|
description,
|
|
1636
1931
|
classifierFlagOn,
|
|
1637
|
-
|
|
1932
|
+
supportedCollections,
|
|
1638
1933
|
workspaceId,
|
|
1639
1934
|
explicitCollectionProvided
|
|
1640
1935
|
} = params;
|
|
1641
1936
|
if (collection) {
|
|
1642
|
-
const classified2 =
|
|
1937
|
+
const classified2 = classifyCollection(name, description);
|
|
1643
1938
|
if (classified2) {
|
|
1644
1939
|
const agrees = classified2.collection === collection;
|
|
1645
1940
|
const classifierMeta2 = {
|
|
1646
1941
|
enabled: true,
|
|
1647
1942
|
autoRouted: false,
|
|
1648
1943
|
agrees,
|
|
1944
|
+
abstained: false,
|
|
1649
1945
|
topConfidence: classified2.topConfidence,
|
|
1650
1946
|
confidence: classified2.confidence,
|
|
1651
1947
|
reasons: classified2.reasons,
|
|
@@ -1673,7 +1969,8 @@ async function resolveCaptureCollection(params) {
|
|
|
1673
1969
|
classifierMeta: {
|
|
1674
1970
|
enabled: true,
|
|
1675
1971
|
autoRouted: false,
|
|
1676
|
-
agrees:
|
|
1972
|
+
agrees: false,
|
|
1973
|
+
abstained: true,
|
|
1677
1974
|
topConfidence: 0,
|
|
1678
1975
|
confidence: 0,
|
|
1679
1976
|
reasons: [],
|
|
@@ -1685,7 +1982,7 @@ async function resolveCaptureCollection(params) {
|
|
|
1685
1982
|
if (!classifierFlagOn) {
|
|
1686
1983
|
return { earlyResult: buildCollectionRequiredResult() };
|
|
1687
1984
|
}
|
|
1688
|
-
const classified =
|
|
1985
|
+
const classified = classifyCollection(name, description);
|
|
1689
1986
|
if (!classified) {
|
|
1690
1987
|
trackClassifierTelemetry({
|
|
1691
1988
|
workspaceId,
|
|
@@ -1698,8 +1995,8 @@ async function resolveCaptureCollection(params) {
|
|
|
1698
1995
|
});
|
|
1699
1996
|
return { earlyResult: buildClassifierUnknownResult() };
|
|
1700
1997
|
}
|
|
1701
|
-
const {
|
|
1702
|
-
if (!
|
|
1998
|
+
const { provisionedCollections, provisionedCandidates } = await getProvisionedCollectionCandidates(classified, supportedCollections);
|
|
1999
|
+
if (!provisionedCollections.has(classified.collection)) {
|
|
1703
2000
|
trackClassifierTelemetry({
|
|
1704
2001
|
workspaceId,
|
|
1705
2002
|
predictedCollection: classified.collection,
|
|
@@ -1719,6 +2016,7 @@ async function resolveCaptureCollection(params) {
|
|
|
1719
2016
|
enabled: true,
|
|
1720
2017
|
autoRouted: autoRoute,
|
|
1721
2018
|
agrees: true,
|
|
2019
|
+
abstained: false,
|
|
1722
2020
|
topConfidence: classified.topConfidence,
|
|
1723
2021
|
confidence: classified.confidence,
|
|
1724
2022
|
reasons: classified.reasons,
|
|
@@ -1757,7 +2055,7 @@ var captureSuccessOutputSchema = z2.object({
|
|
|
1757
2055
|
entryId: z2.string(),
|
|
1758
2056
|
collection: z2.string(),
|
|
1759
2057
|
name: z2.string(),
|
|
1760
|
-
status: z2.enum(["draft", "committed"]),
|
|
2058
|
+
status: z2.enum(["draft", "committed", "proposed"]),
|
|
1761
2059
|
qualityScore: z2.number(),
|
|
1762
2060
|
qualityVerdict: z2.record(z2.unknown()).optional(),
|
|
1763
2061
|
classifier: captureClassifierSchema.optional(),
|
|
@@ -1786,14 +2084,14 @@ var batchCaptureOutputSchema = z2.object({
|
|
|
1786
2084
|
})).optional()
|
|
1787
2085
|
});
|
|
1788
2086
|
function registerSmartCaptureTools(server) {
|
|
1789
|
-
const
|
|
1790
|
-
|
|
2087
|
+
const supportedCollections = new Set(
|
|
2088
|
+
CLASSIFIABLE_COLLECTIONS.filter((slug) => PROFILES.has(slug))
|
|
1791
2089
|
);
|
|
1792
2090
|
const captureTool = server.registerTool(
|
|
1793
2091
|
"capture",
|
|
1794
2092
|
{
|
|
1795
2093
|
title: "Capture",
|
|
1796
|
-
description: "The single tool for creating knowledge entries. Creates an entry, auto-links related entries, and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional when `capture-without-thinking` is enabled.\n\nSupported collections with smart profiles: tensions, business-rules, glossary, decisions, features, audiences, strategy, standards, maps, bets, insights, assumptions, principles, tracking-events.\nAll other collections get an ENT-{random} ID and sensible defaults.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. Top-level `name` and `description` always win for those fields. `data` wins over inference for all other fields.\n\n**Compound capture:** Pass `links` to create relations in the same call (skips auto-link discovery). Pass `autoCommit: true` to promote the entry from draft to SSOT immediately after linking. Governed collections (glossary, business-rules, principles, standards, strategy, features) will warn but still commit \u2014 use only when you're certain.\n\nAlways creates as 'draft' unless `autoCommit` is true. Use `update-entry` for post-creation adjustments.",
|
|
2094
|
+
description: "The single tool for creating knowledge entries. Creates an entry, auto-links related entries, and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional when `capture-without-thinking` is enabled.\n\nSupported collections with smart profiles: tensions, business-rules, glossary, decisions, features, audiences, strategy, standards, maps, bets, insights, assumptions, principles, tracking-events.\nAll other collections get an ENT-{random} ID and sensible defaults.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. Top-level `name` and `description` always win for those fields. `data` wins over inference for all other fields.\n\n**Compound capture:** Pass `links` to create relations in the same call (skips auto-link discovery). Pass `autoCommit: true` to promote the entry from draft to SSOT immediately after linking. Governed collections (glossary, business-rules, principles, standards, strategy, features, architecture) will warn but still commit \u2014 use only when you're certain.\n\nAlways creates as 'draft' unless `autoCommit` is true. Use `update-entry` for post-creation adjustments.",
|
|
1797
2095
|
inputSchema: captureSchema.shape,
|
|
1798
2096
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
1799
2097
|
},
|
|
@@ -1811,7 +2109,7 @@ function registerSmartCaptureTools(server) {
|
|
|
1811
2109
|
name,
|
|
1812
2110
|
description,
|
|
1813
2111
|
classifierFlagOn,
|
|
1814
|
-
|
|
2112
|
+
supportedCollections,
|
|
1815
2113
|
workspaceId: wsCtx.workspaceId,
|
|
1816
2114
|
explicitCollectionProvided
|
|
1817
2115
|
});
|
|
@@ -1895,10 +2193,10 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
1895
2193
|
}
|
|
1896
2194
|
data[profile.descriptionField || "description"] = description;
|
|
1897
2195
|
const status = "draft";
|
|
2196
|
+
const agentId = getAgentSessionId();
|
|
1898
2197
|
let finalEntryId;
|
|
1899
2198
|
let internalId;
|
|
1900
2199
|
try {
|
|
1901
|
-
const agentId = getAgentSessionId();
|
|
1902
2200
|
const result = await mcpMutation("chain.createEntry", {
|
|
1903
2201
|
collectionSlug: resolvedCollection,
|
|
1904
2202
|
entryId: entryId ?? void 0,
|
|
@@ -1911,7 +2209,6 @@ Or use \`collections action=list\` to see available collections.`
|
|
|
1911
2209
|
});
|
|
1912
2210
|
internalId = result.docId;
|
|
1913
2211
|
finalEntryId = result.entryId;
|
|
1914
|
-
await recordSessionActivity({ entryCreated: internalId });
|
|
1915
2212
|
} catch (error) {
|
|
1916
2213
|
const msg = error instanceof Error ? error.message : String(error);
|
|
1917
2214
|
if (msg.includes("Duplicate") || msg.includes("already exists")) {
|
|
@@ -1967,7 +2264,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
1967
2264
|
await mcpMutation("chain.createEntryRelation", {
|
|
1968
2265
|
fromEntryId: finalEntryId,
|
|
1969
2266
|
toEntryId: c.entryId,
|
|
1970
|
-
type: relationType
|
|
2267
|
+
type: relationType,
|
|
2268
|
+
sessionId: agentId ?? void 0
|
|
1971
2269
|
});
|
|
1972
2270
|
linksCreated.push({
|
|
1973
2271
|
targetEntryId: c.entryId,
|
|
@@ -2001,7 +2299,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2001
2299
|
await mcpMutation("chain.createEntryRelation", {
|
|
2002
2300
|
fromEntryId: finalEntryId,
|
|
2003
2301
|
toEntryId: link.to,
|
|
2004
|
-
type: link.type
|
|
2302
|
+
type: link.type,
|
|
2303
|
+
sessionId: agentId ?? void 0
|
|
2005
2304
|
});
|
|
2006
2305
|
userLinkResults.push({ label: `\u2713 ${link.type} \u2192 ${link.to}`, ok: true });
|
|
2007
2306
|
linksCreated.push({
|
|
@@ -2082,9 +2381,15 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2082
2381
|
let commitError = null;
|
|
2083
2382
|
if (shouldAutoCommit && finalEntryId) {
|
|
2084
2383
|
try {
|
|
2085
|
-
await mcpMutation("chain.commitEntry", {
|
|
2086
|
-
|
|
2087
|
-
|
|
2384
|
+
const commitResult = await mcpMutation("chain.commitEntry", {
|
|
2385
|
+
entryId: finalEntryId,
|
|
2386
|
+
author: agentId ? `agent:${agentId}` : void 0,
|
|
2387
|
+
sessionId: agentId ?? void 0
|
|
2388
|
+
});
|
|
2389
|
+
finalStatus = commitResult?.status === "proposal_created" ? "proposed" : "committed";
|
|
2390
|
+
if (finalStatus === "committed") {
|
|
2391
|
+
await recordSessionActivity({ entryModified: internalId });
|
|
2392
|
+
}
|
|
2088
2393
|
} catch (e) {
|
|
2089
2394
|
commitError = e instanceof Error ? e.message : "unknown error";
|
|
2090
2395
|
}
|
|
@@ -2094,10 +2399,12 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2094
2399
|
`**${name}** added to \`${resolvedCollection}\` as \`${finalStatus}\``,
|
|
2095
2400
|
`**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
|
|
2096
2401
|
];
|
|
2097
|
-
if (classifierMeta
|
|
2402
|
+
if (classifierMeta) {
|
|
2098
2403
|
lines.push("");
|
|
2099
2404
|
lines.push("## Classification");
|
|
2100
|
-
if (classifierMeta.
|
|
2405
|
+
if (classifierMeta.abstained) {
|
|
2406
|
+
lines.push(`No classifier coverage for \`${resolvedCollection}\` \u2014 entry accepted as-is.`);
|
|
2407
|
+
} else if (classifierMeta.autoRouted) {
|
|
2101
2408
|
lines.push(`Auto-routed to \`${resolvedCollection}\` (${classifierMeta.topConfidence}% confidence).`);
|
|
2102
2409
|
if (classifierMeta.reasons.length > 0) {
|
|
2103
2410
|
lines.push(`Reason: ${classifierMeta.reasons.join("; ")}.`);
|
|
@@ -2107,7 +2414,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2107
2414
|
lines.push(`Classifier confirms \`${resolvedCollection}\` (${classifierMeta.topConfidence}% confidence).`);
|
|
2108
2415
|
} else {
|
|
2109
2416
|
const suggested = classifierMeta.candidates[0]?.collection ?? "unknown";
|
|
2110
|
-
lines.push(`
|
|
2417
|
+
lines.push(`Classifier suggests \`${suggested}\` (${classifierMeta.topConfidence}% confidence) \u2014 review classification.`);
|
|
2111
2418
|
if (classifierMeta.reasons.length > 0) {
|
|
2112
2419
|
lines.push(`Reason: ${classifierMeta.reasons.join("; ")}.`);
|
|
2113
2420
|
}
|
|
@@ -2147,6 +2454,10 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2147
2454
|
if (GOVERNED_COLLECTIONS.has(resolvedCollection)) {
|
|
2148
2455
|
lines.push(`_Note: \`${resolvedCollection}\` is a governed collection \u2014 ensure this entry has been reviewed._`);
|
|
2149
2456
|
}
|
|
2457
|
+
} else if (finalStatus === "proposed") {
|
|
2458
|
+
lines.push("");
|
|
2459
|
+
lines.push(`## Proposal created: ${finalEntryId}`);
|
|
2460
|
+
lines.push(`**${name}** requires consent before it can be committed, so a proposal was created instead of publishing directly.`);
|
|
2150
2461
|
} else if (commitError) {
|
|
2151
2462
|
lines.push("");
|
|
2152
2463
|
lines.push("## Commit failed");
|
|
@@ -2201,6 +2512,11 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2201
2512
|
if (failedChecks.length > 0) {
|
|
2202
2513
|
lines.push(`2. **Improve quality:** \`update-entry entryId="${eid}"\` \u2014 fill missing fields`);
|
|
2203
2514
|
}
|
|
2515
|
+
} else if (finalStatus === "proposed") {
|
|
2516
|
+
lines.push(`1. **Connect it:** \`graph action=suggest entryId="${eid}"\` \u2014 discover additional links to support the proposal`);
|
|
2517
|
+
if (failedChecks.length > 0) {
|
|
2518
|
+
lines.push(`2. **Improve quality:** \`update-entry entryId="${eid}"\` \u2014 strengthen the entry before approval`);
|
|
2519
|
+
}
|
|
2204
2520
|
} else {
|
|
2205
2521
|
if (userLinkResults.length === 0) {
|
|
2206
2522
|
lines.push(`1. **Connect it:** \`graph action=suggest entryId="${eid}"\` \u2014 discover what this should link to`);
|
|
@@ -2225,13 +2541,15 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2225
2541
|
const next = [];
|
|
2226
2542
|
if (finalStatus === "committed") {
|
|
2227
2543
|
next.push({ tool: "graph", description: "Discover connections", parameters: { action: "suggest", entryId: finalEntryId } });
|
|
2544
|
+
} else if (finalStatus === "proposed") {
|
|
2545
|
+
next.push({ tool: "graph", description: "Discover connections", parameters: { action: "suggest", entryId: finalEntryId } });
|
|
2228
2546
|
} else {
|
|
2229
2547
|
if (userLinkResults.length === 0) {
|
|
2230
2548
|
next.push({ tool: "graph", description: "Discover links", parameters: { action: "suggest", entryId: finalEntryId } });
|
|
2231
2549
|
}
|
|
2232
2550
|
next.push({ tool: "commit-entry", description: "Commit to Chain", parameters: { entryId: finalEntryId } });
|
|
2233
2551
|
}
|
|
2234
|
-
const summary = finalStatus === "committed" ? `Captured and committed ${finalEntryId} (${name}) to ${resolvedCollection}. Quality ${quality.score}/10.` : `Captured ${finalEntryId} (${name}) as draft in ${resolvedCollection}. Quality ${quality.score}/10.`;
|
|
2552
|
+
const summary = finalStatus === "committed" ? `Captured and committed ${finalEntryId} (${name}) to ${resolvedCollection}. Quality ${quality.score}/10.` : finalStatus === "proposed" ? `Captured ${finalEntryId} (${name}) in ${resolvedCollection} and created a proposal for commit. Quality ${quality.score}/10.` : `Captured ${finalEntryId} (${name}) as draft in ${resolvedCollection}. Quality ${quality.score}/10.`;
|
|
2235
2553
|
const toolResult = {
|
|
2236
2554
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
2237
2555
|
structuredContent: success(
|
|
@@ -2360,7 +2678,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2360
2678
|
await mcpMutation("chain.createEntryRelation", {
|
|
2361
2679
|
fromEntryId: finalEntryId,
|
|
2362
2680
|
toEntryId: c.entryId,
|
|
2363
|
-
type: relationType
|
|
2681
|
+
type: relationType,
|
|
2682
|
+
sessionId: agentId ?? void 0
|
|
2364
2683
|
});
|
|
2365
2684
|
autoLinkCount++;
|
|
2366
2685
|
} catch {
|
|
@@ -2370,7 +2689,6 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2370
2689
|
}
|
|
2371
2690
|
}
|
|
2372
2691
|
results.push({ name: entry.name, collection: entry.collection, entryId: finalEntryId, ok: true, autoLinks: autoLinkCount });
|
|
2373
|
-
await recordSessionActivity({ entryCreated: internalId });
|
|
2374
2692
|
} catch (error) {
|
|
2375
2693
|
const msg = error instanceof Error ? error.message : String(error);
|
|
2376
2694
|
results.push({ name: entry.name, collection: entry.collection, entryId: "", ok: false, autoLinks: 0, error: msg });
|
|
@@ -2672,15 +2990,20 @@ export {
|
|
|
2672
2990
|
requireActiveSession,
|
|
2673
2991
|
requireWriteAccess,
|
|
2674
2992
|
recoverSessionState,
|
|
2993
|
+
deriveEpistemicStatus,
|
|
2994
|
+
formatEpistemicLine,
|
|
2995
|
+
toEpistemicInput,
|
|
2675
2996
|
extractPreview,
|
|
2676
2997
|
translateStaleToolNames,
|
|
2677
2998
|
initToolSurface,
|
|
2678
2999
|
trackWriteTool,
|
|
2679
3000
|
initFeatureFlags,
|
|
2680
3001
|
CLASSIFIER_AUTO_ROUTE_THRESHOLD,
|
|
3002
|
+
CLASSIFIABLE_COLLECTIONS,
|
|
2681
3003
|
STARTER_COLLECTIONS,
|
|
2682
|
-
|
|
3004
|
+
classifyCollection,
|
|
2683
3005
|
isClassificationAmbiguous,
|
|
3006
|
+
classifyStarterCollection,
|
|
2684
3007
|
success,
|
|
2685
3008
|
failure,
|
|
2686
3009
|
parseOrFail,
|
|
@@ -2690,6 +3013,7 @@ export {
|
|
|
2690
3013
|
notFoundResult,
|
|
2691
3014
|
validationResult,
|
|
2692
3015
|
withEnvelope,
|
|
3016
|
+
inferStrategyCategory,
|
|
2693
3017
|
formatQualityReport,
|
|
2694
3018
|
checkEntryQuality,
|
|
2695
3019
|
captureSchema,
|
|
@@ -2702,4 +3026,4 @@ export {
|
|
|
2702
3026
|
formatRubricCoaching,
|
|
2703
3027
|
formatRubricVerdictSection
|
|
2704
3028
|
};
|
|
2705
|
-
//# sourceMappingURL=chunk-
|
|
3029
|
+
//# sourceMappingURL=chunk-ED3KCWZE.js.map
|