@productbrain/mcp 0.0.1-beta.9635 → 0.0.1-beta.9656
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-GLXQMNAS.js → chunk-H5B6RWE2.js} +3 -2
- package/dist/chunk-H5B6RWE2.js.map +1 -0
- package/dist/{chunk-LLNKILES.js → chunk-MYMVFOM3.js} +647 -624
- package/dist/chunk-MYMVFOM3.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-54YRIRJN.js → setup-473FGGGS.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-GLXQMNAS.js.map +0 -1
- package/dist/chunk-LLNKILES.js.map +0 -1
- /package/dist/{setup-54YRIRJN.js.map → setup-473FGGGS.js.map} +0 -0
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
trackQualityVerdict,
|
|
44
44
|
trackSessionCaptureRate,
|
|
45
45
|
trackZeroCaptureAuditFired
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-H5B6RWE2.js";
|
|
47
47
|
|
|
48
48
|
// src/server.ts
|
|
49
49
|
import { McpServer as McpServer2 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -4049,7 +4049,7 @@ async function handleDelete(from, to, type) {
|
|
|
4049
4049
|
}
|
|
4050
4050
|
|
|
4051
4051
|
// src/tools/context.ts
|
|
4052
|
-
import { z as
|
|
4052
|
+
import { z as z17 } from "zod/v3";
|
|
4053
4053
|
|
|
4054
4054
|
// src/tools/documents.ts
|
|
4055
4055
|
import { z as z13 } from "zod/v3";
|
|
@@ -4130,7 +4130,7 @@ This row pre-dates snapshot capture (legacy backfill), so no summary is availabl
|
|
|
4130
4130
|
}
|
|
4131
4131
|
|
|
4132
4132
|
// src/tools/contextLookups.ts
|
|
4133
|
-
import { z as
|
|
4133
|
+
import { z as z16 } from "zod/v3";
|
|
4134
4134
|
|
|
4135
4135
|
// src/tools/graph.ts
|
|
4136
4136
|
import { z as z14 } from "zod/v3";
|
|
@@ -4250,45 +4250,198 @@ async function handleFind(entryId, direction) {
|
|
|
4250
4250
|
};
|
|
4251
4251
|
}
|
|
4252
4252
|
|
|
4253
|
+
// src/tools/people.ts
|
|
4254
|
+
import { z as z15 } from "zod/v3";
|
|
4255
|
+
|
|
4256
|
+
// src/lib/seatSentence.ts
|
|
4257
|
+
function formatSeatSentence(action, reply, clean) {
|
|
4258
|
+
if (reply.outcome === "refused") {
|
|
4259
|
+
return `Refused: ${reply.refusal?.reason ?? reply.refusal?.code ?? "not allowed"}${reply.refusal?.requiredAction ? ` ${reply.refusal.requiredAction}` : ""}`;
|
|
4260
|
+
}
|
|
4261
|
+
const who = `${clean(reply.person ?? "")}${reply.personStatus && reply.personStatus !== "active" ? ` (${clean(reply.personStatus)})` : ""}`;
|
|
4262
|
+
const roleLabel2 = `${clean(reply.roleName ?? "")} (${reply.role ?? ""})`;
|
|
4263
|
+
const teamLabel = clean(reply.teamName ?? "");
|
|
4264
|
+
if (action === "seat") {
|
|
4265
|
+
const id = reply.personId ? ` [${reply.personId}]` : "";
|
|
4266
|
+
return `${reply.created ? "Seated" : "Confirmed"} ${who}${id} as ${roleLabel2} in ${teamLabel}.`;
|
|
4267
|
+
}
|
|
4268
|
+
return reply.removed ? `Unseated ${who} from ${roleLabel2} in ${teamLabel}.` : `${who} did not hold ${roleLabel2} in ${teamLabel}; nothing changed.`;
|
|
4269
|
+
}
|
|
4270
|
+
function formatInviteSentence(reply, clean) {
|
|
4271
|
+
const who = `${clean(reply.person)} [${reply.personId}]`;
|
|
4272
|
+
return reply.inPlace ? `Invited ${who} at ${clean(reply.email)}; they keep every role they already hold.` : `Invited ${who} at ${clean(reply.email)} as a new person.`;
|
|
4273
|
+
}
|
|
4274
|
+
|
|
4275
|
+
// src/tools/people.ts
|
|
4276
|
+
var PEOPLE_ACTIONS = ["invite", "remove"];
|
|
4277
|
+
var peopleSchema = z15.object({
|
|
4278
|
+
action: z15.enum(PEOPLE_ACTIONS).describe("'invite': send a login link by email. 'remove': take a person out of a team."),
|
|
4279
|
+
email: z15.string().max(320).optional().describe("'invite': where the login link goes. Required for 'invite'."),
|
|
4280
|
+
person: z15.string().max(320).optional().describe(
|
|
4281
|
+
"'invite': a placeholder's person id, instead of newPersonName. 'remove': the person, by person id or exact email."
|
|
4282
|
+
),
|
|
4283
|
+
newPersonName: z15.string().max(120).optional().describe("'invite': the name of a new person to invite, instead of person."),
|
|
4284
|
+
teamId: z15.string().max(200).optional().describe("'remove': the team, by chain id or entry id. Required for 'remove'.")
|
|
4285
|
+
});
|
|
4286
|
+
var inviteVariant = z15.object({
|
|
4287
|
+
action: z15.literal("invite"),
|
|
4288
|
+
email: z15.string().max(320),
|
|
4289
|
+
person: z15.string().max(320).optional(),
|
|
4290
|
+
newPersonName: z15.string().max(120).optional()
|
|
4291
|
+
});
|
|
4292
|
+
var removeVariant = z15.object({
|
|
4293
|
+
action: z15.literal("remove"),
|
|
4294
|
+
person: z15.string().max(320),
|
|
4295
|
+
teamId: z15.string().max(200)
|
|
4296
|
+
});
|
|
4297
|
+
var peopleActionUnion = z15.discriminatedUnion("action", [inviteVariant, removeVariant]);
|
|
4298
|
+
var PEOPLE_ACTION_SPECS = {
|
|
4299
|
+
invite: { params: ["email", "person", "newPersonName"], description: "email is required, plus exactly one of person (a placeholder's id) or newPersonName." },
|
|
4300
|
+
remove: { params: ["person", "teamId"], description: "person and teamId are required." }
|
|
4301
|
+
};
|
|
4302
|
+
async function handlePeopleInvite(email, person, newPersonName) {
|
|
4303
|
+
const params = { email, person, newPersonName };
|
|
4304
|
+
try {
|
|
4305
|
+
requireWriteAccess();
|
|
4306
|
+
const result2 = await kernelMutation("people.invite", {
|
|
4307
|
+
email,
|
|
4308
|
+
targetPersonId: person,
|
|
4309
|
+
displayName: newPersonName,
|
|
4310
|
+
sessionId: getAgentSessionId()
|
|
4311
|
+
});
|
|
4312
|
+
const message = formatInviteSentence(result2, sanitizeSingleLineField);
|
|
4313
|
+
return successResult(message, message, result2);
|
|
4314
|
+
} catch (err) {
|
|
4315
|
+
return peopleErrorResult(err, "invite", params);
|
|
4316
|
+
}
|
|
4317
|
+
}
|
|
4318
|
+
async function handlePeopleRemove(person, teamId) {
|
|
4319
|
+
try {
|
|
4320
|
+
requireWriteAccess();
|
|
4321
|
+
const result2 = await kernelMutation("organisation.removeMembership", {
|
|
4322
|
+
targetPersonRef: person,
|
|
4323
|
+
teamRef: teamId,
|
|
4324
|
+
sessionId: getAgentSessionId()
|
|
4325
|
+
});
|
|
4326
|
+
if (result2.outcome === "refused") {
|
|
4327
|
+
const { reason, requiredAction } = result2.refusal;
|
|
4328
|
+
const message2 = `Refused: ${reason}${requiredAction ? ` ${requiredAction}` : ""}`;
|
|
4329
|
+
return failureResult(
|
|
4330
|
+
message2,
|
|
4331
|
+
"PERMISSION_DENIED",
|
|
4332
|
+
message2,
|
|
4333
|
+
requiredAction ?? "Ask the team's Team Lead to remove them.",
|
|
4334
|
+
void 0,
|
|
4335
|
+
result2
|
|
4336
|
+
);
|
|
4337
|
+
}
|
|
4338
|
+
const who = sanitizeSingleLineField(result2.person);
|
|
4339
|
+
const message = result2.removed ? `Removed ${who} from ${result2.team}.` : `${who} was not assigned to ${result2.team}; nothing changed.`;
|
|
4340
|
+
return successResult(message, message, result2);
|
|
4341
|
+
} catch (err) {
|
|
4342
|
+
return peopleErrorResult(err, "remove", { person, teamId });
|
|
4343
|
+
}
|
|
4344
|
+
}
|
|
4345
|
+
async function handlePeopleList() {
|
|
4346
|
+
try {
|
|
4347
|
+
const { people, truncated } = await kernelQuery("people.list", {});
|
|
4348
|
+
const lines = people.map((p) => `${sanitizeSingleLineField(p.displayName)} <${p.email ? sanitizeSingleLineField(p.email) : "no email"}> \xB7 ${p.status} \xB7 ${p.role}`);
|
|
4349
|
+
if (people.length === 0) lines.push("No people in this workspace.");
|
|
4350
|
+
if (truncated) lines.push("List cut at 200 live people; the full list is on Settings, Members in the web app.");
|
|
4351
|
+
const text = lines.join("\n");
|
|
4352
|
+
return successResult(text, text, { people, truncated, total: people.length });
|
|
4353
|
+
} catch (err) {
|
|
4354
|
+
const classified = classifyError(err);
|
|
4355
|
+
return failureResult(
|
|
4356
|
+
classified.message,
|
|
4357
|
+
classified.code,
|
|
4358
|
+
classified.message,
|
|
4359
|
+
classified.recovery ?? "Check the workspace key, then call context action=people again.",
|
|
4360
|
+
classified.availableActions,
|
|
4361
|
+
classified.diagnostics
|
|
4362
|
+
);
|
|
4363
|
+
}
|
|
4364
|
+
}
|
|
4365
|
+
function peopleErrorResult(err, action, params) {
|
|
4366
|
+
const classified = classifyError(err);
|
|
4367
|
+
const definedParams = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== void 0));
|
|
4368
|
+
const fallbackActions = retryIsFutile(classified.code) ? void 0 : [{ tool: "people", description: `Retry ${action}`, parameters: { action, ...definedParams } }];
|
|
4369
|
+
return failureResult(
|
|
4370
|
+
classified.message,
|
|
4371
|
+
classified.code,
|
|
4372
|
+
classified.message,
|
|
4373
|
+
classified.recovery ?? `Fix the input the message names and call action='${action}' again.`,
|
|
4374
|
+
classified.availableActions ?? fallbackActions,
|
|
4375
|
+
classified.diagnostics
|
|
4376
|
+
);
|
|
4377
|
+
}
|
|
4378
|
+
function registerPeopleTools(server) {
|
|
4379
|
+
const peopleHandlers = {
|
|
4380
|
+
invite: (data) => handlePeopleInvite(data.email, data.person, data.newPersonName),
|
|
4381
|
+
remove: (data) => handlePeopleRemove(data.person, data.teamId)
|
|
4382
|
+
};
|
|
4383
|
+
server.registerTool(
|
|
4384
|
+
"people",
|
|
4385
|
+
{
|
|
4386
|
+
title: "People",
|
|
4387
|
+
description: "People in the workspace. Two actions:\n\n- **invite**: send a login link to `email`. Give `person` (a placeholder's id, as `role action=seat` printed it) to invite that person in place: they keep every role they hold. Or give `newPersonName` to invite someone new. A person who already has a login or an invite is refused. Needs a workspace owner or admin.\n- **remove**: take `person` out of the team `teamId`; every role they hold there goes with it. To take one role, use `role action=unseat`. Needs the team's Team Lead.",
|
|
4388
|
+
inputSchema: peopleSchema,
|
|
4389
|
+
// TASK-677 (DEC-1981, DEC-74): invite emails an address outside the workspace (open world);
|
|
4390
|
+
// remove deletes a membership row and every role on it (destructive); neither is idempotent.
|
|
4391
|
+
annotations: { readOnlyHint: false, idempotentHint: false, destructiveHint: true, openWorldHint: true }
|
|
4392
|
+
},
|
|
4393
|
+
thinWrapper(async (args) => {
|
|
4394
|
+
const parsed = parseOrFail(peopleSchema, args);
|
|
4395
|
+
if (!parsed.ok) return parsed.result;
|
|
4396
|
+
const { action } = parsed.data;
|
|
4397
|
+
return runWithToolContext(
|
|
4398
|
+
{ tool: "people", action },
|
|
4399
|
+
() => dispatchDiscriminated("people", peopleActionUnion, parsed.data, PEOPLE_ACTION_SPECS, peopleHandlers)
|
|
4400
|
+
);
|
|
4401
|
+
})
|
|
4402
|
+
);
|
|
4403
|
+
}
|
|
4404
|
+
|
|
4253
4405
|
// src/tools/contextLookups.ts
|
|
4254
|
-
var LOOKUP_ACTIONS = ["get", "batch", "history", "list", "search", "find"];
|
|
4255
|
-
var statusFilterSchema =
|
|
4256
|
-
var LOOKUP_ACTION_DESCRIBE = "'get': one entry in full by ID. 'batch': up to 20 entries by ID. 'history': audit trail for an entry. 'list': browse entries with filters (accepted by default). 'search': full-text search across entries. 'find': an entry's direct relations (direction: incoming|outgoing|both, default both). ";
|
|
4257
|
-
var LOOKUP_TOOL_LINES = "- **get**: Fetch a single entry by ID \u2014 full record with data, labels, relations, history.\n- **batch**: Fetch multiple entries (max 20) in one call. Same shape as get per entry.\n- **history**: Audit trail for an entry.\n- **list**: Browse entries with optional filters (collection, status, tag, label). Use collections action=list first to discover slugs.\n- **search**: Full-text search across entries. Scope by collection or filter by status.\n- **find**: An entry's direct relations, incoming and outgoing. NOT full-text search (use search).\n";
|
|
4406
|
+
var LOOKUP_ACTIONS = ["get", "batch", "history", "list", "search", "find", "people"];
|
|
4407
|
+
var statusFilterSchema = z16.union([z16.string().max(200), z16.array(z16.enum(ENTRY_STATUS_READ_WORDS)).max(5)]);
|
|
4408
|
+
var LOOKUP_ACTION_DESCRIBE = "'get': one entry in full by ID. 'batch': up to 20 entries by ID. 'history': audit trail for an entry. 'list': browse entries with filters (accepted by default). 'search': full-text search across entries. 'find': an entry's direct relations (direction: incoming|outgoing|both, default both). 'people': the workspace's members with name, email and status. ";
|
|
4409
|
+
var LOOKUP_TOOL_LINES = "- **get**: Fetch a single entry by ID \u2014 full record with data, labels, relations, history.\n- **batch**: Fetch multiple entries (max 20) in one call. Same shape as get per entry.\n- **history**: Audit trail for an entry.\n- **list**: Browse entries with optional filters (collection, status, tag, label). Use collections action=list first to discover slugs.\n- **search**: Full-text search across entries. Scope by collection or filter by status.\n- **find**: An entry's direct relations, incoming and outgoing. NOT full-text search (use search).\n- **people**: The workspace's members: name, email, status, role. Max 200.\n";
|
|
4258
4410
|
var lookupParams = {
|
|
4259
|
-
entryIds:
|
|
4260
|
-
collection:
|
|
4261
|
-
query:
|
|
4411
|
+
entryIds: z16.array(z16.string().max(200)).min(1).max(20).optional().describe("For 'batch': entry IDs, e.g. ['TYPE-strategy', 'STR-jljeg7']"),
|
|
4412
|
+
collection: z16.string().max(200).optional().describe("For 'list'/'search': collection slug, e.g. 'glossary', 'tracking-events'."),
|
|
4413
|
+
query: z16.string().min(2).max(500).optional().describe("For 'search': search text (min 2 characters)."),
|
|
4262
4414
|
// 'active'/'accepted'/'current' are the same trust level (DEC-1575/DEC-1788) — all enumerated, never one substituted.
|
|
4263
4415
|
status: statusFilterSchema.optional().describe(
|
|
4264
4416
|
`For 'list': defaults to accepted entries (active/accepted/current); use status='draft' to discover drafts. One lifecycle or category value (${ENTRY_STATUS_READ_WORDS.join("|")}). For 'search': one value OR an array of up to 5 (e.g. ['active','accepted']).`
|
|
4265
4417
|
),
|
|
4266
|
-
tag:
|
|
4267
|
-
label:
|
|
4418
|
+
tag: z16.string().max(200).optional().describe("For 'list': filter by internal tag."),
|
|
4419
|
+
label: z16.string().max(200).optional().describe("For 'list': filter by label slug \u2014 matches entries across all collections.")
|
|
4268
4420
|
};
|
|
4269
4421
|
var lookupVariants = [
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
action:
|
|
4275
|
-
collection:
|
|
4276
|
-
status:
|
|
4422
|
+
z16.object({ action: z16.literal("get"), entryId: z16.string().max(200) }),
|
|
4423
|
+
z16.object({ action: z16.literal("batch"), entryIds: z16.array(z16.string().max(200)).min(1).max(20) }),
|
|
4424
|
+
z16.object({ action: z16.literal("history"), entryId: z16.string().max(200) }),
|
|
4425
|
+
z16.object({
|
|
4426
|
+
action: z16.literal("list"),
|
|
4427
|
+
collection: z16.string().max(200).optional(),
|
|
4428
|
+
status: z16.string().max(200).optional(),
|
|
4277
4429
|
// one status word; the flat union serves search
|
|
4278
|
-
tag:
|
|
4279
|
-
label:
|
|
4430
|
+
tag: z16.string().max(200).optional(),
|
|
4431
|
+
label: z16.string().max(200).optional()
|
|
4280
4432
|
}),
|
|
4281
|
-
|
|
4282
|
-
action:
|
|
4283
|
-
query:
|
|
4284
|
-
collection:
|
|
4433
|
+
z16.object({
|
|
4434
|
+
action: z16.literal("search"),
|
|
4435
|
+
query: z16.string().min(2).max(500),
|
|
4436
|
+
collection: z16.string().max(200).optional(),
|
|
4285
4437
|
status: statusFilterSchema.optional()
|
|
4286
4438
|
}),
|
|
4287
|
-
|
|
4288
|
-
action:
|
|
4289
|
-
entryId:
|
|
4290
|
-
direction:
|
|
4291
|
-
})
|
|
4439
|
+
z16.object({
|
|
4440
|
+
action: z16.literal("find"),
|
|
4441
|
+
entryId: z16.string().max(200),
|
|
4442
|
+
direction: z16.enum(["incoming", "outgoing", "both"]).optional().default("both")
|
|
4443
|
+
}),
|
|
4444
|
+
z16.object({ action: z16.literal("people") })
|
|
4292
4445
|
];
|
|
4293
4446
|
var LOOKUP_ACTION_SPECS = {
|
|
4294
4447
|
get: { params: ["entryId"], description: "entryId is required." },
|
|
@@ -4296,7 +4449,8 @@ var LOOKUP_ACTION_SPECS = {
|
|
|
4296
4449
|
history: { params: ["entryId"], description: "entryId is required." },
|
|
4297
4450
|
list: { params: ["collection", "status", "tag", "label"], description: "Browse accepted entries by default; status='draft' lists drafts; status is one word. All params optional." },
|
|
4298
4451
|
search: { params: ["query", "collection", "status"], description: "Full-text search; query is required (min 2 chars)." },
|
|
4299
|
-
find: { params: ["entryId", "direction"], description: "entryId is required." }
|
|
4452
|
+
find: { params: ["entryId", "direction"], description: "entryId is required." },
|
|
4453
|
+
people: { params: [], description: "No params." }
|
|
4300
4454
|
};
|
|
4301
4455
|
function lookupHandlers(server) {
|
|
4302
4456
|
return {
|
|
@@ -4306,7 +4460,8 @@ function lookupHandlers(server) {
|
|
|
4306
4460
|
list: (data) => handleList(data.collection, data.status, data.tag, data.label),
|
|
4307
4461
|
search: (data) => handleSearch(server, data.query, data.collection, data.status),
|
|
4308
4462
|
// logs progress to the client
|
|
4309
|
-
find: (data) => handleFind(data.entryId, data.direction ?? "both")
|
|
4463
|
+
find: (data) => handleFind(data.entryId, data.direction ?? "both"),
|
|
4464
|
+
people: () => handlePeopleList()
|
|
4310
4465
|
};
|
|
4311
4466
|
}
|
|
4312
4467
|
|
|
@@ -4322,90 +4477,90 @@ function epistemicCollectionHint(collectionName) {
|
|
|
4322
4477
|
return "";
|
|
4323
4478
|
}
|
|
4324
4479
|
var CONTEXT_ACTIONS = [...LOOKUP_ACTIONS, "gather", "build", "neighborhood", "changes", "chain", "cross-cut", "incremental", "brief", "last-verified-brief"];
|
|
4325
|
-
var contextSchema =
|
|
4480
|
+
var contextSchema = z17.object({
|
|
4326
4481
|
// provenance: neighborhood BET-142; changes/chain/cross-cut/incremental/brief BET-239 (E4, E6)
|
|
4327
|
-
action:
|
|
4482
|
+
action: z17.enum(CONTEXT_ACTIONS).describe(
|
|
4328
4483
|
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 (absorbs documents action=get-last-verified-brief). Requires templateId and scopeKey."
|
|
4329
4484
|
),
|
|
4330
|
-
entryId:
|
|
4485
|
+
entryId: z17.string().max(200).optional().describe("For 'get'/'history'/'find'/'build'/'neighborhood'/'chain': entry ID, e.g. '<PREFIX>-<n>'. For 'gather': optional (entry-graph mode)."),
|
|
4331
4486
|
...lookupParams,
|
|
4332
|
-
mapEntryId:
|
|
4487
|
+
mapEntryId: z17.string().max(200).optional().describe(
|
|
4333
4488
|
"For 'gather': journey map entry ID for journey-aware context. Returns context organised by journey stage. Takes precedence over entryId when both are supplied. Example: '<PREFIX>-<n>'."
|
|
4334
4489
|
),
|
|
4335
|
-
task:
|
|
4336
|
-
since:
|
|
4490
|
+
task: z17.string().max(2e3).optional().describe("For 'gather': natural-language task description for loading task-relevant governance, binding constraints, and supporting context."),
|
|
4491
|
+
since: z17.string().max(200).optional().describe(
|
|
4337
4492
|
"For 'changes': ISO 8601 timestamp \u2014 returns entries/relations modified since this time. For 'brief' briefType='delta': optional custom timestamp. Example: '2026-03-24T00:00:00Z'."
|
|
4338
4493
|
),
|
|
4339
|
-
direction:
|
|
4340
|
-
relationType:
|
|
4494
|
+
direction: z17.enum(["outgoing", "incoming", "both"]).optional().describe("For 'chain': 'outgoing' follows relations from source, 'incoming' to source (default outgoing). For 'find': incoming|outgoing|both (default both)."),
|
|
4495
|
+
relationType: z17.string().max(200).optional().describe(
|
|
4341
4496
|
"Relation type filter. For 'chain': optional filter to traverse only this relation type. For 'cross-cut': required \u2014 scans all relations of this type across the workspace. Examples: 'part_of', 'informs', 'governs', 'depends_on'."
|
|
4342
4497
|
),
|
|
4343
|
-
mode:
|
|
4344
|
-
maxHops:
|
|
4345
|
-
maxResults:
|
|
4346
|
-
strategy:
|
|
4347
|
-
skill:
|
|
4498
|
+
mode: z17.enum(["search", "graph"]).default("search").optional().describe("For gather: 'search' (default) or 'graph' (enhanced with provenance paths). Ignored when mapEntryId is provided."),
|
|
4499
|
+
maxHops: z17.number().min(1).max(4).default(2).describe("Relation traversal depth (1=direct only, 2=default, 3=wide net, 4=deep chain walk)"),
|
|
4500
|
+
maxResults: z17.number().min(1).max(25).default(10).optional().describe("Max entries to return in gather task mode (default 10)"),
|
|
4501
|
+
strategy: z17.enum(["hybrid", "keyword"]).default("keyword").optional().describe("Seed strategy for task-based gather: 'keyword' (FTS only, default) or 'hybrid' (vector + FTS). Only affects task mode."),
|
|
4502
|
+
skill: z17.string().max(200).optional().describe(
|
|
4348
4503
|
"Skill name for 'incremental' action \u2014 identifies which skill's brief history to compare against. Examples: 'preflight', 'shaping', 'review'. Required when action is 'incremental'."
|
|
4349
4504
|
),
|
|
4350
|
-
briefType:
|
|
4505
|
+
briefType: z17.enum(["steering", "confidence", "delta"]).optional().describe(
|
|
4351
4506
|
"Compound query type for 'brief' action. 'steering': 7d changes + structural aggregation (part_of, depends_on, constrains) + incremental delta + workspace readiness. 'confidence': 7d changes + active bets summary (tensions: use the pb CLI's `tensions list`, not this action). 'delta': changes + relations since a custom timestamp (use 'since' param). Required when action is 'brief'."
|
|
4352
4507
|
),
|
|
4353
|
-
templateId:
|
|
4508
|
+
templateId: z17.string().max(200).optional().describe(
|
|
4354
4509
|
"For 'last-verified-brief': brief template identifier \u2014 currently 'steering-brief' is the only registered template."
|
|
4355
4510
|
),
|
|
4356
|
-
scopeKey:
|
|
4511
|
+
scopeKey: z17.string().max(200).optional().describe(
|
|
4357
4512
|
"For 'last-verified-brief': canonical scope key \u2014 'workspace:<workspaceId>' or 'initiative:<INI-ID>'."
|
|
4358
4513
|
)
|
|
4359
4514
|
});
|
|
4360
|
-
var contextGatherVariant =
|
|
4361
|
-
action:
|
|
4362
|
-
entryId:
|
|
4363
|
-
mapEntryId:
|
|
4364
|
-
task:
|
|
4365
|
-
mode:
|
|
4366
|
-
maxHops:
|
|
4367
|
-
maxResults:
|
|
4368
|
-
strategy:
|
|
4515
|
+
var contextGatherVariant = z17.object({
|
|
4516
|
+
action: z17.literal("gather"),
|
|
4517
|
+
entryId: z17.string().max(200).optional(),
|
|
4518
|
+
mapEntryId: z17.string().max(200).optional(),
|
|
4519
|
+
task: z17.string().max(2e3).optional(),
|
|
4520
|
+
mode: z17.enum(["search", "graph"]).optional().default("search"),
|
|
4521
|
+
maxHops: z17.number().min(1).max(4).optional().default(2),
|
|
4522
|
+
maxResults: z17.number().min(1).max(25).optional().default(10),
|
|
4523
|
+
strategy: z17.enum(["hybrid", "keyword"]).optional().default("keyword")
|
|
4369
4524
|
});
|
|
4370
|
-
var contextBuildVariant =
|
|
4371
|
-
action:
|
|
4372
|
-
entryId:
|
|
4373
|
-
maxHops:
|
|
4525
|
+
var contextBuildVariant = z17.object({
|
|
4526
|
+
action: z17.literal("build"),
|
|
4527
|
+
entryId: z17.string().max(200),
|
|
4528
|
+
maxHops: z17.number().min(1).max(4).optional().default(2)
|
|
4374
4529
|
});
|
|
4375
|
-
var contextNeighborhoodVariant =
|
|
4376
|
-
action:
|
|
4377
|
-
entryId:
|
|
4530
|
+
var contextNeighborhoodVariant = z17.object({
|
|
4531
|
+
action: z17.literal("neighborhood"),
|
|
4532
|
+
entryId: z17.string().max(200)
|
|
4378
4533
|
});
|
|
4379
|
-
var contextChangesVariant =
|
|
4380
|
-
action:
|
|
4381
|
-
since:
|
|
4534
|
+
var contextChangesVariant = z17.object({
|
|
4535
|
+
action: z17.literal("changes"),
|
|
4536
|
+
since: z17.string().max(200)
|
|
4382
4537
|
});
|
|
4383
|
-
var contextChainVariant =
|
|
4384
|
-
action:
|
|
4385
|
-
entryId:
|
|
4386
|
-
direction:
|
|
4387
|
-
maxHops:
|
|
4388
|
-
relationType:
|
|
4538
|
+
var contextChainVariant = z17.object({
|
|
4539
|
+
action: z17.literal("chain"),
|
|
4540
|
+
entryId: z17.string().max(200),
|
|
4541
|
+
direction: z17.enum(["outgoing", "incoming"]).optional().default("outgoing"),
|
|
4542
|
+
maxHops: z17.number().min(1).max(4).optional().default(2),
|
|
4543
|
+
relationType: z17.string().max(200).optional()
|
|
4389
4544
|
});
|
|
4390
|
-
var contextCrossCutVariant =
|
|
4391
|
-
action:
|
|
4392
|
-
relationType:
|
|
4545
|
+
var contextCrossCutVariant = z17.object({
|
|
4546
|
+
action: z17.literal("cross-cut"),
|
|
4547
|
+
relationType: z17.string().max(200)
|
|
4393
4548
|
});
|
|
4394
|
-
var contextIncrementalVariant =
|
|
4395
|
-
action:
|
|
4396
|
-
skill:
|
|
4549
|
+
var contextIncrementalVariant = z17.object({
|
|
4550
|
+
action: z17.literal("incremental"),
|
|
4551
|
+
skill: z17.string().max(200)
|
|
4397
4552
|
});
|
|
4398
|
-
var contextBriefVariant =
|
|
4399
|
-
action:
|
|
4400
|
-
briefType:
|
|
4401
|
-
since:
|
|
4553
|
+
var contextBriefVariant = z17.object({
|
|
4554
|
+
action: z17.literal("brief"),
|
|
4555
|
+
briefType: z17.enum(["steering", "confidence", "delta"]),
|
|
4556
|
+
since: z17.string().max(200).optional()
|
|
4402
4557
|
});
|
|
4403
|
-
var contextLastVerifiedBriefVariant =
|
|
4404
|
-
action:
|
|
4405
|
-
templateId:
|
|
4406
|
-
scopeKey:
|
|
4558
|
+
var contextLastVerifiedBriefVariant = z17.object({
|
|
4559
|
+
action: z17.literal("last-verified-brief"),
|
|
4560
|
+
templateId: z17.string().max(200),
|
|
4561
|
+
scopeKey: z17.string().max(200)
|
|
4407
4562
|
});
|
|
4408
|
-
var contextActionUnion =
|
|
4563
|
+
var contextActionUnion = z17.discriminatedUnion("action", [
|
|
4409
4564
|
...lookupVariants,
|
|
4410
4565
|
contextGatherVariant,
|
|
4411
4566
|
contextBuildVariant,
|
|
@@ -5403,7 +5558,7 @@ function formatTimeAgo(ms) {
|
|
|
5403
5558
|
}
|
|
5404
5559
|
|
|
5405
5560
|
// src/tools/collections.ts
|
|
5406
|
-
import { z as
|
|
5561
|
+
import { z as z19 } from "zod/v3";
|
|
5407
5562
|
|
|
5408
5563
|
// src/lib/bodyTemplate.ts
|
|
5409
5564
|
function readBodyTemplateGuidance(bodyTemplate) {
|
|
@@ -5413,17 +5568,17 @@ ${entry.guidance}`).join("\n\n");
|
|
|
5413
5568
|
}
|
|
5414
5569
|
|
|
5415
5570
|
// src/tools/labels.ts
|
|
5416
|
-
import { z as
|
|
5417
|
-
var labelsSchema =
|
|
5418
|
-
action:
|
|
5419
|
-
slug:
|
|
5420
|
-
name:
|
|
5421
|
-
color:
|
|
5422
|
-
description:
|
|
5423
|
-
parentSlug:
|
|
5424
|
-
isGroup:
|
|
5425
|
-
order:
|
|
5426
|
-
entryId:
|
|
5571
|
+
import { z as z18 } from "zod/v3";
|
|
5572
|
+
var labelsSchema = z18.object({
|
|
5573
|
+
action: z18.enum(["list", "create", "update", "delete", "apply", "remove"]).describe("Action: list all labels, create/update/delete a label, or apply/remove a label on an entry"),
|
|
5574
|
+
slug: z18.string().max(200).optional().describe("Label slug (required for create/update/delete/apply/remove)"),
|
|
5575
|
+
name: z18.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Display name (required for create)"),
|
|
5576
|
+
color: z18.string().max(50).optional().describe("Hex color, e.g. '#ef4444'"),
|
|
5577
|
+
description: z18.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional().describe("What this label means"),
|
|
5578
|
+
parentSlug: z18.string().max(200).optional().describe("Parent group slug for label hierarchy"),
|
|
5579
|
+
isGroup: z18.boolean().optional().describe("True if this is a group container, not a taggable label"),
|
|
5580
|
+
order: z18.number().optional().describe("Sort order within its group"),
|
|
5581
|
+
entryId: z18.string().max(200).optional().describe("Entry ID for apply/remove actions")
|
|
5427
5582
|
});
|
|
5428
5583
|
async function handleLabelsList() {
|
|
5429
5584
|
const labels = await kernelQuery("chain.listLabels");
|
|
@@ -5528,108 +5683,108 @@ var COLLECTIONS_ACTIONS = [
|
|
|
5528
5683
|
"label-remove"
|
|
5529
5684
|
];
|
|
5530
5685
|
var STATUS_CATEGORIES2 = ["draft", "current", "past", "discarded"];
|
|
5531
|
-
var statusListEntrySchema =
|
|
5532
|
-
var qualityCriterionSchema =
|
|
5533
|
-
field:
|
|
5686
|
+
var statusListEntrySchema = z19.object({ label: z19.string().max(200), category: z19.enum(STATUS_CATEGORIES2), archiveDefault: z19.boolean().optional(), resolveDefault: z19.boolean().optional() });
|
|
5687
|
+
var qualityCriterionSchema = z19.object({
|
|
5688
|
+
field: z19.string().max(200).describe("Entry data field key this criterion applies to, e.g. 'description', 'owner'"),
|
|
5534
5689
|
// WP-480 S1: `max_length` — must mirror the Convex rule union, or the tool rejects a
|
|
5535
5690
|
// valid criterion before the request ever reaches the server.
|
|
5536
|
-
rule:
|
|
5537
|
-
value:
|
|
5691
|
+
rule: z19.enum(["required", "min_length", "max_length", "pattern"]).describe("'required': field must be non-empty (blocks accept). 'min_length': minimum string length (warns). 'max_length': maximum string length (warns). 'pattern': regex match (warns)."),
|
|
5692
|
+
value: z19.string().max(500).optional().describe("For min_length/max_length: the length bound as a string integer. For pattern: the regex string. Unused for 'required'.")
|
|
5538
5693
|
});
|
|
5539
|
-
var fieldSchema =
|
|
5540
|
-
key:
|
|
5541
|
-
label:
|
|
5542
|
-
type:
|
|
5543
|
-
required:
|
|
5544
|
-
options:
|
|
5545
|
-
searchable:
|
|
5546
|
-
displayHint:
|
|
5547
|
-
zone:
|
|
5548
|
-
colorMap:
|
|
5549
|
-
accentSource:
|
|
5550
|
-
iconMap:
|
|
5551
|
-
helpText:
|
|
5552
|
-
optionDescriptions:
|
|
5553
|
-
semanticRole:
|
|
5554
|
-
maxLength:
|
|
5555
|
-
minLength:
|
|
5694
|
+
var fieldSchema = z19.object({
|
|
5695
|
+
key: z19.string().max(200).describe("Field key, e.g. 'description', 'severity', 'status'"),
|
|
5696
|
+
label: z19.string().max(200).describe("Display label, e.g. 'Description', 'Severity'"),
|
|
5697
|
+
type: z19.string().max(50).describe("Field type: 'string', 'select', 'array', 'number', 'boolean'"),
|
|
5698
|
+
required: z19.boolean().optional().describe("Whether this field is required"),
|
|
5699
|
+
options: z19.array(z19.string().max(200)).max(200).optional().describe("Options for 'select' type fields"),
|
|
5700
|
+
searchable: z19.boolean().optional().describe("Whether this field is included in full-text search"),
|
|
5701
|
+
displayHint: z19.enum(["hero", "badge", "meta", "section", "hidden", "inline-meta"]).optional().describe("V2 rendering hint: how the field should be displayed in Cortex"),
|
|
5702
|
+
zone: z19.enum(["header", "body", "meta"]).optional().describe("V2 layout zone: where the field appears in the entry view"),
|
|
5703
|
+
colorMap: z19.record(z19.string().max(50)).optional().describe("V2 value-to-semantic-color mapping, e.g. { critical: 'danger', low: 'success' }"),
|
|
5704
|
+
accentSource: z19.boolean().optional().describe("When true, this field's colorMap value drives the card-level accent styling"),
|
|
5705
|
+
iconMap: z19.record(z19.string(), z19.string().max(50)).optional().describe("Maps field values to icons (emoji/symbol), prepended to badge text"),
|
|
5706
|
+
helpText: z19.string().max(2e3).optional().describe("Help text shown in admin field editors"),
|
|
5707
|
+
optionDescriptions: z19.record(z19.string().max(500)).optional().describe("Per-option guidance for select fields"),
|
|
5708
|
+
semanticRole: z19.enum(["problem", "appetite", "elements", "architecture", "done_when", "risks", "exclusions"]).optional().describe("Semantic role for schema-driven consumers \u2014 enables field-key-independent validation and rendering"),
|
|
5709
|
+
maxLength: z19.number().optional().describe("Maximum character length for field values. Three-tier resolution: explicit > displayHint > type fallback."),
|
|
5710
|
+
minLength: z19.number().optional().describe("Minimum character length for field values. Only explicit \u2014 no defaults.")
|
|
5556
5711
|
});
|
|
5557
|
-
var collectionsSchema =
|
|
5558
|
-
action:
|
|
5712
|
+
var collectionsSchema = z19.object({
|
|
5713
|
+
action: z19.enum(COLLECTIONS_ACTIONS).describe(
|
|
5559
5714
|
"'list': browse all collections. 'update': update an existing collection. 'describe': full documentation for one collection \u2014 fields, option guides, usage guidance, examples. 'audit': health report for all collections \u2014 missing classification, displayHint coverage, and field schema gaps. 'export': full system_collection_definitions export with classification metadata (thinkingLayer, classificationPriority, classificationCheck, classificationSignals, governanceRole, governanceFunction, timelineRole, canBeElementOf, descriptionFieldKey). Admin only. 'label-list'/'label-create'/'label-update'/'label-delete'/'label-apply'/'label-remove': manage workspace labels (absorbs the `labels` tool). Creating a new collection is not offered here \u2014 ask a platform admin to provision it, or enable the module ontology pack that owns the drawer."
|
|
5560
5715
|
),
|
|
5561
|
-
slug:
|
|
5562
|
-
name:
|
|
5563
|
-
description:
|
|
5564
|
-
purpose:
|
|
5565
|
-
icon:
|
|
5566
|
-
navGroup:
|
|
5567
|
-
fields:
|
|
5568
|
-
axis:
|
|
5569
|
-
stageLabelMap:
|
|
5570
|
-
defaultCanonicalKey:
|
|
5571
|
-
defaultWorkflowStatus:
|
|
5572
|
-
validWorkflowStatuses:
|
|
5716
|
+
slug: z19.string().max(200).optional().describe("URL-safe identifier for create/update, e.g. 'glossary', 'tech-debt'. For label-*: label slug."),
|
|
5717
|
+
name: z19.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("For label-*: the label's name. For update: refused (the catalog's)."),
|
|
5718
|
+
description: z19.string().max(2e4).optional().describe("For label-*: what the label means (max 2,000 chars). For update: refused (the catalog's)."),
|
|
5719
|
+
purpose: z19.string().max(2e3).optional().describe("Why this collection exists \u2014 strategic reason"),
|
|
5720
|
+
icon: z19.string().max(50).optional().describe("For update: always refused \u2014 a collection's icon comes from the platform catalog."),
|
|
5721
|
+
navGroup: z19.enum(["daily", "strategic", "governance", "reference", "collections"]).optional().describe("Sidebar placement: 'daily', 'strategic', 'governance', 'reference', 'collections'"),
|
|
5722
|
+
fields: z19.array(fieldSchema).max(200).optional().describe("Field definitions for create, or replacement schema for update (replaces all fields)"),
|
|
5723
|
+
axis: z19.enum(["work", "none", "pending"]).optional().describe("REQUIRED for create: 'work' (needs stageLabelMap + validWorkflowStatuses), 'none', or 'pending'. For update: always refused \u2014 a collection's axis comes from the platform catalog."),
|
|
5724
|
+
stageLabelMap: z19.record(z19.string(), z19.enum(["open", "in_progress", "done", "stopped", "tag"])).optional().describe("Required when axis is 'work': maps each valid workflowStatus to a canonical stage."),
|
|
5725
|
+
defaultCanonicalKey: z19.string().max(200).optional().describe("The canonical_key entries in this collection default to (e.g. 'decision', 'insight'). Consumers read from collection doc; code map is fallback."),
|
|
5726
|
+
defaultWorkflowStatus: z19.string().max(200).optional().describe("Default workflowStatus for new entries. For update: always refused \u2014 the status words come from the platform catalog."),
|
|
5727
|
+
validWorkflowStatuses: z19.array(z19.string().max(200)).max(50).optional().describe("The allowed workflowStatus values for entries in this collection. For update: always refused \u2014 the status words come from the platform catalog."),
|
|
5573
5728
|
// ENT-65, FEAT-200
|
|
5574
|
-
classificationCheck:
|
|
5575
|
-
classificationPriority:
|
|
5576
|
-
qualityCriteria:
|
|
5577
|
-
statusList:
|
|
5729
|
+
classificationCheck: z19.string().max(500).optional().describe("LLM decision-tree check for this collection (3\u2013500 chars). Guides the classifier in routing entries here."),
|
|
5730
|
+
classificationPriority: z19.number().optional().describe("Classifier priority (1\u20139, lower = higher priority). Used with classificationCheck to order the decision tree."),
|
|
5731
|
+
qualityCriteria: z19.array(qualityCriterionSchema).max(50).optional().describe("Per-collection accept gate rules. 'required' rule hard-blocks accepts on empty fields; 'min_length'/'pattern' rules warn. Pass an empty array to clear all criteria."),
|
|
5732
|
+
statusList: z19.array(statusListEntrySchema).max(50).optional().describe("Ordered status vocabulary: {label, category, archiveDefault?}[]. For update: always refused \u2014 the status words come from the platform catalog."),
|
|
5578
5733
|
// For label-*
|
|
5579
|
-
color:
|
|
5580
|
-
parentSlug:
|
|
5581
|
-
isGroup:
|
|
5582
|
-
order:
|
|
5583
|
-
entryId:
|
|
5734
|
+
color: z19.string().max(50).optional().describe("For label-create/label-update: hex color, e.g. '#ef4444'."),
|
|
5735
|
+
parentSlug: z19.string().max(200).optional().describe("For label-create: parent group slug for label hierarchy."),
|
|
5736
|
+
isGroup: z19.boolean().optional().describe("For label-create/label-update: true if this is a group container, not a taggable label."),
|
|
5737
|
+
order: z19.number().optional().describe("For label-create/label-update: sort order within its group."),
|
|
5738
|
+
entryId: z19.string().max(200).optional().describe("For label-apply/label-remove: entry ID.")
|
|
5584
5739
|
});
|
|
5585
|
-
var collectionsListVariant =
|
|
5586
|
-
var collectionsDescribeVariant =
|
|
5587
|
-
var collectionsUpdateVariant =
|
|
5588
|
-
action:
|
|
5589
|
-
slug:
|
|
5590
|
-
name:
|
|
5591
|
-
description:
|
|
5592
|
-
purpose:
|
|
5593
|
-
icon:
|
|
5594
|
-
navGroup:
|
|
5595
|
-
fields:
|
|
5596
|
-
axis:
|
|
5597
|
-
stageLabelMap:
|
|
5740
|
+
var collectionsListVariant = z19.object({ action: z19.literal("list") });
|
|
5741
|
+
var collectionsDescribeVariant = z19.object({ action: z19.literal("describe"), slug: z19.string().max(200) });
|
|
5742
|
+
var collectionsUpdateVariant = z19.object({
|
|
5743
|
+
action: z19.literal("update"),
|
|
5744
|
+
slug: z19.string().max(200),
|
|
5745
|
+
name: z19.string().max(ENTRY_NAME_MAX_CHARS).optional(),
|
|
5746
|
+
description: z19.string().max(2e4).optional(),
|
|
5747
|
+
purpose: z19.string().max(2e3).optional(),
|
|
5748
|
+
icon: z19.string().max(50).optional(),
|
|
5749
|
+
navGroup: z19.enum(["daily", "strategic", "governance", "reference", "collections"]).optional(),
|
|
5750
|
+
fields: z19.array(fieldSchema).optional(),
|
|
5751
|
+
axis: z19.enum(["work", "none", "pending"]).optional(),
|
|
5752
|
+
stageLabelMap: z19.record(z19.string(), z19.enum(["open", "in_progress", "done", "stopped", "tag"])).optional(),
|
|
5598
5753
|
// WP-640 SWEEP (P1): axis/stageLabelMap repair legacy custom collections — see collections.ts's updateCollection.
|
|
5599
|
-
defaultCanonicalKey:
|
|
5600
|
-
defaultWorkflowStatus:
|
|
5601
|
-
validWorkflowStatuses:
|
|
5602
|
-
classificationCheck:
|
|
5603
|
-
classificationPriority:
|
|
5604
|
-
qualityCriteria:
|
|
5605
|
-
statusList:
|
|
5754
|
+
defaultCanonicalKey: z19.string().max(200).optional(),
|
|
5755
|
+
defaultWorkflowStatus: z19.string().max(200).optional(),
|
|
5756
|
+
validWorkflowStatuses: z19.array(z19.string().max(200)).optional(),
|
|
5757
|
+
classificationCheck: z19.string().max(500).optional(),
|
|
5758
|
+
classificationPriority: z19.number().optional(),
|
|
5759
|
+
qualityCriteria: z19.array(qualityCriterionSchema).optional(),
|
|
5760
|
+
statusList: z19.array(statusListEntrySchema).optional()
|
|
5606
5761
|
});
|
|
5607
|
-
var collectionsAuditVariant =
|
|
5608
|
-
var collectionsExportVariant =
|
|
5609
|
-
var collectionsLabelListVariant =
|
|
5610
|
-
var collectionsLabelCreateVariant =
|
|
5611
|
-
action:
|
|
5612
|
-
slug:
|
|
5613
|
-
name:
|
|
5614
|
-
color:
|
|
5615
|
-
description:
|
|
5616
|
-
parentSlug:
|
|
5617
|
-
isGroup:
|
|
5618
|
-
order:
|
|
5762
|
+
var collectionsAuditVariant = z19.object({ action: z19.literal("audit") });
|
|
5763
|
+
var collectionsExportVariant = z19.object({ action: z19.literal("export") });
|
|
5764
|
+
var collectionsLabelListVariant = z19.object({ action: z19.literal("label-list") });
|
|
5765
|
+
var collectionsLabelCreateVariant = z19.object({
|
|
5766
|
+
action: z19.literal("label-create"),
|
|
5767
|
+
slug: z19.string().max(200),
|
|
5768
|
+
name: z19.string().max(ENTRY_NAME_MAX_CHARS),
|
|
5769
|
+
color: z19.string().max(50).optional(),
|
|
5770
|
+
description: z19.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
|
|
5771
|
+
parentSlug: z19.string().max(200).optional(),
|
|
5772
|
+
isGroup: z19.boolean().optional(),
|
|
5773
|
+
order: z19.number().optional()
|
|
5619
5774
|
});
|
|
5620
|
-
var collectionsLabelUpdateVariant =
|
|
5621
|
-
action:
|
|
5622
|
-
slug:
|
|
5623
|
-
name:
|
|
5624
|
-
color:
|
|
5625
|
-
description:
|
|
5626
|
-
isGroup:
|
|
5627
|
-
order:
|
|
5775
|
+
var collectionsLabelUpdateVariant = z19.object({
|
|
5776
|
+
action: z19.literal("label-update"),
|
|
5777
|
+
slug: z19.string().max(200),
|
|
5778
|
+
name: z19.string().max(ENTRY_NAME_MAX_CHARS).optional(),
|
|
5779
|
+
color: z19.string().max(50).optional(),
|
|
5780
|
+
description: z19.string().max(LABEL_DESCRIPTION_MAX_CHARS).optional(),
|
|
5781
|
+
isGroup: z19.boolean().optional(),
|
|
5782
|
+
order: z19.number().optional()
|
|
5628
5783
|
});
|
|
5629
|
-
var collectionsLabelDeleteVariant =
|
|
5630
|
-
var collectionsLabelApplyVariant =
|
|
5631
|
-
var collectionsLabelRemoveVariant =
|
|
5632
|
-
var collectionsActionUnion =
|
|
5784
|
+
var collectionsLabelDeleteVariant = z19.object({ action: z19.literal("label-delete"), slug: z19.string().max(200) });
|
|
5785
|
+
var collectionsLabelApplyVariant = z19.object({ action: z19.literal("label-apply"), slug: z19.string().max(200), entryId: z19.string().max(200) });
|
|
5786
|
+
var collectionsLabelRemoveVariant = z19.object({ action: z19.literal("label-remove"), slug: z19.string().max(200), entryId: z19.string().max(200) });
|
|
5787
|
+
var collectionsActionUnion = z19.discriminatedUnion("action", [
|
|
5633
5788
|
collectionsListVariant,
|
|
5634
5789
|
collectionsDescribeVariant,
|
|
5635
5790
|
collectionsUpdateVariant,
|
|
@@ -5937,7 +6092,7 @@ async function handleExport() {
|
|
|
5937
6092
|
}
|
|
5938
6093
|
|
|
5939
6094
|
// src/tools/orient.ts
|
|
5940
|
-
import { z as
|
|
6095
|
+
import { z as z20 } from "zod/v3";
|
|
5941
6096
|
|
|
5942
6097
|
// src/tools/planned-work.ts
|
|
5943
6098
|
var MORE_DRAFTS_LINE = "_More drafts exist than shown. `context action=list status=draft` lists more, but that list is capped as well; page with limit/cursor once context list supports it._";
|
|
@@ -7008,25 +7163,25 @@ async function markOrientedWithSnapshotFallback(agentSessionId, coherenceSnapsho
|
|
|
7008
7163
|
}
|
|
7009
7164
|
}
|
|
7010
7165
|
var ORIENT_ACTIONS = ["task"];
|
|
7011
|
-
var orientSchema =
|
|
7012
|
-
action:
|
|
7166
|
+
var orientSchema = z20.object({
|
|
7167
|
+
action: z20.enum(ORIENT_ACTIONS).optional().default("task").describe(
|
|
7013
7168
|
"'task': task-grounded context loader, the only action."
|
|
7014
7169
|
),
|
|
7015
|
-
mode:
|
|
7016
|
-
tier:
|
|
7170
|
+
mode: z20.enum(["full", "brief"]).optional().default("full").describe("For 'task': full = full context (default). brief = compact summary for mid-session re-orientation. Prefer using the `tier` param for depth control."),
|
|
7171
|
+
tier: z20.enum(["summary", "standard", "full"]).optional().describe(
|
|
7017
7172
|
"For 'task': payload depth. Defaults to summary (~10 KB) when task is provided; standard (~256 KB) when task is absent. Pass summary, standard, or full to override."
|
|
7018
7173
|
),
|
|
7019
|
-
task:
|
|
7174
|
+
task: z20.string().max(2e3).optional().describe(
|
|
7020
7175
|
"For 'task': natural-language task description for task-scoped context. When provided, orient returns scored, relevant entries for the task."
|
|
7021
7176
|
),
|
|
7022
7177
|
// D1d (WP-754/TASK-204): matches the server's StartupResolutionSignals shape; domain resolution (original purpose) is deleted, sole survivor is `context.served` telemetry.
|
|
7023
|
-
startupSignals:
|
|
7024
|
-
changedPaths:
|
|
7025
|
-
reviewedArtifactRefs:
|
|
7026
|
-
branchName:
|
|
7027
|
-
worktreeName:
|
|
7178
|
+
startupSignals: z20.object({
|
|
7179
|
+
changedPaths: z20.array(z20.string()).max(25).optional().describe("Paths changed in the current working tree, if known (e.g. from a prior git status/diff tool call)."),
|
|
7180
|
+
reviewedArtifactRefs: z20.array(z20.string()).max(25).optional().describe("Chain entry IDs the caller has already reviewed this session, if tracked."),
|
|
7181
|
+
branchName: z20.string().max(120).optional().describe("Current git branch name, if known."),
|
|
7182
|
+
worktreeName: z20.string().max(120).optional().describe("Current worktree/directory name, if known.")
|
|
7028
7183
|
}).optional().describe("For 'task': best-effort startup signals \u2014 changedPaths/reviewedArtifactRefs/branchName/worktreeName. All optional; omit fields you don't know."),
|
|
7029
|
-
invocationPath:
|
|
7184
|
+
invocationPath: z20.enum(["session-start", "session-close", "manual-orient", "handshake", "unknown"]).optional().describe("For 'task': how this orient was invoked. Defaults to 'manual-orient' (the direct `orient task=...` call shape) when omitted.")
|
|
7030
7185
|
});
|
|
7031
7186
|
function taskGroundingWarningLines(task, hasTaskGrounding = false) {
|
|
7032
7187
|
if (hasTaskGrounding) return [];
|
|
@@ -7700,7 +7855,7 @@ async function _handleOrient({ mode = "full", tier, task, startupSignals, invoca
|
|
|
7700
7855
|
}
|
|
7701
7856
|
|
|
7702
7857
|
// src/tools/workflows.ts
|
|
7703
|
-
import { z as
|
|
7858
|
+
import { z as z21 } from "zod/v3";
|
|
7704
7859
|
|
|
7705
7860
|
// src/workflows/descriptor.ts
|
|
7706
7861
|
function cloneWorkflowQuestion(question) {
|
|
@@ -8545,73 +8700,73 @@ function workflowRunOutputToText(output) {
|
|
|
8545
8700
|
|
|
8546
8701
|
// src/tools/workflows.ts
|
|
8547
8702
|
var WORKFLOWS_ACTIONS = ["list", "start", "checkpoint", "get-run"];
|
|
8548
|
-
var jsonValueSchema =
|
|
8549
|
-
() =>
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8703
|
+
var jsonValueSchema = z21.lazy(
|
|
8704
|
+
() => z21.union([
|
|
8705
|
+
z21.string(),
|
|
8706
|
+
z21.number(),
|
|
8707
|
+
z21.boolean(),
|
|
8708
|
+
z21.null(),
|
|
8709
|
+
z21.array(jsonValueSchema),
|
|
8710
|
+
z21.record(jsonValueSchema)
|
|
8556
8711
|
])
|
|
8557
8712
|
);
|
|
8558
|
-
var workflowRunOutputInputSchema =
|
|
8559
|
-
|
|
8560
|
-
format:
|
|
8561
|
-
value:
|
|
8713
|
+
var workflowRunOutputInputSchema = z21.union([
|
|
8714
|
+
z21.object({
|
|
8715
|
+
format: z21.literal("freetext"),
|
|
8716
|
+
value: z21.string()
|
|
8562
8717
|
}),
|
|
8563
|
-
|
|
8564
|
-
format:
|
|
8565
|
-
value:
|
|
8718
|
+
z21.object({
|
|
8719
|
+
format: z21.literal("list"),
|
|
8720
|
+
value: z21.array(z21.string())
|
|
8566
8721
|
}),
|
|
8567
|
-
|
|
8568
|
-
format:
|
|
8569
|
-
value:
|
|
8722
|
+
z21.object({
|
|
8723
|
+
format: z21.literal("choice"),
|
|
8724
|
+
value: z21.union([z21.string(), z21.array(z21.string())])
|
|
8570
8725
|
}),
|
|
8571
|
-
|
|
8572
|
-
format:
|
|
8726
|
+
z21.object({
|
|
8727
|
+
format: z21.literal("structured"),
|
|
8573
8728
|
value: jsonValueSchema
|
|
8574
8729
|
})
|
|
8575
8730
|
]);
|
|
8576
|
-
var workflowsSchema =
|
|
8577
|
-
action:
|
|
8731
|
+
var workflowsSchema = z21.object({
|
|
8732
|
+
action: z21.enum(WORKFLOWS_ACTIONS).describe(
|
|
8578
8733
|
"'list': browse available workflows. 'start': start or resume a workflow \u2014 returns first (or current) round and next-step checkpoint call. 'checkpoint': record round output or final summary. 'get-run': inspect a persisted workflow run."
|
|
8579
8734
|
),
|
|
8580
|
-
workflowId:
|
|
8581
|
-
runId:
|
|
8582
|
-
roundId:
|
|
8583
|
-
output:
|
|
8584
|
-
isFinal:
|
|
8585
|
-
restart:
|
|
8586
|
-
summaryName:
|
|
8587
|
-
summaryDescription:
|
|
8588
|
-
summaryEntryId:
|
|
8735
|
+
workflowId: z21.string().max(200).optional().describe("Workflow ID for start, checkpoint, or get-run, e.g. 'retro', 'implementation-review'"),
|
|
8736
|
+
runId: z21.string().max(200).optional().describe("Workflow run ID: for get-run, which run to load; for checkpoint, target this run (avoids session drift \u2014 pass runId from get-run)."),
|
|
8737
|
+
roundId: z21.string().max(200).optional().describe("Round ID for checkpoint, e.g. 'what-went-well'"),
|
|
8738
|
+
output: z21.union([z21.string(), workflowRunOutputInputSchema]).optional().describe("The round's output \u2014 either legacy synthesized text or a typed workflow run payload."),
|
|
8739
|
+
isFinal: z21.boolean().optional().describe("If true, finalize an existing durable workflow run from its terminal round and create the summary chain entry."),
|
|
8740
|
+
restart: z21.boolean().optional().describe("If true, start a new durable run from the workflow's first round in the current session."),
|
|
8741
|
+
summaryName: z21.string().max(ENTRY_NAME_MAX_CHARS).optional().describe("Optional name for final chain entry. If omitted, the workflow summary template is used."),
|
|
8742
|
+
summaryDescription: z21.string().max(ENTRY_BODY_MAX_CHARS).optional().describe("Optional override for the final chain entry description. Defaults to the final round output text."),
|
|
8743
|
+
summaryEntryId: z21.string().max(200).optional().describe("Link an existing entry as the run's summary instead of creating one. Used by facilitated workflows (e.g. shape) where the primary record is created by the specialized tool."),
|
|
8589
8744
|
// WP-513: team+role to create the finalize summary AS OWNER of (rung 2 only).
|
|
8590
|
-
ownerTeamEntryId:
|
|
8591
|
-
ownerRoleEntryId:
|
|
8745
|
+
ownerTeamEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning team (rung-2)."),
|
|
8746
|
+
ownerRoleEntryId: z21.string().max(200).optional().describe("For 'checkpoint' (isFinal): owning role (rung-2).")
|
|
8592
8747
|
});
|
|
8593
|
-
var workflowsListVariant =
|
|
8594
|
-
var workflowsGetRunVariant =
|
|
8595
|
-
action:
|
|
8596
|
-
runId:
|
|
8597
|
-
workflowId:
|
|
8748
|
+
var workflowsListVariant = z21.object({ action: z21.literal("list") });
|
|
8749
|
+
var workflowsGetRunVariant = z21.object({
|
|
8750
|
+
action: z21.literal("get-run"),
|
|
8751
|
+
runId: z21.string().max(200).optional(),
|
|
8752
|
+
workflowId: z21.string().max(200).optional()
|
|
8598
8753
|
});
|
|
8599
|
-
var workflowsStartVariant =
|
|
8600
|
-
var workflowsCheckpointVariant =
|
|
8601
|
-
action:
|
|
8602
|
-
workflowId:
|
|
8603
|
-
roundId:
|
|
8604
|
-
output:
|
|
8605
|
-
isFinal:
|
|
8606
|
-
restart:
|
|
8607
|
-
summaryName:
|
|
8608
|
-
summaryDescription:
|
|
8609
|
-
summaryEntryId:
|
|
8610
|
-
runId:
|
|
8611
|
-
ownerTeamEntryId:
|
|
8612
|
-
ownerRoleEntryId:
|
|
8754
|
+
var workflowsStartVariant = z21.object({ action: z21.literal("start"), workflowId: z21.string().max(200) });
|
|
8755
|
+
var workflowsCheckpointVariant = z21.object({
|
|
8756
|
+
action: z21.literal("checkpoint"),
|
|
8757
|
+
workflowId: z21.string().max(200),
|
|
8758
|
+
roundId: z21.string().max(200),
|
|
8759
|
+
output: z21.union([z21.string(), workflowRunOutputInputSchema]),
|
|
8760
|
+
isFinal: z21.boolean().optional(),
|
|
8761
|
+
restart: z21.boolean().optional(),
|
|
8762
|
+
summaryName: z21.string().max(ENTRY_NAME_MAX_CHARS).optional(),
|
|
8763
|
+
summaryDescription: z21.string().max(ENTRY_BODY_MAX_CHARS).optional(),
|
|
8764
|
+
summaryEntryId: z21.string().max(200).optional(),
|
|
8765
|
+
runId: z21.string().max(200).optional(),
|
|
8766
|
+
ownerTeamEntryId: z21.string().max(200).optional(),
|
|
8767
|
+
ownerRoleEntryId: z21.string().max(200).optional()
|
|
8613
8768
|
});
|
|
8614
|
-
var workflowsActionUnion =
|
|
8769
|
+
var workflowsActionUnion = z21.discriminatedUnion("action", [
|
|
8615
8770
|
workflowsListVariant,
|
|
8616
8771
|
workflowsGetRunVariant,
|
|
8617
8772
|
workflowsStartVariant,
|
|
@@ -9340,7 +9495,7 @@ function parseListOutput(output) {
|
|
|
9340
9495
|
}
|
|
9341
9496
|
|
|
9342
9497
|
// src/tools/quality.ts
|
|
9343
|
-
import { z as
|
|
9498
|
+
import { z as z22 } from "zod/v3";
|
|
9344
9499
|
|
|
9345
9500
|
// src/lib/spineVerdictRead.ts
|
|
9346
9501
|
function isRecord(value) {
|
|
@@ -9505,36 +9660,36 @@ async function handleSpineCheck(story, refresh = false) {
|
|
|
9505
9660
|
|
|
9506
9661
|
// src/tools/quality.ts
|
|
9507
9662
|
var QUALITY_ACTIONS = ["check", "re-evaluate", "verify-chain", "spine-check"];
|
|
9508
|
-
var qualitySchema =
|
|
9509
|
-
action:
|
|
9663
|
+
var qualitySchema = z22.object({
|
|
9664
|
+
action: z22.enum(QUALITY_ACTIONS).describe(
|
|
9510
9665
|
"'check': read the entry's server quality verdict (tier + criteria). 're-evaluate': trigger fresh evaluation. 'verify-chain': verify entries against the codebase (codeMapping drift, cross-references) \u2014 absorbs `verify`. 'spine-check': structural completeness of the purpose+vision+strategy spine \u2014 story:true also runs the on-demand one-story judgment."
|
|
9511
9666
|
),
|
|
9512
|
-
entryId:
|
|
9513
|
-
context:
|
|
9514
|
-
collection:
|
|
9515
|
-
mode:
|
|
9516
|
-
story:
|
|
9517
|
-
refresh:
|
|
9667
|
+
entryId: z22.string().max(200).optional().describe("For 'check'/'re-evaluate': entry ID, e.g. 'TEN-graph-db', '<PREFIX>-<n>'."),
|
|
9668
|
+
context: z22.enum(["capture", "commit", "review"]).default("review").optional().describe("For re-evaluate: evaluation context"),
|
|
9669
|
+
collection: z22.string().max(200).optional().describe("For 'verify-chain': collection slug to verify (default: glossary)."),
|
|
9670
|
+
mode: z22.enum(["report", "fix"]).optional().describe("For 'verify-chain': 'report' = read-only trust report (default). 'fix' = also update drifted codeMapping statuses."),
|
|
9671
|
+
story: z22.boolean().optional().describe("For 'spine-check': also run the on-demand one-story LLM judgment (never scheduled; result labelled [unvalidated])."),
|
|
9672
|
+
refresh: z22.boolean().optional().describe(
|
|
9518
9673
|
"For 'spine-check': force a new run even if a fresh verdict already exists. Default false \u2014 a plain call NEVER re-triggers work just to read the last result; it auto-schedules only when no run is already in flight AND the stored verdict is absent/stale/missing the requested story pass."
|
|
9519
9674
|
)
|
|
9520
9675
|
});
|
|
9521
|
-
var qualityCheckVariant =
|
|
9522
|
-
var qualityReEvaluateVariant =
|
|
9523
|
-
action:
|
|
9524
|
-
entryId:
|
|
9525
|
-
context:
|
|
9676
|
+
var qualityCheckVariant = z22.object({ action: z22.literal("check"), entryId: z22.string().max(200) });
|
|
9677
|
+
var qualityReEvaluateVariant = z22.object({
|
|
9678
|
+
action: z22.literal("re-evaluate"),
|
|
9679
|
+
entryId: z22.string().max(200),
|
|
9680
|
+
context: z22.enum(["capture", "commit", "review"]).optional().default("review")
|
|
9526
9681
|
});
|
|
9527
|
-
var qualityVerifyChainVariant =
|
|
9528
|
-
action:
|
|
9529
|
-
collection:
|
|
9530
|
-
mode:
|
|
9682
|
+
var qualityVerifyChainVariant = z22.object({
|
|
9683
|
+
action: z22.literal("verify-chain"),
|
|
9684
|
+
collection: z22.string().max(200).optional().default("glossary"),
|
|
9685
|
+
mode: z22.enum(["report", "fix"]).optional().default("report")
|
|
9531
9686
|
});
|
|
9532
|
-
var qualitySpineCheckVariant =
|
|
9533
|
-
action:
|
|
9534
|
-
story:
|
|
9535
|
-
refresh:
|
|
9687
|
+
var qualitySpineCheckVariant = z22.object({
|
|
9688
|
+
action: z22.literal("spine-check"),
|
|
9689
|
+
story: z22.boolean().optional().default(false),
|
|
9690
|
+
refresh: z22.boolean().optional().default(false)
|
|
9536
9691
|
});
|
|
9537
|
-
var qualityActionUnion =
|
|
9692
|
+
var qualityActionUnion = z22.discriminatedUnion("action", [
|
|
9538
9693
|
qualityCheckVariant,
|
|
9539
9694
|
qualityReEvaluateVariant,
|
|
9540
9695
|
qualityVerifyChainVariant,
|
|
@@ -9546,43 +9701,43 @@ var QUALITY_ACTION_SPECS = {
|
|
|
9546
9701
|
"verify-chain": { params: ["collection", "mode"], description: "All params optional; collection defaults to 'glossary'." },
|
|
9547
9702
|
"spine-check": { params: ["story", "refresh"], description: "All params optional; story and refresh default to false \u2014 a plain call never re-triggers work, it just reads back the latest verdict (auto-refreshing only when stale/absent)." }
|
|
9548
9703
|
};
|
|
9549
|
-
var qualityCheckOutputSchema =
|
|
9550
|
-
entryId:
|
|
9704
|
+
var qualityCheckOutputSchema = z22.object({
|
|
9705
|
+
entryId: z22.string(),
|
|
9551
9706
|
/** WP-480 S1: false = the ID does not resolve to an entry (typo/deleted) — distinct from "no verdict yet". */
|
|
9552
|
-
entryFound:
|
|
9553
|
-
hasVerdict:
|
|
9707
|
+
entryFound: z22.boolean().optional(),
|
|
9708
|
+
hasVerdict: z22.boolean(),
|
|
9554
9709
|
/** WP-480 S1: the verdict was judged against content the entry no longer has — re-evaluate for a current one. */
|
|
9555
|
-
stale:
|
|
9556
|
-
tier:
|
|
9557
|
-
passed:
|
|
9558
|
-
criteria:
|
|
9559
|
-
id:
|
|
9560
|
-
passed:
|
|
9561
|
-
hint:
|
|
9710
|
+
stale: z22.boolean().optional(),
|
|
9711
|
+
tier: z22.string().optional(),
|
|
9712
|
+
passed: z22.boolean().optional(),
|
|
9713
|
+
criteria: z22.array(z22.object({
|
|
9714
|
+
id: z22.string(),
|
|
9715
|
+
passed: z22.boolean(),
|
|
9716
|
+
hint: z22.string().optional()
|
|
9562
9717
|
}))
|
|
9563
9718
|
});
|
|
9564
|
-
var qualityReevaluateOutputSchema =
|
|
9565
|
-
entryId:
|
|
9566
|
-
context:
|
|
9567
|
-
score:
|
|
9568
|
-
maxScore:
|
|
9569
|
-
improved:
|
|
9719
|
+
var qualityReevaluateOutputSchema = z22.object({
|
|
9720
|
+
entryId: z22.string(),
|
|
9721
|
+
context: z22.string(),
|
|
9722
|
+
score: z22.number(),
|
|
9723
|
+
maxScore: z22.number(),
|
|
9724
|
+
improved: z22.boolean()
|
|
9570
9725
|
});
|
|
9571
|
-
var qualitySpineCheckOutputSchema =
|
|
9572
|
-
hasVerdict:
|
|
9573
|
-
noSpineEntries:
|
|
9574
|
-
structuralPassed:
|
|
9575
|
-
storyPassed:
|
|
9576
|
-
stale:
|
|
9726
|
+
var qualitySpineCheckOutputSchema = z22.object({
|
|
9727
|
+
hasVerdict: z22.boolean(),
|
|
9728
|
+
noSpineEntries: z22.boolean().optional(),
|
|
9729
|
+
structuralPassed: z22.boolean().optional(),
|
|
9730
|
+
storyPassed: z22.boolean().nullable().optional(),
|
|
9731
|
+
stale: z22.boolean().optional(),
|
|
9577
9732
|
// TASK-156: a capped membership scan must stay distinguishable from a complete one, and a
|
|
9578
9733
|
// malformed verdict needs its own discriminator — both were silently stripped before this.
|
|
9579
|
-
staleMemberIds:
|
|
9580
|
-
membershipTruncated:
|
|
9734
|
+
staleMemberIds: z22.array(z22.string()).optional(),
|
|
9735
|
+
membershipTruncated: z22.boolean().optional(),
|
|
9581
9736
|
// PRRT_kwDORS4ils6i_PVS: a KNOWN relations-fingerprint mismatch, distinct from "unknown" —
|
|
9582
9737
|
// without this, a detected topology change and an unverifiable legacy fingerprint were
|
|
9583
9738
|
// indistinguishable in structured output.
|
|
9584
|
-
relationsChanged:
|
|
9585
|
-
malformed:
|
|
9739
|
+
relationsChanged: z22.boolean().optional(),
|
|
9740
|
+
malformed: z22.boolean().optional()
|
|
9586
9741
|
});
|
|
9587
9742
|
function registerQualityTools(server) {
|
|
9588
9743
|
const qualityHandlers = {
|
|
@@ -9738,10 +9893,10 @@ async function handleReEvaluate(entryId, context) {
|
|
|
9738
9893
|
}
|
|
9739
9894
|
|
|
9740
9895
|
// src/tools/session.ts
|
|
9741
|
-
import { z as
|
|
9896
|
+
import { z as z25 } from "zod/v3";
|
|
9742
9897
|
|
|
9743
9898
|
// src/tools/wrapup.ts
|
|
9744
|
-
import { z as
|
|
9899
|
+
import { z as z23 } from "zod/v3";
|
|
9745
9900
|
|
|
9746
9901
|
// src/lib/compose-wrapup-view.ts
|
|
9747
9902
|
function toComposed(e) {
|
|
@@ -10029,8 +10184,8 @@ async function runWrapupCommitAll(data) {
|
|
|
10029
10184
|
overflowUnscanned
|
|
10030
10185
|
};
|
|
10031
10186
|
}
|
|
10032
|
-
var wrapupSchema =
|
|
10033
|
-
action:
|
|
10187
|
+
var wrapupSchema = z23.object({
|
|
10188
|
+
action: z23.enum(["review", "commit-all"]).optional().describe(
|
|
10034
10189
|
"Action to perform. 'review' (default) shows the wrapup summary. 'commit-all' accepts all uncommitted drafts; it writes no relations."
|
|
10035
10190
|
)
|
|
10036
10191
|
});
|
|
@@ -10123,26 +10278,26 @@ ${text}` : text;
|
|
|
10123
10278
|
}
|
|
10124
10279
|
|
|
10125
10280
|
// src/tools/facilitate.ts
|
|
10126
|
-
import { z as
|
|
10281
|
+
import { z as z24 } from "zod/v3";
|
|
10127
10282
|
var FACILITATE_ACTIONS = ["resume", "commit-constellation"];
|
|
10128
|
-
var coherencyAcknowledgementSchema =
|
|
10129
|
-
response:
|
|
10130
|
-
entryId:
|
|
10131
|
-
reason:
|
|
10132
|
-
subjectEntryId:
|
|
10283
|
+
var coherencyAcknowledgementSchema = z24.object({
|
|
10284
|
+
response: z24.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
10285
|
+
entryId: z24.string().max(200).optional().describe("Entry the acknowledgement links to (e.g. the strategic spine entry)."),
|
|
10286
|
+
reason: z24.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
10287
|
+
subjectEntryId: z24.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
10133
10288
|
});
|
|
10134
|
-
var facilitateSchema =
|
|
10135
|
-
action:
|
|
10289
|
+
var facilitateSchema = z24.object({
|
|
10290
|
+
action: z24.enum(FACILITATE_ACTIONS).describe(
|
|
10136
10291
|
"'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."
|
|
10137
10292
|
),
|
|
10138
|
-
betEntryId:
|
|
10139
|
-
operationId:
|
|
10293
|
+
betEntryId: z24.string().max(200).optional().describe("Bet entry ID. Required for both actions."),
|
|
10294
|
+
operationId: z24.string().max(200).optional().describe("Optional idempotency key for commit-constellation retries."),
|
|
10140
10295
|
// WP-465 slice ⑤: coherency retry controls for a COHERENCY_REFUSED constellation hold.
|
|
10141
10296
|
// Forwarded verbatim to agentKnowledge.facilitateEnvelope (validation lives at the gate).
|
|
10142
|
-
coherencyAcknowledgements:
|
|
10297
|
+
coherencyAcknowledgements: z24.array(coherencyAcknowledgementSchema).max(20).optional().describe(
|
|
10143
10298
|
"Per-offender acknowledgements to retry a constellation held under standard/strict coherency mode. Each: {subjectEntryId, response: 'linked' | 'accepted-fix' | 'diverged', entryId?, reason?}."
|
|
10144
10299
|
),
|
|
10145
|
-
steeringOverrideReason:
|
|
10300
|
+
steeringOverrideReason: z24.string().max(2e3).optional().describe(
|
|
10146
10301
|
"Typed override reason (>= 12 chars) to push a constellation past a coherency hold instead of acknowledging."
|
|
10147
10302
|
)
|
|
10148
10303
|
});
|
|
@@ -10487,44 +10642,44 @@ var SESSION_ACTIONS = [
|
|
|
10487
10642
|
"resume",
|
|
10488
10643
|
"commit-constellation"
|
|
10489
10644
|
];
|
|
10490
|
-
var coherencyAcknowledgementFlatSchema2 =
|
|
10491
|
-
response:
|
|
10492
|
-
entryId:
|
|
10493
|
-
reason:
|
|
10494
|
-
subjectEntryId:
|
|
10645
|
+
var coherencyAcknowledgementFlatSchema2 = z25.object({
|
|
10646
|
+
response: z25.string().max(200).describe("Acknowledgement response per offender: 'linked' | 'accepted-fix' | 'diverged'."),
|
|
10647
|
+
entryId: z25.string().max(200).optional().describe("Entry the acknowledgement links to."),
|
|
10648
|
+
reason: z25.string().max(2e3).optional().describe("Free-text justification, required for a 'diverged' response."),
|
|
10649
|
+
subjectEntryId: z25.string().max(200).optional().describe("The refused entry this acknowledgement answers.")
|
|
10495
10650
|
});
|
|
10496
|
-
var sessionSchema =
|
|
10497
|
-
action:
|
|
10651
|
+
var sessionSchema = z25.object({
|
|
10652
|
+
action: z25.enum(SESSION_ACTIONS).describe(
|
|
10498
10653
|
"'start': begin a tracked session. 'close': end the session and record activity. 'status': check current session state. 'wrapup-review': review uncommitted drafts before closing (absorbs session-wrapup action=review). 'wrapup-commit': accept all uncommitted drafts (absorbs session-wrapup action=commit-all). 'resume': load session state from an existing bet entry (absorbs facilitate action=resume). 'commit-constellation': atomically accept a bet and its linked drafts (absorbs facilitate action=commit-constellation)."
|
|
10499
10654
|
),
|
|
10500
|
-
betEntryId:
|
|
10501
|
-
operationId:
|
|
10502
|
-
coherencyAcknowledgements:
|
|
10655
|
+
betEntryId: z25.string().max(200).optional().describe("For 'resume'/'commit-constellation': bet entry ID. Required for both."),
|
|
10656
|
+
operationId: z25.string().max(200).optional().describe("For 'commit-constellation': optional idempotency key for retries."),
|
|
10657
|
+
coherencyAcknowledgements: z25.array(coherencyAcknowledgementFlatSchema2).max(20).optional().describe(
|
|
10503
10658
|
"For 'commit-constellation': per-offender acknowledgements to retry a constellation held under standard/strict coherency mode."
|
|
10504
10659
|
),
|
|
10505
|
-
steeringOverrideReason:
|
|
10660
|
+
steeringOverrideReason: z25.string().max(2e3).optional().describe(
|
|
10506
10661
|
"For 'commit-constellation': typed override reason (>= 12 chars) to push past a coherency hold instead of acknowledging."
|
|
10507
10662
|
),
|
|
10508
10663
|
// DEC-1715 (WP-753 O1a)
|
|
10509
|
-
role:
|
|
10664
|
+
role: z25.string().max(200).optional().describe(
|
|
10510
10665
|
"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."
|
|
10511
10666
|
)
|
|
10512
10667
|
});
|
|
10513
|
-
var sessionStartVariant =
|
|
10514
|
-
action:
|
|
10668
|
+
var sessionStartVariant = z25.object({
|
|
10669
|
+
action: z25.literal("start"),
|
|
10515
10670
|
// DEC-1715 (WP-753 O1a): the role to act as this session — only needed when the person holds
|
|
10516
10671
|
// more than one role; the server refuses and lists the choices when it's required and omitted.
|
|
10517
|
-
role:
|
|
10672
|
+
role: z25.string().max(200).optional().describe(
|
|
10518
10673
|
"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."
|
|
10519
10674
|
)
|
|
10520
10675
|
});
|
|
10521
|
-
var sessionCloseVariant =
|
|
10522
|
-
var sessionStatusVariant =
|
|
10523
|
-
var sessionWrapupReviewVariant =
|
|
10524
|
-
var sessionWrapupCommitVariant =
|
|
10525
|
-
var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action:
|
|
10526
|
-
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action:
|
|
10527
|
-
var sessionActionUnion =
|
|
10676
|
+
var sessionCloseVariant = z25.object({ action: z25.literal("close") });
|
|
10677
|
+
var sessionStatusVariant = z25.object({ action: z25.literal("status") });
|
|
10678
|
+
var sessionWrapupReviewVariant = z25.object({ action: z25.literal("wrapup-review") });
|
|
10679
|
+
var sessionWrapupCommitVariant = z25.object({ action: z25.literal("wrapup-commit") });
|
|
10680
|
+
var sessionResumeVariant = facilitateSchema.omit({ action: true }).extend({ action: z25.literal("resume") });
|
|
10681
|
+
var sessionCommitConstellationVariant = facilitateSchema.omit({ action: true }).extend({ action: z25.literal("commit-constellation") });
|
|
10682
|
+
var sessionActionUnion = z25.discriminatedUnion("action", [
|
|
10528
10683
|
sessionStartVariant,
|
|
10529
10684
|
sessionCloseVariant,
|
|
10530
10685
|
sessionStatusVariant,
|
|
@@ -10775,10 +10930,10 @@ async function handleStatus() {
|
|
|
10775
10930
|
}
|
|
10776
10931
|
|
|
10777
10932
|
// src/tools/workspace.ts
|
|
10778
|
-
import { z as
|
|
10933
|
+
import { z as z28 } from "zod/v3";
|
|
10779
10934
|
|
|
10780
10935
|
// src/tools/health.ts
|
|
10781
|
-
import { z as
|
|
10936
|
+
import { z as z26 } from "zod/v3";
|
|
10782
10937
|
|
|
10783
10938
|
// src/lib/auditView.ts
|
|
10784
10939
|
async function buildTenantAuditView(limit) {
|
|
@@ -11122,60 +11277,60 @@ ${logLines.join("\n")}${seamSummaryText}` }],
|
|
|
11122
11277
|
};
|
|
11123
11278
|
}
|
|
11124
11279
|
var HEALTH_ACTIONS = ["check", "whoami", "status", "audit", "self-test"];
|
|
11125
|
-
var healthSchema =
|
|
11126
|
-
action:
|
|
11280
|
+
var healthSchema = z26.object({
|
|
11281
|
+
action: z26.enum(HEALTH_ACTIONS).describe(
|
|
11127
11282
|
"'check': connectivity and workspace stats. 'whoami': session identity. 'status': workspace readiness. 'audit': session audit log. 'self-test': validate all tool schemas."
|
|
11128
11283
|
),
|
|
11129
|
-
limit:
|
|
11284
|
+
limit: z26.number().min(1).max(50).default(20).optional().describe("For audit: how many recent calls to show (max 50)")
|
|
11130
11285
|
});
|
|
11131
|
-
var healthCheckOutputSchema =
|
|
11132
|
-
healthy:
|
|
11133
|
-
collections:
|
|
11134
|
-
entries:
|
|
11135
|
-
latencyMs:
|
|
11136
|
-
workspace:
|
|
11286
|
+
var healthCheckOutputSchema = z26.object({
|
|
11287
|
+
healthy: z26.boolean(),
|
|
11288
|
+
collections: z26.number(),
|
|
11289
|
+
entries: z26.number(),
|
|
11290
|
+
latencyMs: z26.number(),
|
|
11291
|
+
workspace: z26.string()
|
|
11137
11292
|
});
|
|
11138
|
-
var organisationHealthSchema =
|
|
11139
|
-
reviewed:
|
|
11140
|
-
agreements:
|
|
11141
|
-
disagreements:
|
|
11142
|
-
abstentions:
|
|
11143
|
-
agreementRate:
|
|
11144
|
-
flags:
|
|
11293
|
+
var organisationHealthSchema = z26.object({
|
|
11294
|
+
reviewed: z26.number(),
|
|
11295
|
+
agreements: z26.number(),
|
|
11296
|
+
disagreements: z26.number(),
|
|
11297
|
+
abstentions: z26.number(),
|
|
11298
|
+
agreementRate: z26.number(),
|
|
11299
|
+
flags: z26.array(z26.object({ collection: z26.string(), count: z26.number(), suggestedCollection: z26.string() }))
|
|
11145
11300
|
});
|
|
11146
|
-
var healthStatusOutputSchema =
|
|
11147
|
-
sampleTruncated:
|
|
11148
|
-
activeEntries:
|
|
11149
|
-
totalRelations:
|
|
11150
|
-
orphanedEntries:
|
|
11151
|
-
checks:
|
|
11152
|
-
gaps:
|
|
11301
|
+
var healthStatusOutputSchema = z26.object({
|
|
11302
|
+
sampleTruncated: z26.boolean().nullable().optional(),
|
|
11303
|
+
activeEntries: z26.number(),
|
|
11304
|
+
totalRelations: z26.number(),
|
|
11305
|
+
orphanedEntries: z26.number(),
|
|
11306
|
+
checks: z26.array(z26.object({ label: z26.string(), passed: z26.boolean(), current: z26.number(), required: z26.number() })),
|
|
11307
|
+
gaps: z26.array(z26.object({ id: z26.string(), label: z26.string(), guidance: z26.string() })),
|
|
11153
11308
|
organisationHealth: organisationHealthSchema.optional()
|
|
11154
11309
|
});
|
|
11155
|
-
var healthAuditOutputSchema =
|
|
11156
|
-
totalCalls:
|
|
11157
|
-
calls:
|
|
11158
|
-
tool:
|
|
11159
|
-
action:
|
|
11160
|
-
timestamp:
|
|
11161
|
-
durationMs:
|
|
11310
|
+
var healthAuditOutputSchema = z26.object({
|
|
11311
|
+
totalCalls: z26.number(),
|
|
11312
|
+
calls: z26.array(z26.object({
|
|
11313
|
+
tool: z26.string(),
|
|
11314
|
+
action: z26.string().optional(),
|
|
11315
|
+
timestamp: z26.string(),
|
|
11316
|
+
durationMs: z26.number().optional()
|
|
11162
11317
|
}))
|
|
11163
11318
|
});
|
|
11164
|
-
var healthWhoamiOutputSchema =
|
|
11165
|
-
workspaceId:
|
|
11166
|
-
workspaceName:
|
|
11167
|
-
scope:
|
|
11168
|
-
sessionId:
|
|
11169
|
-
oriented:
|
|
11319
|
+
var healthWhoamiOutputSchema = z26.object({
|
|
11320
|
+
workspaceId: z26.string(),
|
|
11321
|
+
workspaceName: z26.string(),
|
|
11322
|
+
scope: z26.string(),
|
|
11323
|
+
sessionId: z26.union([z26.string(), z26.null()]),
|
|
11324
|
+
oriented: z26.boolean()
|
|
11170
11325
|
});
|
|
11171
|
-
var selfTestOutputSchema =
|
|
11172
|
-
passed:
|
|
11173
|
-
failed:
|
|
11174
|
-
total:
|
|
11175
|
-
results:
|
|
11176
|
-
tool:
|
|
11177
|
-
valid:
|
|
11178
|
-
error:
|
|
11326
|
+
var selfTestOutputSchema = z26.object({
|
|
11327
|
+
passed: z26.number(),
|
|
11328
|
+
failed: z26.number(),
|
|
11329
|
+
total: z26.number(),
|
|
11330
|
+
results: z26.array(z26.object({
|
|
11331
|
+
tool: z26.string(),
|
|
11332
|
+
valid: z26.boolean(),
|
|
11333
|
+
error: z26.string().optional()
|
|
11179
11334
|
}))
|
|
11180
11335
|
});
|
|
11181
11336
|
function handleSelfTest(server) {
|
|
@@ -11226,9 +11381,9 @@ function handleSelfTest(server) {
|
|
|
11226
11381
|
}
|
|
11227
11382
|
|
|
11228
11383
|
// src/tools/usage.ts
|
|
11229
|
-
import { z as
|
|
11230
|
-
var usageSummarySchema =
|
|
11231
|
-
periodDays:
|
|
11384
|
+
import { z as z27 } from "zod/v3";
|
|
11385
|
+
var usageSummarySchema = z27.object({
|
|
11386
|
+
periodDays: z27.number().min(1).max(90).optional().describe("Number of days to look back (default 30, max 90)")
|
|
11232
11387
|
});
|
|
11233
11388
|
async function handleUsageSummary(periodDays) {
|
|
11234
11389
|
const ws = await getWorkspaceContext();
|
|
@@ -11298,20 +11453,20 @@ var WORKSPACE_ACTIONS = [
|
|
|
11298
11453
|
"self-test",
|
|
11299
11454
|
"usage"
|
|
11300
11455
|
];
|
|
11301
|
-
var workspaceSchema =
|
|
11302
|
-
action:
|
|
11456
|
+
var workspaceSchema = z28.object({
|
|
11457
|
+
action: z28.enum(WORKSPACE_ACTIONS).describe(
|
|
11303
11458
|
"'check': connectivity and workspace stats (absorbs health action=check). 'whoami': session identity (absorbs health action=whoami). 'status': workspace readiness (absorbs health action=status). 'audit': session audit log (absorbs health action=audit). 'self-test': validate all tool schemas (absorbs health action=self-test). 'usage': LLM usage and cost summary (absorbs get-usage-summary)."
|
|
11304
11459
|
),
|
|
11305
|
-
limit:
|
|
11306
|
-
periodDays:
|
|
11460
|
+
limit: z28.number().min(1).max(50).optional().describe("For 'audit': how many recent calls to show (max 50, default 20)."),
|
|
11461
|
+
periodDays: z28.number().min(1).max(90).optional().describe("For 'usage': number of days to look back (default 30, max 90).")
|
|
11307
11462
|
});
|
|
11308
|
-
var workspaceCheckVariant =
|
|
11309
|
-
var workspaceWhoamiVariant =
|
|
11310
|
-
var workspaceStatusVariant =
|
|
11311
|
-
var workspaceAuditVariant =
|
|
11312
|
-
var workspaceSelfTestVariant =
|
|
11313
|
-
var workspaceUsageVariant =
|
|
11314
|
-
var workspaceActionUnion =
|
|
11463
|
+
var workspaceCheckVariant = z28.object({ action: z28.literal("check") });
|
|
11464
|
+
var workspaceWhoamiVariant = z28.object({ action: z28.literal("whoami") });
|
|
11465
|
+
var workspaceStatusVariant = z28.object({ action: z28.literal("status") });
|
|
11466
|
+
var workspaceAuditVariant = z28.object({ action: z28.literal("audit"), limit: z28.number().min(1).max(50).optional().default(20) });
|
|
11467
|
+
var workspaceSelfTestVariant = z28.object({ action: z28.literal("self-test") });
|
|
11468
|
+
var workspaceUsageVariant = z28.object({ action: z28.literal("usage"), periodDays: z28.number().min(1).max(90).optional() });
|
|
11469
|
+
var workspaceActionUnion = z28.discriminatedUnion("action", [
|
|
11315
11470
|
workspaceCheckVariant,
|
|
11316
11471
|
workspaceWhoamiVariant,
|
|
11317
11472
|
workspaceStatusVariant,
|
|
@@ -11357,7 +11512,7 @@ function registerWorkspaceTools(server) {
|
|
|
11357
11512
|
}
|
|
11358
11513
|
|
|
11359
11514
|
// src/tools/feedback.ts
|
|
11360
|
-
import { z as
|
|
11515
|
+
import { z as z29 } from "zod/v3";
|
|
11361
11516
|
|
|
11362
11517
|
// src/lib/productFeedbackConstants.ts
|
|
11363
11518
|
var PRODUCT_FEEDBACK_CATEGORIES = ["bug", "friction", "idea", "praise", "other"];
|
|
@@ -11368,37 +11523,37 @@ var VENDOR_SETTABLE_STATUSES = PRODUCT_FEEDBACK_STATUSES.filter(
|
|
|
11368
11523
|
|
|
11369
11524
|
// src/tools/feedback.ts
|
|
11370
11525
|
var actions = ["submit", "list", "queue", "note", "group", "status"];
|
|
11371
|
-
var category =
|
|
11372
|
-
var status =
|
|
11373
|
-
var vendorStatus =
|
|
11526
|
+
var category = z29.enum(PRODUCT_FEEDBACK_CATEGORIES);
|
|
11527
|
+
var status = z29.enum(PRODUCT_FEEDBACK_STATUSES);
|
|
11528
|
+
var vendorStatus = z29.enum(VENDOR_SETTABLE_STATUSES);
|
|
11374
11529
|
var MESSAGE_DISPLAY_LIMIT = 1e3;
|
|
11375
11530
|
var FULL_MESSAGE_MAX_LIMIT = 5;
|
|
11376
|
-
var feedbackSchema =
|
|
11377
|
-
action:
|
|
11378
|
-
message:
|
|
11531
|
+
var feedbackSchema = z29.object({
|
|
11532
|
+
action: z29.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."),
|
|
11533
|
+
message: z29.string().max(1e4).optional().describe("Required for submit: the product feedback text (max 10,000 characters)."),
|
|
11379
11534
|
category: category.optional().describe("Submit/queue category; submit defaults to other."),
|
|
11380
|
-
command:
|
|
11381
|
-
route:
|
|
11382
|
-
client:
|
|
11383
|
-
feedbackId:
|
|
11384
|
-
feedbackIds:
|
|
11385
|
-
note:
|
|
11535
|
+
command: z29.string().max(1e3).optional().describe("Optional submit command context; argument values are scrubbed server-side."),
|
|
11536
|
+
route: z29.string().max(500).optional().describe("Optional submit route context."),
|
|
11537
|
+
client: z29.string().max(100).optional().describe("Optional submit client label."),
|
|
11538
|
+
feedbackId: z29.string().max(200).optional().describe("Required for note/status: target feedback ID."),
|
|
11539
|
+
feedbackIds: z29.array(z29.string().max(200)).max(100).optional().describe("Required for group: 1\u2013100 target feedback IDs."),
|
|
11540
|
+
note: z29.string().max(4e3).optional().describe("Required for note: replacement triage note (max 4,000 characters)."),
|
|
11386
11541
|
status: status.optional().describe("list/queue filter (any status, including 'screening'); the status action's required target value excludes 'screening' (system-only)."),
|
|
11387
|
-
groupId:
|
|
11388
|
-
workspaceId:
|
|
11389
|
-
since:
|
|
11390
|
-
before:
|
|
11391
|
-
limit:
|
|
11392
|
-
cursor:
|
|
11393
|
-
full:
|
|
11542
|
+
groupId: z29.string().min(1).max(200).nullable().optional().describe("Group filter, or required group destination; null explicitly clears grouping."),
|
|
11543
|
+
workspaceId: z29.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."),
|
|
11544
|
+
since: z29.number().optional().describe("Queue-only lower createdAt window bound (inclusive) in epoch milliseconds."),
|
|
11545
|
+
before: z29.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."),
|
|
11546
|
+
limit: z29.number().int().min(1).max(100).optional().describe("list/queue row limit, default 50, maximum 100."),
|
|
11547
|
+
cursor: z29.string().max(2e3).optional().describe("Opaque pagination cursor from a previous list/queue response (continueCursor); omit for the first page."),
|
|
11548
|
+
full: z29.boolean().optional().describe(`list/queue only: return untruncated messages; allowed only when limit <= ${FULL_MESSAGE_MAX_LIMIT}.`)
|
|
11394
11549
|
});
|
|
11395
|
-
var union =
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
|
|
11401
|
-
|
|
11550
|
+
var union = z29.discriminatedUnion("action", [
|
|
11551
|
+
z29.object({ action: z29.literal("submit"), message: z29.string().min(1).max(1e4), category: category.optional(), command: z29.string().max(1e3).optional(), route: z29.string().max(500).optional(), client: z29.string().max(100).optional() }),
|
|
11552
|
+
z29.object({ action: z29.literal("list"), status: status.optional(), limit: z29.number().int().min(1).max(100).optional(), cursor: z29.string().max(2e3).optional(), full: z29.boolean().optional() }),
|
|
11553
|
+
z29.object({ action: z29.literal("queue"), status: status.optional(), category: category.optional(), groupId: z29.string().min(1).max(200).optional(), workspaceId: z29.string().max(200).optional(), since: z29.number().optional(), before: z29.number().optional(), limit: z29.number().int().min(1).max(100).optional(), cursor: z29.string().max(2e3).optional(), full: z29.boolean().optional() }),
|
|
11554
|
+
z29.object({ action: z29.literal("note"), feedbackId: z29.string().min(1).max(200), note: z29.string().max(4e3) }),
|
|
11555
|
+
z29.object({ action: z29.literal("group"), feedbackIds: z29.array(z29.string().min(1).max(200)).min(1).max(100), groupId: z29.string().min(1).max(200).nullable() }),
|
|
11556
|
+
z29.object({ action: z29.literal("status"), feedbackId: z29.string().min(1).max(200), status: vendorStatus })
|
|
11402
11557
|
]);
|
|
11403
11558
|
var specs = {
|
|
11404
11559
|
submit: { params: ["message", "category", "command", "route", "client"], description: "message is required; category defaults to other." },
|
|
@@ -11525,34 +11680,34 @@ function registerFeedbackTool(server) {
|
|
|
11525
11680
|
}
|
|
11526
11681
|
|
|
11527
11682
|
// src/tools/shape.ts
|
|
11528
|
-
import { z as
|
|
11683
|
+
import { z as z30 } from "zod/v3";
|
|
11529
11684
|
var SHAPE_ACTIONS = ["list", "show", "agree", "dismiss"];
|
|
11530
11685
|
var LIST_DISPOSITIONS = ["pending", "agreed", "dismissed", "expired"];
|
|
11531
11686
|
var LIST_OUTCOMES = ["not_candidate", "atomic", "compound", "unavailable"];
|
|
11532
|
-
var shapeSchema =
|
|
11533
|
-
action:
|
|
11687
|
+
var shapeSchema = z30.object({
|
|
11688
|
+
action: z30.enum(SHAPE_ACTIONS).describe(
|
|
11534
11689
|
"'list': list shape advisories for this workspace, latest per subject. 'show': show one shape advisory by id. 'agree': agree with a compound advisory's split verdict. 'dismiss': dismiss a compound advisory's split verdict."
|
|
11535
11690
|
),
|
|
11536
|
-
disposition:
|
|
11691
|
+
disposition: z30.enum(LIST_DISPOSITIONS).optional().describe(
|
|
11537
11692
|
"For 'list': filter by disposition. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
11538
11693
|
),
|
|
11539
|
-
outcome:
|
|
11694
|
+
outcome: z30.enum(LIST_OUTCOMES).optional().describe(
|
|
11540
11695
|
"For 'list': filter by outcome. Omitting both disposition and outcome defaults to the actionable set (disposition:pending, outcome:compound)."
|
|
11541
11696
|
),
|
|
11542
|
-
limit:
|
|
11543
|
-
rowId:
|
|
11544
|
-
reason:
|
|
11697
|
+
limit: z30.number().min(1).max(200).optional().describe("For 'list': max rows (default 50, max 200)."),
|
|
11698
|
+
rowId: z30.string().max(200).optional().describe("For 'show'/'agree'/'dismiss': the advisory row id."),
|
|
11699
|
+
reason: z30.string().max(1e3).optional().describe("For 'agree'/'dismiss': optional reason (capped at 1000 chars).")
|
|
11545
11700
|
});
|
|
11546
|
-
var shapeListVariant =
|
|
11547
|
-
action:
|
|
11548
|
-
disposition:
|
|
11549
|
-
outcome:
|
|
11550
|
-
limit:
|
|
11701
|
+
var shapeListVariant = z30.object({
|
|
11702
|
+
action: z30.literal("list"),
|
|
11703
|
+
disposition: z30.enum(LIST_DISPOSITIONS).optional(),
|
|
11704
|
+
outcome: z30.enum(LIST_OUTCOMES).optional(),
|
|
11705
|
+
limit: z30.number().min(1).max(200).optional()
|
|
11551
11706
|
});
|
|
11552
|
-
var shapeShowVariant =
|
|
11553
|
-
var shapeAgreeVariant =
|
|
11554
|
-
var shapeDismissVariant =
|
|
11555
|
-
var shapeActionUnion =
|
|
11707
|
+
var shapeShowVariant = z30.object({ action: z30.literal("show"), rowId: z30.string().max(200) });
|
|
11708
|
+
var shapeAgreeVariant = z30.object({ action: z30.literal("agree"), rowId: z30.string().max(200), reason: z30.string().max(1e3).optional() });
|
|
11709
|
+
var shapeDismissVariant = z30.object({ action: z30.literal("dismiss"), rowId: z30.string().max(200), reason: z30.string().max(1e3).optional() });
|
|
11710
|
+
var shapeActionUnion = z30.discriminatedUnion("action", [
|
|
11556
11711
|
shapeListVariant,
|
|
11557
11712
|
shapeShowVariant,
|
|
11558
11713
|
shapeAgreeVariant,
|
|
@@ -11698,26 +11853,26 @@ function registerShapeTools(server) {
|
|
|
11698
11853
|
}
|
|
11699
11854
|
|
|
11700
11855
|
// src/tools/question.ts
|
|
11701
|
-
import { z as
|
|
11856
|
+
import { z as z31 } from "zod/v3";
|
|
11702
11857
|
var QUESTION_ACTIONS = ["create", "assign", "answer", "force-close", "list"];
|
|
11703
|
-
var questionSchema =
|
|
11704
|
-
action:
|
|
11858
|
+
var questionSchema = z31.object({
|
|
11859
|
+
action: z31.enum(QUESTION_ACTIONS).describe(
|
|
11705
11860
|
"'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)."
|
|
11706
11861
|
),
|
|
11707
|
-
entryId:
|
|
11708
|
-
text:
|
|
11709
|
-
blocks:
|
|
11710
|
-
toRole:
|
|
11711
|
-
reason:
|
|
11712
|
-
answerEntryId:
|
|
11713
|
-
mine:
|
|
11862
|
+
entryId: z31.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'."),
|
|
11863
|
+
text: z31.string().max(5e3).optional().describe("'create': the question text. 'answer': the answer text (mutually exclusive with answerEntryId, max 2000 chars)."),
|
|
11864
|
+
blocks: z31.array(z31.string().max(200)).max(50).optional().describe("'create': entry ids this question is blocking (repeatable)."),
|
|
11865
|
+
toRole: z31.string().max(200).optional().describe("'assign': reassign to this role (human ROL-nnn form or a raw entry id) \u2014 required."),
|
|
11866
|
+
reason: z31.string().max(2e3).optional().describe("'force-close': required reason."),
|
|
11867
|
+
answerEntryId: z31.string().max(200).optional().describe("'answer': point at an already-written entry instead of supplying text (mutually exclusive with text)."),
|
|
11868
|
+
mine: z31.boolean().optional().describe("'list': true for arm C (every question YOU asked, every status). Omit/false for the ack-gate view (what you owe).")
|
|
11714
11869
|
});
|
|
11715
|
-
var createVariant =
|
|
11716
|
-
var assignVariant =
|
|
11717
|
-
var answerVariant =
|
|
11718
|
-
var forceCloseVariant =
|
|
11719
|
-
var listVariant =
|
|
11720
|
-
var questionActionUnion =
|
|
11870
|
+
var createVariant = z31.object({ action: z31.literal("create"), text: z31.string().min(1).max(5e3), blocks: z31.array(z31.string().max(200)).max(50).optional() });
|
|
11871
|
+
var assignVariant = z31.object({ action: z31.literal("assign"), entryId: z31.string().max(200), toRole: z31.string().max(200).min(1) });
|
|
11872
|
+
var answerVariant = z31.object({ action: z31.literal("answer"), entryId: z31.string().max(200), text: z31.string().max(2e3).optional(), answerEntryId: z31.string().max(200).optional() });
|
|
11873
|
+
var forceCloseVariant = z31.object({ action: z31.literal("force-close"), entryId: z31.string().max(200), reason: z31.string().min(1).max(2e3) });
|
|
11874
|
+
var listVariant = z31.object({ action: z31.literal("list"), mine: z31.boolean().optional() });
|
|
11875
|
+
var questionActionUnion = z31.discriminatedUnion("action", [
|
|
11721
11876
|
createVariant,
|
|
11722
11877
|
assignVariant,
|
|
11723
11878
|
answerVariant,
|
|
@@ -11871,68 +12026,47 @@ function registerQuestionTools(server) {
|
|
|
11871
12026
|
}
|
|
11872
12027
|
|
|
11873
12028
|
// src/tools/role.ts
|
|
11874
|
-
import { z as
|
|
11875
|
-
|
|
11876
|
-
// src/lib/seatSentence.ts
|
|
11877
|
-
function formatSeatSentence(action, reply, clean) {
|
|
11878
|
-
if (reply.outcome === "refused") {
|
|
11879
|
-
return `Refused: ${reply.refusal?.reason ?? reply.refusal?.code ?? "not allowed"}${reply.refusal?.requiredAction ? ` ${reply.refusal.requiredAction}` : ""}`;
|
|
11880
|
-
}
|
|
11881
|
-
const who = `${clean(reply.person ?? "")}${reply.personStatus && reply.personStatus !== "active" ? ` (${clean(reply.personStatus)})` : ""}`;
|
|
11882
|
-
const roleLabel2 = `${clean(reply.roleName ?? "")} (${reply.role ?? ""})`;
|
|
11883
|
-
const teamLabel = clean(reply.teamName ?? "");
|
|
11884
|
-
if (action === "seat") {
|
|
11885
|
-
const id = reply.personId ? ` [${reply.personId}]` : "";
|
|
11886
|
-
return `${reply.created ? "Seated" : "Confirmed"} ${who}${id} as ${roleLabel2} in ${teamLabel}.`;
|
|
11887
|
-
}
|
|
11888
|
-
return reply.removed ? `Unseated ${who} from ${roleLabel2} in ${teamLabel}.` : `${who} did not hold ${roleLabel2} in ${teamLabel}; nothing changed.`;
|
|
11889
|
-
}
|
|
11890
|
-
function formatInviteSentence(reply, clean) {
|
|
11891
|
-
const who = `${clean(reply.person)} [${reply.personId}]`;
|
|
11892
|
-
return reply.inPlace ? `Invited ${who} at ${clean(reply.email)}; they keep every role they already hold.` : `Invited ${who} at ${clean(reply.email)} as a new person.`;
|
|
11893
|
-
}
|
|
11894
|
-
|
|
11895
|
-
// src/tools/role.ts
|
|
12029
|
+
import { z as z32 } from "zod/v3";
|
|
11896
12030
|
var ROLE_ACTIONS = ["accountable", "seat", "unseat"];
|
|
11897
|
-
var roleSchema =
|
|
11898
|
-
action:
|
|
12031
|
+
var roleSchema = z32.object({
|
|
12032
|
+
action: z32.enum(ROLE_ACTIONS).describe(
|
|
11899
12033
|
"'accountable': what this role owns (explicit), reports on (reporting), and \u2014 not yet computed \u2014 inherits via Team-Lead vacancy coverage. 'seat': put a person in this role. 'unseat': take this role from a person."
|
|
11900
12034
|
),
|
|
11901
|
-
roleId:
|
|
11902
|
-
canonicalKey:
|
|
11903
|
-
limit:
|
|
11904
|
-
cursor:
|
|
11905
|
-
person:
|
|
12035
|
+
roleId: z32.string().max(200).optional().describe("The role, by the human chain id `chain.getEntry` or `pb get` would print for it, or a raw entry id."),
|
|
12036
|
+
canonicalKey: z32.string().max(200).optional().describe("'accountable': narrow to one kind (e.g. objective, key_result, tension)."),
|
|
12037
|
+
limit: z32.number().int().positive().max(200).optional().describe("'accountable': max explicit-list rows per page (default and maximum 200)."),
|
|
12038
|
+
cursor: z32.number().optional().describe("'accountable': continue the explicit list from an earlier truncated page's nextCursor."),
|
|
12039
|
+
person: z32.string().max(200).optional().describe(
|
|
11906
12040
|
"'seat' / 'unseat': an existing person, by person id or exact email. For 'seat', give this or newPersonName, not both."
|
|
11907
12041
|
),
|
|
11908
|
-
newPersonName:
|
|
12042
|
+
newPersonName: z32.string().max(120).optional().describe(
|
|
11909
12043
|
"'seat': the name of a person who has no login yet; a placeholder person is created once and reused for the same exact name. Refused when the name belongs to someone with an account."
|
|
11910
12044
|
),
|
|
11911
|
-
teamId:
|
|
12045
|
+
teamId: z32.string().max(200).optional().describe(
|
|
11912
12046
|
"'seat' / 'unseat': the team, by chain id or entry id. Only needed for Team Lead, which lives in every team; any other role is seated in its home team."
|
|
11913
12047
|
)
|
|
11914
12048
|
});
|
|
11915
|
-
var accountableVariant =
|
|
11916
|
-
action:
|
|
11917
|
-
roleId:
|
|
11918
|
-
canonicalKey:
|
|
11919
|
-
limit:
|
|
11920
|
-
cursor:
|
|
12049
|
+
var accountableVariant = z32.object({
|
|
12050
|
+
action: z32.literal("accountable"),
|
|
12051
|
+
roleId: z32.string().max(200),
|
|
12052
|
+
canonicalKey: z32.string().max(200).optional(),
|
|
12053
|
+
limit: z32.number().int().positive().max(200).optional(),
|
|
12054
|
+
cursor: z32.number().optional()
|
|
11921
12055
|
});
|
|
11922
|
-
var seatVariant =
|
|
11923
|
-
action:
|
|
11924
|
-
roleId:
|
|
11925
|
-
person:
|
|
11926
|
-
newPersonName:
|
|
11927
|
-
teamId:
|
|
12056
|
+
var seatVariant = z32.object({
|
|
12057
|
+
action: z32.literal("seat"),
|
|
12058
|
+
roleId: z32.string().max(200),
|
|
12059
|
+
person: z32.string().max(200).optional(),
|
|
12060
|
+
newPersonName: z32.string().max(120).optional(),
|
|
12061
|
+
teamId: z32.string().max(200).optional()
|
|
11928
12062
|
});
|
|
11929
|
-
var unseatVariant =
|
|
11930
|
-
action:
|
|
11931
|
-
roleId:
|
|
11932
|
-
person:
|
|
11933
|
-
teamId:
|
|
12063
|
+
var unseatVariant = z32.object({
|
|
12064
|
+
action: z32.literal("unseat"),
|
|
12065
|
+
roleId: z32.string().max(200),
|
|
12066
|
+
person: z32.string().max(200),
|
|
12067
|
+
teamId: z32.string().max(200).optional()
|
|
11934
12068
|
});
|
|
11935
|
-
var roleActionUnion =
|
|
12069
|
+
var roleActionUnion = z32.discriminatedUnion("action", [accountableVariant, seatVariant, unseatVariant]);
|
|
11936
12070
|
var ROLE_ACTION_SPECS = {
|
|
11937
12071
|
accountable: { params: ["roleId", "canonicalKey", "limit", "cursor"], description: "roleId is required; canonicalKey/limit/cursor are optional." },
|
|
11938
12072
|
seat: { params: ["roleId", "person", "newPersonName", "teamId"], description: "roleId is required, plus exactly one of person or newPersonName; teamId only for Team Lead." },
|
|
@@ -12059,117 +12193,6 @@ function registerRoleTools(server) {
|
|
|
12059
12193
|
);
|
|
12060
12194
|
}
|
|
12061
12195
|
|
|
12062
|
-
// src/tools/people.ts
|
|
12063
|
-
import { z as z32 } from "zod/v3";
|
|
12064
|
-
var PEOPLE_ACTIONS = ["invite", "remove"];
|
|
12065
|
-
var peopleSchema = z32.object({
|
|
12066
|
-
action: z32.enum(PEOPLE_ACTIONS).describe("'invite': send a login link by email. 'remove': take a person out of a team."),
|
|
12067
|
-
email: z32.string().max(320).optional().describe("'invite': where the login link goes. Required for 'invite'."),
|
|
12068
|
-
person: z32.string().max(320).optional().describe(
|
|
12069
|
-
"'invite': a placeholder's person id, instead of newPersonName. 'remove': the person, by person id or exact email."
|
|
12070
|
-
),
|
|
12071
|
-
newPersonName: z32.string().max(120).optional().describe("'invite': the name of a new person to invite, instead of person."),
|
|
12072
|
-
teamId: z32.string().max(200).optional().describe("'remove': the team, by chain id or entry id. Required for 'remove'.")
|
|
12073
|
-
});
|
|
12074
|
-
var inviteVariant = z32.object({
|
|
12075
|
-
action: z32.literal("invite"),
|
|
12076
|
-
email: z32.string().max(320),
|
|
12077
|
-
person: z32.string().max(320).optional(),
|
|
12078
|
-
newPersonName: z32.string().max(120).optional()
|
|
12079
|
-
});
|
|
12080
|
-
var removeVariant = z32.object({
|
|
12081
|
-
action: z32.literal("remove"),
|
|
12082
|
-
person: z32.string().max(320),
|
|
12083
|
-
teamId: z32.string().max(200)
|
|
12084
|
-
});
|
|
12085
|
-
var peopleActionUnion = z32.discriminatedUnion("action", [inviteVariant, removeVariant]);
|
|
12086
|
-
var PEOPLE_ACTION_SPECS = {
|
|
12087
|
-
invite: { params: ["email", "person", "newPersonName"], description: "email is required, plus exactly one of person (a placeholder's id) or newPersonName." },
|
|
12088
|
-
remove: { params: ["person", "teamId"], description: "person and teamId are required." }
|
|
12089
|
-
};
|
|
12090
|
-
async function handlePeopleInvite(email, person, newPersonName) {
|
|
12091
|
-
const params = { email, person, newPersonName };
|
|
12092
|
-
try {
|
|
12093
|
-
requireWriteAccess();
|
|
12094
|
-
const result2 = await kernelMutation("people.invite", {
|
|
12095
|
-
email,
|
|
12096
|
-
targetPersonId: person,
|
|
12097
|
-
displayName: newPersonName,
|
|
12098
|
-
sessionId: getAgentSessionId()
|
|
12099
|
-
});
|
|
12100
|
-
const message = formatInviteSentence(result2, sanitizeSingleLineField);
|
|
12101
|
-
return successResult(message, message, result2);
|
|
12102
|
-
} catch (err) {
|
|
12103
|
-
return peopleErrorResult(err, "invite", params);
|
|
12104
|
-
}
|
|
12105
|
-
}
|
|
12106
|
-
async function handlePeopleRemove(person, teamId) {
|
|
12107
|
-
try {
|
|
12108
|
-
requireWriteAccess();
|
|
12109
|
-
const result2 = await kernelMutation("organisation.removeMembership", {
|
|
12110
|
-
targetPersonRef: person,
|
|
12111
|
-
teamRef: teamId,
|
|
12112
|
-
sessionId: getAgentSessionId()
|
|
12113
|
-
});
|
|
12114
|
-
if (result2.outcome === "refused") {
|
|
12115
|
-
const { reason, requiredAction } = result2.refusal;
|
|
12116
|
-
const message2 = `Refused: ${reason}${requiredAction ? ` ${requiredAction}` : ""}`;
|
|
12117
|
-
return failureResult(
|
|
12118
|
-
message2,
|
|
12119
|
-
"PERMISSION_DENIED",
|
|
12120
|
-
message2,
|
|
12121
|
-
requiredAction ?? "Ask the team's Team Lead to remove them.",
|
|
12122
|
-
void 0,
|
|
12123
|
-
result2
|
|
12124
|
-
);
|
|
12125
|
-
}
|
|
12126
|
-
const who = sanitizeSingleLineField(result2.person);
|
|
12127
|
-
const message = result2.removed ? `Removed ${who} from ${result2.team}.` : `${who} was not assigned to ${result2.team}; nothing changed.`;
|
|
12128
|
-
return successResult(message, message, result2);
|
|
12129
|
-
} catch (err) {
|
|
12130
|
-
return peopleErrorResult(err, "remove", { person, teamId });
|
|
12131
|
-
}
|
|
12132
|
-
}
|
|
12133
|
-
function peopleErrorResult(err, action, params) {
|
|
12134
|
-
const classified = classifyError(err);
|
|
12135
|
-
const definedParams = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== void 0));
|
|
12136
|
-
const fallbackActions = retryIsFutile(classified.code) ? void 0 : [{ tool: "people", description: `Retry ${action}`, parameters: { action, ...definedParams } }];
|
|
12137
|
-
return failureResult(
|
|
12138
|
-
classified.message,
|
|
12139
|
-
classified.code,
|
|
12140
|
-
classified.message,
|
|
12141
|
-
classified.recovery ?? `Fix the input the message names and call action='${action}' again.`,
|
|
12142
|
-
classified.availableActions ?? fallbackActions,
|
|
12143
|
-
classified.diagnostics
|
|
12144
|
-
);
|
|
12145
|
-
}
|
|
12146
|
-
function registerPeopleTools(server) {
|
|
12147
|
-
const peopleHandlers = {
|
|
12148
|
-
invite: (data) => handlePeopleInvite(data.email, data.person, data.newPersonName),
|
|
12149
|
-
remove: (data) => handlePeopleRemove(data.person, data.teamId)
|
|
12150
|
-
};
|
|
12151
|
-
server.registerTool(
|
|
12152
|
-
"people",
|
|
12153
|
-
{
|
|
12154
|
-
title: "People",
|
|
12155
|
-
description: "People in the workspace. Two actions:\n\n- **invite**: send a login link to `email`. Give `person` (a placeholder's id, as `role action=seat` printed it) to invite that person in place: they keep every role they hold. Or give `newPersonName` to invite someone new. A person who already has a login or an invite is refused. Needs a workspace owner or admin.\n- **remove**: take `person` out of the team `teamId`; every role they hold there goes with it. To take one role, use `role action=unseat`. Needs the team's Team Lead.",
|
|
12156
|
-
inputSchema: peopleSchema,
|
|
12157
|
-
// TASK-677 (DEC-1981, DEC-74): invite emails an address outside the workspace (open world);
|
|
12158
|
-
// remove deletes a membership row and every role on it (destructive); neither is idempotent.
|
|
12159
|
-
annotations: { readOnlyHint: false, idempotentHint: false, destructiveHint: true, openWorldHint: true }
|
|
12160
|
-
},
|
|
12161
|
-
thinWrapper(async (args) => {
|
|
12162
|
-
const parsed = parseOrFail(peopleSchema, args);
|
|
12163
|
-
if (!parsed.ok) return parsed.result;
|
|
12164
|
-
const { action } = parsed.data;
|
|
12165
|
-
return runWithToolContext(
|
|
12166
|
-
{ tool: "people", action },
|
|
12167
|
-
() => dispatchDiscriminated("people", peopleActionUnion, parsed.data, PEOPLE_ACTION_SPECS, peopleHandlers)
|
|
12168
|
-
);
|
|
12169
|
-
})
|
|
12170
|
-
);
|
|
12171
|
-
}
|
|
12172
|
-
|
|
12173
12196
|
// src/tools/outcome.ts
|
|
12174
12197
|
import { z as z33 } from "zod/v3";
|
|
12175
12198
|
var OUTCOME_ACTIONS = ["record", "list", "show"];
|
|
@@ -13038,4 +13061,4 @@ export {
|
|
|
13038
13061
|
createProductBrainServer,
|
|
13039
13062
|
initFeatureFlags
|
|
13040
13063
|
};
|
|
13041
|
-
//# sourceMappingURL=chunk-
|
|
13064
|
+
//# sourceMappingURL=chunk-MYMVFOM3.js.map
|