@productbrain/mcp 0.0.1-beta.11506 → 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-P5TJID57.js → chunk-FFOGLME6.js} +221 -584
- package/dist/chunk-FFOGLME6.js.map +1 -0
- package/dist/{chunk-YFH3QOQZ.js → chunk-PTRT75UR.js} +2 -2
- package/dist/{chunk-YFH3QOQZ.js.map → chunk-PTRT75UR.js.map} +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/http.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{setup-FVZNB7A6.js → setup-JS3ZNO44.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-P5TJID57.js.map +0 -1
- /package/dist/{setup-FVZNB7A6.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.
|
|
@@ -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;
|
|
@@ -10309,78 +9976,52 @@ function formatNoticeLines(notices) {
|
|
|
10309
9976
|
|
|
10310
9977
|
// src/tools/session.ts
|
|
10311
9978
|
var START_PREFLIGHT_NEXT = 'Next: context action=preflight collection=<kind> links=[{"type":"part_of","entryId":"<PARENT-ID>"}]';
|
|
10312
|
-
var SESSION_ACTIONS = [
|
|
10313
|
-
|
|
10314
|
-
"
|
|
10315
|
-
"
|
|
10316
|
-
|
|
10317
|
-
"wrapup-commit",
|
|
10318
|
-
"resume",
|
|
10319
|
-
"commit-constellation"
|
|
10320
|
-
];
|
|
10321
|
-
var coherencyAcknowledgementFlatSchema2 = z28.object({
|
|
10322
|
-
response: z28.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
10323
|
-
entryId: z28.string().max(200).optional().describe("Entry the acknowledgement links to."),
|
|
10324
|
-
reason: z28.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
10325
|
-
subjectEntryId: z28.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
10326
|
-
});
|
|
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
|
+
};
|
|
10327
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.";
|
|
10328
|
-
var sessionSchema =
|
|
10329
|
-
action:
|
|
10330
|
-
"'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review':
|
|
10331
|
-
),
|
|
10332
|
-
betEntryId: z28.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
|
|
10333
|
-
operationId: z28.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
|
|
10334
|
-
coherencyAcknowledgements: z28.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
|
|
10335
|
-
"For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
|
|
10336
|
-
),
|
|
10337
|
-
steeringOverrideReason: z28.string().max(2e3).optional().describe(
|
|
10338
|
-
"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."
|
|
10339
9988
|
),
|
|
9989
|
+
betEntryId: z27.string().max(200).optional().describe("For 'resume': work package entry ID. Required."),
|
|
10340
9990
|
// DEC-1715 (WP-753 O1a)
|
|
10341
|
-
role:
|
|
9991
|
+
role: z27.string().max(200).optional().describe(
|
|
10342
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."
|
|
10343
9993
|
),
|
|
10344
|
-
team:
|
|
9994
|
+
team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
|
|
10345
9995
|
// TASK-801
|
|
10346
9996
|
});
|
|
10347
|
-
var sessionStartVariant =
|
|
10348
|
-
action:
|
|
9997
|
+
var sessionStartVariant = z27.object({
|
|
9998
|
+
action: z27.literal("start"),
|
|
10349
9999
|
// DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
|
|
10350
10000
|
// more than one role; the server refuses and lists the choices when it's required and omitted.
|
|
10351
|
-
role:
|
|
10001
|
+
role: z27.string().max(200).optional().describe(
|
|
10352
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."
|
|
10353
10003
|
),
|
|
10354
|
-
team:
|
|
10004
|
+
team: z27.string().max(200).optional().describe(TEAM_PARAM_DESCRIPTION)
|
|
10355
10005
|
// TASK-801
|
|
10356
10006
|
});
|
|
10357
|
-
var sessionCloseVariant =
|
|
10358
|
-
var sessionStatusVariant =
|
|
10359
|
-
var sessionWrapupReviewVariant =
|
|
10360
|
-
var
|
|
10361
|
-
var
|
|
10362
|
-
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z28.literal("commit-constellation") });
|
|
10363
|
-
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", [
|
|
10364
10012
|
sessionStartVariant,
|
|
10365
10013
|
sessionCloseVariant,
|
|
10366
10014
|
sessionStatusVariant,
|
|
10367
10015
|
sessionWrapupReviewVariant,
|
|
10368
|
-
|
|
10369
|
-
sessionResumeVariant,
|
|
10370
|
-
sessionCommitConstellationVariant
|
|
10016
|
+
sessionResumeVariant
|
|
10371
10017
|
]);
|
|
10372
10018
|
var SESSION_ACTION_SPECS = {
|
|
10373
10019
|
// DEC-1715 (WP-753 O1a), TASK-801
|
|
10374
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." },
|
|
10375
10021
|
close: { params: [], description: "End the current session; no params." },
|
|
10376
10022
|
status: { params: [], description: "Check current session state; no params." },
|
|
10377
|
-
"wrapup-review": { params: [], description: "
|
|
10378
|
-
|
|
10379
|
-
resume: { params: ["betEntryId"], description: "betEntryId is required." },
|
|
10380
|
-
"commit-constellation": {
|
|
10381
|
-
params: ["betEntryId", "operationId", "coherencyAcknowledgements", "steeringOverrideReason"],
|
|
10382
|
-
description: "betEntryId is required; every other field is optional."
|
|
10383
|
-
}
|
|
10023
|
+
"wrapup-review": { params: [], description: "List this session's drafts; no params." },
|
|
10024
|
+
resume: { params: ["betEntryId"], description: "betEntryId is required." }
|
|
10384
10025
|
};
|
|
10385
10026
|
function registerSessionTools(server) {
|
|
10386
10027
|
const wrapupHandler = createWrapupHandler();
|
|
@@ -10388,10 +10029,8 @@ function registerSessionTools(server) {
|
|
|
10388
10029
|
start: (data) => handleStart2(data),
|
|
10389
10030
|
close: () => handleClose(),
|
|
10390
10031
|
status: () => handleStatus(),
|
|
10391
|
-
"wrapup-review": () => wrapupHandler(
|
|
10392
|
-
|
|
10393
|
-
resume: (data) => handleResume(data),
|
|
10394
|
-
"commit-constellation": (data) => handleCommitConstellation(data)
|
|
10032
|
+
"wrapup-review": () => wrapupHandler(),
|
|
10033
|
+
resume: (data) => handleResume(data)
|
|
10395
10034
|
};
|
|
10396
10035
|
server.registerTool(
|
|
10397
10036
|
"session",
|
|
@@ -10401,15 +10040,13 @@ function registerSessionTools(server) {
|
|
|
10401
10040
|
|
|
10402
10041
|
Session lifecycle, wrapup review, and work package facilitation.
|
|
10403
10042
|
|
|
10404
|
-
- **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.
|
|
10405
10044
|
- **close**: End the current session. Records structured data (entries created, modified, relations). Run \`session action=wrapup-review\` before closing.
|
|
10406
10045
|
- **status**: Check current session \u2014 active or not, oriented, activity counts.
|
|
10407
|
-
- **wrapup-review**:
|
|
10408
|
-
- **
|
|
10409
|
-
- **resume**: Load session state (work package data, constellation, drafts) from an existing work package entry.
|
|
10410
|
-
- **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.`,
|
|
10411
10048
|
inputSchema: sessionSchema,
|
|
10412
|
-
// Mixed read/write noun (§3 R3):
|
|
10049
|
+
// Mixed read/write noun (§3 R3): start and close write.
|
|
10413
10050
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
|
|
10414
10051
|
},
|
|
10415
10052
|
thinWrapper(async (args) => {
|
|
@@ -10494,7 +10131,7 @@ async function handleClose() {
|
|
|
10494
10131
|
"",
|
|
10495
10132
|
text,
|
|
10496
10133
|
"",
|
|
10497
|
-
`> **${data.drafts.length}
|
|
10134
|
+
`> **${data.drafts.length} draft(s) not yet accepted.** Accept each with \`entries action=accept\` before closing next time.`,
|
|
10498
10135
|
"",
|
|
10499
10136
|
"---",
|
|
10500
10137
|
""
|
|
@@ -10611,10 +10248,10 @@ async function handleStatus() {
|
|
|
10611
10248
|
}
|
|
10612
10249
|
|
|
10613
10250
|
// src/tools/workspace.ts
|
|
10614
|
-
import { z as
|
|
10251
|
+
import { z as z30 } from "zod/v3";
|
|
10615
10252
|
|
|
10616
10253
|
// src/tools/health.ts
|
|
10617
|
-
import { z as
|
|
10254
|
+
import { z as z28 } from "zod/v3";
|
|
10618
10255
|
|
|
10619
10256
|
// src/lib/auditView.ts
|
|
10620
10257
|
async function buildTenantAuditView(limit) {
|
|
@@ -10883,7 +10520,7 @@ async function handleWorkspaceStatus() {
|
|
|
10883
10520
|
`- **Entries:** ${stats.totalEntries} (${stats.activeCount} accepted/active, ${stats.draftCount} draft)`,
|
|
10884
10521
|
`- **Relations:** ${stats.totalRelations}`,
|
|
10885
10522
|
`- **Collections:** ${stats.collectionCount}`,
|
|
10886
|
-
`- **Orphaned:** ${stats.orphanedCount}
|
|
10523
|
+
`- **Orphaned:** ${stats.orphanedCount} accepted entries with no relations`,
|
|
10887
10524
|
""
|
|
10888
10525
|
];
|
|
10889
10526
|
if (gaps.length > 0 && !result2.sampleTruncated) {
|
|
@@ -10960,60 +10597,60 @@ ${logLines.join("\n")}${seamSummaryText}` }],
|
|
|
10960
10597
|
};
|
|
10961
10598
|
}
|
|
10962
10599
|
var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
|
|
10963
|
-
var healthSchema =
|
|
10964
|
-
action:
|
|
10600
|
+
var healthSchema = z28.object({
|
|
10601
|
+
action: z28.enum(HEALTH_ACTIONS).describe(
|
|
10965
10602
|
"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
|
|
10966
10603
|
),
|
|
10967
|
-
limit:
|
|
10604
|
+
limit: z28.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
|
|
10968
10605
|
});
|
|
10969
|
-
var healthCheckOutputSchema =
|
|
10970
|
-
healthy:
|
|
10971
|
-
collections:
|
|
10972
|
-
entries:
|
|
10973
|
-
latencyMs:
|
|
10974
|
-
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()
|
|
10975
10612
|
});
|
|
10976
|
-
var organisationHealthSchema =
|
|
10977
|
-
reviewed:
|
|
10978
|
-
agreements:
|
|
10979
|
-
disagreements:
|
|
10980
|
-
abstentions:
|
|
10981
|
-
agreementRate:
|
|
10982
|
-
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() }))
|
|
10983
10620
|
});
|
|
10984
|
-
var healthStatusOutputSchema =
|
|
10985
|
-
sampleTruncated:
|
|
10986
|
-
activeEntries:
|
|
10987
|
-
totalRelations:
|
|
10988
|
-
orphanedEntries:
|
|
10989
|
-
checks:
|
|
10990
|
-
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() })),
|
|
10991
10628
|
organisationHealth: organisationHealthSchema.optional()
|
|
10992
10629
|
});
|
|
10993
|
-
var healthAuditOutputSchema =
|
|
10994
|
-
totalCalls:
|
|
10995
|
-
calls:
|
|
10996
|
-
tool:
|
|
10997
|
-
action:
|
|
10998
|
-
timestamp:
|
|
10999
|
-
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()
|
|
11000
10637
|
}))
|
|
11001
10638
|
});
|
|
11002
|
-
var healthWhoamiOutputSchema =
|
|
11003
|
-
workspaceId:
|
|
11004
|
-
workspaceName:
|
|
11005
|
-
scope:
|
|
11006
|
-
sessionId:
|
|
11007
|
-
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()
|
|
11008
10645
|
});
|
|
11009
|
-
var selfTestOutputSchema =
|
|
11010
|
-
passed:
|
|
11011
|
-
failed:
|
|
11012
|
-
total:
|
|
11013
|
-
results:
|
|
11014
|
-
tool:
|
|
11015
|
-
valid:
|
|
11016
|
-
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()
|
|
11017
10654
|
}))
|
|
11018
10655
|
});
|
|
11019
10656
|
function handleSelfTest(server) {
|
|
@@ -11064,9 +10701,9 @@ function handleSelfTest(server) {
|
|
|
11064
10701
|
}
|
|
11065
10702
|
|
|
11066
10703
|
// src/tools/usage.ts
|
|
11067
|
-
import { z as
|
|
11068
|
-
var usageSummarySchema =
|
|
11069
|
-
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)")
|
|
11070
10707
|
});
|
|
11071
10708
|
async function handleUsageSummary(periodDays) {
|
|
11072
10709
|
const ws = await getWorkspaceContext();
|
|
@@ -11136,20 +10773,20 @@ var WORKSPACE_ACTIONS = [
|
|
|
11136
10773
|
"self-test",
|
|
11137
10774
|
"usage"
|
|
11138
10775
|
];
|
|
11139
|
-
var workspaceSchema =
|
|
11140
|
-
action:
|
|
10776
|
+
var workspaceSchema = z30.object({
|
|
10777
|
+
action: z30.enum(WORKSPACE_ACTIONS).describe(
|
|
11141
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."
|
|
11142
10779
|
),
|
|
11143
|
-
limit:
|
|
11144
|
-
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).")
|
|
11145
10782
|
});
|
|
11146
|
-
var workspaceCheckVariant =
|
|
11147
|
-
var workspaceWhoamiVariant =
|
|
11148
|
-
var workspaceStatusVariant =
|
|
11149
|
-
var workspaceAuditVariant =
|
|
11150
|
-
var workspaceSelfTestVariant =
|
|
11151
|
-
var workspaceUsageVariant =
|
|
11152
|
-
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", [
|
|
11153
10790
|
workspaceCheckVariant,
|
|
11154
10791
|
workspaceWhoamiVariant,
|
|
11155
10792
|
workspaceStatusVariant,
|
|
@@ -11195,7 +10832,7 @@ function registerWorkspaceTools(server) {
|
|
|
11195
10832
|
}
|
|
11196
10833
|
|
|
11197
10834
|
// src/tools/feedback.ts
|
|
11198
|
-
import { z as
|
|
10835
|
+
import { z as z31 } from "zod/v3";
|
|
11199
10836
|
|
|
11200
10837
|
// src/lib/productFeedbackConstants.ts
|
|
11201
10838
|
var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
|
|
@@ -11208,41 +10845,41 @@ var MAX_FEEDBACK_ANSWER_LENGTH = 240;
|
|
|
11208
10845
|
|
|
11209
10846
|
// src/tools/feedback.ts
|
|
11210
10847
|
var actions = ["submit", "list", "queue", "note", "group", "status"];
|
|
11211
|
-
var category =
|
|
11212
|
-
var status =
|
|
11213
|
-
var vendorStatus =
|
|
11214
|
-
var tensionId =
|
|
11215
|
-
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);
|
|
11216
10853
|
var MESSAGE_DISPLAY_LIMIT = 1e3;
|
|
11217
10854
|
var FULL_MESSAGE_MAX_LIMIT = 5;
|
|
11218
|
-
var feedbackSchema =
|
|
11219
|
-
action:
|
|
11220
|
-
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)."),
|
|
11221
10858
|
category: category.optional().describe("Submit/queue category; submit defaults to other."),
|
|
11222
|
-
command:
|
|
11223
|
-
route:
|
|
11224
|
-
client:
|
|
11225
|
-
feedbackId:
|
|
11226
|
-
feedbackIds:
|
|
11227
|
-
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)."),
|
|
11228
10865
|
status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
|
|
11229
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)."),
|
|
11230
10867
|
answer: answer.optional().describe(`status only: the one sentence the reporter reads under their report, dated (max ${MAX_FEEDBACK_ANSWER_LENGTH} characters).`),
|
|
11231
|
-
groupId:
|
|
11232
|
-
workspaceId:
|
|
11233
|
-
since:
|
|
11234
|
-
before:
|
|
11235
|
-
limit:
|
|
11236
|
-
cursor:
|
|
11237
|
-
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}.`)
|
|
11238
10875
|
});
|
|
11239
|
-
var union =
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
|
|
11244
|
-
|
|
11245
|
-
|
|
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() })
|
|
11246
10883
|
]);
|
|
11247
10884
|
var specs = {
|
|
11248
10885
|
submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
|
|
@@ -11371,19 +11008,19 @@ function registerFeedbackTool(server) {
|
|
|
11371
11008
|
}
|
|
11372
11009
|
|
|
11373
11010
|
// src/tools/conflicts.ts
|
|
11374
|
-
import { z as
|
|
11011
|
+
import { z as z32 } from "zod/v3";
|
|
11375
11012
|
var ACTIONS = ["list", "resolve"];
|
|
11376
|
-
var mode =
|
|
11377
|
-
var verdict =
|
|
11378
|
-
var conflictsSchema =
|
|
11379
|
-
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),
|
|
11380
11017
|
mode: mode.optional().describe("list: all adds judged and snoozed rows."),
|
|
11381
|
-
issueId:
|
|
11018
|
+
issueId: z32.string().max(200).optional().describe("resolve: an id from list."),
|
|
11382
11019
|
verdict: verdict.optional().describe("resolve: real keeps the row open; noise closes it.")
|
|
11383
11020
|
});
|
|
11384
|
-
var conflictsActionUnion =
|
|
11385
|
-
|
|
11386
|
-
|
|
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 })
|
|
11387
11024
|
]);
|
|
11388
11025
|
var CONFLICTS_ACTION_SPECS = {
|
|
11389
11026
|
list: { params: ["mode"], description: "mode defaults to actionable." },
|
|
@@ -11426,26 +11063,26 @@ function registerConflictsTool(server) {
|
|
|
11426
11063
|
}
|
|
11427
11064
|
|
|
11428
11065
|
// src/tools/question.ts
|
|
11429
|
-
import { z as
|
|
11066
|
+
import { z as z33 } from "zod/v3";
|
|
11430
11067
|
var QUESTION_ACTIONS = ["create", "assign", "answer", "force-close", "list"];
|
|
11431
|
-
var questionSchema =
|
|
11432
|
-
action:
|
|
11068
|
+
var questionSchema = z33.object({
|
|
11069
|
+
action: z33.enum(QUESTION_ACTIONS).describe(
|
|
11433
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)."
|
|
11434
11071
|
),
|
|
11435
|
-
entryId:
|
|
11436
|
-
text:
|
|
11437
|
-
blocks:
|
|
11438
|
-
toRole:
|
|
11439
|
-
reason:
|
|
11440
|
-
answerEntryId:
|
|
11441
|
-
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).")
|
|
11442
11079
|
});
|
|
11443
|
-
var createVariant =
|
|
11444
|
-
var assignVariant =
|
|
11445
|
-
var answerVariant =
|
|
11446
|
-
var forceCloseVariant =
|
|
11447
|
-
var listVariant =
|
|
11448
|
-
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", [
|
|
11449
11086
|
createVariant,
|
|
11450
11087
|
assignVariant,
|
|
11451
11088
|
answerVariant,
|
|
@@ -11927,7 +11564,7 @@ ${entry.labels.map((l) => `- ${l.name ?? l.slug}`).join("\n")}`);
|
|
|
11927
11564
|
}
|
|
11928
11565
|
|
|
11929
11566
|
// src/prompts/index.ts
|
|
11930
|
-
import { z as
|
|
11567
|
+
import { z as z34 } from "zod/v3";
|
|
11931
11568
|
async function buildReviewAgainstRulesPrompt(domain) {
|
|
11932
11569
|
const entries = await kernelQuery("chain.listEntries", { collectionSlug: "rules" });
|
|
11933
11570
|
const rules = entries.slice(0, 50);
|
|
@@ -12009,27 +11646,27 @@ function registerPrompts(server) {
|
|
|
12009
11646
|
server.prompt(
|
|
12010
11647
|
"review-against-rules",
|
|
12011
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.",
|
|
12012
|
-
{ domain:
|
|
11649
|
+
{ domain: z34.string().describe("Business rule domain (e.g. 'Identity & Access', 'Governance & Decision-Making')") },
|
|
12013
11650
|
async ({ domain }) => buildReviewAgainstRulesPrompt(domain)
|
|
12014
11651
|
);
|
|
12015
11652
|
server.prompt(
|
|
12016
11653
|
"name-check",
|
|
12017
11654
|
"Check variable names, field names, or API names against the glossary for terminology alignment. Flags drift from canonical terms.",
|
|
12018
|
-
{ names:
|
|
11655
|
+
{ names: z34.string().describe("Comma-separated list of names to check (e.g. 'user_id, workspace_id, entry_status')") },
|
|
12019
11656
|
async ({ names }) => buildNameCheckPrompt(names)
|
|
12020
11657
|
);
|
|
12021
11658
|
server.prompt(
|
|
12022
11659
|
"draft-decision-record",
|
|
12023
11660
|
"Draft a structured decision record from a description of what was decided. Includes context from recent decisions and relevant rules.",
|
|
12024
|
-
{ context:
|
|
11661
|
+
{ context: z34.string().describe("Description of the decision (e.g. 'We decided to keep one body field per entry because...')") },
|
|
12025
11662
|
async ({ context }) => buildDraftDecisionRecordPrompt(context)
|
|
12026
11663
|
);
|
|
12027
11664
|
server.prompt(
|
|
12028
11665
|
"draft-rule-from-context",
|
|
12029
11666
|
"Draft a new business rule from an observation or discovery made while coding. Fetches existing rules for the domain to ensure consistency.",
|
|
12030
11667
|
{
|
|
12031
|
-
observation:
|
|
12032
|
-
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')")
|
|
12033
11670
|
},
|
|
12034
11671
|
async ({ observation, domain }) => buildDraftRuleFromContextPrompt(observation, domain)
|
|
12035
11672
|
);
|
|
@@ -12118,16 +11755,16 @@ var INSTRUCTIONS = [
|
|
|
12118
11755
|
"",
|
|
12119
11756
|
"## Writing",
|
|
12120
11757
|
"",
|
|
12121
|
-
"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.",
|
|
12122
11759
|
"Pass the `sessionId` that `session action=start` returned on every write: the connection does not remember it.",
|
|
12123
|
-
"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`.",
|
|
12124
11761
|
"Link entries with `relations action=create` \u2014 a relation is written only when you ask, with exactly the verb you send.",
|
|
12125
11762
|
...SPINE_LINKS_LINES,
|
|
12126
11763
|
// TASK-1022 (WP-862): the spine grammar session start prints, a backup for the clients that load instructions
|
|
12127
11764
|
"Finish with `session action=wrapup-review`, then `session action=close`.",
|
|
12128
11765
|
"If the work falls outside the active work packages, name the gap and ask the user before designing it."
|
|
12129
11766
|
].join("\n");
|
|
12130
|
-
var sessionIdArg =
|
|
11767
|
+
var sessionIdArg = z35.string().max(200).optional().describe(
|
|
12131
11768
|
"The sessionId `session action=start` returned. Pass it on every write: the connection does not remember your session between calls."
|
|
12132
11769
|
);
|
|
12133
11770
|
function acceptSessionIdOnEveryTool(server) {
|
|
@@ -12196,4 +11833,4 @@ export {
|
|
|
12196
11833
|
SERVER_VERSION,
|
|
12197
11834
|
createProductBrainServer
|
|
12198
11835
|
};
|
|
12199
|
-
//# sourceMappingURL=chunk-
|
|
11836
|
+
//# sourceMappingURL=chunk-FFOGLME6.js.map
|