@productbrain/mcp 0.0.1-beta.62 → 0.0.1-beta.63
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-4M3SUZHX.js → chunk-DM5DZC7B.js} +103 -18
- package/dist/chunk-DM5DZC7B.js.map +1 -0
- package/dist/{chunk-MH5MYP76.js → chunk-GKMXGRJW.js} +217 -53
- package/dist/chunk-GKMXGRJW.js.map +1 -0
- package/dist/{chunk-MRIO53BY.js → chunk-RQXM3TCI.js} +19 -1
- package/dist/chunk-RQXM3TCI.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +3 -3
- package/dist/index.js +3 -3
- package/dist/{setup-LSCFKMW7.js → setup-GQ3LQS2L.js} +9 -7
- package/dist/setup-GQ3LQS2L.js.map +1 -0
- package/dist/{smart-capture-NXLUISUD.js → smart-capture-NYOKGAFS.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-4M3SUZHX.js.map +0 -1
- package/dist/chunk-MH5MYP76.js.map +0 -1
- package/dist/chunk-MRIO53BY.js.map +0 -1
- package/dist/setup-LSCFKMW7.js.map +0 -1
- /package/dist/{smart-capture-NXLUISUD.js.map → smart-capture-NYOKGAFS.js.map} +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
trackCaptureClassifierFallback,
|
|
6
6
|
trackQualityVerdict,
|
|
7
7
|
trackToolCall
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RQXM3TCI.js";
|
|
9
9
|
|
|
10
10
|
// src/tools/smart-capture.ts
|
|
11
11
|
import { z as z2 } from "zod";
|
|
@@ -1780,7 +1780,9 @@ var captureSchema = z2.object({
|
|
|
1780
1780
|
to: z2.string().describe("Target entry ID (e.g. 'BR-64', 'ARCH-8')"),
|
|
1781
1781
|
type: z2.string().describe("Relation type (e.g. 'governs', 'related_to', 'informs')")
|
|
1782
1782
|
})).optional().describe("Relations to create after capture. Skips auto-link discovery when provided."),
|
|
1783
|
-
autoCommit: z2.boolean().optional().describe(
|
|
1783
|
+
autoCommit: z2.boolean().optional().describe(
|
|
1784
|
+
"If true, commits the entry immediately after capture + linking. If omitted, Open mode workspaces auto-commit by default and consensus/role modes stay draft-first."
|
|
1785
|
+
)
|
|
1784
1786
|
});
|
|
1785
1787
|
var batchCaptureSchema = z2.object({
|
|
1786
1788
|
entries: z2.array(z2.object({
|
|
@@ -1788,7 +1790,10 @@ var batchCaptureSchema = z2.object({
|
|
|
1788
1790
|
name: z2.string().describe("Display name"),
|
|
1789
1791
|
description: z2.string().describe("Full context / definition"),
|
|
1790
1792
|
entryId: z2.string().optional().describe("Optional custom entry ID")
|
|
1791
|
-
})).min(1).max(50).describe("Array of entries to capture")
|
|
1793
|
+
})).min(1).max(50).describe("Array of entries to capture"),
|
|
1794
|
+
autoCommit: z2.boolean().optional().describe(
|
|
1795
|
+
"If true, commits created entries immediately after linking. If omitted, Open mode workspaces commit by default and consensus/role modes stay draft-first."
|
|
1796
|
+
)
|
|
1792
1797
|
});
|
|
1793
1798
|
var captureClassifierSchema = z2.object({
|
|
1794
1799
|
enabled: z2.boolean(),
|
|
@@ -2073,10 +2078,15 @@ var batchCaptureOutputSchema = z2.object({
|
|
|
2073
2078
|
captured: z2.array(z2.object({
|
|
2074
2079
|
entryId: z2.string(),
|
|
2075
2080
|
collection: z2.string(),
|
|
2076
|
-
name: z2.string()
|
|
2081
|
+
name: z2.string(),
|
|
2082
|
+
status: z2.enum(["draft", "committed", "proposed"])
|
|
2077
2083
|
})),
|
|
2078
2084
|
total: z2.number(),
|
|
2079
2085
|
failed: z2.number(),
|
|
2086
|
+
committed: z2.number(),
|
|
2087
|
+
proposed: z2.number(),
|
|
2088
|
+
drafts: z2.number(),
|
|
2089
|
+
autoCommitApplied: z2.boolean(),
|
|
2080
2090
|
failedEntries: z2.array(z2.object({
|
|
2081
2091
|
index: z2.number(),
|
|
2082
2092
|
collection: z2.string(),
|
|
@@ -2084,6 +2094,9 @@ var batchCaptureOutputSchema = z2.object({
|
|
|
2084
2094
|
error: z2.string()
|
|
2085
2095
|
})).optional()
|
|
2086
2096
|
});
|
|
2097
|
+
function shouldAutoCommitCapture(autoCommit, governanceMode) {
|
|
2098
|
+
return autoCommit === true || autoCommit === void 0 && governanceMode === "open";
|
|
2099
|
+
}
|
|
2087
2100
|
function registerSmartCaptureTools(server) {
|
|
2088
2101
|
const supportedCollections = new Set(
|
|
2089
2102
|
CLASSIFIABLE_COLLECTIONS.filter((slug) => PROFILES.has(slug))
|
|
@@ -2092,7 +2105,7 @@ function registerSmartCaptureTools(server) {
|
|
|
2092
2105
|
"capture",
|
|
2093
2106
|
{
|
|
2094
2107
|
title: "Capture",
|
|
2095
|
-
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\
|
|
2108
|
+
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). In Open mode, entries commit by default when `autoCommit` is omitted. Pass `autoCommit: true` to promote the entry from draft to SSOT immediately after linking when you want to be explicit. Governed collections (glossary, business-rules, principles, standards, strategy, features, architecture) will warn but still commit \u2014 use only when you're certain.\n\nEntries are created as `draft` first, then may publish immediately depending on governance and `autoCommit`. Use `update-entry` for post-creation adjustments.",
|
|
2096
2109
|
inputSchema: captureSchema.shape,
|
|
2097
2110
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
2098
2111
|
},
|
|
@@ -2377,7 +2390,7 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2377
2390
|
} catch {
|
|
2378
2391
|
}
|
|
2379
2392
|
}
|
|
2380
|
-
const shouldAutoCommit = autoCommit
|
|
2393
|
+
const shouldAutoCommit = shouldAutoCommitCapture(autoCommit, wsCtx.governanceMode);
|
|
2381
2394
|
let finalStatus = "draft";
|
|
2382
2395
|
let commitError = null;
|
|
2383
2396
|
if (shouldAutoCommit && finalEntryId) {
|
|
@@ -2576,14 +2589,16 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2576
2589
|
"batch-capture",
|
|
2577
2590
|
{
|
|
2578
2591
|
title: "Batch Capture",
|
|
2579
|
-
description: "Create multiple knowledge entries in one call. Ideal for workspace setup, document ingestion, or any scenario where you need to capture many entries at once.\n\nEach entry is created independently \u2014 if one fails, the others still succeed. Returns a compact summary instead of per-entry quality scorecards.\n\nAuto-linking runs per entry but contradiction checks and readiness hints are skipped for speed. Use `quality action=check` on individual entries afterward if needed.",
|
|
2592
|
+
description: "Create multiple knowledge entries in one call. Ideal for workspace setup, document ingestion, or any scenario where you need to capture many entries at once.\n\nEach entry is created independently \u2014 if one fails, the others still succeed. Returns a compact summary instead of per-entry quality scorecards.\n\nAuto-linking runs per entry but contradiction checks and readiness hints are skipped for speed. Use `quality action=check` on individual entries afterward if needed.\n\nPass `autoCommit: false` to keep the whole batch draft-first. If omitted, Open mode workspaces commit by default and consensus/role modes keep drafts.",
|
|
2580
2593
|
inputSchema: batchCaptureSchema.shape,
|
|
2581
2594
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
2582
2595
|
},
|
|
2583
|
-
withEnvelope(async ({ entries }) => {
|
|
2596
|
+
withEnvelope(async ({ entries, autoCommit }) => {
|
|
2584
2597
|
requireWriteAccess();
|
|
2585
2598
|
const agentId = getAgentSessionId();
|
|
2586
2599
|
const createdBy = agentId ? `agent:${agentId}` : "capture";
|
|
2600
|
+
const wsCtx = await getWorkspaceContext();
|
|
2601
|
+
const autoCommitApplied = shouldAutoCommitCapture(autoCommit, wsCtx.governanceMode);
|
|
2587
2602
|
const results = [];
|
|
2588
2603
|
await server.sendLoggingMessage({
|
|
2589
2604
|
level: "info",
|
|
@@ -2607,7 +2622,15 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2607
2622
|
const profile = PROFILES.get(entry.collection) ?? FALLBACK_PROFILE;
|
|
2608
2623
|
const col = collCache.get(entry.collection);
|
|
2609
2624
|
if (!col) {
|
|
2610
|
-
results.push({
|
|
2625
|
+
results.push({
|
|
2626
|
+
name: entry.name,
|
|
2627
|
+
collection: entry.collection,
|
|
2628
|
+
entryId: "",
|
|
2629
|
+
ok: false,
|
|
2630
|
+
autoLinks: 0,
|
|
2631
|
+
status: "draft",
|
|
2632
|
+
error: `Collection "${entry.collection}" not found`
|
|
2633
|
+
});
|
|
2611
2634
|
continue;
|
|
2612
2635
|
}
|
|
2613
2636
|
const data = {};
|
|
@@ -2657,6 +2680,8 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2657
2680
|
});
|
|
2658
2681
|
const internalId = result.docId;
|
|
2659
2682
|
const finalEntryId = result.entryId;
|
|
2683
|
+
let finalStatus = "draft";
|
|
2684
|
+
let commitError;
|
|
2660
2685
|
let autoLinkCount = 0;
|
|
2661
2686
|
const searchQuery = extractSearchTerms(entry.name, entry.description);
|
|
2662
2687
|
if (searchQuery) {
|
|
@@ -2689,14 +2714,49 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2689
2714
|
} catch {
|
|
2690
2715
|
}
|
|
2691
2716
|
}
|
|
2692
|
-
|
|
2717
|
+
if (autoCommitApplied) {
|
|
2718
|
+
try {
|
|
2719
|
+
const commitResult = await mcpMutation("chain.commitEntry", {
|
|
2720
|
+
entryId: finalEntryId,
|
|
2721
|
+
author: agentId ? `agent:${agentId}` : void 0,
|
|
2722
|
+
sessionId: agentId ?? void 0
|
|
2723
|
+
});
|
|
2724
|
+
finalStatus = commitResult?.status === "proposal_created" ? "proposed" : "committed";
|
|
2725
|
+
if (finalStatus === "committed") {
|
|
2726
|
+
await recordSessionActivity({ entryModified: internalId });
|
|
2727
|
+
}
|
|
2728
|
+
} catch (error) {
|
|
2729
|
+
commitError = error instanceof Error ? error.message : String(error);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
results.push({
|
|
2733
|
+
name: entry.name,
|
|
2734
|
+
collection: entry.collection,
|
|
2735
|
+
entryId: finalEntryId,
|
|
2736
|
+
ok: true,
|
|
2737
|
+
autoLinks: autoLinkCount,
|
|
2738
|
+
status: finalStatus,
|
|
2739
|
+
...commitError ? { commitError } : {}
|
|
2740
|
+
});
|
|
2693
2741
|
} catch (error) {
|
|
2694
2742
|
const msg = error instanceof Error ? error.message : String(error);
|
|
2695
|
-
results.push({
|
|
2743
|
+
results.push({
|
|
2744
|
+
name: entry.name,
|
|
2745
|
+
collection: entry.collection,
|
|
2746
|
+
entryId: "",
|
|
2747
|
+
ok: false,
|
|
2748
|
+
autoLinks: 0,
|
|
2749
|
+
status: "draft",
|
|
2750
|
+
error: msg
|
|
2751
|
+
});
|
|
2696
2752
|
}
|
|
2697
2753
|
}
|
|
2698
2754
|
const created = results.filter((r) => r.ok);
|
|
2699
2755
|
const failed = results.filter((r) => !r.ok);
|
|
2756
|
+
const committed = created.filter((r) => r.status === "committed");
|
|
2757
|
+
const proposed = created.filter((r) => r.status === "proposed");
|
|
2758
|
+
const drafts = created.filter((r) => r.status === "draft");
|
|
2759
|
+
const commitFailures = created.filter((r) => r.commitError);
|
|
2700
2760
|
await server.sendLoggingMessage({
|
|
2701
2761
|
level: "info",
|
|
2702
2762
|
data: `Batch complete. ${created.length} succeeded, ${failed.length} failed.`,
|
|
@@ -2713,6 +2773,12 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2713
2773
|
`**Auto-links created:** ${totalAutoLinks}`,
|
|
2714
2774
|
""
|
|
2715
2775
|
];
|
|
2776
|
+
if (created.length > 0) {
|
|
2777
|
+
lines.push(
|
|
2778
|
+
`**Statuses:** ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft.`
|
|
2779
|
+
);
|
|
2780
|
+
lines.push("");
|
|
2781
|
+
}
|
|
2716
2782
|
if (byCollection.size > 0) {
|
|
2717
2783
|
lines.push("## By Collection");
|
|
2718
2784
|
for (const [col, count] of byCollection) {
|
|
@@ -2723,8 +2789,15 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2723
2789
|
if (created.length > 0) {
|
|
2724
2790
|
lines.push("## Created");
|
|
2725
2791
|
for (const r of created) {
|
|
2726
|
-
const linkNote = r.autoLinks > 0 ?
|
|
2727
|
-
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}]
|
|
2792
|
+
const linkNote = r.autoLinks > 0 ? `, ${r.autoLinks} auto-links` : "";
|
|
2793
|
+
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 \`${r.status}\`${linkNote}`);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
if (commitFailures.length > 0) {
|
|
2797
|
+
lines.push("");
|
|
2798
|
+
lines.push("## Saved as draft");
|
|
2799
|
+
for (const r of commitFailures) {
|
|
2800
|
+
lines.push(`- **${r.entryId}**: ${r.name} [${r.collection}] \u2014 ${r.commitError}`);
|
|
2728
2801
|
}
|
|
2729
2802
|
}
|
|
2730
2803
|
if (failed.length > 0) {
|
|
@@ -2741,22 +2814,34 @@ Use \`entries action=get\` to inspect the existing entry, or \`update-entry\` to
|
|
|
2741
2814
|
lines.push("");
|
|
2742
2815
|
lines.push("## Next Steps");
|
|
2743
2816
|
lines.push(`- **Connect:** Run \`graph action=suggest\` on key entries to build the knowledge graph`);
|
|
2744
|
-
|
|
2817
|
+
if (drafts.length > 0) {
|
|
2818
|
+
lines.push(`- **Commit:** Use \`commit-entry\` to promote remaining drafts to SSOT`);
|
|
2819
|
+
}
|
|
2745
2820
|
lines.push(`- **Quality:** Run \`quality action=check\` on individual entries to assess completeness`);
|
|
2746
2821
|
}
|
|
2747
|
-
const summary = failed.length > 0 ? `Batch captured ${created.length}/${entries.length} entries (${failed.length} failed).` : `Batch captured ${created.length} entries successfully.`;
|
|
2822
|
+
const summary = failed.length > 0 ? `Batch captured ${created.length}/${entries.length} entries (${failed.length} failed, ${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft).` : `Batch captured ${created.length} entries successfully (${committed.length} committed, ${proposed.length} proposed, ${drafts.length} draft).`;
|
|
2823
|
+
const firstDraft = drafts[0];
|
|
2748
2824
|
const next = created.length > 0 ? [
|
|
2749
2825
|
{ tool: "graph", description: "Discover connections", parameters: { action: "suggest", entryId: created[0].entryId } },
|
|
2750
|
-
{ tool: "commit-entry", description: "Commit first
|
|
2826
|
+
...firstDraft ? [{ tool: "commit-entry", description: "Commit first draft", parameters: { entryId: firstDraft.entryId } }] : []
|
|
2751
2827
|
] : [];
|
|
2752
2828
|
return {
|
|
2753
2829
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
2754
2830
|
structuredContent: success(
|
|
2755
2831
|
summary,
|
|
2756
2832
|
{
|
|
2757
|
-
captured: created.map((r) => ({
|
|
2833
|
+
captured: created.map((r) => ({
|
|
2834
|
+
entryId: r.entryId,
|
|
2835
|
+
collection: r.collection,
|
|
2836
|
+
name: r.name,
|
|
2837
|
+
status: r.status
|
|
2838
|
+
})),
|
|
2758
2839
|
total: created.length,
|
|
2759
2840
|
failed: failed.length,
|
|
2841
|
+
committed: committed.length,
|
|
2842
|
+
proposed: proposed.length,
|
|
2843
|
+
drafts: drafts.length,
|
|
2844
|
+
autoCommitApplied,
|
|
2760
2845
|
...failed.length > 0 && {
|
|
2761
2846
|
failedEntries: failed.map((r) => ({
|
|
2762
2847
|
index: results.indexOf(r),
|
|
@@ -3026,4 +3111,4 @@ export {
|
|
|
3026
3111
|
formatRubricCoaching,
|
|
3027
3112
|
formatRubricVerdictSection
|
|
3028
3113
|
};
|
|
3029
|
-
//# sourceMappingURL=chunk-
|
|
3114
|
+
//# sourceMappingURL=chunk-DM5DZC7B.js.map
|