@productbrain/mcp 0.0.1-beta.11500 → 0.0.1-beta.11515
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-AMTSVZXV.js → chunk-FFOGLME6.js} +225 -596
- package/dist/chunk-FFOGLME6.js.map +1 -0
- package/dist/{chunk-3STAPRQ3.js → chunk-PTRT75UR.js} +2 -2
- package/dist/chunk-PTRT75UR.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-JSUEHMKA.js → setup-JS3ZNO44.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-3STAPRQ3.js.map +0 -1
- package/dist/chunk-AMTSVZXV.js.map +0 -1
- /package/dist/{setup-JSUEHMKA.js.map → setup-JS3ZNO44.js.map} +0 -0
|
@@ -35,11 +35,11 @@ import {
|
|
|
35
35
|
runWithToolContext,
|
|
36
36
|
setSessionOriented,
|
|
37
37
|
startAgentSession
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-PTRT75UR.js";
|
|
39
39
|
|
|
40
40
|
// src/server.ts
|
|
41
41
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
42
|
-
import { z as
|
|
42
|
+
import { z as z35 } from "zod/v3";
|
|
43
43
|
|
|
44
44
|
// src/lib/mcpGatewayClientMessages.ts
|
|
45
45
|
function agentSessionNotActiveMessage(status2) {
|
|
@@ -175,7 +175,7 @@ function thinWrapper(handler) {
|
|
|
175
175
|
return {
|
|
176
176
|
content: [{
|
|
177
177
|
type: "text",
|
|
178
|
-
text:
|
|
178
|
+
text: `[${classified.code}] ${classified.message}`
|
|
179
179
|
}],
|
|
180
180
|
structuredContent: envelope,
|
|
181
181
|
isError: true
|
|
@@ -498,15 +498,14 @@ var TOOL_NAME_MIGRATIONS = /* @__PURE__ */ new Map([
|
|
|
498
498
|
// (WP-687 S2 retired the map tool and its 4 migration rows below.)
|
|
499
499
|
// Multi-action retired tools map to the FULL action menu (pipe / wildcard
|
|
500
500
|
// form), never a single default action: the coach only matches the retired
|
|
501
|
-
// NAME, so historical text like `facilitate action=
|
|
502
|
-
//
|
|
503
|
-
// send the agent down the wrong path (PR #362 review finding).
|
|
501
|
+
// NAME, so historical text like `facilitate action=resume` maps to the
|
|
502
|
+
// matching action (PR #362 review finding).
|
|
504
503
|
["update-entry", 'entries action="update"'],
|
|
505
504
|
["get-history", 'context action="history"'],
|
|
506
|
-
["commit-entry", 'entries action="
|
|
505
|
+
["commit-entry", 'entries action="accept"'],
|
|
507
506
|
["move-entry", 'entries action="move"'],
|
|
508
|
-
["session-wrapup", 'session action="wrapup-review
|
|
509
|
-
["facilitate", 'session action="resume
|
|
507
|
+
["session-wrapup", 'session action="wrapup-review", then entries action="accept" per draft'],
|
|
508
|
+
["facilitate", 'session action="resume", then entries action="accept" per entry'],
|
|
510
509
|
["graph", 'context action="find" (same action name)'],
|
|
511
510
|
["documents", 'context action="last-verified-brief"'],
|
|
512
511
|
["labels", 'collections action="label-*" (list/create/update/delete/apply/remove \u2192 label-<same>)'],
|
|
@@ -1055,7 +1054,7 @@ function registerSmartCaptureTools(server) {
|
|
|
1055
1054
|
"capture",
|
|
1056
1055
|
{
|
|
1057
1056
|
title: "Capture",
|
|
1058
|
-
description: "The tool for creating a single knowledge entry. Creates an entry and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional \u2014 the kernel classifies when omitted and files a low-confidence pick as a draft with one line saying so. An agent capturing several atoms from one text calls this once per atom.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. A value in `data` is kept as sent; `description` is the entry's text and fills the collection's prose field only when `data` leaves it empty (the same rule as `pb capture`); when `data` carries the prose field, `description` and `context` are used for classification and judging only and are not stored. Governance entries also require a top-level `why`.\n\n**Compound capture:** Pass `links` to create relations in the same call; a capture writes no other relations. A capture lands as a `draft` to accept with `entries action=
|
|
1057
|
+
description: "The tool for creating a single knowledge entry. Creates an entry and returns a quality scorecard \u2014 all in one call. Provide a name and description; `collection` is optional \u2014 the kernel classifies when omitted and files a low-confidence pick as a draft with one line saying so. An agent capturing several atoms from one text calls this once per atom.\n\n**Explicit data:** When you know the schema, pass `data: { field: value }` to set fields directly. A value in `data` is kept as sent; `description` is the entry's text and fills the collection's prose field only when `data` leaves it empty (the same rule as `pb capture`); when `data` carries the prose field, `description` and `context` are used for classification and judging only and are not stored. Governance entries also require a top-level `why`.\n\n**Compound capture:** Pass `links` to create relations in the same call; a capture writes no other relations. A capture lands as a `draft` to accept with `entries action=accept`; a question is born open. The reply names possible duplicates; only an exact name in the collection is refused.",
|
|
1059
1058
|
inputSchema: captureCompoundSchema,
|
|
1060
1059
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
1061
1060
|
},
|
|
@@ -1278,7 +1277,7 @@ Use \`context action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
1278
1277
|
} else if (spineFloor) {
|
|
1279
1278
|
const { relationType: relationType2, parentKind, exempt, linkWritten } = spineFloor, id = finalEntryId, to = `<${parentKind.toUpperCase().replace(/_/g, "-")}-ID>`;
|
|
1280
1279
|
lines.push("", "## Saved as draft", `**${name}** ${exempt ? SPINE_FLOOR_EXEMPT_SENTENCE : `kept as a draft. ${rungLine(parentKind)}`}`);
|
|
1281
|
-
lines.push(exempt || linkWritten ? `Next: \`entries action=
|
|
1280
|
+
lines.push(exempt || linkWritten ? `Next: \`entries action=accept entryId="${id}"\`.` : `Next: \`relations action=create from="${id}" type="${relationType2}" to="${to}"\`.`);
|
|
1282
1281
|
}
|
|
1283
1282
|
if (groundingCaveat) lines.push("", groundingCaveat);
|
|
1284
1283
|
const named = groundingReport.duplicates.slice(0, 3).map((d) => `${d.entryId} "${d.name}"`).join(", ");
|
|
@@ -1325,7 +1324,7 @@ Use \`context action=get\` to inspect the existing entry, or \`entries action=up
|
|
|
1325
1324
|
next.push({ tool: "context", description: "See its connections", parameters: { action: "find", entryId: finalEntryId } });
|
|
1326
1325
|
} else {
|
|
1327
1326
|
next.push({ tool: "context", description: "Review the draft alternative", parameters: { action: "get", entryId: finalEntryId } });
|
|
1328
|
-
next.push(spineFloor && !spineFloor.exempt && !spineFloor.linkWritten ? { tool: "relations", description: "Write the spine link it owes", parameters: { action: "create", from: finalEntryId, type: spineFloor.relationType } } : { tool: "entries", description: "Accept onto Chain", parameters: { action: "
|
|
1327
|
+
next.push(spineFloor && !spineFloor.exempt && !spineFloor.linkWritten ? { tool: "relations", description: "Write the spine link it owes", parameters: { action: "create", from: finalEntryId, type: spineFloor.relationType } } : { tool: "entries", description: "Accept onto Chain", parameters: { action: "accept", entryId: finalEntryId } });
|
|
1329
1328
|
}
|
|
1330
1329
|
const qualityPhrase = verdictQualityPhrase(verdictResult);
|
|
1331
1330
|
const summary = finalStatus === "committed" ? `Captured and accepted ${finalEntryId} (${name}) onto ${landedCollection}. ${qualityPhrase}` : `Captured ${finalEntryId} (${name}) as draft in ${landedCollection}. ${qualityPhrase}`;
|
|
@@ -1599,11 +1598,11 @@ var updateEntrySchema = z7.object({
|
|
|
1599
1598
|
name: z7.string().optional().describe("New display name"),
|
|
1600
1599
|
// Chain-ID-leak guard (check:chain-id-leaks): the retired legacy-shim ticket number stays in
|
|
1601
1600
|
// the code comment above, never in this user-visible describe() string. T8 (TASK-393, WP-779): narrowed to generated ENTRY_STATUS_WRITE_WORDS.
|
|
1602
|
-
status: z7.enum(ENTRY_STATUS_WRITE_WORDS).optional().describe(`Lifecycle status: ${ENTRY_STATUS_WRITE_WORDS.join(" | ")}. 'accepted' is set via '
|
|
1601
|
+
status: z7.enum(ENTRY_STATUS_WRITE_WORDS).optional().describe(`Lifecycle status: ${ENTRY_STATUS_WRITE_WORDS.join(" | ")}. 'accepted' is set via 'accept', never 'update'; 'active'/'deprecated' are legacy words and are refused here. Use \`workflowStatus\` for collection-specific workflow values \u2014 those are no longer accepted via \`status\`.`),
|
|
1603
1602
|
workflowStatus: z7.string().optional().describe("Collection workflow state. Valid values are collection-specific and server-owned \u2014 discover them via `collections action=describe` for the target collection. The server rejects invalid values and returns the valid set in the error."),
|
|
1604
1603
|
data: z7.record(z7.unknown()).optional().describe("Fields to update (merged with existing data)"),
|
|
1605
1604
|
order: z7.number().optional().describe("New sort order"),
|
|
1606
|
-
canonicalKey: z7.string().optional().describe("Semantic type (e.g. 'decision', 'tension'). Only changeable on draft
|
|
1605
|
+
canonicalKey: z7.string().optional().describe("Semantic type (e.g. 'decision', 'tension'). Only changeable on draft entries."),
|
|
1607
1606
|
autoPublish: z7.boolean().optional().default(false).describe("Accepted for backward compatibility but IGNORED \u2014 draft vs. published is decided by the entry's own accepted/active status, never by this flag. Removal tracked as a follow-up."),
|
|
1608
1607
|
// DEC-1716
|
|
1609
1608
|
changeReason: z7.string().optional().describe("Change reason: required when this update changes a promise field (or the name of a collection that declares one) of an accepted entry \u2014 why what the entry promises is changing. Recorded on the history event and the version. Not the same as changeNote."),
|
|
@@ -1716,7 +1715,7 @@ ${mcp}`, "QUALITY_HELD", mcp.split("\n")[0] ?? mcp, mcp.split("\n")[1] ?? mcp, v
|
|
|
1716
1715
|
const next = [
|
|
1717
1716
|
{ tool: "context", description: "View updated entry", parameters: { action: "get", entryId } },
|
|
1718
1717
|
// DEC-1894: reads live on context
|
|
1719
|
-
{ tool: toolName, description: "Accept onto Chain", parameters: { action: "
|
|
1718
|
+
{ tool: toolName, description: "Accept onto Chain", parameters: { action: "accept", entryId } }
|
|
1720
1719
|
];
|
|
1721
1720
|
return {
|
|
1722
1721
|
content: [{ type: "text", text: responseLines.join("\n") }],
|
|
@@ -1791,7 +1790,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
|
|
|
1791
1790
|
...conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}
|
|
1792
1791
|
});
|
|
1793
1792
|
if (result2?.status === "coherency_refused" && result2?.refusal) {
|
|
1794
|
-
return coherencyRefusedResult(`${toolName} action=
|
|
1793
|
+
return coherencyRefusedResult(`${toolName} action=accept`, entryId, result2.refusal);
|
|
1795
1794
|
}
|
|
1796
1795
|
if (result2?.preview) {
|
|
1797
1796
|
const wouldBlock = result2.wouldBlock === true;
|
|
@@ -1808,7 +1807,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
|
|
|
1808
1807
|
...wouldBlock && result2.blockingReason ? { blockingReason: result2.blockingReason } : {},
|
|
1809
1808
|
...previewContradictionAdvisory ? { contradictionAdvisory: previewContradictionAdvisory } : {}
|
|
1810
1809
|
},
|
|
1811
|
-
[{ tool: toolName, description: "Accept for real", parameters: { action: "
|
|
1810
|
+
[{ tool: toolName, description: "Accept for real", parameters: { action: "accept", entryId } }]
|
|
1812
1811
|
);
|
|
1813
1812
|
if (result2.contract) {
|
|
1814
1813
|
previewEnvelope.contract = result2.contract;
|
|
@@ -1820,7 +1819,7 @@ async function handleCommitEntry({ entryId, preview, steeringOverrideReason, qua
|
|
|
1820
1819
|
**Would be blocked** by the coherency/grounding gate.` : "";
|
|
1821
1820
|
const advisoryNote = previewContradictionAdvisory ? `
|
|
1822
1821
|
|
|
1823
|
-
\u26A0 Contradiction advisory (would be attached on real
|
|
1822
|
+
\u26A0 Contradiction advisory (would be attached on a real accept): ${previewContradictionAdvisory.reason}
|
|
1824
1823
|
${previewContradictionAdvisory.conflictDetails.map((c) => `- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`).join("\n")}` : "";
|
|
1825
1824
|
return {
|
|
1826
1825
|
content: [{ type: "text", text: `# Preview: would ${wouldBlock ? "BLOCK accept" : "accept"} ${entryId}
|
|
@@ -1838,14 +1837,14 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
1838
1837
|
const lines = [
|
|
1839
1838
|
`# Accepted: ${entryId}`,
|
|
1840
1839
|
...judged ? [judged] : [],
|
|
1841
|
-
`**${entry.name}**
|
|
1840
|
+
`**${entry.name}** accepted onto the Chain.`,
|
|
1842
1841
|
`**Workspace:** ${wsCtx.workspaceSlug} (${wsCtx.workspaceId})`
|
|
1843
1842
|
];
|
|
1844
1843
|
const autoVerified = result2?.autoVerified;
|
|
1845
1844
|
if (autoVerified?.strength) {
|
|
1846
1845
|
const who = autoVerified.verifiedBy ? ` (${autoVerified.verifiedBy})` : "";
|
|
1847
1846
|
lines.push("");
|
|
1848
|
-
lines.push(`_Auto-verified as part of
|
|
1847
|
+
lines.push(`_Auto-verified as part of this accept \u2014 ${autoVerified.strength}${who}._`);
|
|
1849
1848
|
}
|
|
1850
1849
|
if (advisoryWarnings.length > 0) {
|
|
1851
1850
|
lines.push("");
|
|
@@ -1876,7 +1875,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
1876
1875
|
const contradictionAdvisory = result2?.contradictionAdvisory;
|
|
1877
1876
|
if (contradictionAdvisory) {
|
|
1878
1877
|
lines.push("");
|
|
1879
|
-
lines.push(`\u26A0 Contradiction advisory (entry
|
|
1878
|
+
lines.push(`\u26A0 Contradiction advisory (entry accepted): ${contradictionAdvisory.reason}`);
|
|
1880
1879
|
for (const c of contradictionAdvisory.conflictDetails) {
|
|
1881
1880
|
lines.push(`- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`);
|
|
1882
1881
|
}
|
|
@@ -1884,7 +1883,7 @@ No DB writes \u2014 call without \`preview:true\` to accept for real.` }],
|
|
|
1884
1883
|
const publishAdvisories = Array.isArray(result2?.publishAdvisories) ? result2.publishAdvisories.filter((a) => typeof a === "string") : void 0;
|
|
1885
1884
|
if (publishAdvisories && publishAdvisories.length > 0) {
|
|
1886
1885
|
lines.push("");
|
|
1887
|
-
lines.push("\u26A0 Direction advisory (entry
|
|
1886
|
+
lines.push("\u26A0 Direction advisory (entry accepted):");
|
|
1888
1887
|
for (const advisory of publishAdvisories) {
|
|
1889
1888
|
lines.push(`- ${advisory}`);
|
|
1890
1889
|
}
|
|
@@ -2443,7 +2442,7 @@ function platformSearchLines(platform) {
|
|
|
2443
2442
|
import { z as z11 } from "zod/v3";
|
|
2444
2443
|
var ENTRIES_ACTIONS = [
|
|
2445
2444
|
"update",
|
|
2446
|
-
"
|
|
2445
|
+
"accept",
|
|
2447
2446
|
"move",
|
|
2448
2447
|
"verify",
|
|
2449
2448
|
"still-true"
|
|
@@ -2453,18 +2452,19 @@ var coherencyAcknowledgementFlatSchema = z11.object({
|
|
|
2453
2452
|
entryId: z11.string().max(200).optional().describe("Authorizing entry being linked/accepted (required for 'linked' and 'accepted-fix')."),
|
|
2454
2453
|
reason: z11.string().max(2e3).optional().describe("Divergence rationale (required for 'diverged', \u226512 chars).")
|
|
2455
2454
|
});
|
|
2456
|
-
var
|
|
2457
|
-
preflight: "entries only writes. Check a collection's requirements with the read-only context tool: context action=preflight collection=..."
|
|
2455
|
+
var ENTRIES_MOVED = {
|
|
2456
|
+
preflight: "entries only writes. Check a collection's requirements with the read-only context tool: context action=preflight collection=...",
|
|
2457
|
+
commit: "commit was renamed accept. Next: entries action=accept entryId=..."
|
|
2458
2458
|
};
|
|
2459
2459
|
var entriesSchema = z11.object({
|
|
2460
|
-
action: actionEnum(ENTRIES_ACTIONS,
|
|
2461
|
-
"'update': change fields on an existing entry (draft by default). '
|
|
2460
|
+
action: actionEnum(ENTRIES_ACTIONS, ENTRIES_MOVED).describe(
|
|
2461
|
+
"'update': change fields on an existing entry (draft by default). 'accept': accept a draft entry onto the Chain. 'move': relocate an entry to a different collection (pass `canonicalKey` too for an atomic move+retype). 'verify': mark an entry as verified (lightweight \u2014 no codebase scan; see `quality action=verify-chain` for that). 'still-true': confirm accuracy (the holder of the owning role, else the nearest seated Team Lead) \u2014 distinct from 'verify'; no content, version, or updatedAt change."
|
|
2462
2462
|
),
|
|
2463
2463
|
entryId: z11.string().max(200).optional().describe(
|
|
2464
|
-
"Entry ID, e.g. '<PREFIX>-<n>'. Required for: update,
|
|
2464
|
+
"Entry ID, e.g. '<PREFIX>-<n>'. Required for: update, accept, move, verify, still-true."
|
|
2465
2465
|
),
|
|
2466
2466
|
status: z11.string().max(200).optional().describe(
|
|
2467
|
-
"For 'update': draft|archived ONLY \u2014 'accepted' is set via '
|
|
2467
|
+
"For 'update': draft|archived ONLY \u2014 'accepted' is set via 'accept', never 'update'; 'active'/'deprecated' are legacy read-only words, refused on write. Workflow values use `workflowStatus` instead."
|
|
2468
2468
|
),
|
|
2469
2469
|
name: z11.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("For 'update': new display name."),
|
|
2470
2470
|
workflowStatus: z11.string().max(200).optional().describe(
|
|
@@ -2473,7 +2473,7 @@ var entriesSchema = z11.object({
|
|
|
2473
2473
|
data: z11.record(z11.unknown()).optional().describe("For 'update': fields to update (merged with existing data)."),
|
|
2474
2474
|
order: z11.number().optional().describe("For 'update': new sort order."),
|
|
2475
2475
|
canonicalKey: z11.string().max(200).optional().describe(
|
|
2476
|
-
"For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft
|
|
2476
|
+
"For 'update': semantic type (e.g. 'decision', 'tension'); only changeable on draft entries. For 'move': optional atomic move+retype target."
|
|
2477
2477
|
),
|
|
2478
2478
|
// DEC-1716: draft vs. published is decided by the entry's own accepted/active status, never this flag.
|
|
2479
2479
|
autoPublish: z11.boolean().optional().default(false).describe(
|
|
@@ -2492,21 +2492,21 @@ var entriesSchema = z11.object({
|
|
|
2492
2492
|
"For 'update': verbatim excerpt from the source backing this entry's claims. Write-once."
|
|
2493
2493
|
),
|
|
2494
2494
|
steeringOverrideReason: z11.string().max(2e3).optional().describe(
|
|
2495
|
-
"For 'update'/'
|
|
2495
|
+
"For 'update'/'accept': typed override (\u226512 chars) that clears a steering coherency block."
|
|
2496
2496
|
),
|
|
2497
2497
|
qualityOverrideReason: z11.string().max(2e3).optional().describe(
|
|
2498
|
-
"For 'update'/'
|
|
2498
|
+
"For 'update'/'accept': why (\u226512 chars) to keep a spine text its quality checklist failed; recorded as an override with who wrote it."
|
|
2499
2499
|
),
|
|
2500
2500
|
coherencyAcknowledgement: coherencyAcknowledgementFlatSchema.optional().describe(
|
|
2501
|
-
"For 'update'/'
|
|
2501
|
+
"For 'update'/'accept': explicit response to a coherency challenge (standard/strict workspace modes)."
|
|
2502
2502
|
),
|
|
2503
2503
|
preview: z11.boolean().optional().describe(
|
|
2504
|
-
"For '
|
|
2504
|
+
"For 'accept': if true, validates the accept without writing \u2014 returns what would happen."
|
|
2505
2505
|
),
|
|
2506
2506
|
toCollection: z11.string().max(200).optional().describe("For 'move': target collection slug, e.g. 'decisions', 'architecture'.")
|
|
2507
2507
|
});
|
|
2508
2508
|
var entriesUpdateVariant = updateEntrySchema.extend({ action: z11.literal("update") });
|
|
2509
|
-
var
|
|
2509
|
+
var entriesAcceptVariant = commitEntrySchema.extend({ action: z11.literal("accept") });
|
|
2510
2510
|
var entriesMoveVariant = z11.object({
|
|
2511
2511
|
action: z11.literal("move"),
|
|
2512
2512
|
entryId: z11.string().max(200),
|
|
@@ -2518,14 +2518,14 @@ var entriesVerifyVariant = verifyEntrySchema.extend({ action: z11.literal("verif
|
|
|
2518
2518
|
var entriesStillTrueVariant = stillTrueEntrySchema.extend({ action: z11.literal("still-true") });
|
|
2519
2519
|
var entriesActionUnion = z11.discriminatedUnion("action", [
|
|
2520
2520
|
entriesUpdateVariant,
|
|
2521
|
-
|
|
2521
|
+
entriesAcceptVariant,
|
|
2522
2522
|
entriesMoveVariant,
|
|
2523
2523
|
entriesVerifyVariant,
|
|
2524
2524
|
entriesStillTrueVariant
|
|
2525
2525
|
]);
|
|
2526
2526
|
var ENTRIES_ACTION_SPECS = {
|
|
2527
2527
|
update: { params: ["entryId", "name", "status", "workflowStatus", "data", "order", "canonicalKey", "autoPublish", "changeNote", "changeReason", "sourceRef", "sourceExcerpt", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required; every other field is optional." },
|
|
2528
|
-
|
|
2528
|
+
accept: { params: ["entryId", "preview", "steeringOverrideReason", "qualityOverrideReason", "coherencyAcknowledgement"], description: "entryId is required." },
|
|
2529
2529
|
move: { params: ["entryId", "toCollection", "canonicalKey"], description: "entryId and toCollection are required; canonicalKey is optional (atomic move+retype)." },
|
|
2530
2530
|
verify: { params: ["entryId"], description: "entryId is required." },
|
|
2531
2531
|
"still-true": { params: ["entryId"], description: "entryId is required. Allowed for the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree." }
|
|
@@ -2673,10 +2673,10 @@ var entriesBatchOutputSchema = z12.object({
|
|
|
2673
2673
|
});
|
|
2674
2674
|
function registerEntriesTools(server) {
|
|
2675
2675
|
const entriesHandlers = {
|
|
2676
|
-
// update/
|
|
2676
|
+
// update/accept reuse knowledge.ts's extracted handlers — "entries" routes
|
|
2677
2677
|
// `next` at itself (toolName="entries") instead of the legacy tool names.
|
|
2678
2678
|
update: (data) => handleUpdateEntry(data, "entries"),
|
|
2679
|
-
|
|
2679
|
+
accept: (data) => handleCommitEntry(data, "entries"),
|
|
2680
2680
|
move: (data) => handleMoveEntry(data.entryId, data.toCollection, data.canonicalKey),
|
|
2681
2681
|
verify: (data) => handleVerifyEntry(data),
|
|
2682
2682
|
"still-true": (data) => handleStillTrueEntry(data)
|
|
@@ -2685,7 +2685,7 @@ function registerEntriesTools(server) {
|
|
|
2685
2685
|
"entries",
|
|
2686
2686
|
{
|
|
2687
2687
|
title: "Entries",
|
|
2688
|
-
description: 'Write entries on the Chain: the entry lifecycle after capture. Reads live on `context`.\n\n- **update**: Change fields on an existing entry (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **
|
|
2688
|
+
description: 'Write entries on the Chain: the entry lifecycle after capture. Reads live on `context`.\n\n- **update**: Change fields on an existing entry (publishes whenever the entry is not draft \u2014 includes archived, not just accepted/active; autoPublish is accepted but ignored).\n- **accept**: Accept a draft entry onto the Chain. Runs the contradiction preflight first.\n- **move**: Relocate an entry to a different collection; pass canonicalKey too for an atomic move+retype.\n- **verify**: Mark verified (lightweight, no scan \u2014 see `quality action=verify-chain`).\n- **still-true**: confirm accuracy (the holder of the owning role; if that role is empty, the nearest seated Team Lead up the team tree).\n\nRead entries with the read-only `context` tool: `context action=get entryId="..."`, `context action=search query="..."`, `context action=preflight`.',
|
|
2689
2689
|
inputSchema: entriesSchema,
|
|
2690
2690
|
// DEC-1894 / DEC-74: every look-up lives on the read-only `context` tool, so this
|
|
2691
2691
|
// annotation tells hosts the truth about the writes left here.
|
|
@@ -4338,7 +4338,7 @@ var CONTEXT_ACTIONS = [...LOOKUP_ACTIONS, "gather", "build", "neighborhood", "ch
|
|
|
4338
4338
|
var contextSchema = z20.object({
|
|
4339
4339
|
// provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
|
|
4340
4340
|
action: z20.enum(CONTEXT_ACTIONS).describe(
|
|
4341
|
-
LOOKUP_ACTION_DESCRIBE + "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair
|
|
4341
|
+
LOOKUP_ACTION_DESCRIBE + "'gather': assemble knowledge context (entry graph, task auto-load, journey mode, or graph mode). 'build': structured build spec for an entry. 'neighborhood': typed graph neighborhood for an entry \u2014 blocking chain, dependencies, parent context, tensions, staleness. 'changes': entries modified and relations created since a timestamp. Requires 'since' parameter. 'chain': directed traversal along one relation type to depth 4. Requires entryId. Optional: direction, relationType, maxHops (1-4). 'cross-cut': structural aggregation \u2014 all relations of a given type grouped by source collection. Requires 'relationType' parameter. 'incremental': delta since last brief run for a skill. Requires 'skill' parameter. Returns only entries changed since the skill's last brief. 'brief': compound intelligence query. Requires 'briefType' parameter: 'steering' (changes + structure + delta + readiness), 'confidence' (changes + active bets \u2014 use the pb CLI's `tensions list` for tensions), or 'delta' (changes + relations since timestamp). Optional 'since' for delta type. 'last-verified-brief': fetch the most recent verified brief snapshot for a (templateId, scopeKey) pair. Requires templateId and scopeKey."
|
|
4342
4342
|
),
|
|
4343
4343
|
entryId: z20.string().max(200).optional().describe("For 'get'/'history'/'find'/'outcome'/'readings'/'build'/'neighborhood'/'chain': entry ID. For 'gather': optional (entry-graph mode)."),
|
|
4344
4344
|
...lookupParams,
|
|
@@ -6749,11 +6749,11 @@ function buildOrientBriefingLines(view) {
|
|
|
6749
6749
|
if (!view) return [];
|
|
6750
6750
|
return formatBriefingLines({ facts: view.briefing ?? void 0, ruleLists: view.ruleLists ?? void 0, surface: "mcp" });
|
|
6751
6751
|
}
|
|
6752
|
-
async function fetchAndRenderOpenerDirection(
|
|
6752
|
+
async function fetchAndRenderOpenerDirection(kernelQuery2, errors, session) {
|
|
6753
6753
|
let view = null;
|
|
6754
6754
|
let fetchFailed = false;
|
|
6755
6755
|
try {
|
|
6756
|
-
view = await
|
|
6756
|
+
view = await kernelQuery2("chain.getOrientView", {
|
|
6757
6757
|
tier: "standard",
|
|
6758
6758
|
invocationPath: session?.invocationPath ?? "session-start",
|
|
6759
6759
|
// Stamps this call onto the current session/conversation/task (same as every other
|
|
@@ -6768,9 +6768,9 @@ async function fetchAndRenderOpenerDirection(kernelQuery3, errors, session) {
|
|
|
6768
6768
|
}
|
|
6769
6769
|
return { lines: [...buildOrientBriefingLines(view), ...buildRitualsSurfaceLines(view, { fetchFailed: fetchFailed || view?.fetchFailed === true })], view };
|
|
6770
6770
|
}
|
|
6771
|
-
async function buildAlreadyOrientedResult(
|
|
6771
|
+
async function buildAlreadyOrientedResult(kernelQuery2, agentSessionId, taskGroundingWarningLines2) {
|
|
6772
6772
|
const errors = [];
|
|
6773
|
-
const { lines, view } = await fetchAndRenderOpenerDirection(
|
|
6773
|
+
const { lines, view } = await fetchAndRenderOpenerDirection(kernelQuery2, errors, { agentSessionId, invocationPath: "manual-orient" });
|
|
6774
6774
|
return {
|
|
6775
6775
|
content: [{
|
|
6776
6776
|
type: "text",
|
|
@@ -7896,7 +7896,7 @@ var SHAPE_WORKFLOW_DESCRIPTOR = {
|
|
|
7896
7896
|
id: "shape",
|
|
7897
7897
|
skill: "shaping",
|
|
7898
7898
|
name: "Shape a Bet",
|
|
7899
|
-
shortDescription: "Integration-aware shaping: maps the system before designing, traces five paths per element, surfaces governance conflicts at design time. Scoring is in the shaping skill; uses capture and
|
|
7899
|
+
shortDescription: "Integration-aware shaping: maps the system before designing, traces five paths per element, surfaces governance conflicts at design time. Scoring is in the shaping skill; uses capture and entries action=accept for Chain capture.",
|
|
7900
7900
|
template: {
|
|
7901
7901
|
slug: "shape-a-bet",
|
|
7902
7902
|
name: "Shape a Bet"
|
|
@@ -7905,7 +7905,7 @@ var SHAPE_WORKFLOW_DESCRIPTOR = {
|
|
|
7905
7905
|
facilitatorPreamble: `You are now in **Shaping Mode**. The shaping skill owns the facilitation loop end-to-end \u2014 read it for scoring rubrics, investigation patterns, and the capture flow.
|
|
7906
7906
|
|
|
7907
7907
|
Use \`capture\` to create constellation entries (elements, risks, decisions, glossary terms) linked to the work package.
|
|
7908
|
-
Use \`
|
|
7908
|
+
Use \`entries action=accept\` on the work package, then on each linked entry, when the shape is complete.
|
|
7909
7909
|
Use \`workflows action=checkpoint\` after each round to persist progress to the durable run.`,
|
|
7910
7910
|
rounds: [
|
|
7911
7911
|
{
|
|
@@ -8016,7 +8016,7 @@ Use \`workflows action=checkpoint\` after each round to persist progress to the
|
|
|
8016
8016
|
label: "Capture & Accept",
|
|
8017
8017
|
type: "close",
|
|
8018
8018
|
instruction: "Capture the pitch to the Chain. Accept draft entries. Connect the constellation.",
|
|
8019
|
-
facilitatorGuidance: "List all draft entries created during shaping (elements, risks, decisions, glossary terms). Ask the user to confirm: 'Ready to accept these onto the Chain?' Call `
|
|
8019
|
+
facilitatorGuidance: "List all draft entries created during shaping (elements, risks, decisions, glossary terms). Ask the user to confirm: 'Ready to accept these onto the Chain?' Call `entries action=accept` on the work package, then on each linked entry. Then link the work package to the entries it relates to via `relations action=batch-create`. Thank the user. State: what was shaped, how many constellation entries captured, what the implementer inherits.",
|
|
8020
8020
|
outputSchema: {
|
|
8021
8021
|
field: "capture",
|
|
8022
8022
|
description: "Final capture summary \u2014 entries accepted, relations created",
|
|
@@ -8275,7 +8275,7 @@ var PROCESS_CHANGE_WORKFLOW_DESCRIPTOR = {
|
|
|
8275
8275
|
- \`context action=search\` \u2014 find related entries
|
|
8276
8276
|
- \`capture\` \u2014 manual fallback only if workflow finalization cannot safely route the entry
|
|
8277
8277
|
- \`relations action=create\` or \`relations action=batch-create\` \u2014 link to related entries
|
|
8278
|
-
- \`entries action=
|
|
8278
|
+
- \`entries action=accept\` \u2014 accept onto the Chain (only on user confirmation)
|
|
8279
8279
|
- \`workflows action=checkpoint\` \u2014 save progress if needed
|
|
8280
8280
|
|
|
8281
8281
|
## Communication Style
|
|
@@ -8333,7 +8333,7 @@ var PROCESS_CHANGE_WORKFLOW_DESCRIPTOR = {
|
|
|
8333
8333
|
label: "Capture & Close",
|
|
8334
8334
|
type: "close",
|
|
8335
8335
|
instruction: "Capture to the Chain. Link to related entries. Confirm with the user.",
|
|
8336
|
-
facilitatorGuidance: "Finalize through workflows action=checkpoint with isFinal=true, passing a summaryName when you have a clean title. The workflow substrate will create the primary record as a draft and attach it to the durable run. After finalization, link the entry to the 2-3 entries it relates to with relations action=create. Show the user what was captured: entry ID, collection it landed in, relations created. Ask if they want to accept now or leave as draft. If they confirm, use entries action=
|
|
8336
|
+
facilitatorGuidance: "Finalize through workflows action=checkpoint with isFinal=true, passing a summaryName when you have a clean title. The workflow substrate will create the primary record as a draft and attach it to the durable run. After finalization, link the entry to the 2-3 entries it relates to with relations action=create. Show the user what was captured: entry ID, collection it landed in, relations created. Ask if they want to accept now or leave as draft. If they confirm, use entries action=accept. If there are stale entries to reconfirm, mention them. Thank the user briefly and exit \u2014 don't linger.",
|
|
8337
8337
|
outputSchema: {
|
|
8338
8338
|
field: "capture",
|
|
8339
8339
|
description: "Entry captured, relations created, accept status",
|
|
@@ -8962,7 +8962,7 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
|
|
|
8962
8962
|
`Collection: \`${result2.summary.collection ?? (resolvedSummaryCapture.routing.mode === "fixed" ? resolvedSummaryCapture.routing.collection : "classifier-routed")}\``,
|
|
8963
8963
|
`Name: ${result2.summary.name}`,
|
|
8964
8964
|
"",
|
|
8965
|
-
`The summary is captured as a draft. Use \`entries action=
|
|
8965
|
+
`The summary is captured as a draft. Use \`entries action=accept entryId="${result2.summary.entryId}"\` to accept it onto the Chain.`,
|
|
8966
8966
|
`Use \`relations action=create\` to link it to the entries it relates to.`
|
|
8967
8967
|
);
|
|
8968
8968
|
return {
|
|
@@ -8981,8 +8981,8 @@ This checkpoint was NOT saved. The conversation context is preserved \u2014 cont
|
|
|
8981
8981
|
[
|
|
8982
8982
|
{
|
|
8983
8983
|
tool: "entries",
|
|
8984
|
-
description: "
|
|
8985
|
-
parameters: { action: "
|
|
8984
|
+
description: "Accept draft onto the Chain",
|
|
8985
|
+
parameters: { action: "accept", entryId: result2.summary.entryId }
|
|
8986
8986
|
},
|
|
8987
8987
|
{
|
|
8988
8988
|
tool: "context",
|
|
@@ -9582,10 +9582,7 @@ async function handleReEvaluate(entryId, context) {
|
|
|
9582
9582
|
}
|
|
9583
9583
|
|
|
9584
9584
|
// src/tools/session.ts
|
|
9585
|
-
import { z as
|
|
9586
|
-
|
|
9587
|
-
// src/tools/wrapup.ts
|
|
9588
|
-
import { z as z26 } from "zod/v3";
|
|
9585
|
+
import { z as z27 } from "zod/v3";
|
|
9589
9586
|
|
|
9590
9587
|
// src/lib/compose-wrapup-view.ts
|
|
9591
9588
|
function toComposed(e) {
|
|
@@ -9660,14 +9657,14 @@ async function runWrapupReview() {
|
|
|
9660
9657
|
}
|
|
9661
9658
|
const lines = [];
|
|
9662
9659
|
lines.push(
|
|
9663
|
-
`**Session activity:** ${data.summary.created} created, ${data.summary.modified} modified, ${data.summary.uncommitted} uncommitted
|
|
9660
|
+
`**Session activity:** ${data.summary.created} created, ${data.summary.modified} modified, ${data.summary.uncommitted} draft${data.summary.uncommitted === 1 ? "" : "s"} not yet accepted.`
|
|
9664
9661
|
);
|
|
9665
9662
|
if (overflowUnscanned > 0) {
|
|
9666
9663
|
lines.push(`_...and ${overflowUnscanned} more entr${overflowUnscanned === 1 ? "y" : "ies"} this session could not be enumerated (past the scan cap)._`);
|
|
9667
9664
|
}
|
|
9668
9665
|
lines.push("");
|
|
9669
9666
|
if (data.drafts.length > 0) {
|
|
9670
|
-
lines.push("###
|
|
9667
|
+
lines.push("### Drafts", "");
|
|
9671
9668
|
lines.push("| Entry | Collection | Quality | Connections | Coaching |");
|
|
9672
9669
|
lines.push("|-------|------------|---------|-------------|----------|");
|
|
9673
9670
|
for (const draft of data.drafts) {
|
|
@@ -9681,7 +9678,7 @@ async function runWrapupReview() {
|
|
|
9681
9678
|
lines.push("");
|
|
9682
9679
|
}
|
|
9683
9680
|
if (data.committed.length > 0) {
|
|
9684
|
-
lines.push(`### Already
|
|
9681
|
+
lines.push(`### Already Accepted (${data.committed.length})`, "");
|
|
9685
9682
|
for (const entry of data.committed) {
|
|
9686
9683
|
const conns = data.connectionCounts[entry.entryId] ?? 0;
|
|
9687
9684
|
lines.push(`- \`${entry.entryId}\` [${entry.collection}] ${entry.name} (${conns} connections)`);
|
|
@@ -9694,7 +9691,7 @@ async function runWrapupReview() {
|
|
|
9694
9691
|
lines.push(`### Beyond Review Cap (${overflowDrafts.length + overflowCommitted.length})`, "");
|
|
9695
9692
|
lines.push("_Past the per-session enrichment cap \u2014 listed by id and name only._", "");
|
|
9696
9693
|
for (const e of overflowCommitted) {
|
|
9697
|
-
lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (
|
|
9694
|
+
lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (accepted)`);
|
|
9698
9695
|
}
|
|
9699
9696
|
for (const e of overflowDrafts) {
|
|
9700
9697
|
lines.push(`- \`${e.entryId}\` \u2014 ${e.name} (draft)`);
|
|
@@ -9773,14 +9770,14 @@ async function runWrapupReview() {
|
|
|
9773
9770
|
if (allDraftEntries.length > 0) {
|
|
9774
9771
|
const draftIds = allDraftEntries.map((d) => `\`${d.entryId}\``).join(", ");
|
|
9775
9772
|
lines.push("### Actions", "");
|
|
9776
|
-
lines.push(`
|
|
9777
|
-
lines.push("- **Accept
|
|
9773
|
+
lines.push(`Drafts: ${draftIds}`);
|
|
9774
|
+
lines.push("- **Accept:** call `entries action=accept entryId=...` for each one you mean to keep.");
|
|
9778
9775
|
lines.push("- **Skip:** call `session action=close` \u2014 drafts remain for next session's orient recovery.");
|
|
9779
9776
|
}
|
|
9780
9777
|
if (overflowUnscanned > 0) {
|
|
9781
9778
|
lines.push("");
|
|
9782
9779
|
lines.push(
|
|
9783
|
-
`> _${overflowUnscanned} draft(s) beyond the scan cap
|
|
9780
|
+
`> _${overflowUnscanned} draft(s) beyond the scan cap are not listed here \u2014 accept each with \`entries action=accept\`, or close via \`session action=close\`._`
|
|
9784
9781
|
);
|
|
9785
9782
|
}
|
|
9786
9783
|
if (data.captureAudit) {
|
|
@@ -9804,127 +9801,9 @@ async function runWrapupReview() {
|
|
|
9804
9801
|
kernelMeta: kernelEnvelope._meta
|
|
9805
9802
|
};
|
|
9806
9803
|
}
|
|
9807
|
-
async function runWrapupCommitAll(data) {
|
|
9808
|
-
requireWriteAccess();
|
|
9809
|
-
const sessionId = getAgentSessionId();
|
|
9810
|
-
if (!sessionId) {
|
|
9811
|
-
return { text: "No active session.", committed: 0, failed: 0, overflowUnscanned: 0 };
|
|
9812
|
-
}
|
|
9813
|
-
const results = [];
|
|
9814
|
-
const allDrafts = [...data.drafts, ...data.overflowDrafts ?? []];
|
|
9815
|
-
const overflowUnscanned = data.overflowUnscanned ?? 0;
|
|
9816
|
-
for (const draft of allDrafts) {
|
|
9817
|
-
try {
|
|
9818
|
-
const result2 = await kernelMutation("chain.commitEntry", {
|
|
9819
|
-
entryId: draft.entryId,
|
|
9820
|
-
author: `agent:${sessionId}`,
|
|
9821
|
-
sessionId
|
|
9822
|
-
});
|
|
9823
|
-
if (result2 && "status" in result2 && result2.status === "coherency_refused") {
|
|
9824
|
-
const refusal = "refusal" in result2 ? result2.refusal : void 0;
|
|
9825
|
-
results.push({
|
|
9826
|
-
entryId: draft.entryId,
|
|
9827
|
-
ok: false,
|
|
9828
|
-
error: `coherency gate refused this accept \u2014 ${refusal?.reason ?? "refused by the coherency gate"}`
|
|
9829
|
-
});
|
|
9830
|
-
continue;
|
|
9831
|
-
}
|
|
9832
|
-
await recordSessionActivity({ entryModified: draft.docId });
|
|
9833
|
-
results.push({ entryId: draft.entryId, ok: true });
|
|
9834
|
-
} catch (err) {
|
|
9835
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
9836
|
-
results.push({ entryId: draft.entryId, ok: false, error: msg });
|
|
9837
|
-
}
|
|
9838
|
-
}
|
|
9839
|
-
const committed = results.filter((r) => r.ok).length;
|
|
9840
|
-
const failed = results.filter((r) => !r.ok);
|
|
9841
|
-
const cleanDrain = failed.length === 0 && overflowUnscanned === 0;
|
|
9842
|
-
if (cleanDrain) {
|
|
9843
|
-
await kernelCall("agent.recordWrapup", {
|
|
9844
|
-
sessionId,
|
|
9845
|
-
draftsReviewed: allDrafts.length,
|
|
9846
|
-
draftsCommitted: committed,
|
|
9847
|
-
linksCreated: 0
|
|
9848
|
-
});
|
|
9849
|
-
}
|
|
9850
|
-
const lines = [
|
|
9851
|
-
"## Wrapup Complete",
|
|
9852
|
-
"",
|
|
9853
|
-
`**${committed}** drafts accepted.`
|
|
9854
|
-
];
|
|
9855
|
-
if (failed.length > 0) {
|
|
9856
|
-
lines.push("");
|
|
9857
|
-
lines.push("### Failed to accept");
|
|
9858
|
-
for (const f of failed) {
|
|
9859
|
-
lines.push(`- \`${f.entryId}\`: ${f.error}`);
|
|
9860
|
-
}
|
|
9861
|
-
lines.push("_These remain as drafts for next session._");
|
|
9862
|
-
}
|
|
9863
|
-
return {
|
|
9864
|
-
text: lines.join("\n"),
|
|
9865
|
-
committed,
|
|
9866
|
-
failed: failed.length,
|
|
9867
|
-
overflowUnscanned
|
|
9868
|
-
};
|
|
9869
|
-
}
|
|
9870
|
-
var wrapupSchema = z26.object({
|
|
9871
|
-
action: z26.enum(["review", "commit-all"]).optional().describe(
|
|
9872
|
-
"Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts; it writes no relations."
|
|
9873
|
-
)
|
|
9874
|
-
});
|
|
9875
9804
|
function createWrapupHandler() {
|
|
9876
|
-
|
|
9877
|
-
let lastReviewSessionId = null;
|
|
9878
|
-
return async ({ action }) => {
|
|
9879
|
-
if (action === "commit-all") {
|
|
9880
|
-
const sessionId = getAgentSessionId();
|
|
9881
|
-
if (!sessionId) {
|
|
9882
|
-
return failureResult(
|
|
9883
|
-
"No active agent session.",
|
|
9884
|
-
"SESSION_REQUIRED",
|
|
9885
|
-
"No active agent session.",
|
|
9886
|
-
"Start a session first.",
|
|
9887
|
-
[{ tool: "session", description: "Start a session", parameters: { action: "start" } }]
|
|
9888
|
-
);
|
|
9889
|
-
}
|
|
9890
|
-
const useCachedReview = lastReviewSessionId === sessionId;
|
|
9891
|
-
let data2;
|
|
9892
|
-
if (useCachedReview && lastReviewData) {
|
|
9893
|
-
data2 = lastReviewData;
|
|
9894
|
-
} else {
|
|
9895
|
-
const { workspaceId } = await getWorkspaceContext();
|
|
9896
|
-
data2 = (await kernelCallEnvelope("agentKnowledge.wrapupEnvelope", {
|
|
9897
|
-
workspaceId,
|
|
9898
|
-
sessionId,
|
|
9899
|
-
action: "review"
|
|
9900
|
-
})).data;
|
|
9901
|
-
}
|
|
9902
|
-
if (data2.drafts.length === 0 && (data2.overflowDrafts ?? []).length === 0) {
|
|
9903
|
-
return failureResult("No uncommitted drafts to accept.", "NOT_FOUND", "No uncommitted drafts to accept.", "Nothing to accept.");
|
|
9904
|
-
}
|
|
9905
|
-
const result2 = await runWrapupCommitAll(data2);
|
|
9906
|
-
lastReviewData = null;
|
|
9907
|
-
lastReviewSessionId = null;
|
|
9908
|
-
const commitNext = result2.overflowUnscanned > 0 ? [
|
|
9909
|
-
{
|
|
9910
|
-
tool: "session",
|
|
9911
|
-
description: `${result2.overflowUnscanned} draft(s) beyond the scan cap can't be auto-committed here \u2014 commit them individually via \`entries action=commit\`, or close via \`session action=close\`.`,
|
|
9912
|
-
parameters: { action: "close" }
|
|
9913
|
-
}
|
|
9914
|
-
] : result2.failed > 0 ? [{ tool: "session", description: "Re-review remaining drafts before closing", parameters: { action: "wrapup-review" } }] : [{ tool: "session", description: "Close the session now that drafts are committed", parameters: { action: "close" } }];
|
|
9915
|
-
return successResult(
|
|
9916
|
-
result2.text,
|
|
9917
|
-
`Wrapup processed: ${result2.committed} accepted.`,
|
|
9918
|
-
{
|
|
9919
|
-
committed: result2.committed,
|
|
9920
|
-
failed: result2.failed
|
|
9921
|
-
},
|
|
9922
|
-
commitNext
|
|
9923
|
-
);
|
|
9924
|
-
}
|
|
9805
|
+
return async () => {
|
|
9925
9806
|
const { text, data, failureCode, gapCount, coherenceVerdict, persistentGaps, kernelSummary, kernelNext, kernelMeta } = await runWrapupReview();
|
|
9926
|
-
lastReviewData = data;
|
|
9927
|
-
lastReviewSessionId = getAgentSessionId();
|
|
9928
9807
|
const composed = data ? composeWrapupView(data) : null;
|
|
9929
9808
|
const fullText = composed && (composed.drafts.length > 0 || composed.committed.length > 0 || composed.discarded.length > 0) ? `## Session Wrapup
|
|
9930
9809
|
|
|
@@ -9932,14 +9811,14 @@ ${text}` : text;
|
|
|
9932
9811
|
if (failureCode) {
|
|
9933
9812
|
return failureResult(fullText, failureCode, text);
|
|
9934
9813
|
}
|
|
9935
|
-
const localNext = composed && !composed.canClose ?
|
|
9814
|
+
const localNext = composed && !composed.canClose ? composed.drafts.slice(0, 1).map((d) => ({ tool: "entries", description: "Accept this draft", parameters: { action: "accept", entryId: d.entryId } })) : void 0;
|
|
9936
9815
|
const next = kernelNext || localNext;
|
|
9937
9816
|
const gapsSummary = gapCount ? `, ${gapCount} knowledge gaps detected` : "";
|
|
9938
9817
|
const coherenceSummary = coherenceVerdict ? `, coherence: ${coherenceVerdict}` : "";
|
|
9939
9818
|
const persistentSummary = persistentGaps?.length ? `, ${persistentGaps.length} persistent coherence gaps` : "";
|
|
9940
9819
|
const draftsCount = composed?.drafts.length ?? data.drafts.length;
|
|
9941
9820
|
const committedCount = composed?.committed.length ?? data.committed.length;
|
|
9942
|
-
const summaryText = `Session review: ${draftsCount}
|
|
9821
|
+
const summaryText = `Session review: ${draftsCount} draft${draftsCount === 1 ? "" : "s"}, ${committedCount} accepted${gapsSummary}${coherenceSummary}${persistentSummary}.`;
|
|
9943
9822
|
return {
|
|
9944
9823
|
content: [{ type: "text", text: fullText }],
|
|
9945
9824
|
structuredContent: {
|
|
@@ -9961,33 +9840,10 @@ ${text}` : text;
|
|
|
9961
9840
|
}
|
|
9962
9841
|
|
|
9963
9842
|
// src/tools/facilitate.ts
|
|
9964
|
-
import { z as
|
|
9965
|
-
var
|
|
9966
|
-
|
|
9967
|
-
response: z27.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
9968
|
-
entryId: z27.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
|
|
9969
|
-
reason: z27.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
9970
|
-
subjectEntryId: z27.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
9971
|
-
});
|
|
9972
|
-
var facilitateSchema = z27.object({
|
|
9973
|
-
action: z27.enum(FACILITATE_ACTIONS).describe(
|
|
9974
|
-
"'resume': load session state from an existing bet entry. 'commit-constellation': atomically accept a bet and all its linked draft entries in one call. Requires betEntryId."
|
|
9975
|
-
),
|
|
9976
|
-
betEntryId: z27.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
|
|
9977
|
-
operationId: z27.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
|
|
9978
|
-
// WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
|
|
9979
|
-
// Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
|
|
9980
|
-
coherencyAcknowledgements: z27.array(coherencyAcknowledgementSchema).max(20).optional().describe(
|
|
9981
|
-
"Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
|
|
9982
|
-
),
|
|
9983
|
-
steeringOverrideReason: z27.string().max(2e3).optional().describe(
|
|
9984
|
-
"Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
|
|
9985
|
-
)
|
|
9843
|
+
import { z as z26 } from "zod/v3";
|
|
9844
|
+
var facilitateSchema = z26.object({
|
|
9845
|
+
betEntryId: z26.string().max(200).optional().describe("Work package entry ID. Required.")
|
|
9986
9846
|
});
|
|
9987
|
-
function conflictSuffix(c) {
|
|
9988
|
-
const seat = c.routeTarget ? `; seat team ${c.routeTarget.teamEntryId} role ${c.routeTarget.roleEntryId}` : "";
|
|
9989
|
-
return ` [${c.code}${seat}]`;
|
|
9990
|
-
}
|
|
9991
9847
|
function buildCortexUrl(workspaceSlug, entryId) {
|
|
9992
9848
|
return `${appUrl()}/w/${workspaceSlug}/chain?entry=${encodeURIComponent(entryId)}&railTab=context`;
|
|
9993
9849
|
}
|
|
@@ -10036,195 +9892,6 @@ async function handleResume(args) {
|
|
|
10036
9892
|
}
|
|
10037
9893
|
};
|
|
10038
9894
|
}
|
|
10039
|
-
async function handleCommitConstellation(args) {
|
|
10040
|
-
requireWriteAccess();
|
|
10041
|
-
const betId = args.betEntryId;
|
|
10042
|
-
if (!betId) {
|
|
10043
|
-
return validationResult("`betEntryId` is required for commit-constellation action.");
|
|
10044
|
-
}
|
|
10045
|
-
const { workspaceId } = await getWorkspaceContext();
|
|
10046
|
-
const sessionId = getAgentSessionId();
|
|
10047
|
-
const operationId = args.operationId ?? `${betId}:${sessionId ?? "sessionless"}:${Date.now()}`;
|
|
10048
|
-
let betName = betId;
|
|
10049
|
-
let betDesc = "";
|
|
10050
|
-
let betCollectionHint;
|
|
10051
|
-
try {
|
|
10052
|
-
const betEnvelope = await kernelCallEnvelope("chain.getEntry", { entryId: betId });
|
|
10053
|
-
const entry = betEnvelope.data;
|
|
10054
|
-
if (entry) {
|
|
10055
|
-
betName = entry.name ?? betId;
|
|
10056
|
-
const d = entry.data ?? {};
|
|
10057
|
-
const links = d["links"];
|
|
10058
|
-
betDesc = d.problem ?? links?.problem ?? d.description ?? "";
|
|
10059
|
-
betCollectionHint = entry.collectionSlug ?? entry.collection?.slug ?? entry.collection?.name;
|
|
10060
|
-
}
|
|
10061
|
-
} catch {
|
|
10062
|
-
}
|
|
10063
|
-
const preflight = await runConflictPreflight(betName, betDesc, betCollectionHint);
|
|
10064
|
-
if (preflight.conflicts.length > 0) {
|
|
10065
|
-
await recordSessionActivity({ contradictionWarning: true });
|
|
10066
|
-
}
|
|
10067
|
-
const conflictEvidence = preflight.conflicts.map((c) => ({
|
|
10068
|
-
chainEntryId: c.chainEntryId,
|
|
10069
|
-
chainEntryName: c.chainEntryName,
|
|
10070
|
-
...c.chainEntryDescription ? { chainEntryDescription: c.chainEntryDescription } : {},
|
|
10071
|
-
type: c.type,
|
|
10072
|
-
confidence: c.confidence,
|
|
10073
|
-
explanation: c.explanation
|
|
10074
|
-
}));
|
|
10075
|
-
let envelope;
|
|
10076
|
-
try {
|
|
10077
|
-
envelope = await kernelCallEnvelope("agentKnowledge.facilitateEnvelope", {
|
|
10078
|
-
workspaceId,
|
|
10079
|
-
action: "commit-constellation",
|
|
10080
|
-
betEntryId: betId,
|
|
10081
|
-
operationId,
|
|
10082
|
-
sessionId: sessionId ?? void 0,
|
|
10083
|
-
author: sessionId ? `agent:${sessionId}` : "kernel:facilitate",
|
|
10084
|
-
// WP-465 slice ⑤ (TEN-2439, §3.7): relay the coherency retry controls so a
|
|
10085
|
-
// COHERENCY_REFUSED constellation hold is actually retryable through MCP.
|
|
10086
|
-
...args.coherencyAcknowledgements ? { coherencyAcknowledgements: args.coherencyAcknowledgements } : {},
|
|
10087
|
-
...args.steeringOverrideReason ? { steeringOverrideReason: args.steeringOverrideReason } : {},
|
|
10088
|
-
...conflictEvidence.length > 0 ? { conflicts: conflictEvidence } : {}
|
|
10089
|
-
});
|
|
10090
|
-
} catch (err) {
|
|
10091
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
10092
|
-
const code = err?.code;
|
|
10093
|
-
const diagnostics = err?.diagnostics;
|
|
10094
|
-
if (code === "COHERENCY_REFUSED") {
|
|
10095
|
-
const coherencyRefusals = Array.isArray(diagnostics?.coherencyRefusals) ? diagnostics.coherencyRefusals : [];
|
|
10096
|
-
const offenderLines = coherencyRefusals.map((r) => `- \`${r.entryId}\` ${r.name}: ${String(r.refusal?.reason ?? "coherency challenge unsatisfied")}`).join("\n");
|
|
10097
|
-
const count = coherencyRefusals.length;
|
|
10098
|
-
return {
|
|
10099
|
-
content: [{
|
|
10100
|
-
type: "text",
|
|
10101
|
-
text: [
|
|
10102
|
-
`# Constellation held by the coherency gate`,
|
|
10103
|
-
"",
|
|
10104
|
-
`\`${betId}\` was not accepted \u2014 ${count} entr${count === 1 ? "y" : "ies"} refused. Nothing was committed; drafts persist.`,
|
|
10105
|
-
...offenderLines ? ["", offenderLines] : []
|
|
10106
|
-
].join("\n")
|
|
10107
|
-
}],
|
|
10108
|
-
structuredContent: failure(
|
|
10109
|
-
"COHERENCY_REFUSED",
|
|
10110
|
-
`Constellation held: ${count} entr${count === 1 ? "y" : "ies"} refused by the coherency gate \u2014 nothing was committed, drafts persist.`,
|
|
10111
|
-
"Respond per offender and retry commit-constellation: link the entry to the strategic spine, pass coherencyAcknowledgements [{subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}], or supply a typed steeringOverrideReason (at least 12 characters).",
|
|
10112
|
-
[{ tool: "session", description: "Retry with coherency acknowledgements", parameters: { action: "commit-constellation", betEntryId: betId } }],
|
|
10113
|
-
{ coherencyRefusals }
|
|
10114
|
-
)
|
|
10115
|
-
};
|
|
10116
|
-
}
|
|
10117
|
-
if (code === "CONSTELLATION_COMMIT_REFUSED") {
|
|
10118
|
-
const conflictIds = Array.isArray(diagnostics?.conflictIds) ? diagnostics.conflictIds : [];
|
|
10119
|
-
const offenderLines = conflictIds.map((c) => `- \`${c.entryId}\` ${c.name}: ${c.reason}${conflictSuffix(c)}`).join("\n");
|
|
10120
|
-
return {
|
|
10121
|
-
content: [{
|
|
10122
|
-
type: "text",
|
|
10123
|
-
text: [
|
|
10124
|
-
`# Constellation commit refused`,
|
|
10125
|
-
"",
|
|
10126
|
-
`\`${betId}\` was not accepted \u2014 the root itself was refused, so nothing was committed.`,
|
|
10127
|
-
...offenderLines ? ["", offenderLines] : []
|
|
10128
|
-
].join("\n")
|
|
10129
|
-
}],
|
|
10130
|
-
structuredContent: failure(
|
|
10131
|
-
"CONSTELLATION_COMMIT_REFUSED",
|
|
10132
|
-
msg,
|
|
10133
|
-
"Resolve the authority conflict (route through the accountable role or Team Lead) and retry commit-constellation.",
|
|
10134
|
-
[{ tool: "session", description: "Retry once authority is resolved", parameters: { action: "commit-constellation", betEntryId: betId } }],
|
|
10135
|
-
{ conflictIds }
|
|
10136
|
-
)
|
|
10137
|
-
};
|
|
10138
|
-
}
|
|
10139
|
-
if (code === "CONTRADICTION_BLOCKED") {
|
|
10140
|
-
return {
|
|
10141
|
-
content: [{
|
|
10142
|
-
type: "text",
|
|
10143
|
-
text: `# Constellation accept blocked
|
|
10144
|
-
|
|
10145
|
-
\`${betId}\` was not accepted: ${msg}
|
|
10146
|
-
|
|
10147
|
-
No constellation entries were accepted.`
|
|
10148
|
-
}],
|
|
10149
|
-
structuredContent: failure(
|
|
10150
|
-
"CONTRADICTION_BLOCKED",
|
|
10151
|
-
msg,
|
|
10152
|
-
"Resolve the contradiction before retrying commit-constellation."
|
|
10153
|
-
)
|
|
10154
|
-
};
|
|
10155
|
-
}
|
|
10156
|
-
return {
|
|
10157
|
-
content: [{
|
|
10158
|
-
type: "text",
|
|
10159
|
-
text: `# Work package accept failed
|
|
10160
|
-
|
|
10161
|
-
\`${betId}\` could not be accepted: ${msg}
|
|
10162
|
-
|
|
10163
|
-
No constellation entries were accepted.`
|
|
10164
|
-
}],
|
|
10165
|
-
structuredContent: failure(
|
|
10166
|
-
"BACKEND_ERROR",
|
|
10167
|
-
`Work package accept failed: ${msg}`,
|
|
10168
|
-
"Retry or check for accept blockers.",
|
|
10169
|
-
[{ tool: "session", description: "Resume session", parameters: { action: "resume", betEntryId: betId } }],
|
|
10170
|
-
diagnostics
|
|
10171
|
-
)
|
|
10172
|
-
};
|
|
10173
|
-
}
|
|
10174
|
-
for (const docId of envelope.data?.result?.committedIds ?? []) {
|
|
10175
|
-
try {
|
|
10176
|
-
await recordSessionActivity({ entryModified: docId });
|
|
10177
|
-
} catch {
|
|
10178
|
-
}
|
|
10179
|
-
}
|
|
10180
|
-
const result2 = envelope.data.result;
|
|
10181
|
-
const suggestions = {
|
|
10182
|
-
...preflight.conflicts.length > 0 ? { conflicts: preflight.conflicts } : {}
|
|
10183
|
-
};
|
|
10184
|
-
const lines = [];
|
|
10185
|
-
const hasIssues = (result2.failedIds?.length ?? 0) > 0 || (result2.conflictIds?.length ?? 0) > 0;
|
|
10186
|
-
lines.push(
|
|
10187
|
-
hasIssues ? `# Accepted with issues` : `# Accepted`,
|
|
10188
|
-
"",
|
|
10189
|
-
`**${result2.committedIds?.length ?? 0} entries** accepted onto the Chain, **${result2.totalRelations} connections** preserved.`,
|
|
10190
|
-
hasIssues ? `\`${betId}\` was partially accepted. Review conflicts/failed entries below before considering the constellation complete.` : `\`${betId}\` and its full constellation are now source of truth.`
|
|
10191
|
-
);
|
|
10192
|
-
if (preflight.conflicts.length > 0) {
|
|
10193
|
-
lines.push(
|
|
10194
|
-
"",
|
|
10195
|
-
`\u26A0 **Semantic conflict preflight** (advisory):`,
|
|
10196
|
-
...preflight.conflicts.map((c) => `- \`${c.chainEntryId}\` ${c.chainEntryName}: ${c.explanation}`)
|
|
10197
|
-
);
|
|
10198
|
-
}
|
|
10199
|
-
if ((result2.committedIds?.length ?? 0) > 0) {
|
|
10200
|
-
lines.push("", `**Accepted:** ${result2.committedIds.join(", ")}`);
|
|
10201
|
-
}
|
|
10202
|
-
if ((result2.alreadyCommittedIds?.length ?? 0) > 0) {
|
|
10203
|
-
lines.push("", `**Already accepted:** ${result2.alreadyCommittedIds.join(", ")}`);
|
|
10204
|
-
}
|
|
10205
|
-
if ((result2.conflictIds?.length ?? 0) > 0) {
|
|
10206
|
-
lines.push("", `**${result2.conflictIds.length} conflicts:**`);
|
|
10207
|
-
for (const c of result2.conflictIds) {
|
|
10208
|
-
lines.push(`- \`${c.entryId}\` ${c.name}: ${c.reason}${conflictSuffix(c)}`);
|
|
10209
|
-
}
|
|
10210
|
-
}
|
|
10211
|
-
if ((result2.failedIds?.length ?? 0) > 0) {
|
|
10212
|
-
lines.push("", `**${result2.failedIds.length} failed:**`);
|
|
10213
|
-
for (const f of result2.failedIds) {
|
|
10214
|
-
lines.push(`- \`${f.entryId}\` ${f.name}: ${f.error}`);
|
|
10215
|
-
}
|
|
10216
|
-
}
|
|
10217
|
-
return {
|
|
10218
|
-
content: [{ type: "text", text: lines.join("\n") }],
|
|
10219
|
-
structuredContent: {
|
|
10220
|
-
ok: true,
|
|
10221
|
-
summary: envelope.summary,
|
|
10222
|
-
data: { result: result2, suggestions },
|
|
10223
|
-
next: envelope.next,
|
|
10224
|
-
_meta: envelope._meta
|
|
10225
|
-
}
|
|
10226
|
-
};
|
|
10227
|
-
}
|
|
10228
9895
|
|
|
10229
9896
|
// src/lib/sessionNotices.ts
|
|
10230
9897
|
var ANSI_AND_CONTROL_RE2 = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[^[\]0-9;A-Za-z]?|[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
|
|
@@ -10240,14 +9907,8 @@ function nextActionForVerb(verb, args) {
|
|
|
10240
9907
|
return { tool: "feedback", description: "Read the vendor triage queue (system admins only)", parameters: { action: "queue" } };
|
|
10241
9908
|
case "question.create":
|
|
10242
9909
|
return { tool: "question", description: "Create a routed question", parameters: { action: "create" } };
|
|
10243
|
-
case "question.adopt":
|
|
10244
|
-
return { tool: "question", description: "Attach routing to a captured tension", parameters: { action: "adopt" } };
|
|
10245
9910
|
case "question.assign":
|
|
10246
9911
|
return { tool: "question", description: "Confirm or reassign a question", parameters: { action: "assign" } };
|
|
10247
|
-
case "question.snooze":
|
|
10248
|
-
return { tool: "question", description: "Snooze a routed/escalated question", parameters: { action: "snooze" } };
|
|
10249
|
-
case "question.decline":
|
|
10250
|
-
return { tool: "question", description: "Pass on or decline a question", parameters: { action: "decline" } };
|
|
10251
9912
|
case "question.answer":
|
|
10252
9913
|
return { tool: "question", description: "Answer a question", parameters: { action: "answer" } };
|
|
10253
9914
|
case "question.forceClose":
|
|
@@ -10274,8 +9935,6 @@ function displayVerbFromRoute(route) {
|
|
|
10274
9935
|
switch (route) {
|
|
10275
9936
|
case "question.assign":
|
|
10276
9937
|
return "take it / reassign";
|
|
10277
|
-
case "question.decline":
|
|
10278
|
-
return "pass / decline";
|
|
10279
9938
|
case "question.forceClose":
|
|
10280
9939
|
return "force-close";
|
|
10281
9940
|
default:
|
|
@@ -10317,78 +9976,52 @@ function formatNoticeLines(notices) {
|
|
|
10317
9976
|
|
|
10318
9977
|
// src/tools/session.ts
|
|
10319
9978
|
var START_PREFLIGHT_NEXT = 'Next: context action=preflight collection=<kind> links=[{"type":"part_of","entryId":"<PARENT-ID>"}]';
|
|
10320
|
-
var SESSION_ACTIONS = [
|
|
10321
|
-
|
|
10322
|
-
"
|
|
10323
|
-
"
|
|
10324
|
-
|
|
10325
|
-
"wrapup-commit",
|
|
10326
|
-
"resume",
|
|
10327
|
-
"commit-constellation"
|
|
10328
|
-
];
|
|
10329
|
-
var coherencyAcknowledgementFlatSchema2 = z28.object({
|
|
10330
|
-
response: z28.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
10331
|
-
entryId: z28.string().max(200).optional().describe("Entry the acknowledgement links to."),
|
|
10332
|
-
reason: z28.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
10333
|
-
subjectEntryId: z28.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
10334
|
-
});
|
|
9979
|
+
var SESSION_ACTIONS = ["start", "close", "status", "wrapup-review", "resume"];
|
|
9980
|
+
var SESSION_MOVED = {
|
|
9981
|
+
"wrapup-commit": "wrapup-commit was removed. Next: session action=wrapup-review, then entries action=accept entryId=... for each draft.",
|
|
9982
|
+
"commit-constellation": "commit-constellation was removed. Next: session action=wrapup-review, then entries action=accept entryId=... for each draft."
|
|
9983
|
+
};
|
|
10335
9984
|
var TEAM_PARAM_DESCRIPTION = "For 'start': the team the role is held in, by its 'TEAM-<n>' id \u2014 only needed with role, when you hold that role in more than one team; a refusal that names the way in prints it.";
|
|
10336
|
-
var sessionSchema =
|
|
10337
|
-
action:
|
|
10338
|
-
"'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review':
|
|
10339
|
-
),
|
|
10340
|
-
betEntryId: z28.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
|
|
10341
|
-
operationId: z28.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
|
|
10342
|
-
coherencyAcknowledgements: z28.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
|
|
10343
|
-
"For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
|
|
10344
|
-
),
|
|
10345
|
-
steeringOverrideReason: z28.string().max(2e3).optional().describe(
|
|
10346
|
-
"For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
|
|
9985
|
+
var sessionSchema = z27.object({
|
|
9986
|
+
action: actionEnum(SESSION_ACTIONS, SESSION_MOVED).describe(
|
|
9987
|
+
"'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review': list this session's drafts before closing. 'resume': load session state from an existing work package entry."
|
|
10347
9988
|
),
|
|
9989
|
+
betEntryId: z27.string().max(200).optional().describe("For 'resume': work package entry ID. Required."),
|
|
10348
9990
|
// DEC-1715 (WP-753 O1a)
|
|
10349
|
-
role:
|
|
9991
|
+
role: z27.string().max(200).optional().describe(
|
|
10350
9992
|
"For 'start': role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
|
|
10351
9993
|
),
|
|
10352
|
-
team:
|
|
9994
|
+
team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
|
|
10353
9995
|
// TASK-801
|
|
10354
9996
|
});
|
|
10355
|
-
var sessionStartVariant =
|
|
10356
|
-
action:
|
|
9997
|
+
var sessionStartVariant = z27.object({
|
|
9998
|
+
action: z27.literal("start"),
|
|
10357
9999
|
// DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
|
|
10358
10000
|
// more than one role; the server refuses and lists the choices when it's required and omitted.
|
|
10359
|
-
role:
|
|
10001
|
+
role: z27.string().max(200).optional().describe(
|
|
10360
10002
|
"Role to act as this session, by the '<PREFIX>-<n>' id a start reply prints beside the role name \u2014 only needed if you hold more than one; the error lists your roles if omitted."
|
|
10361
10003
|
),
|
|
10362
|
-
team:
|
|
10004
|
+
team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
|
|
10363
10005
|
// TASK-801
|
|
10364
10006
|
});
|
|
10365
|
-
var sessionCloseVariant =
|
|
10366
|
-
var sessionStatusVariant =
|
|
10367
|
-
var sessionWrapupReviewVariant =
|
|
10368
|
-
var
|
|
10369
|
-
var
|
|
10370
|
-
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z28.literal("commit-constellation") });
|
|
10371
|
-
var sessionActionUnion = z28.discriminatedUnion("action", [
|
|
10007
|
+
var sessionCloseVariant = z27.object({ action: z27.literal("close") });
|
|
10008
|
+
var sessionStatusVariant = z27.object({ action: z27.literal("status") });
|
|
10009
|
+
var sessionWrapupReviewVariant = z27.object({ action: z27.literal("wrapup-review") });
|
|
10010
|
+
var sessionResumeVariant = facilitateSchema.extend({ action: z27.literal("resume") });
|
|
10011
|
+
var sessionActionUnion = z27.discriminatedUnion("action", [
|
|
10372
10012
|
sessionStartVariant,
|
|
10373
10013
|
sessionCloseVariant,
|
|
10374
10014
|
sessionStatusVariant,
|
|
10375
10015
|
sessionWrapupReviewVariant,
|
|
10376
|
-
|
|
10377
|
-
sessionResumeVariant,
|
|
10378
|
-
sessionCommitConstellationVariant
|
|
10016
|
+
sessionResumeVariant
|
|
10379
10017
|
]);
|
|
10380
10018
|
var SESSION_ACTION_SPECS = {
|
|
10381
10019
|
// DEC-1715 (WP-753 O1a), TASK-801
|
|
10382
10020
|
start: { params: ["role", "team"], description: "role is optional \u2014 only needed if you hold more than one role; team only with role, when you hold it in several teams." },
|
|
10383
10021
|
close: { params: [], description: "End the current session; no params." },
|
|
10384
10022
|
status: { params: [], description: "Check current session state; no params." },
|
|
10385
|
-
"wrapup-review": { params: [], description: "
|
|
10386
|
-
|
|
10387
|
-
resume: { params: ["betEntryId"], description: "betEntryId is required." },
|
|
10388
|
-
"commit-constellation": {
|
|
10389
|
-
params: ["betEntryId", "operationId", "coherencyAcknowledgements", "steeringOverrideReason"],
|
|
10390
|
-
description: "betEntryId is required; every other field is optional."
|
|
10391
|
-
}
|
|
10023
|
+
"wrapup-review": { params: [], description: "List this session's drafts; no params." },
|
|
10024
|
+
resume: { params: ["betEntryId"], description: "betEntryId is required." }
|
|
10392
10025
|
};
|
|
10393
10026
|
function registerSessionTools(server) {
|
|
10394
10027
|
const wrapupHandler = createWrapupHandler();
|
|
@@ -10396,10 +10029,8 @@ function registerSessionTools(server) {
|
|
|
10396
10029
|
start: (data) => handleStart2(data),
|
|
10397
10030
|
close: () => handleClose(),
|
|
10398
10031
|
status: () => handleStatus(),
|
|
10399
|
-
"wrapup-review": () => wrapupHandler(
|
|
10400
|
-
|
|
10401
|
-
resume: (data) => handleResume(data),
|
|
10402
|
-
"commit-constellation": (data) => handleCommitConstellation(data)
|
|
10032
|
+
"wrapup-review": () => wrapupHandler(),
|
|
10033
|
+
resume: (data) => handleResume(data)
|
|
10403
10034
|
};
|
|
10404
10035
|
server.registerTool(
|
|
10405
10036
|
"session",
|
|
@@ -10409,15 +10040,13 @@ function registerSessionTools(server) {
|
|
|
10409
10040
|
|
|
10410
10041
|
Session lifecycle, wrapup review, and work package facilitation.
|
|
10411
10042
|
|
|
10412
|
-
- **start**: Begin a tracked write session for attribution. **This is the ONLY call that creates a session** \u2014 write tools (capture, entries action=update/
|
|
10043
|
+
- **start**: Begin a tracked write session for attribution. **This is the ONLY call that creates a session** \u2014 write tools (capture, entries action=update/accept, relations) require it. Its reply is the briefing; then \`orient task="<what you are doing>"\` loads the context for a task.
|
|
10413
10044
|
- **close**: End the current session. Records structured data (entries created, modified, relations). Run \`session action=wrapup-review\` before closing.
|
|
10414
10045
|
- **status**: Check current session \u2014 active or not, oriented, activity counts.
|
|
10415
|
-
- **wrapup-review**:
|
|
10416
|
-
- **
|
|
10417
|
-
- **resume**: Load session state (work package data, constellation, drafts) from an existing work package entry.
|
|
10418
|
-
- **commit-constellation**: Atomically accept a work package and all its linked draft entries in one call.`,
|
|
10046
|
+
- **wrapup-review**: List this session's drafts with quality scores; accept each with entries action=accept. Run before close.
|
|
10047
|
+
- **resume**: Load session state (work package data, linked entries, drafts) from an existing work package entry.`,
|
|
10419
10048
|
inputSchema: sessionSchema,
|
|
10420
|
-
// Mixed read/write noun (§3 R3):
|
|
10049
|
+
// Mixed read/write noun (§3 R3): start and close write.
|
|
10421
10050
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
10422
10051
|
},
|
|
10423
10052
|
thinWrapper(async (args) => {
|
|
@@ -10502,7 +10131,7 @@ async function handleClose() {
|
|
|
10502
10131
|
"",
|
|
10503
10132
|
text,
|
|
10504
10133
|
"",
|
|
10505
|
-
`> **${data.drafts.length}
|
|
10134
|
+
`> **${data.drafts.length} draft(s) not yet accepted.** Accept each with \`entries action=accept\` before closing next time.`,
|
|
10506
10135
|
"",
|
|
10507
10136
|
"---",
|
|
10508
10137
|
""
|
|
@@ -10619,10 +10248,10 @@ async function handleStatus() {
|
|
|
10619
10248
|
}
|
|
10620
10249
|
|
|
10621
10250
|
// src/tools/workspace.ts
|
|
10622
|
-
import { z as
|
|
10251
|
+
import { z as z30 } from "zod/v3";
|
|
10623
10252
|
|
|
10624
10253
|
// src/tools/health.ts
|
|
10625
|
-
import { z as
|
|
10254
|
+
import { z as z28 } from "zod/v3";
|
|
10626
10255
|
|
|
10627
10256
|
// src/lib/auditView.ts
|
|
10628
10257
|
async function buildTenantAuditView(limit) {
|
|
@@ -10891,7 +10520,7 @@ async function handleWorkspaceStatus() {
|
|
|
10891
10520
|
`- **Entries:** ${stats.totalEntries} (${stats.activeCount} accepted/active, ${stats.draftCount} draft)`,
|
|
10892
10521
|
`- **Relations:** ${stats.totalRelations}`,
|
|
10893
10522
|
`- **Collections:** ${stats.collectionCount}`,
|
|
10894
|
-
`- **Orphaned:** ${stats.orphanedCount}
|
|
10523
|
+
`- **Orphaned:** ${stats.orphanedCount} accepted entries with no relations`,
|
|
10895
10524
|
""
|
|
10896
10525
|
];
|
|
10897
10526
|
if (gaps.length > 0 && !result2.sampleTruncated) {
|
|
@@ -10968,60 +10597,60 @@ ${logLines.join("\n")}${seamSummaryText}` }],
|
|
|
10968
10597
|
};
|
|
10969
10598
|
}
|
|
10970
10599
|
var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
|
|
10971
|
-
var healthSchema =
|
|
10972
|
-
action:
|
|
10600
|
+
var healthSchema = z28.object({
|
|
10601
|
+
action: z28.enum(HEALTH_ACTIONS).describe(
|
|
10973
10602
|
"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
|
|
10974
10603
|
),
|
|
10975
|
-
limit:
|
|
10604
|
+
limit: z28.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
|
|
10976
10605
|
});
|
|
10977
|
-
var healthCheckOutputSchema =
|
|
10978
|
-
healthy:
|
|
10979
|
-
collections:
|
|
10980
|
-
entries:
|
|
10981
|
-
latencyMs:
|
|
10982
|
-
workspace:
|
|
10606
|
+
var healthCheckOutputSchema = z28.object({
|
|
10607
|
+
healthy: z28.boolean(),
|
|
10608
|
+
collections: z28.number(),
|
|
10609
|
+
entries: z28.number(),
|
|
10610
|
+
latencyMs: z28.number(),
|
|
10611
|
+
workspace: z28.string()
|
|
10983
10612
|
});
|
|
10984
|
-
var organisationHealthSchema =
|
|
10985
|
-
reviewed:
|
|
10986
|
-
agreements:
|
|
10987
|
-
disagreements:
|
|
10988
|
-
abstentions:
|
|
10989
|
-
agreementRate:
|
|
10990
|
-
flags:
|
|
10613
|
+
var organisationHealthSchema = z28.object({
|
|
10614
|
+
reviewed: z28.number(),
|
|
10615
|
+
agreements: z28.number(),
|
|
10616
|
+
disagreements: z28.number(),
|
|
10617
|
+
abstentions: z28.number(),
|
|
10618
|
+
agreementRate: z28.number(),
|
|
10619
|
+
flags: z28.array(z28.object({ collection: z28.string(), count: z28.number(), suggestedCollection: z28.string() }))
|
|
10991
10620
|
});
|
|
10992
|
-
var healthStatusOutputSchema =
|
|
10993
|
-
sampleTruncated:
|
|
10994
|
-
activeEntries:
|
|
10995
|
-
totalRelations:
|
|
10996
|
-
orphanedEntries:
|
|
10997
|
-
checks:
|
|
10998
|
-
gaps:
|
|
10621
|
+
var healthStatusOutputSchema = z28.object({
|
|
10622
|
+
sampleTruncated: z28.boolean().nullable().optional(),
|
|
10623
|
+
activeEntries: z28.number(),
|
|
10624
|
+
totalRelations: z28.number(),
|
|
10625
|
+
orphanedEntries: z28.number(),
|
|
10626
|
+
checks: z28.array(z28.object({ label: z28.string(), passed: z28.boolean(), current: z28.number(), required: z28.number() })),
|
|
10627
|
+
gaps: z28.array(z28.object({ id: z28.string(), label: z28.string(), guidance: z28.string() })),
|
|
10999
10628
|
organisationHealth: organisationHealthSchema.optional()
|
|
11000
10629
|
});
|
|
11001
|
-
var healthAuditOutputSchema =
|
|
11002
|
-
totalCalls:
|
|
11003
|
-
calls:
|
|
11004
|
-
tool:
|
|
11005
|
-
action:
|
|
11006
|
-
timestamp:
|
|
11007
|
-
durationMs:
|
|
10630
|
+
var healthAuditOutputSchema = z28.object({
|
|
10631
|
+
totalCalls: z28.number(),
|
|
10632
|
+
calls: z28.array(z28.object({
|
|
10633
|
+
tool: z28.string(),
|
|
10634
|
+
action: z28.string().optional(),
|
|
10635
|
+
timestamp: z28.string(),
|
|
10636
|
+
durationMs: z28.number().optional()
|
|
11008
10637
|
}))
|
|
11009
10638
|
});
|
|
11010
|
-
var healthWhoamiOutputSchema =
|
|
11011
|
-
workspaceId:
|
|
11012
|
-
workspaceName:
|
|
11013
|
-
scope:
|
|
11014
|
-
sessionId:
|
|
11015
|
-
oriented:
|
|
10639
|
+
var healthWhoamiOutputSchema = z28.object({
|
|
10640
|
+
workspaceId: z28.string(),
|
|
10641
|
+
workspaceName: z28.string(),
|
|
10642
|
+
scope: z28.string(),
|
|
10643
|
+
sessionId: z28.union([z28.string(), z28.null()]),
|
|
10644
|
+
oriented: z28.boolean()
|
|
11016
10645
|
});
|
|
11017
|
-
var selfTestOutputSchema =
|
|
11018
|
-
passed:
|
|
11019
|
-
failed:
|
|
11020
|
-
total:
|
|
11021
|
-
results:
|
|
11022
|
-
tool:
|
|
11023
|
-
valid:
|
|
11024
|
-
error:
|
|
10646
|
+
var selfTestOutputSchema = z28.object({
|
|
10647
|
+
passed: z28.number(),
|
|
10648
|
+
failed: z28.number(),
|
|
10649
|
+
total: z28.number(),
|
|
10650
|
+
results: z28.array(z28.object({
|
|
10651
|
+
tool: z28.string(),
|
|
10652
|
+
valid: z28.boolean(),
|
|
10653
|
+
error: z28.string().optional()
|
|
11025
10654
|
}))
|
|
11026
10655
|
});
|
|
11027
10656
|
function handleSelfTest(server) {
|
|
@@ -11072,9 +10701,9 @@ function handleSelfTest(server) {
|
|
|
11072
10701
|
}
|
|
11073
10702
|
|
|
11074
10703
|
// src/tools/usage.ts
|
|
11075
|
-
import { z as
|
|
11076
|
-
var usageSummarySchema =
|
|
11077
|
-
periodDays:
|
|
10704
|
+
import { z as z29 } from "zod/v3";
|
|
10705
|
+
var usageSummarySchema = z29.object({
|
|
10706
|
+
periodDays: z29.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
|
|
11078
10707
|
});
|
|
11079
10708
|
async function handleUsageSummary(periodDays) {
|
|
11080
10709
|
const ws = await getWorkspaceContext();
|
|
@@ -11144,20 +10773,20 @@ var WORKSPACE_ACTIONS = [
|
|
|
11144
10773
|
"self-test",
|
|
11145
10774
|
"usage"
|
|
11146
10775
|
];
|
|
11147
|
-
var workspaceSchema =
|
|
11148
|
-
action:
|
|
11149
|
-
"'check': connectivity and workspace stats
|
|
10776
|
+
var workspaceSchema = z30.object({
|
|
10777
|
+
action: z30.enum(WORKSPACE_ACTIONS).describe(
|
|
10778
|
+
"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas. 'usage': LLM usage and cost summary."
|
|
11150
10779
|
),
|
|
11151
|
-
limit:
|
|
11152
|
-
periodDays:
|
|
10780
|
+
limit: z30.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
|
|
10781
|
+
periodDays: z30.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
|
|
11153
10782
|
});
|
|
11154
|
-
var workspaceCheckVariant =
|
|
11155
|
-
var workspaceWhoamiVariant =
|
|
11156
|
-
var workspaceStatusVariant =
|
|
11157
|
-
var workspaceAuditVariant =
|
|
11158
|
-
var workspaceSelfTestVariant =
|
|
11159
|
-
var workspaceUsageVariant =
|
|
11160
|
-
var workspaceActionUnion =
|
|
10783
|
+
var workspaceCheckVariant = z30.object({ action: z30.literal("check") });
|
|
10784
|
+
var workspaceWhoamiVariant = z30.object({ action: z30.literal("whoami") });
|
|
10785
|
+
var workspaceStatusVariant = z30.object({ action: z30.literal("status") });
|
|
10786
|
+
var workspaceAuditVariant = z30.object({ action: z30.literal("audit"), limit: z30.number().min(1).max(50).optional().default(20) });
|
|
10787
|
+
var workspaceSelfTestVariant = z30.object({ action: z30.literal("self-test") });
|
|
10788
|
+
var workspaceUsageVariant = z30.object({ action: z30.literal("usage"), periodDays: z30.number().min(1).max(90).optional() });
|
|
10789
|
+
var workspaceActionUnion = z30.discriminatedUnion("action", [
|
|
11161
10790
|
workspaceCheckVariant,
|
|
11162
10791
|
workspaceWhoamiVariant,
|
|
11163
10792
|
workspaceStatusVariant,
|
|
@@ -11186,7 +10815,7 @@ function registerWorkspaceTools(server) {
|
|
|
11186
10815
|
"workspace",
|
|
11187
10816
|
{
|
|
11188
10817
|
title: "Workspace",
|
|
11189
|
-
description: "Diagnostics, session identity, and usage for the current workspace. Six actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown
|
|
10818
|
+
description: "Diagnostics, session identity, and usage for the current workspace. Six actions:\n\n- **check**: Verify connectivity \u2014 workspace, collections, entries, latency.\n- **whoami**: Session identity \u2014 workspace ID, slug, name.\n- **status**: Workspace readiness \u2014 checks (pass/fail), gaps, stats (entries, relations, orphans).\n- **audit**: Session audit log \u2014 last N backend calls with summary.\n- **self-test**: Validate all registered tool schemas.\n- **usage**: LLM usage and cost summary \u2014 spend, tokens, model/feature breakdown.",
|
|
11190
10819
|
inputSchema: workspaceSchema,
|
|
11191
10820
|
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false }
|
|
11192
10821
|
},
|
|
@@ -11203,7 +10832,7 @@ function registerWorkspaceTools(server) {
|
|
|
11203
10832
|
}
|
|
11204
10833
|
|
|
11205
10834
|
// src/tools/feedback.ts
|
|
11206
|
-
import { z as
|
|
10835
|
+
import { z as z31 } from "zod/v3";
|
|
11207
10836
|
|
|
11208
10837
|
// src/lib/productFeedbackConstants.ts
|
|
11209
10838
|
var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
|
|
@@ -11216,41 +10845,41 @@ var MAX_FEEDBACK_ANSWER_LENGTH = 240;
|
|
|
11216
10845
|
|
|
11217
10846
|
// src/tools/feedback.ts
|
|
11218
10847
|
var actions = ["submit", "list", "queue", "note", "group", "status"];
|
|
11219
|
-
var category =
|
|
11220
|
-
var status =
|
|
11221
|
-
var vendorStatus =
|
|
11222
|
-
var tensionId =
|
|
11223
|
-
var answer =
|
|
10848
|
+
var category = z31.enum(PRODUCT_FEEDBACK_CATEGORIES);
|
|
10849
|
+
var status = z31.enum(PRODUCT_FEEDBACK_STATUSES);
|
|
10850
|
+
var vendorStatus = z31.enum(VENDOR_SETTABLE_STATUSES);
|
|
10851
|
+
var tensionId = z31.string().regex(FEEDBACK_TENSION_ID_PATTERN);
|
|
10852
|
+
var answer = z31.string().trim().min(1).max(MAX_FEEDBACK_ANSWER_LENGTH);
|
|
11224
10853
|
var MESSAGE_DISPLAY_LIMIT = 1e3;
|
|
11225
10854
|
var FULL_MESSAGE_MAX_LIMIT = 5;
|
|
11226
|
-
var feedbackSchema =
|
|
11227
|
-
action:
|
|
11228
|
-
message:
|
|
10855
|
+
var feedbackSchema = z31.object({
|
|
10856
|
+
action: z31.enum(actions).describe("submit requires message; list returns your own workspace's feedback (all statuses); queue is the vendor triage queue (system admins only) and accepts filters; note requires feedbackId+note; group requires feedbackIds+groupId (null clears); status requires feedbackId+status and may carry tensionId and answer."),
|
|
10857
|
+
message: z31.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
|
|
11229
10858
|
category: category.optional().describe("Submit/queue category; submit defaults to other."),
|
|
11230
|
-
command:
|
|
11231
|
-
route:
|
|
11232
|
-
client:
|
|
11233
|
-
feedbackId:
|
|
11234
|
-
feedbackIds:
|
|
11235
|
-
note:
|
|
10859
|
+
command: z31.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
|
|
10860
|
+
route: z31.string().max(500).optional().describe("Optional submit route context."),
|
|
10861
|
+
client: z31.string().max(100).optional().describe("Optional submit client label."),
|
|
10862
|
+
feedbackId: z31.string().max(200).optional().describe("Required for note/status: target feedback ID."),
|
|
10863
|
+
feedbackIds: z31.array(z31.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
|
|
10864
|
+
note: z31.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
|
|
11236
10865
|
status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
|
|
11237
10866
|
tensionId: tensionId.optional().describe("status only: the tension the report joined, its display id TEN- and a number (vendor-only, never shown to the reporter)."),
|
|
11238
10867
|
answer: answer.optional().describe(`status only: the one sentence the reporter reads under their report, dated (max ${MAX_FEEDBACK_ANSWER_LENGTH} characters).`),
|
|
11239
|
-
groupId:
|
|
11240
|
-
workspaceId:
|
|
11241
|
-
since:
|
|
11242
|
-
before:
|
|
11243
|
-
limit:
|
|
11244
|
-
cursor:
|
|
11245
|
-
full:
|
|
10868
|
+
groupId: z31.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
|
|
10869
|
+
workspaceId: z31.string().max(200).optional().describe("Queue-only filter (vendor cross-workspace triage); omitted means all workspaces. Has no effect on list \u2014 your own workspace is always injected server-side."),
|
|
10870
|
+
since: z31.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
|
|
10871
|
+
before: z31.number().optional().describe("Queue-only upper createdAt window bound (exclusive) in epoch milliseconds. A time-window FILTER, not the pager \u2014 use cursor to page."),
|
|
10872
|
+
limit: z31.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
|
|
10873
|
+
cursor: z31.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
|
|
10874
|
+
full: z31.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
|
|
11246
10875
|
});
|
|
11247
|
-
var union =
|
|
11248
|
-
|
|
11249
|
-
|
|
11250
|
-
|
|
11251
|
-
|
|
11252
|
-
|
|
11253
|
-
|
|
10876
|
+
var union = z31.discriminatedUnion("action", [
|
|
10877
|
+
z31.object({ action: z31.literal("submit"), message: z31.string().min(1).max(1e4), category: category.optional(), command: z31.string().max(1e3).optional(), route: z31.string().max(500).optional(), client: z31.string().max(100).optional() }),
|
|
10878
|
+
z31.object({ action: z31.literal("list"), status: status.optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
|
|
10879
|
+
z31.object({ action: z31.literal("queue"), status: status.optional(), category: category.optional(), groupId: z31.string().min(1).max(200).optional(), workspaceId: z31.string().max(200).optional(), since: z31.number().optional(), before: z31.number().optional(), limit: z31.number().int().min(1).max(100).optional(), cursor: z31.string().max(2e3).optional(), full: z31.boolean().optional() }),
|
|
10880
|
+
z31.object({ action: z31.literal("note"), feedbackId: z31.string().min(1).max(200), note: z31.string().max(4e3) }),
|
|
10881
|
+
z31.object({ action: z31.literal("group"), feedbackIds: z31.array(z31.string().min(1).max(200)).min(1).max(100), groupId: z31.string().min(1).max(200).nullable() }),
|
|
10882
|
+
z31.object({ action: z31.literal("status"), feedbackId: z31.string().min(1).max(200), status: vendorStatus, tensionId: tensionId.optional(), answer: answer.optional() })
|
|
11254
10883
|
]);
|
|
11255
10884
|
var specs = {
|
|
11256
10885
|
submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
|
|
@@ -11379,19 +11008,19 @@ function registerFeedbackTool(server) {
|
|
|
11379
11008
|
}
|
|
11380
11009
|
|
|
11381
11010
|
// src/tools/conflicts.ts
|
|
11382
|
-
import { z as
|
|
11011
|
+
import { z as z32 } from "zod/v3";
|
|
11383
11012
|
var ACTIONS = ["list", "resolve"];
|
|
11384
|
-
var mode =
|
|
11385
|
-
var verdict =
|
|
11386
|
-
var conflictsSchema =
|
|
11387
|
-
action:
|
|
11013
|
+
var mode = z32.enum(["actionable", "all"]);
|
|
11014
|
+
var verdict = z32.enum(["real", "noise"]);
|
|
11015
|
+
var conflictsSchema = z32.object({
|
|
11016
|
+
action: z32.enum(ACTIONS),
|
|
11388
11017
|
mode: mode.optional().describe("list: all adds judged and snoozed rows."),
|
|
11389
|
-
issueId:
|
|
11018
|
+
issueId: z32.string().max(200).optional().describe("resolve: an id from list."),
|
|
11390
11019
|
verdict: verdict.optional().describe("resolve: real keeps the row open; noise closes it.")
|
|
11391
11020
|
});
|
|
11392
|
-
var conflictsActionUnion =
|
|
11393
|
-
|
|
11394
|
-
|
|
11021
|
+
var conflictsActionUnion = z32.discriminatedUnion("action", [
|
|
11022
|
+
z32.object({ action: z32.literal("list"), mode: mode.optional() }),
|
|
11023
|
+
z32.object({ action: z32.literal("resolve"), issueId: z32.string().min(1).max(200), verdict })
|
|
11395
11024
|
]);
|
|
11396
11025
|
var CONFLICTS_ACTION_SPECS = {
|
|
11397
11026
|
list: { params: ["mode"], description: "mode defaults to actionable." },
|
|
@@ -11434,26 +11063,26 @@ function registerConflictsTool(server) {
|
|
|
11434
11063
|
}
|
|
11435
11064
|
|
|
11436
11065
|
// src/tools/question.ts
|
|
11437
|
-
import { z as
|
|
11066
|
+
import { z as z33 } from "zod/v3";
|
|
11438
11067
|
var QUESTION_ACTIONS = ["create", "assign", "answer", "force-close", "list"];
|
|
11439
|
-
var questionSchema =
|
|
11440
|
-
action:
|
|
11068
|
+
var questionSchema = z33.object({
|
|
11069
|
+
action: z33.enum(QUESTION_ACTIONS).describe(
|
|
11441
11070
|
"'create': create a new routed question from text \u2014 the dedicated birth action; every question is born escalated to the team lead (generic entry creation and move-and-retype also pair a routing facet). 'assign': reassign ownership to a role (toRole required \u2014 no bare self-confirm, no toPerson). 'answer': close the loop \u2014 writes the answer on the question and moves it to answered; --entry links an existing decision instead. 'force-close': Team-Lead-only escape hatch \u2014 reason required. 'list': the ack-gate read model \u2014 what you owe (or, with mine:true, every question you asked, including closed ones)."
|
|
11442
11071
|
),
|
|
11443
|
-
entryId:
|
|
11444
|
-
text:
|
|
11445
|
-
blocks:
|
|
11446
|
-
toRole:
|
|
11447
|
-
reason:
|
|
11448
|
-
answerEntryId:
|
|
11449
|
-
mine:
|
|
11072
|
+
entryId: z33.string().max(200).optional().describe("Target question's id (human TEN-nnn form or a raw entry id). Required for every action except 'create'/'list'."),
|
|
11073
|
+
text: z33.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
|
|
11074
|
+
blocks: z33.array(z33.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
|
|
11075
|
+
toRole: z33.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
|
|
11076
|
+
reason: z33.string().max(2e3).optional().describe("'force-close': required reason."),
|
|
11077
|
+
answerEntryId: z33.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
|
|
11078
|
+
mine: z33.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
|
|
11450
11079
|
});
|
|
11451
|
-
var createVariant =
|
|
11452
|
-
var assignVariant =
|
|
11453
|
-
var answerVariant =
|
|
11454
|
-
var forceCloseVariant =
|
|
11455
|
-
var listVariant =
|
|
11456
|
-
var questionActionUnion =
|
|
11080
|
+
var createVariant = z33.object({ action: z33.literal("create"), text: z33.string().min(1).max(5e3), blocks: z33.array(z33.string().max(200)).max(50).optional() });
|
|
11081
|
+
var assignVariant = z33.object({ action: z33.literal("assign"), entryId: z33.string().max(200), toRole: z33.string().max(200).min(1) });
|
|
11082
|
+
var answerVariant = z33.object({ action: z33.literal("answer"), entryId: z33.string().max(200), text: z33.string().max(2e3).optional(), answerEntryId: z33.string().max(200).optional() });
|
|
11083
|
+
var forceCloseVariant = z33.object({ action: z33.literal("force-close"), entryId: z33.string().max(200), reason: z33.string().min(1).max(2e3) });
|
|
11084
|
+
var listVariant = z33.object({ action: z33.literal("list"), mine: z33.boolean().optional() });
|
|
11085
|
+
var questionActionUnion = z33.discriminatedUnion("action", [
|
|
11457
11086
|
createVariant,
|
|
11458
11087
|
assignVariant,
|
|
11459
11088
|
answerVariant,
|
|
@@ -11672,7 +11301,7 @@ function registerResources(server) {
|
|
|
11672
11301
|
async (uri) => {
|
|
11673
11302
|
const collections = await kernelQuery("chain.listCollections") ?? [];
|
|
11674
11303
|
if (collections.length === 0) {
|
|
11675
|
-
return { contents: [{ uri: uri.href, text: "No collections in this workspace. Ask a platform admin to provision one, or enable a module ontology pack
|
|
11304
|
+
return { contents: [{ uri: uri.href, text: "No collections in this workspace. Ask a platform admin to provision one, or enable a module ontology pack.", mimeType: "text/markdown" }] };
|
|
11676
11305
|
}
|
|
11677
11306
|
const formatted = collections.map((c) => {
|
|
11678
11307
|
const fieldList = (c.fields ?? []).map((f) => ` - \`${f.key}\` (${f.type}${f.required ? ", required" : ""}${f.searchable ? ", searchable" : ""})`).join("\n");
|
|
@@ -11935,7 +11564,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
|
|
|
11935
11564
|
}
|
|
11936
11565
|
|
|
11937
11566
|
// src/prompts/index.ts
|
|
11938
|
-
import { z as
|
|
11567
|
+
import { z as z34 } from "zod/v3";
|
|
11939
11568
|
async function buildReviewAgainstRulesPrompt(domain) {
|
|
11940
11569
|
const entries = await kernelQuery("chain.listEntries", { collectionSlug: "rules" });
|
|
11941
11570
|
const rules = entries.slice(0, 50);
|
|
@@ -12017,27 +11646,27 @@ function registerPrompts(server) {
|
|
|
12017
11646
|
server.prompt(
|
|
12018
11647
|
"review-against-rules",
|
|
12019
11648
|
"Review code or a design decision against the rules, focused on a given area. Fetches the rules and asks you to do a structured compliance review.",
|
|
12020
|
-
{ domain:
|
|
11649
|
+
{ domain: z34.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
|
|
12021
11650
|
async ({ domain }) => buildReviewAgainstRulesPrompt(domain)
|
|
12022
11651
|
);
|
|
12023
11652
|
server.prompt(
|
|
12024
11653
|
"name-check",
|
|
12025
11654
|
"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
|
|
12026
|
-
{ names:
|
|
11655
|
+
{ names: z34.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
|
|
12027
11656
|
async ({ names }) => buildNameCheckPrompt(names)
|
|
12028
11657
|
);
|
|
12029
11658
|
server.prompt(
|
|
12030
11659
|
"draft-decision-record",
|
|
12031
11660
|
"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
|
|
12032
|
-
{ context:
|
|
11661
|
+
{ context: z34.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
|
|
12033
11662
|
async ({ context }) => buildDraftDecisionRecordPrompt(context)
|
|
12034
11663
|
);
|
|
12035
11664
|
server.prompt(
|
|
12036
11665
|
"draft-rule-from-context",
|
|
12037
11666
|
"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
|
|
12038
11667
|
{
|
|
12039
|
-
observation:
|
|
12040
|
-
domain:
|
|
11668
|
+
observation: z34.string().describe("What you observed or discovered (e.g. 'A workspace can have more than one owner role')"),
|
|
11669
|
+
domain: z34.string().describe("Which domain this rule belongs to (e.g. 'Governance & Decision-Making')")
|
|
12041
11670
|
},
|
|
12042
11671
|
async ({ observation, domain }) => buildDraftRuleFromContextPrompt(observation, domain)
|
|
12043
11672
|
);
|
|
@@ -12126,16 +11755,16 @@ var INSTRUCTIONS = [
|
|
|
12126
11755
|
"",
|
|
12127
11756
|
"## Writing",
|
|
12128
11757
|
"",
|
|
12129
|
-
"Write actions (capture, entries update and
|
|
11758
|
+
"Write actions (capture, entries update and accept, relations create, batch-create and delete, people invite and remove, role seat and unseat) need an active session and a readwrite key.",
|
|
12130
11759
|
"Pass the `sessionId` that `session action=start` returned on every write: the connection does not remember it.",
|
|
12131
|
-
"Use `capture` to create an entry and read its reply: it lands as a draft, except a question, which is born open and needs no `entries action=
|
|
11760
|
+
"Use `capture` to create an entry and read its reply: it lands as a draft, except a question, which is born open and needs no `entries action=accept`.",
|
|
12132
11761
|
"Link entries with `relations action=create` \u2014 a relation is written only when you ask, with exactly the verb you send.",
|
|
12133
11762
|
...SPINE_LINKS_LINES,
|
|
12134
11763
|
// TASK-1022 (WP-862): the spine grammar session start prints, a backup for the clients that load instructions
|
|
12135
11764
|
"Finish with `session action=wrapup-review`, then `session action=close`.",
|
|
12136
11765
|
"If the work falls outside the active work packages, name the gap and ask the user before designing it."
|
|
12137
11766
|
].join("\n");
|
|
12138
|
-
var sessionIdArg =
|
|
11767
|
+
var sessionIdArg = z35.string().max(200).optional().describe(
|
|
12139
11768
|
"The sessionId `session action=start` returned. Pass it on every write: the connection does not remember your session between calls."
|
|
12140
11769
|
);
|
|
12141
11770
|
function acceptSessionIdOnEveryTool(server) {
|
|
@@ -12204,4 +11833,4 @@ export {
|
|
|
12204
11833
|
SERVER_VERSION,
|
|
12205
11834
|
createProductBrainServer
|
|
12206
11835
|
};
|
|
12207
|
-
//# sourceMappingURL=chunk-
|
|
11836
|
+
//# sourceMappingURL=chunk-FFOGLME6.js.map
|