@cat-factory/mcp-server 0.23.0 → 0.25.0

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/server.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { type CatFactoryMcpOptions } from './config.ts';
3
3
  import { type CatFactoryTool } from './tools.generated.ts';
4
4
  /** The npm version, stamped into the SDK's `User-Agent` so a deployment can attribute calls. */
5
- export declare const MCP_SERVER_VERSION = "0.23.0";
5
+ export declare const MCP_SERVER_VERSION = "0.25.0";
6
6
  /** The name this server reports to a host. */
7
7
  export declare const MCP_SERVER_NAME = "cat-factory";
8
8
  export interface CatFactoryMcpServer {
package/dist/server.js CHANGED
@@ -19,7 +19,7 @@ import { CAT_FACTORY_TOOLS } from './tools.generated.js';
19
19
  // has been round-tripped through a second type system, and every gap in that conversion becomes a
20
20
  // tool that misdescribes its own input.
21
21
  /** The npm version, stamped into the SDK's `User-Agent` so a deployment can attribute calls. */
22
- export const MCP_SERVER_VERSION = '0.23.0';
22
+ export const MCP_SERVER_VERSION = '0.25.0';
23
23
  /** The name this server reports to a host. */
24
24
  export const MCP_SERVER_NAME = 'cat-factory';
25
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tools.generated.d.ts","sourceRoot":"","sources":["../src/tools.generated.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAA;IACnB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAA;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACnC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5B,oBAAoB,EAAE,KAAK,CAAA;KAC5B,CAAA;IACD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;IACD,kDAAkD;IAClD,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACtF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAyCD,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EA8+BtD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,EAAE,SAAS,0BAA0B,EAmB/E,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAepE,CAAA"}
1
+ {"version":3,"file":"tools.generated.d.ts","sourceRoot":"","sources":["../src/tools.generated.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAA;IACnB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAA;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACnC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5B,oBAAoB,EAAE,KAAK,CAAA;KAC5B,CAAA;IACD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;IACD,kDAAkD;IAClD,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACtF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAuHD,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EAgjCtD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,EAAE,SAAS,0BAA0B,EAmB/E,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBpE,CAAA"}
@@ -15,25 +15,99 @@ function str(args, name) {
15
15
  * parameters to the same level, so "whatever is not a path parameter" would forward a model's
16
16
  * typo as a query parameter the deployment then ignores, and the caller would see a filter that
17
17
  * silently did nothing.
18
+ *
19
+ * Returns the call site's own query type, and CHECKS rather than assumes: a required parameter
20
+ * that `args` omits throws here, the way a missing path parameter already does through
21
+ * `str()`. The tool's `inputSchema` marks the same parameters required, but a host is not
22
+ * obliged to validate against it and the reference server in this package does not, so trusting
23
+ * it made the narrowing a claim about a bag that had just dropped the field the call needs. The
24
+ * failure that produced is the worst kind for a model: a 400 about a parameter it believes it
25
+ * supplied, several turns after the tool description explained it.
26
+ *
27
+ * PRESENCE only. What a value may BE is the deployment's judgement, already stated in the schema
28
+ * the model was given, and its refusal names the field; re-deriving it here would be a second
29
+ * copy of the contract, free to disagree with the first.
18
30
  */
19
- function pick(args, names) {
31
+ function pick(args, params) {
20
32
  const out = {};
21
- for (const name of names) {
22
- if (args[name] !== undefined)
23
- out[name] = args[name];
33
+ for (const param of params) {
34
+ const value = args[param.name];
35
+ if (value === undefined) {
36
+ if (param.required) {
37
+ throw new TypeError(`${param.name} is required`);
38
+ }
39
+ continue;
40
+ }
41
+ out[param.name] = value;
24
42
  }
25
43
  return out;
26
44
  }
27
- const QUERY_JOBS_LIST = ['limit', 'cursor', 'status', 'since'];
28
- const QUERY_TASKS_LIST_BY_SERVICE = ['limit', 'cursor', 'status'];
29
- const QUERY_DEBUG_GET_AGENT_CONTEXT = ['bodyChars', 'bodyOffset'];
30
- const QUERY_DEBUG_GET_LLM_CALL = ['bodyChars', 'bodyOffset', 'view'];
31
- const QUERY_DEBUG_LIST_AGENT_CONTEXT = ['stepIndex', 'limit', 'cursor'];
32
- const QUERY_DEBUG_LIST_LLM_CALLS = ['agentKind', 'phase', 'outcome', 'contains', 'order', 'limit', 'cursor', 'bodyChars'];
33
- const QUERY_DEBUG_LIST_LOGS = ['limit', 'cursor'];
34
- const QUERY_DEBUG_LIST_RUNS = ['status', 'since', 'limit', 'cursor'];
35
- const QUERY_DEBUG_LIST_SEARCH_QUERIES = ['limit', 'cursor'];
36
- const QUERY_DEBUG_LIST_TOOL_CALLS = ['limit', 'cursor', 'jobId', 'order', 'outcome'];
45
+ const QUERY_JOBS_LIST = [
46
+ { name: 'limit', required: false },
47
+ { name: 'cursor', required: false },
48
+ { name: 'status', required: false },
49
+ { name: 'since', required: false },
50
+ ];
51
+ const QUERY_TASKS_LIST_BY_SERVICE = [
52
+ { name: 'limit', required: false },
53
+ { name: 'cursor', required: false },
54
+ { name: 'status', required: false },
55
+ ];
56
+ const QUERY_USAGE_SPEND = [
57
+ { name: 'dimension', required: true },
58
+ { name: 'window', required: false },
59
+ { name: 'limit', required: false },
60
+ ];
61
+ const QUERY_DEBUG_GET_AGENT_CONTEXT = [
62
+ { name: 'bodyChars', required: false },
63
+ { name: 'bodyOffset', required: false },
64
+ ];
65
+ const QUERY_DEBUG_GET_LLM_CALL = [
66
+ { name: 'bodyChars', required: false },
67
+ { name: 'bodyOffset', required: false },
68
+ { name: 'view', required: false },
69
+ ];
70
+ const QUERY_DEBUG_GET_LLM_EXPORT = [
71
+ { name: 'limit', required: false },
72
+ { name: 'order', required: false },
73
+ { name: 'bodyChars', required: false },
74
+ ];
75
+ const QUERY_DEBUG_LIST_AGENT_CONTEXT = [
76
+ { name: 'stepIndex', required: false },
77
+ { name: 'limit', required: false },
78
+ { name: 'cursor', required: false },
79
+ ];
80
+ const QUERY_DEBUG_LIST_LLM_CALLS = [
81
+ { name: 'agentKind', required: false },
82
+ { name: 'phase', required: false },
83
+ { name: 'outcome', required: false },
84
+ { name: 'contains', required: false },
85
+ { name: 'order', required: false },
86
+ { name: 'limit', required: false },
87
+ { name: 'cursor', required: false },
88
+ { name: 'bodyChars', required: false },
89
+ ];
90
+ const QUERY_DEBUG_LIST_LOGS = [
91
+ { name: 'limit', required: false },
92
+ { name: 'cursor', required: false },
93
+ ];
94
+ const QUERY_DEBUG_LIST_RUNS = [
95
+ { name: 'status', required: false },
96
+ { name: 'since', required: false },
97
+ { name: 'limit', required: false },
98
+ { name: 'cursor', required: false },
99
+ ];
100
+ const QUERY_DEBUG_LIST_SEARCH_QUERIES = [
101
+ { name: 'limit', required: false },
102
+ { name: 'cursor', required: false },
103
+ ];
104
+ const QUERY_DEBUG_LIST_TOOL_CALLS = [
105
+ { name: 'limit', required: false },
106
+ { name: 'cursor', required: false },
107
+ { name: 'jobId', required: false },
108
+ { name: 'order', required: false },
109
+ { name: 'outcome', required: false },
110
+ ];
37
111
  /** Every `/api/v1` operation this facade exposes as a tool, in resource-group order. */
38
112
  export const CAT_FACTORY_TOOLS = [
39
113
  {
@@ -88,7 +162,7 @@ export const CAT_FACTORY_TOOLS = [
88
162
  operationId: 'createPublicService',
89
163
  readOnly: false,
90
164
  description: 'Create a service\n\nCreate a board service, optionally backed by a repository from `GET /api/v1/repos`. The repository link is what makes the service runnable: execution resolves a task’s repository by walking up to its enclosing service frame, so a service with none holds tasks and can start none of them. A whole-repo repository that already backs a service in this account is MOUNTED rather than duplicated; a monorepo service must name its subdirectory. The board lays the service out itself: this surface publishes no coordinates. Requires an `admin` key.\n\nCalls `POST /api/v1/services` (operation `createPublicService`).',
91
- inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "description": { "type": "string", "maxLength": 2000 }, "repo": { "type": "object", "properties": { "directory": { "type": "string", "maxLength": 400 }, "monorepo": { "type": "boolean" }, "repoId": { "type": "number" } }, "required": ["repoId"] }, "title": { "type": "string", "minLength": 1, "maxLength": 200 }, "type": { "type": "string", "enum": ["service", "frontend", "library", "document"] } }, "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
165
+ inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "description": { "type": "string", "maxLength": 2000 }, "repo": { "type": "object", "properties": { "directory": { "type": "string", "maxLength": 400 }, "monorepo": { "type": "boolean" }, "repoId": { "type": "number" } }, "required": ["repoId"] }, "title": { "type": "string", "minLength": 1, "maxLength": 200 }, "type": { "type": "string", "enum": ["service", "frontend", "library", "document"] } }, "description": "The request body." } }, "additionalProperties": false },
92
166
  outputSchema: { "type": "object", "properties": { "description": { "type": "string" }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "title": { "type": "string" }, "type": { "type": "string", "description": "One of: frontend, service, library, document, api, database, queue, integration, external, environment. A newer deployment may report a member not in this list." } } },
93
167
  invoke: (client, args) => client.services.create(args.body),
94
168
  },
@@ -243,7 +317,7 @@ export const CAT_FACTORY_TOOLS = [
243
317
  readOnly: false,
244
318
  hints: { "destructive": true, "idempotent": false },
245
319
  description: 'Start (run) a task\n\nStart a task’s pipeline. Uses the request’s pipelineId, else the task’s pinned pipeline. A pipeline that can park on a human decision requires a `decide`-scope key. A task on an individual-usage model cannot be started through the API (no headless personal-credential unlock).\n\nCalls `POST /api/v1/tasks/{taskId}/start` (operation `startPublicTask`).',
246
- inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "pipelineId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId", "body"] },
320
+ inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "pipelineId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId"] },
247
321
  outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
248
322
  invoke: (client, args) => client.tasks.start(str(args, 'taskId'), args.body),
249
323
  },
@@ -265,7 +339,7 @@ export const CAT_FACTORY_TOOLS = [
265
339
  operationId: 'updatePublicTask',
266
340
  readOnly: false,
267
341
  description: 'Edit a task\'s inputs\n\nEdit a task’s human-authored inputs before it runs: its title, its description, and `fields`, the per-case values for its own task type (checked against the descriptors `GET /api/v1/task-types` serves). All are optional. `fields` is MERGED over what the task already carries — a key you send is written, a key you omit keeps its stored value — because this API does not serve the bag back. This is what makes an input the pre-dispatch gate refused repairable: supply the value it named, then recheck the parked run.\n\nCalls `PATCH /api/v1/tasks/{taskId}` (operation `updatePublicTask`).',
268
- inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "description": { "type": "string", "maxLength": 2000 }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId", "body"] },
342
+ inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "description": { "type": "string", "maxLength": 2000 }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId"] },
269
343
  outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
270
344
  invoke: (client, args) => client.tasks.update(str(args, 'taskId'), args.body),
271
345
  },
@@ -298,10 +372,10 @@ export const CAT_FACTORY_TOOLS = [
298
372
  operationId: 'actPublicNotification',
299
373
  readOnly: false,
300
374
  hints: { "destructive": true, "idempotent": false },
301
- description: 'Act on a notification\n\nRun a notification’s typed side-effect and resolve it: merge the PR (merge_review / pipeline_complete) or retry the run (ci_failed / test_failed). Performs a real GitHub merge, so it requires an admin-scoped key. Only these automated-action types are actionable through the API — a notification that parks a run on an interactive human decision cannot be acted on headlessly (dismiss it instead). A card that would retry a run on an individual-usage model likewise cannot be acted on through the API.\n\nCalls `POST /api/v1/notifications/{id}/act` (operation `actPublicNotification`).',
302
- inputSchema: { "type": "object", "properties": { "id": { "type": "string", "description": "Path parameter `id`." } }, "additionalProperties": false, "required": ["id"] },
375
+ description: 'Act on a notification\n\nRun a notification’s typed side-effect and resolve it: merge the PR (merge_review / pipeline_complete) or retry the run (ci_failed / test_failed). Performs a real GitHub merge, so it requires an admin-scoped key. Only these automated-action types are actionable through the API — a notification that parks a run on an interactive human decision cannot be acted on headlessly (dismiss it instead). A card that would retry a run on an individual-usage model likewise cannot be acted on through the API. To record how much review a merged pull request needed, call `POST /api/v1/merge-records/{recordId}/effort` (a `write` key) before or after this; a `merge_tag_request` card carries its record id on the payload and is resolved by tagging that record and dismissing the card.\n\nCalls `POST /api/v1/notifications/{id}/act` (operation `actPublicNotification`).',
376
+ inputSchema: { "type": "object", "properties": { "id": { "type": "string", "description": "Path parameter `id`." }, "body": { "type": "object", "properties": { "reviewEffort": { "anyOf": [{ "type": "string", "enum": ["none", "minor", "major"] }, { "type": "null" }] } }, "description": "The request body." } }, "additionalProperties": false, "required": ["id"] },
303
377
  outputSchema: { "type": "object", "properties": { "blockId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "body": { "type": "string" }, "createdAt": { "type": "number" }, "executionId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "id": { "type": "string" }, "payload": { "anyOf": [{ "type": "object", "properties": { "assessment": { "type": "object", "properties": { "complexity": { "type": "number" }, "impact": { "type": "number" }, "rationale": { "type": "string" }, "risk": { "type": "number" } } }, "budgetAlerts": { "type": "array", "items": { "type": "object", "properties": { "projectedOverrun": { "type": "boolean" }, "threshold": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "tier": { "type": "string", "description": "One of: workspace, account. A newer deployment may report a member not in this list." } } } }, "budgetPeriodStart": { "type": "number" }, "changeClass": { "type": "string", "description": "One of: docs, test, dependency, config, source, schema, unknown. A newer deployment may report a member not in this list." }, "driftAffected": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "label": { "type": "string" }, "reason": { "type": "string", "description": "One of: key-mismatch, corrupt. A newer deployment may report a member not in this list." }, "sealedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "source": { "type": "string" } } } }, "findingCount": { "type": "number" }, "forkCount": { "type": "number" }, "initiativeReason": { "type": "string", "description": "One of: item_blocked, complete, checkpoint. A newer deployment may report a member not in this list." }, "mergeTrackRecordId": { "type": "string" }, "mergedRepos": { "type": "array", "items": { "type": "string" } }, "onCallAssessment": { "type": "object", "properties": { "culpritConfidence": { "type": "number" }, "evidence": { "type": "array", "items": { "type": "string" } }, "rationale": { "type": "string" }, "recommendation": { "type": "string", "description": "One of: revert, hold, monitor. A newer deployment may report a member not in this list." } } }, "pipelineName": { "type": "string" }, "platformAlertFailureKinds": { "type": "array", "items": { "type": "string" } }, "platformAlertTransition": { "type": "number" }, "platformAlerts": { "type": "array", "items": { "type": "string", "description": "One of: failure_rate_high, duration_p99_high, backlog_high, throughput_stalled, failure_kind_dominant, failure_kind_rate_high, sweep_degraded. A newer deployment may report a member not in this list." } }, "platformFailedTotal": { "type": "number" }, "platformFailingRuns": { "type": "array", "items": { "type": "object", "properties": { "blockId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "createdAt": { "type": "number" }, "executionId": { "type": "string" }, "failureKind": { "type": "string" } } } }, "platformWindow": { "type": "string", "description": "One of: 1h, 24h, 7d. A newer deployment may report a member not in this list." }, "prUrl": { "type": "string" }, "releaseSignals": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "id": { "type": "string" }, "kind": { "type": "string", "description": "One of: monitor, slo. A newer deployment may report a member not in this list." }, "name": { "type": "string" }, "state": { "type": "string", "description": "One of: ok, warn, alert, no_data. A newer deployment may report a member not in this list." } } } }, "revertUrl": { "type": "string" }, "sliceCount": { "type": "number" }, "targetUserId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "unmergedRepos": { "type": "array", "items": { "type": "string" } }, "unreachableAreas": { "type": "array", "items": { "type": "string", "description": "One of: ephemeralEnvironments, agentExecutor, binaryStorage. A newer deployment may report a member not in this list." } } } }, { "type": "null" }] }, "resolvedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "severity": { "type": "string", "description": "One of: normal, urgent. A newer deployment may report a member not in this list." }, "status": { "type": "string", "description": "One of: open, acted, dismissed. A newer deployment may report a member not in this list." }, "title": { "type": "string" }, "type": { "type": "string", "description": "One of: merge_review, pipeline_complete, ci_failed, test_failed, requirement_review, clarity_review, release_regression, decision_required, human_test_ready, visual_confirmation_ready, human_review, followup_pending, fork_decision_pending, judge_review, pr_review_ready, initiative, platform_health, infra_unreachable, budget_paused, budget_threshold, key_drift, merge_tag_request. A newer deployment may report a member not in this list." } } },
304
- invoke: (client, args) => client.notifications.act(str(args, 'id')),
378
+ invoke: (client, args) => client.notifications.act(str(args, 'id'), args.body),
305
379
  },
306
380
  {
307
381
  name: 'notifications_dismiss',
@@ -388,7 +462,7 @@ export const CAT_FACTORY_TOOLS = [
388
462
  readOnly: false,
389
463
  hints: { "destructive": true, "idempotent": true },
390
464
  description: 'Register or update the outbound webhook\n\nRegister the HTTPS endpoint deliveries are POSTed to, or update the one already registered. Every omitted field keeps its stored value, so subscribing to run events is a one-field call that re-sends neither the URL nor the secret. `url` is required only on the first call, when there is nothing registered to keep; omitting it otherwise leaves the endpoint alone. Supplying `secret` rotates the signing secret; omitting it keeps the current one. The endpoint must be `https:` and publicly routable unless the deployment widened its allow-list.\n\nCalls `PUT /api/v1/notification-webhook` (operation `putPublicNotificationWebhook`).',
391
- inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "enum": ["platform_health.firing", "platform_health.resolved"] } }, "enabled": { "type": "boolean" }, "name": { "type": "string", "minLength": 1, "maxLength": 100 }, "runEvents": { "type": "array", "items": { "type": "string", "enum": ["run.started", "run.completed", "run.failed"] } }, "secret": { "type": "string", "minLength": 16, "maxLength": 200 }, "types": { "type": "array", "items": { "type": "string", "enum": ["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "budget_threshold", "key_drift", "merge_tag_request"] } }, "url": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
465
+ inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "enum": ["platform_health.firing", "platform_health.resolved"] } }, "enabled": { "type": "boolean" }, "name": { "type": "string", "minLength": 1, "maxLength": 100 }, "runEvents": { "type": "array", "items": { "type": "string", "enum": ["run.started", "run.completed", "run.failed"] } }, "secret": { "type": "string", "minLength": 16, "maxLength": 200 }, "types": { "type": "array", "items": { "type": "string", "enum": ["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "budget_threshold", "key_drift", "merge_tag_request"] } }, "url": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false },
392
466
  outputSchema: { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "description": "One of: platform_health.firing, platform_health.resolved. A newer deployment may report a member not in this list." } }, "enabled": { "type": "boolean" }, "hasSecret": { "type": "boolean" }, "id": { "type": "string" }, "name": { "type": "string" }, "runEvents": { "type": "array", "items": { "type": "string", "description": "One of: run.started, run.completed, run.failed. A newer deployment may report a member not in this list." } }, "types": { "type": "array", "items": { "type": "string", "description": "One of: merge_review, pipeline_complete, ci_failed, test_failed, requirement_review, clarity_review, release_regression, decision_required, human_test_ready, visual_confirmation_ready, human_review, followup_pending, fork_decision_pending, judge_review, pr_review_ready, initiative, platform_health, infra_unreachable, budget_paused, budget_threshold, key_drift, merge_tag_request. A newer deployment may report a member not in this list." } }, "updatedAt": { "type": "number" }, "url": { "type": "string" } } },
393
467
  invoke: (client, args) => client.webhook.set(args.body),
394
468
  },
@@ -400,7 +474,7 @@ export const CAT_FACTORY_TOOLS = [
400
474
  readOnly: false,
401
475
  hints: { "destructive": true, "idempotent": true },
402
476
  description: 'Register or update one named outbound webhook\n\nRegister an endpoint under an id YOU choose (1-63 characters of lowercase letters, digits, `-` or `_`), or update the one already there. Idempotent by id, so an integration can enroll its own receiver on every cold start without tracking whether it has enrolled before, and without displacing anything else the workspace registered. Every field follows the same keep-on-omit rule as the unnamed route, `url` being required only when there is nothing under this id to keep, and a supplied `secret` rotating this endpoint\'s own signing secret. Refused with `reason: "invalid_webhook_id"` for an id that is not a slug, and `reason: "webhook_limit_reached"` (409) when registering a NEW id would exceed the per-workspace cap; editing an existing one is admitted either way.\n\nCalls `PUT /api/v1/notification-webhooks/{webhookId}` (operation `putPublicNamedNotificationWebhook`).',
403
- inputSchema: { "type": "object", "properties": { "webhookId": { "type": "string", "description": "Path parameter `webhookId`." }, "body": { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "enum": ["platform_health.firing", "platform_health.resolved"] } }, "enabled": { "type": "boolean" }, "name": { "type": "string", "minLength": 1, "maxLength": 100 }, "runEvents": { "type": "array", "items": { "type": "string", "enum": ["run.started", "run.completed", "run.failed"] } }, "secret": { "type": "string", "minLength": 16, "maxLength": 200 }, "types": { "type": "array", "items": { "type": "string", "enum": ["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "budget_threshold", "key_drift", "merge_tag_request"] } }, "url": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["webhookId", "body"] },
477
+ inputSchema: { "type": "object", "properties": { "webhookId": { "type": "string", "description": "Path parameter `webhookId`." }, "body": { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "enum": ["platform_health.firing", "platform_health.resolved"] } }, "enabled": { "type": "boolean" }, "name": { "type": "string", "minLength": 1, "maxLength": 100 }, "runEvents": { "type": "array", "items": { "type": "string", "enum": ["run.started", "run.completed", "run.failed"] } }, "secret": { "type": "string", "minLength": 16, "maxLength": 200 }, "types": { "type": "array", "items": { "type": "string", "enum": ["merge_review", "pipeline_complete", "ci_failed", "test_failed", "requirement_review", "clarity_review", "release_regression", "decision_required", "human_test_ready", "visual_confirmation_ready", "human_review", "followup_pending", "fork_decision_pending", "judge_review", "pr_review_ready", "initiative", "platform_health", "infra_unreachable", "budget_paused", "budget_threshold", "key_drift", "merge_tag_request"] } }, "url": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["webhookId"] },
404
478
  outputSchema: { "type": "object", "properties": { "alertEvents": { "type": "array", "items": { "type": "string", "description": "One of: platform_health.firing, platform_health.resolved. A newer deployment may report a member not in this list." } }, "enabled": { "type": "boolean" }, "hasSecret": { "type": "boolean" }, "id": { "type": "string" }, "name": { "type": "string" }, "runEvents": { "type": "array", "items": { "type": "string", "description": "One of: run.started, run.completed, run.failed. A newer deployment may report a member not in this list." } }, "types": { "type": "array", "items": { "type": "string", "description": "One of: merge_review, pipeline_complete, ci_failed, test_failed, requirement_review, clarity_review, release_regression, decision_required, human_test_ready, visual_confirmation_ready, human_review, followup_pending, fork_decision_pending, judge_review, pr_review_ready, initiative, platform_health, infra_unreachable, budget_paused, budget_threshold, key_drift, merge_tag_request. A newer deployment may report a member not in this list." } }, "updatedAt": { "type": "number" }, "url": { "type": "string" } } },
405
479
  invoke: (client, args) => client.webhook.setNamed(str(args, 'webhookId'), args.body),
406
480
  },
@@ -415,6 +489,17 @@ export const CAT_FACTORY_TOOLS = [
415
489
  outputSchema: { "type": "object", "properties": { "budget": { "type": "object", "properties": { "costLimit": { "type": "number" }, "costSpent": { "type": "number" }, "exceeded": { "type": "boolean" }, "inputTokens": { "type": "number" }, "outputTokens": { "type": "number" } } }, "currency": { "type": "string" }, "periodStart": { "type": "number" }, "rows": { "type": "array", "items": { "type": "object", "properties": { "billing": { "type": "string", "description": "One of: metered, subscription. A newer deployment may report a member not in this list." }, "calls": { "type": "number" }, "costEstimate": { "type": "number" }, "inputTokens": { "type": "number" }, "model": { "type": "string" }, "outputTokens": { "type": "number" }, "provider": { "type": "string" }, "vendor": { "anyOf": [{ "type": "string" }, { "type": "null" }] } } } } } },
416
490
  invoke: (client, args) => client.usage.get(),
417
491
  },
492
+ {
493
+ name: 'usage_spend',
494
+ title: 'Break the workspace\'s spend down by repository, ticket, run or step kind',
495
+ group: 'usage',
496
+ operationId: 'getPublicSpend',
497
+ readOnly: true,
498
+ description: 'Break the workspace\'s spend down by repository, ticket, run or step kind\n\nGroup the board’s spend over a window (`24h`, `7d`, `30d`, `90d`) by ONE dimension: `repo`, `ticket` and `run` are the cost-attribution axes an organisation budgets against, and `model` / `agentKind` / `service` / `taskType` slice the same money the other ways. `meteredCost` is real money and `subscriptionCost` is the illustrative equivalent-API cost of flat-rate quota usage, so never sum them. The EMPTY `key` is the unattributed bucket, a real slice rather than a dropped row, never dropped from the breakdown. `rows` is the heaviest `limit` slices (default 100, max 500) and `truncated` says when there was a tail, while `totals` aggregates the WHOLE window either way, so a capped answer still reports what the board spent. `source` says which store answered: the short windows scan the live ledger, which resolves a repository or a ticket through today’s links, while the long ones read the durable daily rollup, which froze that attribution while the money was spent and is never pruned. Read `rolledUpThrough` before reporting a quiet quarter, since a rollup that has never run and a board that spent nothing look identical. Workspace-scoped: the account-wide view is not reachable through this surface.\n\nCalls `GET /api/v1/usage/spend` (operation `getPublicSpend`).',
499
+ inputSchema: { "type": "object", "properties": { "dimension": { "type": "string", "enum": ["model", "agentKind", "service", "repo", "taskType", "ticket", "run"] }, "window": { "type": "string", "enum": ["24h", "7d", "30d", "90d"] }, "limit": { "type": "integer" } }, "additionalProperties": false, "required": ["dimension"] },
500
+ outputSchema: { "type": "object", "properties": { "currency": { "type": "string" }, "dimension": { "type": "string", "description": "One of: model, agentKind, service, repo, taskType, ticket, run. A newer deployment may report a member not in this list." }, "generatedAt": { "type": "number" }, "rolledUpThrough": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "rows": { "type": "array", "items": { "type": "object", "properties": { "calls": { "type": "number" }, "inputTokens": { "type": "number" }, "key": { "type": "string" }, "label": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "meteredCost": { "type": "number" }, "outputTokens": { "type": "number" }, "subscriptionCost": { "type": "number" } } } }, "since": { "type": "number" }, "source": { "type": "string", "description": "One of: ledger, daily-rollup. A newer deployment may report a member not in this list." }, "totals": { "type": "object", "properties": { "calls": { "type": "number" }, "inputTokens": { "type": "number" }, "meteredCost": { "type": "number" }, "outputTokens": { "type": "number" }, "subscriptionCost": { "type": "number" } } }, "truncated": { "type": "boolean" }, "window": { "type": "string", "description": "One of: 24h, 7d, 30d, 90d. A newer deployment may report a member not in this list." } } },
501
+ invoke: (client, args) => client.usage.spend(pick(args, QUERY_USAGE_SPEND)),
502
+ },
418
503
  {
419
504
  name: 'me_get',
420
505
  title: 'Describe the calling key',
@@ -466,7 +551,7 @@ export const CAT_FACTORY_TOOLS = [
466
551
  operationId: 'approvePublicRunStep',
467
552
  readOnly: false,
468
553
  description: 'Approve a parked step\n\nApprove the proposal a gated step is holding up, optionally replacing it with an edited one (the edit is what flows to every downstream step), and advance the run. The `approvalId` comes from the run\'s decision list; passing it back is what makes a racing app user and a racing integration resolve the same gate. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/approvals/{approvalId}/approve` (operation `approvePublicRunStep`).',
469
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "approvalId": { "type": "string", "description": "Path parameter `approvalId`." }, "body": { "type": "object", "properties": { "proposal": { "type": "string", "maxLength": 50000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "approvalId", "body"] },
554
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "approvalId": { "type": "string", "description": "Path parameter `approvalId`." }, "body": { "type": "object", "properties": { "proposal": { "type": "string", "maxLength": 50000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "approvalId"] },
470
555
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
471
556
  invoke: (client, args) => client.decisions.approveStep(str(args, 'runId'), str(args, 'approvalId'), args.body),
472
557
  },
@@ -488,7 +573,7 @@ export const CAT_FACTORY_TOOLS = [
488
573
  operationId: 'challengePublicRunPrReviewFinding',
489
574
  readOnly: false,
490
575
  description: 'Challenge a PR review finding\n\nDispatch a read-only investigator to re-examine one finding against the full source, optionally with a specific concern. It upholds, strengthens or retracts the finding, and the review re-parks carrying the verdict. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/pr-review/findings/{findingId}/challenge` (operation `challengePublicRunPrReviewFinding`).',
491
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "findingId": { "type": "string", "description": "Path parameter `findingId`." }, "body": { "type": "object", "properties": { "question": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "findingId", "body"] },
576
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "findingId": { "type": "string", "description": "Path parameter `findingId`." }, "body": { "type": "object", "properties": { "question": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "findingId"] },
492
577
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
493
578
  invoke: (client, args) => client.decisions.challengePrReviewFinding(str(args, 'runId'), str(args, 'findingId'), args.body),
494
579
  },
@@ -499,7 +584,7 @@ export const CAT_FACTORY_TOOLS = [
499
584
  operationId: 'choosePublicRunFork',
500
585
  readOnly: false,
501
586
  description: 'Choose an implementation approach\n\nPick one of the proposed implementation forks (by id) or submit your own approach. The Coder then runs with the choice folded in as a binding directive. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/fork/choose` (operation `choosePublicRunFork`).',
502
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "custom": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "forkId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "note": { "anyOf": [{ "type": "string" }, { "type": "null" }] } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "body"] },
587
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "custom": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "forkId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "note": { "anyOf": [{ "type": "string" }, { "type": "null" }] } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId"] },
503
588
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
504
589
  invoke: (client, args) => client.decisions.chooseFork(str(args, 'runId'), args.body),
505
590
  },
@@ -565,7 +650,7 @@ export const CAT_FACTORY_TOOLS = [
565
650
  operationId: 'incorporatePublicRunRequirements',
566
651
  readOnly: false,
567
652
  description: 'Incorporate the answers\n\nFold the recorded answers into one standardized requirements document. Asynchronous — the run re-reviews in the background, so the response shows the review `incorporating`. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/requirements/incorporate` (operation `incorporatePublicRunRequirements`).',
568
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "body"] },
653
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId"] },
569
654
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
570
655
  invoke: (client, args) => client.decisions.incorporate(str(args, 'runId'), args.body),
571
656
  },
@@ -576,7 +661,7 @@ export const CAT_FACTORY_TOOLS = [
576
661
  operationId: 'incorporatePublicRunBrainstorm',
577
662
  readOnly: false,
578
663
  description: 'Incorporate brainstorm picks\n\nFold the picks into one converged direction. ASYNCHRONOUS: the response shows the session `incorporating` while the durable driver folds and re-runs in the background. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/brainstorm/{stage}/incorporate` (operation `incorporatePublicRunBrainstorm`).',
579
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "stage": { "type": "string", "description": "Path parameter `stage`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "stage", "body"] },
664
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "stage": { "type": "string", "description": "Path parameter `stage`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "stage"] },
580
665
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
581
666
  invoke: (client, args) => client.decisions.incorporateBrainstorm(str(args, 'runId'), str(args, 'stage'), args.body),
582
667
  },
@@ -587,7 +672,7 @@ export const CAT_FACTORY_TOOLS = [
587
672
  operationId: 'incorporatePublicRunClarity',
588
673
  readOnly: false,
589
674
  description: 'Incorporate clarity answers\n\nFold the recorded answers into one standardized bug report. ASYNCHRONOUS: the response shows the review `incorporating` while the durable driver folds and re-reviews in the background. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/clarity/incorporate` (operation `incorporatePublicRunClarity`).',
590
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "body"] },
675
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "feedback": { "type": "string", "maxLength": 4000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId"] },
591
676
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
592
677
  invoke: (client, args) => client.decisions.incorporateClarity(str(args, 'runId'), args.body),
593
678
  },
@@ -653,7 +738,7 @@ export const CAT_FACTORY_TOOLS = [
653
738
  operationId: 'rejectPublicRunStep',
654
739
  readOnly: false,
655
740
  description: 'Reject a parked step\n\nReject the gated proposal: the run stops entirely, recording a terminal `rejected` failure the board can retry. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/approvals/{approvalId}/reject` (operation `rejectPublicRunStep`).',
656
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "approvalId": { "type": "string", "description": "Path parameter `approvalId`." }, "body": { "type": "object", "properties": { "reason": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "approvalId", "body"] },
741
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "approvalId": { "type": "string", "description": "Path parameter `approvalId`." }, "body": { "type": "object", "properties": { "reason": { "type": "string", "maxLength": 2000 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "approvalId"] },
657
742
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
658
743
  invoke: (client, args) => client.decisions.rejectStep(str(args, 'runId'), str(args, 'approvalId'), args.body),
659
744
  },
@@ -818,7 +903,7 @@ export const CAT_FACTORY_TOOLS = [
818
903
  operationId: 'resolvePublicRunPrReview',
819
904
  readOnly: false,
820
905
  description: 'Resolve a parked PR deep review\n\nRecord the curated finding selection and say what to do with it: `finish` completes the read-only review, `fix` hands the selected findings to a fixer that commits onto the reviewed PR branch, `post` publishes them as inline PR review comments. `fix` and `post` need at least one selected finding and act on the real pull request. Requires a `decide`-scope key.\n\nCalls `POST /api/v1/runs/{runId}/decisions/pr-review/resolve` (operation `resolvePublicRunPrReview`).',
821
- inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "action": { "type": "string", "enum": ["finish", "fix", "post"] }, "findingIds": { "type": "array", "items": { "type": "string" } } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId", "body"] },
906
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "body": { "type": "object", "properties": { "action": { "type": "string", "enum": ["finish", "fix", "post"] }, "findingIds": { "type": "array", "items": { "type": "string" } } }, "description": "The request body." } }, "additionalProperties": false, "required": ["runId"] },
822
907
  outputSchema: { "type": "object", "properties": { "decisions": { "type": "array", "items": { "description": "Discriminated by `kind` (requirements-review | fork | judge | input-gate | approval-gate | agent-decision | clarity-review | brainstorm | pr-review | human-test | visual-confirmation | follow-ups | interview). A newer deployment may report a variant not in this list." } }, "parked": { "type": "boolean" }, "runId": { "type": "string" }, "status": { "type": "string", "description": "One of: running, blocked, paused, done, failed. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "unanswerable": { "type": "array", "items": { "type": "object", "properties": { "detail": { "type": "string" }, "reason": { "type": "string", "description": "One of: human_wait_gate, unclassified_gate, unwired_interview_gate. A newer deployment may report a member not in this list." }, "stepIndex": { "type": "number" }, "stepKind": { "type": "string" } } } } } },
823
908
  invoke: (client, args) => client.decisions.resolvePrReview(str(args, 'runId'), args.body),
824
909
  },
@@ -899,6 +984,17 @@ export const CAT_FACTORY_TOOLS = [
899
984
  outputSchema: { "type": "object", "properties": { "agentKind": { "type": "string" }, "cacheReadTokens": { "type": "number" }, "cacheWriteTokens": { "type": "number" }, "callId": { "type": "string" }, "completionTokens": { "type": "number" }, "createdAt": { "type": "number" }, "elidedLeadingMessages": { "type": "number" }, "errorMessage": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "finishReason": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "httpStatus": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "messageCount": { "type": "number" }, "model": { "type": "string" }, "ok": { "type": "boolean" }, "outcome": { "type": "string", "description": "One of: ok, warning, error. A newer deployment may report a member not in this list." }, "overheadMs": { "type": "number" }, "phase": { "type": "string" }, "prompt": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "promptMessages": { "anyOf": [{ "type": "array", "items": { "type": "object", "properties": { "content": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "index": { "type": "number" }, "name": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "role": { "type": "string" }, "toolCallId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "toolCalls": { "type": "array", "items": { "type": "object", "properties": { "args": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "name": { "type": "string" } } } } } } }, { "type": "null" }] }, "promptTokens": { "type": "number" }, "provider": { "type": "string" }, "reasoning": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "requestMaxTokens": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "response": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "streaming": { "type": "boolean" }, "toolCount": { "type": "number" }, "totalMs": { "type": "number" }, "totalTokens": { "type": "number" }, "turnIndex": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "upstreamMs": { "type": "number" } } },
900
985
  invoke: (client, args) => client.debug.getLlmCall(str(args, 'callId'), pick(args, QUERY_DEBUG_GET_LLM_CALL)),
901
986
  },
987
+ {
988
+ name: 'debug_get_llm_export',
989
+ title: 'Export a run\'s model activity as one bundle',
990
+ group: 'debug',
991
+ operationId: 'getDebugLlmExport',
992
+ readOnly: true,
993
+ description: 'Export a run\'s model activity as one bundle\n\nThe whole of a run’s model activity as one self-describing document, for handing straight to a model asked why the run truncated, spent or stalled: the SQL rollups (run totals, per agent kind, per phase, with the carry cost that says which slice burdened everything after it) plus a bounded window of the individual calls behind them. The rollups cover EVERY recorded call and do not move with `limit`, so a windowed bundle still reports what the run actually cost; `truncated` says the calls are a window and `order` says which end was kept. Bodies are omitted unless `bodyChars` asks, and the resumable call list is the way to walk a long run whole.\n\nCalls `GET /api/v1/debug/runs/{runId}/llm-export` (operation `getDebugLlmExport`).',
994
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." }, "limit": { "type": "integer" }, "order": { "type": "string", "enum": ["newest", "oldest"] }, "bodyChars": { "type": "integer" } }, "additionalProperties": false, "required": ["runId"] },
995
+ outputSchema: { "type": "object", "properties": { "available": { "type": "boolean" }, "calls": { "type": "array", "items": { "type": "object", "properties": { "agentKind": { "type": "string" }, "cacheReadTokens": { "type": "number" }, "cacheWriteTokens": { "type": "number" }, "callId": { "type": "string" }, "completionTokens": { "type": "number" }, "createdAt": { "type": "number" }, "elidedLeadingMessages": { "type": "number" }, "errorMessage": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "finishReason": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "httpStatus": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "messageCount": { "type": "number" }, "model": { "type": "string" }, "ok": { "type": "boolean" }, "outcome": { "type": "string", "description": "One of: ok, warning, error. A newer deployment may report a member not in this list." }, "overheadMs": { "type": "number" }, "phase": { "type": "string" }, "prompt": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "promptMessages": { "anyOf": [{ "type": "array", "items": { "type": "object", "properties": { "content": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "index": { "type": "number" }, "name": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "role": { "type": "string" }, "toolCallId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "toolCalls": { "type": "array", "items": { "type": "object", "properties": { "args": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "name": { "type": "string" } } } } } } }, { "type": "null" }] }, "promptTokens": { "type": "number" }, "provider": { "type": "string" }, "reasoning": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "requestMaxTokens": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "response": { "type": "object", "properties": { "chars": { "type": "number" }, "matchOffset": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "offset": { "type": "number" }, "text": { "type": "string" }, "totalChars": { "type": "number" }, "truncated": { "type": "boolean" } } }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "streaming": { "type": "boolean" }, "toolCount": { "type": "number" }, "totalMs": { "type": "number" }, "totalTokens": { "type": "number" }, "turnIndex": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "upstreamMs": { "type": "number" } } } }, "generatedAt": { "type": "number" }, "kind": { "type": "string" }, "llm": { "type": "object", "properties": { "byAgentKind": { "type": "array", "items": { "type": "object", "properties": { "agentKind": { "type": "string" }, "cacheHitRate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "cacheReadTokens": { "type": "number" }, "cacheWriteTokens": { "type": "number" }, "calls": { "type": "number" }, "completionTokens": { "type": "number" }, "costEstimate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "errors": { "type": "number" }, "maxOutputTokens": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "outputHeadroomRatio": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "overheadMs": { "type": "number" }, "peakCompletionTokens": { "type": "number" }, "promptTokens": { "type": "number" }, "transportOverheadRatio": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "truncatedCalls": { "type": "number" }, "upstreamMs": { "type": "number" }, "warnings": { "type": "number" } } } }, "byPhase": { "type": "array", "items": { "type": "object", "properties": { "cacheHitRate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "cacheReadTokens": { "type": "number" }, "cacheWriteTokens": { "type": "number" }, "calls": { "type": "number" }, "carryCostShare": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "carryCostTokens": { "type": "number" }, "completionTokens": { "type": "number" }, "costEstimate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "errors": { "type": "number" }, "overheadMs": { "type": "number" }, "phase": { "type": "string" }, "promptTokens": { "type": "number" }, "truncatedCalls": { "type": "number" }, "upstreamMs": { "type": "number" }, "warnings": { "type": "number" } } } }, "costCurrency": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "totals": { "type": "object", "properties": { "cacheHitRate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "cacheReadTokens": { "type": "number" }, "cacheWriteTokens": { "type": "number" }, "calls": { "type": "number" }, "completionTokens": { "type": "number" }, "costEstimate": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "errors": { "type": "number" }, "overheadMs": { "type": "number" }, "promptTokens": { "type": "number" }, "transportOverheadRatio": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "truncatedCalls": { "type": "number" }, "upstreamMs": { "type": "number" }, "warnings": { "type": "number" } } } } }, "order": { "type": "string", "description": "One of: newest, oldest. A newer deployment may report a member not in this list." }, "runId": { "type": "string" }, "truncated": { "type": "boolean" }, "version": { "type": "number" } } },
996
+ invoke: (client, args) => client.debug.getLlmExport(str(args, 'runId'), pick(args, QUERY_DEBUG_GET_LLM_EXPORT)),
997
+ },
902
998
  {
903
999
  name: 'debug_get_run',
904
1000
  title: 'Get a run\'s diagnostic map',
@@ -1009,6 +1105,50 @@ export const CAT_FACTORY_TOOLS = [
1009
1105
  outputSchema: { "type": "object", "properties": { "artifacts": { "type": "array", "items": { "type": "object", "properties": { "artifactId": { "type": "string" }, "byteSize": { "type": "number" }, "contentType": { "type": "string" }, "createdAt": { "type": "number" }, "hash": { "type": "string" }, "kind": { "type": "string", "description": "One of: screenshot, reference. A newer deployment may report a member not in this list." }, "scope": { "type": "string", "description": "One of: run, task. A newer deployment may report a member not in this list." }, "view": { "anyOf": [{ "type": "string" }, { "type": "null" }] } } } } } },
1010
1106
  invoke: (client, args) => client.evidence.listArtifacts(str(args, 'runId')),
1011
1107
  },
1108
+ {
1109
+ name: 'merge_records_get',
1110
+ title: 'Get one merge record',
1111
+ group: 'merge_records',
1112
+ operationId: 'getPublicMergeRecord',
1113
+ readOnly: true,
1114
+ description: 'Get one merge record\n\nThe same record addressed by its own id, for a caller that holds one without the run: the id a `merge_tag_request` notification carries on its payload, for instance. Scoped to the calling key’s workspace.\n\nCalls `GET /api/v1/merge-records/{recordId}` (operation `getPublicMergeRecord`).',
1115
+ inputSchema: { "type": "object", "properties": { "recordId": { "type": "string", "description": "Path parameter `recordId`." } }, "additionalProperties": false, "required": ["recordId"] },
1116
+ outputSchema: { "type": "object", "properties": { "changeClass": { "type": "string", "description": "One of: docs, test, dependency, config, source, schema, unknown. A newer deployment may report a member not in this list." }, "changedFileCount": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "complexity": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "createdAt": { "type": "number" }, "decision": { "type": "string", "description": "One of: pending_review, auto_merged, human_merged, external_merged, rejected. A newer deployment may report a member not in this list." }, "impact": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "mergePresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "mergePresetName": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "prNumber": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "prUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "provider": { "anyOf": [{ "type": "string", "description": "One of: github, gitlab. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "recordId": { "type": "string" }, "repoId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "resolvedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "reviewEffort": { "anyOf": [{ "type": "string", "description": "One of: none, minor, major. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "risk": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "taggedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "taskId": { "type": "string" } } },
1117
+ invoke: (client, args) => client.mergeRecords.get(str(args, 'recordId')),
1118
+ },
1119
+ {
1120
+ name: 'merge_records_get_for_run',
1121
+ title: 'Get the merge decision a run left behind',
1122
+ group: 'merge_records',
1123
+ operationId: 'getPublicRunMergeRecord',
1124
+ readOnly: true,
1125
+ description: 'Get the merge decision a run left behind\n\nWhat kind of change the run’s pull request made (a change class derived on the backend from the changed-file list, never from an agent’s opinion), what the merger scored it, which merge-threshold preset the decision was compared against, what ultimately happened to the pull request, and how much review a human spent if anybody has tagged it. The entry point of the merge-evidence loop for a caller holding a run id: it also hands back the `recordId` the effort-tag route takes. A run whose pipeline had no `merger` step made no merge decision and answers `404` with `details.reason: "no_merge_record"`, distinct from the `"run_not_found"` a run this key cannot read gets.\n\nCalls `GET /api/v1/runs/{runId}/merge-record` (operation `getPublicRunMergeRecord`).',
1126
+ inputSchema: { "type": "object", "properties": { "runId": { "type": "string", "description": "Path parameter `runId`." } }, "additionalProperties": false, "required": ["runId"] },
1127
+ outputSchema: { "type": "object", "properties": { "changeClass": { "type": "string", "description": "One of: docs, test, dependency, config, source, schema, unknown. A newer deployment may report a member not in this list." }, "changedFileCount": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "complexity": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "createdAt": { "type": "number" }, "decision": { "type": "string", "description": "One of: pending_review, auto_merged, human_merged, external_merged, rejected. A newer deployment may report a member not in this list." }, "impact": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "mergePresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "mergePresetName": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "prNumber": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "prUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "provider": { "anyOf": [{ "type": "string", "description": "One of: github, gitlab. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "recordId": { "type": "string" }, "repoId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "resolvedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "reviewEffort": { "anyOf": [{ "type": "string", "description": "One of: none, minor, major. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "risk": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "taggedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "taskId": { "type": "string" } } },
1128
+ invoke: (client, args) => client.mergeRecords.getForRun(str(args, 'runId')),
1129
+ },
1130
+ {
1131
+ name: 'merge_records_list_rollups',
1132
+ title: 'List the per-change-class merge rollups',
1133
+ group: 'merge_records',
1134
+ operationId: 'listPublicMergeClassRollups',
1135
+ readOnly: true,
1136
+ description: 'List the per-change-class merge rollups\n\nEvery change class’s accumulated track record for the workspace, as one aggregate: how many records it holds, how many landed and by which route (auto-merged, merged through the app, merged directly on the provider), how many were rejected or are still awaiting review, and the distribution of reviewer-effort tags. This is the evidence that justifies widening a per-class auto-merge rule; nothing widens one automatically. A class with no records is present as zeros rather than absent, so "nothing has landed here yet" never reads as a class the response left out. `unknown` is a real class (no changed-file list was available) and never matches a per-class rule.\n\nCalls `GET /api/v1/merge-records/rollups` (operation `listPublicMergeClassRollups`).',
1137
+ inputSchema: { "type": "object", "properties": {}, "additionalProperties": false },
1138
+ outputSchema: { "type": "object", "properties": { "rollups": { "type": "array", "items": { "type": "object", "properties": { "autoMerged": { "type": "number" }, "changeClass": { "type": "string", "description": "One of: docs, test, dependency, config, source, schema, unknown. A newer deployment may report a member not in this list." }, "effort": { "type": "object", "properties": { "major": { "type": "number" }, "minor": { "type": "number" }, "none": { "type": "number" }, "untagged": { "type": "number" } } }, "externalMerged": { "type": "number" }, "humanMerged": { "type": "number" }, "merged": { "type": "number" }, "pendingReview": { "type": "number" }, "rejected": { "type": "number" }, "total": { "type": "number" } } } } } },
1139
+ invoke: (client, args) => client.mergeRecords.listRollups(),
1140
+ },
1141
+ {
1142
+ name: 'merge_records_tag_effort',
1143
+ title: 'Tag the reviewer effort a merge took',
1144
+ group: 'merge_records',
1145
+ operationId: 'tagPublicMergeReviewEffort',
1146
+ readOnly: false,
1147
+ description: 'Tag the reviewer effort a merge took\n\nRecord how much review a landed pull request actually needed (`none` for zero blocking comments, `minor` for a nit pass, `major` for real rework), or `null` to clear the tag. This is the ground truth the auto-merge score thresholds are trying to approximate, and it is never mandatory: an untagged merge records a null tag and nothing downstream breaks. A `write` key, not an `admin` one: the pull request already landed, so tagging it merges nothing. Idempotent, and orthogonal to the decision, so a record can be tagged whenever the effort becomes known, before or after the `act` that merged it.\n\nCalls `POST /api/v1/merge-records/{recordId}/effort` (operation `tagPublicMergeReviewEffort`).',
1148
+ inputSchema: { "type": "object", "properties": { "recordId": { "type": "string", "description": "Path parameter `recordId`." }, "body": { "type": "object", "properties": { "reviewEffort": { "anyOf": [{ "type": "string", "enum": ["none", "minor", "major"] }, { "type": "null" }], "description": "Always present in a response; `null` when the server has no value for it." } }, "required": ["reviewEffort"], "description": "The request body." } }, "additionalProperties": false, "required": ["recordId", "body"] },
1149
+ outputSchema: { "type": "object", "properties": { "changeClass": { "type": "string", "description": "One of: docs, test, dependency, config, source, schema, unknown. A newer deployment may report a member not in this list." }, "changedFileCount": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "complexity": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "createdAt": { "type": "number" }, "decision": { "type": "string", "description": "One of: pending_review, auto_merged, human_merged, external_merged, rejected. A newer deployment may report a member not in this list." }, "impact": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "mergePresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "mergePresetName": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "prNumber": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "prUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "provider": { "anyOf": [{ "type": "string", "description": "One of: github, gitlab. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "recordId": { "type": "string" }, "repoId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "resolvedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "reviewEffort": { "anyOf": [{ "type": "string", "description": "One of: none, minor, major. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "risk": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "taggedAt": { "anyOf": [{ "type": "number" }, { "type": "null" }] }, "taskId": { "type": "string" } } },
1150
+ invoke: (client, args) => client.mergeRecords.tagEffort(str(args, 'recordId'), args.body),
1151
+ },
1012
1152
  {
1013
1153
  name: 'keys_create',
1014
1154
  title: 'Provision an API key',
@@ -1073,11 +1213,12 @@ export const CAT_FACTORY_TOOL_GROUPS = {
1073
1213
  'task_types': 'What a task can be created AS in this workspace (the built-in kinds plus the operations the deployment registered), and the fields each one accepts.',
1074
1214
  'notifications': 'The workspace\'s human-actionable inbox: list, act on, or dismiss a run tail.',
1075
1215
  'webhook': 'The workspace\'s outbound endpoints: register, inspect or remove the receivers that notifications, run-lifecycle events and health alerts are pushed to. The unnamed calls address the `default` endpoint; the named ones let an integration enroll its own receiver, with its own signing secret and filters, beside whatever else is registered.',
1076
- 'usage': 'The billing period\'s metered budget position and the per-model breakdown behind it.',
1216
+ 'usage': 'The workspace\'s money, two ways: the billing period\'s metered budget position with the per-model breakdown behind it, and spend over a window sliced by the dimension a budget is kept against (a repository, a tracker ticket, one run).',
1077
1217
  'me': 'What the calling key is and what it may do — the self-check an integration runs at startup.',
1078
1218
  'decisions': 'Every way a run stops for a person: approval gates, review and brainstorm loops, forks, judge verdicts, PR review findings, the human-verdict gates, follow-up triage and the interview gates.',
1079
- 'debug': 'A run\'s recorded telemetry: LLM calls, the context each agent was given, the tool calls it made, infra logs.',
1219
+ 'debug': 'A run\'s recorded telemetry: LLM calls, the context each agent was given, the tool calls it made, infra logs, and the whole model-activity bundle as one document.',
1080
1220
  'evidence': 'What a run proved: the engine\'s verification report, the outcome summary behind it, and the artifacts it captured, bytes included.',
1221
+ 'merge_records': 'The evidence behind the auto-merge policy: what kind of change each merged run made, what the merger scored it, what happened to the pull request, and how much review a human actually spent, plus the per-class rollups that justify widening a rule. Reading takes a `read` key and recording an effort tag a `write` one: neither merges anything.',
1081
1222
  'keys': 'The workspace\'s own API keys: provision one headlessly, list them, revoke one (and what it minted).',
1082
1223
  };
1083
1224
  //# sourceMappingURL=tools.generated.js.map