@rallycry/conveyor-mcp 4.3.2 → 4.3.6
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-GNC7IHOT.js → chunk-OAHDLTC6.js} +55 -1
- package/dist/chunk-OAHDLTC6.js.map +1 -0
- package/dist/cli.js +394 -198
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/tunnel-cli.js +1 -1
- package/dist/tunnel.d.ts +72 -0
- package/package.json +1 -1
- package/dist/chunk-GNC7IHOT.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConveyorConnection
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-OAHDLTC6.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { createRequire } from "module";
|
|
@@ -55,8 +55,158 @@ function registerProjectTools(server2, conn2) {
|
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// src/tools/
|
|
58
|
+
// src/tools/project-config.ts
|
|
59
59
|
import { z as z2 } from "zod";
|
|
60
|
+
function jsonResult(data) {
|
|
61
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
62
|
+
}
|
|
63
|
+
function textResult(text) {
|
|
64
|
+
return { content: [{ type: "text", text }] };
|
|
65
|
+
}
|
|
66
|
+
var AGENT_DEFAULT_KEYS = [
|
|
67
|
+
"defaultPmAgentId",
|
|
68
|
+
"defaultTaskAgentId",
|
|
69
|
+
"defaultReviewerAgentId",
|
|
70
|
+
"helperAgentId"
|
|
71
|
+
];
|
|
72
|
+
function registerGetConnectUrls(server2, conn2) {
|
|
73
|
+
server2.tool(
|
|
74
|
+
"get_connect_urls",
|
|
75
|
+
"Get browser-only setup URLs to hand to the user: the Google Cloud OAuth connect link (gcpConnect) plus Settings deep links (gcpSettings, memberSettings, projectSettings, setupWizard). Use these for setup steps an agent cannot perform (OAuth grants, secret entry). Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
76
|
+
{
|
|
77
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID")
|
|
78
|
+
},
|
|
79
|
+
async (params) => jsonResult(await conn2.getConnectUrls(params.projectId))
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function registerUpdateProjectSettings(server2, conn2) {
|
|
83
|
+
server2.tool(
|
|
84
|
+
"update_project_settings",
|
|
85
|
+
"Update project configuration: name, description, default agent assignments, or a shallow-merged patch of the project settings JSON (e.g. compute tier keys). Requires a Moderate project role. Does NOT touch repositories or branches \u2014 those are configured in the Conveyor UI.",
|
|
86
|
+
{
|
|
87
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID"),
|
|
88
|
+
name: z2.string().optional().describe("New project name"),
|
|
89
|
+
description: z2.string().optional().describe("New project description"),
|
|
90
|
+
settings: z2.record(z2.unknown()).optional().describe("Shallow-merged patch of the project settings JSON (advanced)"),
|
|
91
|
+
defaultPmAgentId: z2.string().nullable().optional().describe("Default PM agent ID"),
|
|
92
|
+
defaultTaskAgentId: z2.string().nullable().optional().describe("Default task agent ID"),
|
|
93
|
+
defaultReviewerAgentId: z2.string().nullable().optional().describe("Default reviewer agent ID"),
|
|
94
|
+
helperAgentId: z2.string().nullable().optional().describe("Helper agent ID")
|
|
95
|
+
},
|
|
96
|
+
async (params) => {
|
|
97
|
+
const { projectId: projectId2, name, description, settings, ...agents } = params;
|
|
98
|
+
const results = [];
|
|
99
|
+
const config = {};
|
|
100
|
+
if (name !== void 0) config.name = name;
|
|
101
|
+
if (description !== void 0) config.description = description;
|
|
102
|
+
if (settings !== void 0) config.settings = settings;
|
|
103
|
+
if (Object.keys(config).length > 0) {
|
|
104
|
+
results.push(await conn2.updateProjectConfig({ projectId: projectId2, ...config }));
|
|
105
|
+
}
|
|
106
|
+
const defaults = {};
|
|
107
|
+
for (const key of AGENT_DEFAULT_KEYS) {
|
|
108
|
+
if (agents[key] !== void 0) defaults[key] = agents[key];
|
|
109
|
+
}
|
|
110
|
+
if (Object.keys(defaults).length > 0) {
|
|
111
|
+
results.push(await conn2.updateProjectAgentDefaults({ projectId: projectId2, ...defaults }));
|
|
112
|
+
}
|
|
113
|
+
if (results.length === 0) return textResult("Nothing to update \u2014 pass at least one field.");
|
|
114
|
+
return jsonResult(results.length === 1 ? results[0] : results);
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
function registerManageTags(server2, conn2) {
|
|
119
|
+
server2.tool(
|
|
120
|
+
"manage_tags",
|
|
121
|
+
"List, create, update, or delete project tags. create requires name (optional color/description); update/delete require the tag id. Mutations require a Moderate project role.",
|
|
122
|
+
{
|
|
123
|
+
action: z2.enum(["list", "create", "update", "delete"]).describe("Operation to perform"),
|
|
124
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID (list/create)"),
|
|
125
|
+
id: z2.string().optional().describe("Tag ID (update/delete)"),
|
|
126
|
+
name: z2.string().optional().describe("Tag name"),
|
|
127
|
+
color: z2.string().optional().describe("Hex color, e.g. #ff0000"),
|
|
128
|
+
description: z2.string().optional().describe("Tag description")
|
|
129
|
+
},
|
|
130
|
+
async (params) => {
|
|
131
|
+
const { action, projectId: projectId2, id, name, color, description } = params;
|
|
132
|
+
if (action === "list") return jsonResult(await conn2.listTagsDetailed(projectId2));
|
|
133
|
+
if (action === "create") {
|
|
134
|
+
if (!name) return textResult("name is required for create.");
|
|
135
|
+
return jsonResult(
|
|
136
|
+
await conn2.createTag({
|
|
137
|
+
projectId: projectId2,
|
|
138
|
+
name,
|
|
139
|
+
...color !== void 0 && { color },
|
|
140
|
+
...description !== void 0 && { description }
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
if (!id) return textResult(`id is required for ${action}.`);
|
|
145
|
+
if (action === "delete") return jsonResult(await conn2.deleteTag(id));
|
|
146
|
+
return jsonResult(
|
|
147
|
+
await conn2.updateTag({
|
|
148
|
+
id,
|
|
149
|
+
...name !== void 0 && { name },
|
|
150
|
+
...color !== void 0 && { color },
|
|
151
|
+
...description !== void 0 && { description }
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
function registerManagePriorities(server2, conn2) {
|
|
158
|
+
server2.tool(
|
|
159
|
+
"manage_priorities",
|
|
160
|
+
"List, create, update, or delete project priorities. create requires value (1-100), name, and color; update/delete require the priority id. create/update require a Moderate role; delete requires Admin.",
|
|
161
|
+
{
|
|
162
|
+
action: z2.enum(["list", "create", "update", "delete"]).describe("Operation to perform"),
|
|
163
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID (list/create)"),
|
|
164
|
+
id: z2.string().optional().describe("Priority ID (update/delete)"),
|
|
165
|
+
value: z2.number().int().min(1).max(100).optional().describe("Priority value (1 = highest urgency scale point)"),
|
|
166
|
+
name: z2.string().optional().describe("Priority name"),
|
|
167
|
+
color: z2.string().optional().describe("Hex color, e.g. #ff0000"),
|
|
168
|
+
description: z2.string().optional().describe("Priority description")
|
|
169
|
+
},
|
|
170
|
+
async (params) => {
|
|
171
|
+
const { action, projectId: projectId2, id, value, name, color, description } = params;
|
|
172
|
+
if (action === "list") return jsonResult(await conn2.listPriorities(projectId2));
|
|
173
|
+
if (action === "create") {
|
|
174
|
+
if (value === void 0 || !name || !color) {
|
|
175
|
+
return textResult("value, name, and color are required for create.");
|
|
176
|
+
}
|
|
177
|
+
return jsonResult(
|
|
178
|
+
await conn2.createPriority({
|
|
179
|
+
projectId: projectId2,
|
|
180
|
+
value,
|
|
181
|
+
name,
|
|
182
|
+
color,
|
|
183
|
+
...description !== void 0 && { description }
|
|
184
|
+
})
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
if (!id) return textResult(`id is required for ${action}.`);
|
|
188
|
+
if (action === "delete") return jsonResult(await conn2.deletePriority(id));
|
|
189
|
+
return jsonResult(
|
|
190
|
+
await conn2.updatePriority({
|
|
191
|
+
id,
|
|
192
|
+
...value !== void 0 && { value },
|
|
193
|
+
...name !== void 0 && { name },
|
|
194
|
+
...color !== void 0 && { color },
|
|
195
|
+
...description !== void 0 && { description }
|
|
196
|
+
})
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
function registerProjectConfigTools(server2, conn2) {
|
|
202
|
+
registerGetConnectUrls(server2, conn2);
|
|
203
|
+
registerUpdateProjectSettings(server2, conn2);
|
|
204
|
+
registerManageTags(server2, conn2);
|
|
205
|
+
registerManagePriorities(server2, conn2);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/tools/tasks.ts
|
|
209
|
+
import { z as z3 } from "zod";
|
|
60
210
|
var CLI_EVENT_FORMATTERS = {
|
|
61
211
|
thinking: (data) => String(data.message ?? ""),
|
|
62
212
|
tool_use: (data) => `${data.tool}: ${String(data.input ?? "").slice(0, 1e3)}`,
|
|
@@ -129,16 +279,19 @@ var RISK_ENUM = ["critical", "high", "medium", "low"];
|
|
|
129
279
|
function registerListTasks(server2, conn2) {
|
|
130
280
|
server2.tool(
|
|
131
281
|
"list_tasks",
|
|
132
|
-
"List project
|
|
282
|
+
"List project cards, optionally filtered by card type, status, or assignment (a specific assignee, or unassigned tasks). Defaults to type=task \u2014 pass typeFilters to list incidents/suggestions. Results are relevance-ordered: highest priority first then newest; suggestions-only queries rank by upvote score. Pass projectId to target a specific project; otherwise the configured default project is used. Returns summaries \u2014 plan omitted, description truncated; use get_task for full details.",
|
|
133
283
|
{
|
|
134
|
-
projectId:
|
|
135
|
-
status:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
284
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
285
|
+
status: z3.enum(STATUS_ENUM).optional().describe("Filter by task status"),
|
|
286
|
+
typeFilters: z3.array(z3.enum(CARD_TYPE_ENUM)).optional().describe(
|
|
287
|
+
'Card types to include, e.g. ["incident"] or ["task", "incident"]. Omit for tasks only.'
|
|
288
|
+
),
|
|
289
|
+
assigneeId: z3.string().optional().describe("Filter by assigned user ID"),
|
|
290
|
+
unassigned: z3.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
291
|
+
subProjectId: z3.string().optional().describe(
|
|
139
292
|
"Scope to a sub-project board (list/search: filter; create/update: assign). Omit for the whole project."
|
|
140
293
|
),
|
|
141
|
-
limit:
|
|
294
|
+
limit: z3.number().optional().describe("Max tasks to return (default 50)")
|
|
142
295
|
},
|
|
143
296
|
async (params) => {
|
|
144
297
|
const tasks = await conn2.listTasks(params);
|
|
@@ -153,8 +306,8 @@ function registerGetTask(server2, conn2) {
|
|
|
153
306
|
"get_task",
|
|
154
307
|
"Get full task details including plan, chat history, PR info, subtasks, and build status. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
155
308
|
{
|
|
156
|
-
projectId:
|
|
157
|
-
taskId:
|
|
309
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
310
|
+
taskId: z3.string().describe("The task ID or slug (the value in a card URL, /cards/<slug>)")
|
|
158
311
|
},
|
|
159
312
|
async (params) => {
|
|
160
313
|
const task = await conn2.getTask(params.taskId, params.projectId);
|
|
@@ -167,8 +320,8 @@ function registerGetCardBySlug(server2, conn2) {
|
|
|
167
320
|
"get_card_by_slug",
|
|
168
321
|
"Get full card details by the slug from a card URL (/cards/<slug>) instead of a task ID. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
169
322
|
{
|
|
170
|
-
projectId:
|
|
171
|
-
slug:
|
|
323
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
324
|
+
slug: z3.string().describe("The card slug from a Conveyor card URL, e.g. 'ship-it'")
|
|
172
325
|
},
|
|
173
326
|
async (params) => {
|
|
174
327
|
const task = await conn2.getCardBySlug(params.slug, params.projectId);
|
|
@@ -181,12 +334,12 @@ function registerCreateTask(server2, conn2) {
|
|
|
181
334
|
"create_task",
|
|
182
335
|
"Create a new task with title, description, and optional plan. Pass projectId to target a specific project; otherwise the configured default project is used. Icon, story points, and agent assignment are auto-filled when a task is created in (or later moved to) a status beyond Planning \u2014 don't spend turns on them.",
|
|
183
336
|
{
|
|
184
|
-
projectId:
|
|
185
|
-
title:
|
|
186
|
-
description:
|
|
187
|
-
plan:
|
|
188
|
-
status:
|
|
189
|
-
subProjectId:
|
|
337
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
338
|
+
title: z3.string().describe("Task title"),
|
|
339
|
+
description: z3.string().optional().describe("Task description"),
|
|
340
|
+
plan: z3.string().optional().describe("Task implementation plan (markdown)"),
|
|
341
|
+
status: z3.enum(["Planning", "Open"]).optional().describe("Initial status (default: Planning)"),
|
|
342
|
+
subProjectId: z3.string().optional().describe(
|
|
190
343
|
"Scope to a sub-project board (list/search: filter; create/update: assign). Omit for the whole project."
|
|
191
344
|
)
|
|
192
345
|
},
|
|
@@ -201,17 +354,19 @@ function registerCreateTask(server2, conn2) {
|
|
|
201
354
|
function registerUpdateTask(server2, conn2) {
|
|
202
355
|
server2.tool(
|
|
203
356
|
"update_task",
|
|
204
|
-
"Update task fields: title, plan, risk, or assignment.
|
|
357
|
+
"Update task fields: title, description, plan, status, risk, or assignment. Set status to claim a card (InProgress), triage it (Open), or cancel it (Cancelled); for review approvals prefer approve_task / request_changes, which guard against stale-state races. Pass projectId to target a specific project; otherwise the configured default project is used. Moving a task beyond Planning auto-fills any missing icon, story points, and agent assignment \u2014 don't spend turns on them.",
|
|
205
358
|
{
|
|
206
|
-
projectId:
|
|
207
|
-
taskId:
|
|
208
|
-
title:
|
|
209
|
-
|
|
210
|
-
|
|
359
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
360
|
+
taskId: z3.string().describe("The task ID"),
|
|
361
|
+
title: z3.string().optional().describe("New title"),
|
|
362
|
+
description: z3.string().optional().describe("New description"),
|
|
363
|
+
plan: z3.string().optional().describe("New plan (markdown)"),
|
|
364
|
+
status: z3.enum(STATUS_ENUM).optional().describe("New status"),
|
|
365
|
+
risk: z3.enum(RISK_ENUM).nullable().optional().describe(
|
|
211
366
|
"Risk level \u2014 how much important surface the task touches (critical/high/medium/low). Pass null to clear."
|
|
212
367
|
),
|
|
213
|
-
assignedUserId:
|
|
214
|
-
subProjectId:
|
|
368
|
+
assignedUserId: z3.string().nullable().optional().describe("User ID to assign, or null"),
|
|
369
|
+
subProjectId: z3.string().nullable().optional().describe(
|
|
215
370
|
"Assign the task to a sub-project board; null moves it back to the parent board. Omit to leave unchanged."
|
|
216
371
|
)
|
|
217
372
|
},
|
|
@@ -228,9 +383,9 @@ function registerMoveCard(server2, conn2) {
|
|
|
228
383
|
"move_card",
|
|
229
384
|
"Move an eligible Planning or Open task, incident, or suggestion card to another project. Cards with identification or automation in progress, active compute, pull requests, deployments, releases, reviews, or delivered reporter email cannot move. Project-specific metadata is cleared instead of mapped by name. Pass projectId for the source project; otherwise the configured default project is used.",
|
|
230
385
|
{
|
|
231
|
-
projectId:
|
|
232
|
-
taskId:
|
|
233
|
-
destinationProjectId:
|
|
386
|
+
projectId: z3.string().optional().describe("Source Conveyor project ID"),
|
|
387
|
+
taskId: z3.string().describe("Card ID or slug"),
|
|
388
|
+
destinationProjectId: z3.string().describe("Destination Conveyor project ID")
|
|
234
389
|
},
|
|
235
390
|
async (params) => {
|
|
236
391
|
const result = await conn2.moveCard(params);
|
|
@@ -251,9 +406,9 @@ function registerChatTools(server2, conn2) {
|
|
|
251
406
|
"read_task_chat",
|
|
252
407
|
"Read messages from a task's chat. Pass projectId to target a specific project; otherwise the configured default project is used. For agent execution logs use get_task_logs.",
|
|
253
408
|
{
|
|
254
|
-
projectId:
|
|
255
|
-
taskId:
|
|
256
|
-
limit:
|
|
409
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
410
|
+
taskId: z3.string().describe("The task ID"),
|
|
411
|
+
limit: z3.number().optional().describe("Max messages to return (default 50)")
|
|
257
412
|
},
|
|
258
413
|
async (params) => {
|
|
259
414
|
const messages = await conn2.getTaskChat(params.taskId, params.limit, params.projectId);
|
|
@@ -264,9 +419,9 @@ function registerChatTools(server2, conn2) {
|
|
|
264
419
|
"post_to_chat",
|
|
265
420
|
"Post a message to a task's chat. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
266
421
|
{
|
|
267
|
-
projectId:
|
|
268
|
-
taskId:
|
|
269
|
-
content:
|
|
422
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
423
|
+
taskId: z3.string().describe("The task ID"),
|
|
424
|
+
content: z3.string().describe("Message content")
|
|
270
425
|
},
|
|
271
426
|
async (params) => {
|
|
272
427
|
await conn2.postToTaskChat(params.taskId, params.content, params.projectId);
|
|
@@ -279,12 +434,12 @@ function registerGetTaskCli(server2, conn2) {
|
|
|
279
434
|
"get_task_logs",
|
|
280
435
|
"Read CLI execution logs from a task. Pass projectId to target a specific project; otherwise the configured default project is used. Returns agent reasoning, tool calls, setup output, and other execution events. For human chat use read_task_chat.",
|
|
281
436
|
{
|
|
282
|
-
projectId:
|
|
283
|
-
taskId:
|
|
284
|
-
source:
|
|
437
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
438
|
+
taskId: z3.string().describe("The task ID or slug"),
|
|
439
|
+
source: z3.enum(["agent", "application"]).optional().describe(
|
|
285
440
|
"Filter by log source: 'agent' for reasoning/tool calls, 'application' for setup/dev-server output"
|
|
286
441
|
),
|
|
287
|
-
limit:
|
|
442
|
+
limit: z3.number().optional().describe("Max entries to return (default 50, max 500)")
|
|
288
443
|
},
|
|
289
444
|
async ({ taskId, source, limit, projectId: projectId2 }) => {
|
|
290
445
|
const effectiveLimit = Math.min(limit ?? 50, 500);
|
|
@@ -303,8 +458,8 @@ function registerGetTaskSessions(server2, conn2) {
|
|
|
303
458
|
"get_task_sessions",
|
|
304
459
|
"Read compute-session state for a task: legacy CodespaceSession rows plus v3 workspaces, including purpose=review review workspaces. Shows pod identity, liveness, lifecycle, and code-review claim state. Use to diagnose stalled/dead agents or code-review runs. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
305
460
|
{
|
|
306
|
-
projectId:
|
|
307
|
-
taskId:
|
|
461
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
462
|
+
taskId: z3.string().describe("The task ID or slug")
|
|
308
463
|
},
|
|
309
464
|
async ({ taskId, projectId: projectId2 }) => {
|
|
310
465
|
const tasks = await conn2.getTaskSessions(taskId, projectId2);
|
|
@@ -320,21 +475,21 @@ function registerGetTaskSessions(server2, conn2) {
|
|
|
320
475
|
function registerSearchTasks(server2, conn2) {
|
|
321
476
|
server2.tool(
|
|
322
477
|
"search_tasks",
|
|
323
|
-
"Search cards by tag name, text query, status, type, and/or assignment. Defaults to type=task \u2014 pass typeFilters to include incidents/suggestions. Pass projectId to target a specific project; otherwise the configured default project is used. Use tag names like 'agent-runner', not IDs. Returns summaries \u2014 plan omitted, description truncated; use get_task for full details.",
|
|
478
|
+
"Search cards by tag name, text query, status, type, and/or assignment. Defaults to type=task \u2014 pass typeFilters to include incidents/suggestions. Results are relevance-ordered: highest priority first then newest; suggestions-only queries rank by upvote score. Pass projectId to target a specific project; otherwise the configured default project is used. Use tag names like 'agent-runner', not IDs. Returns summaries \u2014 plan omitted, description truncated; use get_task for full details.",
|
|
324
479
|
{
|
|
325
|
-
projectId:
|
|
326
|
-
tagNames:
|
|
327
|
-
searchQuery:
|
|
328
|
-
statusFilters:
|
|
329
|
-
typeFilters:
|
|
480
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
481
|
+
tagNames: z3.array(z3.string()).optional().describe('Tag names to filter by (e.g., ["agent-runner", "chat"])'),
|
|
482
|
+
searchQuery: z3.string().optional().describe("Text search on title and description"),
|
|
483
|
+
statusFilters: z3.array(z3.enum(STATUS_ENUM)).optional().describe("Filter by one or more statuses"),
|
|
484
|
+
typeFilters: z3.array(z3.enum(CARD_TYPE_ENUM)).optional().describe(
|
|
330
485
|
'Card types to include (default ["task"]). Pass e.g. ["incident"] or list several to search across types.'
|
|
331
486
|
),
|
|
332
|
-
assigneeId:
|
|
333
|
-
unassigned:
|
|
334
|
-
subProjectId:
|
|
487
|
+
assigneeId: z3.string().optional().describe("Filter by assigned user ID"),
|
|
488
|
+
unassigned: z3.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
489
|
+
subProjectId: z3.string().optional().describe(
|
|
335
490
|
"Scope to a sub-project board (list/search: filter; create/update: assign). Omit for the whole project."
|
|
336
491
|
),
|
|
337
|
-
limit:
|
|
492
|
+
limit: z3.number().optional().describe("Max results to return (default 20)")
|
|
338
493
|
},
|
|
339
494
|
async (params) => {
|
|
340
495
|
const tasks = await conn2.searchTasks(params);
|
|
@@ -349,7 +504,7 @@ function registerListTags(server2, conn2) {
|
|
|
349
504
|
"list_tags",
|
|
350
505
|
"List all project tags with their names, IDs, and colors. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
351
506
|
{
|
|
352
|
-
projectId:
|
|
507
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID")
|
|
353
508
|
},
|
|
354
509
|
async (params) => {
|
|
355
510
|
const tags = await conn2.listTags(params.projectId);
|
|
@@ -362,9 +517,9 @@ function registerReviewTools(server2, conn2) {
|
|
|
362
517
|
"approve_task",
|
|
363
518
|
"Move a task forward in the review flow (ReviewPR -> ReviewDev, or -> Complete). Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
364
519
|
{
|
|
365
|
-
projectId:
|
|
366
|
-
taskId:
|
|
367
|
-
risk:
|
|
520
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
521
|
+
taskId: z3.string().describe("The task ID"),
|
|
522
|
+
risk: z3.enum(RISK_ENUM).optional().describe("Optional risk level to record; defaults to a raise-only 'low' on approval.")
|
|
368
523
|
},
|
|
369
524
|
async (params) => {
|
|
370
525
|
const result = await conn2.approveTask(params.taskId, params.projectId, params.risk);
|
|
@@ -377,8 +532,8 @@ function registerReviewTools(server2, conn2) {
|
|
|
377
532
|
"approve_and_merge_pr",
|
|
378
533
|
"Approve and merge a child task's pull request. Pass projectId to target a specific project; otherwise the configured default project is used. Only succeeds if all CI/CD checks are passing. The child task must be in ReviewPR status with a PR.",
|
|
379
534
|
{
|
|
380
|
-
projectId:
|
|
381
|
-
childTaskId:
|
|
535
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
536
|
+
childTaskId: z3.string().describe("The child task ID whose PR should be approved and merged")
|
|
382
537
|
},
|
|
383
538
|
async (params) => {
|
|
384
539
|
const result = await conn2.approveAndMergePR(params.childTaskId, params.projectId);
|
|
@@ -396,10 +551,10 @@ function registerReviewTools(server2, conn2) {
|
|
|
396
551
|
"request_changes",
|
|
397
552
|
"Post feedback and send task back to InProgress for more work. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
398
553
|
{
|
|
399
|
-
projectId:
|
|
400
|
-
taskId:
|
|
401
|
-
feedback:
|
|
402
|
-
risk:
|
|
554
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
555
|
+
taskId: z3.string().describe("The task ID"),
|
|
556
|
+
feedback: z3.string().describe("Feedback message describing requested changes"),
|
|
557
|
+
risk: z3.enum(RISK_ENUM).optional().describe("Optional risk level to record; defaults to a raise-only 'medium' on changes.")
|
|
403
558
|
},
|
|
404
559
|
async (params) => {
|
|
405
560
|
await conn2.requestChanges(params.taskId, params.feedback, params.projectId, params.risk);
|
|
@@ -416,9 +571,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
416
571
|
"add_reviewer",
|
|
417
572
|
"Add a project member as a reviewer on a task. Pass projectId to target a specific project; otherwise the configured default project is used. Idempotent \u2014 adding an existing reviewer is a no-op.",
|
|
418
573
|
{
|
|
419
|
-
projectId:
|
|
420
|
-
taskId:
|
|
421
|
-
userId:
|
|
574
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
575
|
+
taskId: z3.string().describe("The task ID or slug"),
|
|
576
|
+
userId: z3.string().describe("User ID of the reviewer (use list_project_members to resolve a name or email)")
|
|
422
577
|
},
|
|
423
578
|
async (params) => {
|
|
424
579
|
const result = await conn2.addReviewer(params);
|
|
@@ -436,9 +591,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
436
591
|
"remove_reviewer",
|
|
437
592
|
"Remove a reviewer from a task. Pass projectId to target a specific project; otherwise the configured default project is used. Idempotent \u2014 removing a non-reviewer is a no-op.",
|
|
438
593
|
{
|
|
439
|
-
projectId:
|
|
440
|
-
taskId:
|
|
441
|
-
userId:
|
|
594
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
595
|
+
taskId: z3.string().describe("The task ID or slug"),
|
|
596
|
+
userId: z3.string().describe("User ID of the reviewer to remove")
|
|
442
597
|
},
|
|
443
598
|
async (params) => {
|
|
444
599
|
const result = await conn2.removeReviewer(params);
|
|
@@ -470,8 +625,8 @@ function registerTaskTools(server2, conn2) {
|
|
|
470
625
|
}
|
|
471
626
|
|
|
472
627
|
// src/tools/builds.ts
|
|
473
|
-
import { z as
|
|
474
|
-
function
|
|
628
|
+
import { z as z4 } from "zod";
|
|
629
|
+
function textResult2(result) {
|
|
475
630
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
476
631
|
}
|
|
477
632
|
function registerTaskLifecycleTools(server2, conn2) {
|
|
@@ -479,37 +634,37 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
479
634
|
"stop_task",
|
|
480
635
|
"Compatibility alias for the legacy stop path. stop_task now performs the same durable sleep behavior as sleep_task, preserving task Claudespace state while stopping compute. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
481
636
|
{
|
|
482
|
-
projectId:
|
|
483
|
-
taskId:
|
|
637
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
638
|
+
taskId: z4.string().describe("The task ID")
|
|
484
639
|
},
|
|
485
|
-
async (params) =>
|
|
640
|
+
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
486
641
|
);
|
|
487
642
|
server2.tool(
|
|
488
643
|
"sleep_task",
|
|
489
644
|
"Sleep a task Claudespace, stopping compute while preserving durable state. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
490
645
|
{
|
|
491
|
-
projectId:
|
|
492
|
-
taskId:
|
|
646
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
647
|
+
taskId: z4.string().describe("The task ID")
|
|
493
648
|
},
|
|
494
|
-
async (params) =>
|
|
649
|
+
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
495
650
|
);
|
|
496
651
|
server2.tool(
|
|
497
652
|
"resume_task",
|
|
498
653
|
"Resume a sleeping task Claudespace. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
499
654
|
{
|
|
500
|
-
projectId:
|
|
501
|
-
taskId:
|
|
655
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
656
|
+
taskId: z4.string().describe("The task ID")
|
|
502
657
|
},
|
|
503
|
-
async (params) =>
|
|
658
|
+
async (params) => textResult2(await conn2.resumeTask(params.taskId, params.projectId))
|
|
504
659
|
);
|
|
505
660
|
server2.tool(
|
|
506
661
|
"delete_task_environment",
|
|
507
662
|
"Delete a task environment, including durable Claudespace state. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
508
663
|
{
|
|
509
|
-
projectId:
|
|
510
|
-
taskId:
|
|
664
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
665
|
+
taskId: z4.string().describe("The task ID")
|
|
511
666
|
},
|
|
512
|
-
async (params) =>
|
|
667
|
+
async (params) => textResult2(await conn2.deleteTaskEnvironment(params.taskId, params.projectId))
|
|
513
668
|
);
|
|
514
669
|
}
|
|
515
670
|
function registerBuildTools(server2, conn2) {
|
|
@@ -517,12 +672,12 @@ function registerBuildTools(server2, conn2) {
|
|
|
517
672
|
"start_task",
|
|
518
673
|
"Start a cloud build (codespace) for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
519
674
|
{
|
|
520
|
-
projectId:
|
|
521
|
-
taskId:
|
|
675
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
676
|
+
taskId: z4.string().describe("The task ID")
|
|
522
677
|
},
|
|
523
678
|
async (params) => {
|
|
524
679
|
const result = await conn2.startBuild(params.taskId, params.projectId);
|
|
525
|
-
return
|
|
680
|
+
return textResult2(result);
|
|
526
681
|
}
|
|
527
682
|
);
|
|
528
683
|
registerTaskLifecycleTools(server2, conn2);
|
|
@@ -530,26 +685,26 @@ function registerBuildTools(server2, conn2) {
|
|
|
530
685
|
"create_release",
|
|
531
686
|
"Create a release for the project \u2014 the same flow as the Release button in the web UI. Pass projectId to target a specific project; otherwise the configured default project is used. Creates a release task with a release/YYYY.MM.N branch and a PR from the dev branch to the default branch. Omit taskIds to release ALL cards currently in Review (Dev); pass a subset to cherry-pick \u2014 a cloud build agent then cherry-picks those changes and resolves conflicts. Fails if a release is already in progress or no cards are in Review (Dev).",
|
|
532
687
|
{
|
|
533
|
-
projectId:
|
|
534
|
-
taskIds:
|
|
688
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
689
|
+
taskIds: z4.array(z4.string()).optional().describe(
|
|
535
690
|
"Task IDs in Review (Dev) to cherry-pick into the release. Omit to release all of them."
|
|
536
691
|
)
|
|
537
692
|
},
|
|
538
693
|
async (params) => {
|
|
539
694
|
const result = await conn2.createRelease(params.taskIds, params.projectId);
|
|
540
|
-
return
|
|
695
|
+
return textResult2(result);
|
|
541
696
|
}
|
|
542
697
|
);
|
|
543
698
|
server2.tool(
|
|
544
699
|
"get_build_status",
|
|
545
700
|
"Check codespace and agent status for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
546
701
|
{
|
|
547
|
-
projectId:
|
|
548
|
-
taskId:
|
|
702
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
703
|
+
taskId: z4.string().describe("The task ID")
|
|
549
704
|
},
|
|
550
705
|
async (params) => {
|
|
551
706
|
const status = await conn2.getBuildStatus(params.taskId, params.projectId);
|
|
552
|
-
return
|
|
707
|
+
return textResult2(status);
|
|
553
708
|
}
|
|
554
709
|
);
|
|
555
710
|
}
|
|
@@ -557,7 +712,7 @@ function registerBuildTools(server2, conn2) {
|
|
|
557
712
|
// src/tools/attachments.ts
|
|
558
713
|
import { readFile, stat } from "fs/promises";
|
|
559
714
|
import { basename, extname } from "path";
|
|
560
|
-
import { z as
|
|
715
|
+
import { z as z5 } from "zod";
|
|
561
716
|
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
562
717
|
var MIME_BY_EXT = {
|
|
563
718
|
".png": "image/png",
|
|
@@ -594,8 +749,8 @@ function registerListTaskFiles(server2, conn2) {
|
|
|
594
749
|
"list_task_files",
|
|
595
750
|
"List all files attached to a task with metadata (no contents \u2014 fast and small). Pass projectId to target a specific project; otherwise the configured default project is used. Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.",
|
|
596
751
|
{
|
|
597
|
-
projectId:
|
|
598
|
-
taskId:
|
|
752
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
753
|
+
taskId: z5.string().describe("The task ID or slug")
|
|
599
754
|
},
|
|
600
755
|
async (params) => {
|
|
601
756
|
const files = await conn2.listTaskFiles(params.taskId, params.projectId);
|
|
@@ -637,11 +792,11 @@ function registerGetAttachment(server2, conn2) {
|
|
|
637
792
|
"get_attachment",
|
|
638
793
|
"Fetch one task file's content plus metadata by file ID (accepts task id or slug). Pass projectId to target a specific project; otherwise the configured default project is used. Images are returned as viewable image blocks. Large text files (logs, JSON) are returned in pages \u2014 use `offset`/`maxBytes` to read more, or fetch `downloadUrl` for the whole file. Call list_task_files first to discover IDs and sizes.",
|
|
639
794
|
{
|
|
640
|
-
projectId:
|
|
641
|
-
taskId:
|
|
642
|
-
fileId:
|
|
643
|
-
offset:
|
|
644
|
-
maxBytes:
|
|
795
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
796
|
+
taskId: z5.string().describe("The task ID or slug"),
|
|
797
|
+
fileId: z5.string().describe("The file ID to fetch"),
|
|
798
|
+
offset: z5.number().int().nonnegative().optional().describe("Byte offset into text content (paging). Default 0."),
|
|
799
|
+
maxBytes: z5.number().int().positive().optional().describe("Max bytes of text content to return from offset.")
|
|
645
800
|
},
|
|
646
801
|
async (params) => {
|
|
647
802
|
const file = await conn2.getAttachment(params.taskId, params.fileId, {
|
|
@@ -658,11 +813,11 @@ function registerUploadAttachment(server2, conn2) {
|
|
|
658
813
|
"upload_attachment",
|
|
659
814
|
"Upload a local file as a task attachment (any file type, up to 25MB). Pass projectId to target a specific project; otherwise the configured default project is used. The file appears under the task's Files. Pass `comment` to also post it to the task chat in the same step.",
|
|
660
815
|
{
|
|
661
|
-
projectId:
|
|
662
|
-
taskId:
|
|
663
|
-
path:
|
|
664
|
-
comment:
|
|
665
|
-
mimeType:
|
|
816
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
817
|
+
taskId: z5.string().describe("The task ID or slug"),
|
|
818
|
+
path: z5.string().describe("Absolute path to the local file to upload"),
|
|
819
|
+
comment: z5.string().optional().describe("When set, also posts the attachment to the task chat with this text"),
|
|
820
|
+
mimeType: z5.string().optional().describe("Override the mime type inferred from the file extension")
|
|
666
821
|
},
|
|
667
822
|
async (params) => {
|
|
668
823
|
const info = await stat(params.path).catch(() => null);
|
|
@@ -725,18 +880,18 @@ function registerAttachmentTools(server2, conn2) {
|
|
|
725
880
|
}
|
|
726
881
|
|
|
727
882
|
// src/tools/pull-request.ts
|
|
728
|
-
import { z as
|
|
883
|
+
import { z as z6 } from "zod";
|
|
729
884
|
function registerPullRequestTools(server2, conn2) {
|
|
730
885
|
server2.tool(
|
|
731
886
|
"create_pull_request",
|
|
732
887
|
"Open a GitHub pull request for a task's existing branch (the branch must already be pushed to origin). Pass projectId to target a specific project; otherwise the configured default project is used. Moves the task to ReviewPR. Returns the PR number and URL.",
|
|
733
888
|
{
|
|
734
|
-
projectId:
|
|
735
|
-
taskId:
|
|
736
|
-
title:
|
|
737
|
-
body:
|
|
738
|
-
head:
|
|
739
|
-
base:
|
|
889
|
+
projectId: z6.string().optional().describe("Target Conveyor project ID"),
|
|
890
|
+
taskId: z6.string().describe("The task ID whose branch should be opened as a PR"),
|
|
891
|
+
title: z6.string().describe("Pull request title"),
|
|
892
|
+
body: z6.string().describe("Pull request body (markdown)"),
|
|
893
|
+
head: z6.string().optional().describe("Source branch for the PR (defaults to the task's branch)"),
|
|
894
|
+
base: z6.string().optional().describe("Target branch for the PR (defaults to the repo default)")
|
|
740
895
|
},
|
|
741
896
|
async (params) => {
|
|
742
897
|
const result = await conn2.createPullRequest(params);
|
|
@@ -748,7 +903,7 @@ function registerPullRequestTools(server2, conn2) {
|
|
|
748
903
|
}
|
|
749
904
|
|
|
750
905
|
// src/tools/subtasks.ts
|
|
751
|
-
import { z as
|
|
906
|
+
import { z as z7 } from "zod";
|
|
752
907
|
var STATUS_ENUM2 = [
|
|
753
908
|
"Planning",
|
|
754
909
|
"Open",
|
|
@@ -766,15 +921,15 @@ function registerCreateSubtask(server2, conn2) {
|
|
|
766
921
|
"create_subtask",
|
|
767
922
|
"Create a subtask under a parent task. Pass projectId to target a specific project; otherwise the configured default project is used. Subtasks break a larger task into independently buildable pieces. For children that instead ship on the parent's own branch/PR (e.g. per-theme tracking cards for one bundled PR), set followParentStatus so their status rides the parent's automatically.",
|
|
768
923
|
{
|
|
769
|
-
projectId:
|
|
770
|
-
parentTaskId:
|
|
771
|
-
title:
|
|
772
|
-
description:
|
|
773
|
-
plan:
|
|
774
|
-
ordinal:
|
|
775
|
-
storyPointValue:
|
|
776
|
-
followParentStatus:
|
|
777
|
-
dependsOn:
|
|
924
|
+
projectId: z7.string().optional().describe("Target Conveyor project ID"),
|
|
925
|
+
parentTaskId: z7.string().describe("The parent task ID"),
|
|
926
|
+
title: z7.string().describe("Subtask title"),
|
|
927
|
+
description: z7.string().optional().describe("Subtask description"),
|
|
928
|
+
plan: z7.string().optional().describe("Subtask implementation plan (markdown)"),
|
|
929
|
+
ordinal: z7.number().optional().describe("Ordering position among siblings"),
|
|
930
|
+
storyPointValue: z7.number().optional().describe(SP_DESCRIPTION),
|
|
931
|
+
followParentStatus: z7.boolean().optional().describe(FOLLOW_PARENT_STATUS_DESCRIPTION),
|
|
932
|
+
dependsOn: z7.array(z7.string()).optional().describe(
|
|
778
933
|
"Sibling subtask ids or slugs this subtask blocks on (it won't start until they merge to dev). Set explicit dependency metadata here instead of describing order in the plan text. Omit / leave empty for independent children so they run in parallel."
|
|
779
934
|
)
|
|
780
935
|
},
|
|
@@ -789,17 +944,20 @@ function registerCreateSubtask(server2, conn2) {
|
|
|
789
944
|
function registerUpdateSubtask(server2, conn2) {
|
|
790
945
|
server2.tool(
|
|
791
946
|
"update_subtask",
|
|
792
|
-
"Update a subtask's fields: title, description, plan, status, ordering,
|
|
947
|
+
"Update a subtask's fields: title, description, plan, status, ordering, story points, or dependencies. Pass projectId to target a specific project; otherwise the configured default project is used. Moving a subtask beyond Planning auto-fills missing story points and agent assignment \u2014 don't spend turns on them.",
|
|
793
948
|
{
|
|
794
|
-
projectId:
|
|
795
|
-
subtaskId:
|
|
796
|
-
title:
|
|
797
|
-
description:
|
|
798
|
-
plan:
|
|
799
|
-
status:
|
|
800
|
-
ordinal:
|
|
801
|
-
storyPointValue:
|
|
802
|
-
followParentStatus:
|
|
949
|
+
projectId: z7.string().optional().describe("Target Conveyor project ID"),
|
|
950
|
+
subtaskId: z7.string().describe("The subtask ID"),
|
|
951
|
+
title: z7.string().optional().describe("New title"),
|
|
952
|
+
description: z7.string().optional().describe("New description"),
|
|
953
|
+
plan: z7.string().optional().describe("New plan (markdown)"),
|
|
954
|
+
status: z7.enum(STATUS_ENUM2).optional().describe("New status"),
|
|
955
|
+
ordinal: z7.number().optional().describe("New ordering position among siblings"),
|
|
956
|
+
storyPointValue: z7.number().optional().describe(SP_DESCRIPTION),
|
|
957
|
+
followParentStatus: z7.boolean().optional().describe(FOLLOW_PARENT_STATUS_DESCRIPTION),
|
|
958
|
+
dependsOn: z7.array(z7.string()).optional().describe(
|
|
959
|
+
"Replace the sibling subtask ids/slugs this subtask blocks on (pass [] to clear). Omit to leave dependencies unchanged."
|
|
960
|
+
)
|
|
803
961
|
},
|
|
804
962
|
async (params) => {
|
|
805
963
|
const result = await conn2.updateSubtask(params);
|
|
@@ -816,8 +974,8 @@ function registerListSubtasks(server2, conn2) {
|
|
|
816
974
|
"list_subtasks",
|
|
817
975
|
"List all subtasks of a parent task with their status and ordering. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
818
976
|
{
|
|
819
|
-
projectId:
|
|
820
|
-
taskId:
|
|
977
|
+
projectId: z7.string().optional().describe("Target Conveyor project ID"),
|
|
978
|
+
taskId: z7.string().describe("The parent task ID")
|
|
821
979
|
},
|
|
822
980
|
async (params) => {
|
|
823
981
|
const subtasks = await conn2.listSubtasks(params.taskId, params.projectId);
|
|
@@ -830,8 +988,8 @@ function registerDeleteSubtask(server2, conn2) {
|
|
|
830
988
|
"delete_subtask",
|
|
831
989
|
"Delete a subtask by ID. Pass projectId to target a specific project; otherwise the configured default project is used. This is permanent \u2014 use update_subtask to set status to Cancelled if you only want to close it.",
|
|
832
990
|
{
|
|
833
|
-
projectId:
|
|
834
|
-
subtaskId:
|
|
991
|
+
projectId: z7.string().optional().describe("Target Conveyor project ID"),
|
|
992
|
+
subtaskId: z7.string().describe("The subtask ID to delete")
|
|
835
993
|
},
|
|
836
994
|
async (params) => {
|
|
837
995
|
const result = await conn2.deleteSubtask(params.subtaskId, params.projectId);
|
|
@@ -851,14 +1009,14 @@ function registerSubtaskTools(server2, conn2) {
|
|
|
851
1009
|
}
|
|
852
1010
|
|
|
853
1011
|
// src/tools/dependencies.ts
|
|
854
|
-
import { z as
|
|
1012
|
+
import { z as z8 } from "zod";
|
|
855
1013
|
function registerGetDependencies(server2, conn2) {
|
|
856
1014
|
server2.tool(
|
|
857
1015
|
"get_dependencies",
|
|
858
1016
|
"Get a task's dependencies and their met/unmet status (met = merged to dev). Pass projectId to target a specific project; otherwise the configured default project is used. Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.",
|
|
859
1017
|
{
|
|
860
|
-
projectId:
|
|
861
|
-
taskId:
|
|
1018
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1019
|
+
taskId: z8.string().describe("The task ID")
|
|
862
1020
|
},
|
|
863
1021
|
async (params) => {
|
|
864
1022
|
const deps = await conn2.getDependencies(params.taskId, params.projectId);
|
|
@@ -871,9 +1029,9 @@ function registerAddDependency(server2, conn2) {
|
|
|
871
1029
|
"add_dependency",
|
|
872
1030
|
"Add a blocking dependency \u2014 this task cannot start until the named task is merged to dev. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
873
1031
|
{
|
|
874
|
-
projectId:
|
|
875
|
-
taskId:
|
|
876
|
-
dependsOnSlugOrId:
|
|
1032
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1033
|
+
taskId: z8.string().describe("The task ID that will be blocked"),
|
|
1034
|
+
dependsOnSlugOrId: z8.string().describe("Slug or ID of the task this one depends on")
|
|
877
1035
|
},
|
|
878
1036
|
async (params) => {
|
|
879
1037
|
await conn2.addDependency(params);
|
|
@@ -886,9 +1044,9 @@ function registerRemoveDependency(server2, conn2) {
|
|
|
886
1044
|
"remove_dependency",
|
|
887
1045
|
"Remove a previously added dependency from a task. Pass projectId to target a specific project; otherwise the configured default project is used. The task is no longer blocked by the named task. Returns: confirmation string.",
|
|
888
1046
|
{
|
|
889
|
-
projectId:
|
|
890
|
-
taskId:
|
|
891
|
-
dependsOnSlugOrId:
|
|
1047
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1048
|
+
taskId: z8.string().describe("The task ID to unblock"),
|
|
1049
|
+
dependsOnSlugOrId: z8.string().describe("Slug or ID of the dependency to remove")
|
|
892
1050
|
},
|
|
893
1051
|
async (params) => {
|
|
894
1052
|
await conn2.removeDependency(params);
|
|
@@ -903,16 +1061,16 @@ function registerDependencyTools(server2, conn2) {
|
|
|
903
1061
|
}
|
|
904
1062
|
|
|
905
1063
|
// src/tools/suggestions.ts
|
|
906
|
-
import { z as
|
|
1064
|
+
import { z as z9 } from "zod";
|
|
907
1065
|
function registerSuggestionTools(server2, conn2) {
|
|
908
1066
|
server2.tool(
|
|
909
1067
|
"create_suggestion",
|
|
910
1068
|
"Suggest a feature, improvement, rule, or idea for the project. Pass projectId to target a specific project; otherwise the configured default project is used. Duplicates are deduped and your upvote is recorded.",
|
|
911
1069
|
{
|
|
912
|
-
projectId:
|
|
913
|
-
title:
|
|
914
|
-
description:
|
|
915
|
-
tagNames:
|
|
1070
|
+
projectId: z9.string().optional().describe("Target Conveyor project ID"),
|
|
1071
|
+
title: z9.string().describe("Suggestion title"),
|
|
1072
|
+
description: z9.string().optional().describe("Suggestion details (markdown)"),
|
|
1073
|
+
tagNames: z9.array(z9.string()).optional().describe('Tag names to categorize the suggestion (e.g., ["agent-runner"])')
|
|
916
1074
|
},
|
|
917
1075
|
async (params) => {
|
|
918
1076
|
const result = await conn2.createSuggestion(params);
|
|
@@ -923,7 +1081,7 @@ function registerSuggestionTools(server2, conn2) {
|
|
|
923
1081
|
}
|
|
924
1082
|
|
|
925
1083
|
// src/tools/checklists.ts
|
|
926
|
-
import { z as
|
|
1084
|
+
import { z as z10 } from "zod";
|
|
927
1085
|
function renderManualTestGroups(groups) {
|
|
928
1086
|
const lines = [];
|
|
929
1087
|
for (const g of groups) {
|
|
@@ -932,7 +1090,7 @@ function renderManualTestGroups(groups) {
|
|
|
932
1090
|
const mark = t.status === "approved" ? "\u2713" : t.status === "rejected" ? "\u2717" : "\u25CB";
|
|
933
1091
|
lines.push(` ${mark} ${t.title} \u2014 ${t.status}`);
|
|
934
1092
|
if (t.status === "rejected") {
|
|
935
|
-
for (const f of t.failures) {
|
|
1093
|
+
for (const f of t.failures ?? []) {
|
|
936
1094
|
lines.push(` \u26A0 ${f.userName ?? "Someone"}: ${f.reason ?? "(no message)"}`);
|
|
937
1095
|
}
|
|
938
1096
|
}
|
|
@@ -946,8 +1104,8 @@ function registerListManualTests(server2, conn2) {
|
|
|
946
1104
|
"list_manual_tests",
|
|
947
1105
|
"List the manual test checklist items for a task. Pass projectId to target a specific project; otherwise the configured default project is used. Use to see what manual verification steps have already been recorded.",
|
|
948
1106
|
{
|
|
949
|
-
projectId:
|
|
950
|
-
taskId:
|
|
1107
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1108
|
+
taskId: z10.string().describe("The task ID or slug (the value in a card URL, /cards/<slug>)")
|
|
951
1109
|
},
|
|
952
1110
|
async (params) => {
|
|
953
1111
|
const items = await conn2.listManualTests(params.taskId, params.projectId);
|
|
@@ -973,9 +1131,9 @@ function registerSetManualTests(server2, conn2) {
|
|
|
973
1131
|
"set_manual_tests",
|
|
974
1132
|
"Add manual test steps to a task's checklist. Pass projectId to target a specific project; otherwise the configured default project is used. Existing items with the same title are automatically skipped (deduplication). Use to record specific manual verification steps that reviewers should follow when testing the task's PR.",
|
|
975
1133
|
{
|
|
976
|
-
projectId:
|
|
977
|
-
taskId:
|
|
978
|
-
items:
|
|
1134
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1135
|
+
taskId: z10.string().describe("The task ID or slug"),
|
|
1136
|
+
items: z10.array(z10.object({ title: z10.string().min(1).describe("A concise, actionable test step") })).min(1).describe("List of manual test steps to add")
|
|
979
1137
|
},
|
|
980
1138
|
async (params) => {
|
|
981
1139
|
const result = await conn2.setManualTests(params.taskId, params.items, params.projectId);
|
|
@@ -990,10 +1148,10 @@ function registerEditManualTest(server2, conn2) {
|
|
|
990
1148
|
"edit_manual_test",
|
|
991
1149
|
"Rename an existing manual test step on a task. Pass projectId to target a specific project; otherwise the configured default project is used. Identify the test by its current title (case-insensitive) and pass the new title to replace it.",
|
|
992
1150
|
{
|
|
993
|
-
projectId:
|
|
994
|
-
taskId:
|
|
995
|
-
title:
|
|
996
|
-
newTitle:
|
|
1151
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1152
|
+
taskId: z10.string().describe("The task ID or slug"),
|
|
1153
|
+
title: z10.string().min(1).describe("The current title of the manual test to edit"),
|
|
1154
|
+
newTitle: z10.string().min(1).describe("The new title for the manual test")
|
|
997
1155
|
},
|
|
998
1156
|
async (params) => {
|
|
999
1157
|
await conn2.editManualTest(params.taskId, params.title, params.newTitle, params.projectId);
|
|
@@ -1006,9 +1164,9 @@ function registerRemoveManualTest(server2, conn2) {
|
|
|
1006
1164
|
"remove_manual_test",
|
|
1007
1165
|
"Remove an existing manual test step from a task's checklist. Pass projectId to target a specific project; otherwise the configured default project is used. Identify the test by its title (case-insensitive).",
|
|
1008
1166
|
{
|
|
1009
|
-
projectId:
|
|
1010
|
-
taskId:
|
|
1011
|
-
title:
|
|
1167
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1168
|
+
taskId: z10.string().describe("The task ID or slug"),
|
|
1169
|
+
title: z10.string().min(1).describe("The title of the manual test to remove")
|
|
1012
1170
|
},
|
|
1013
1171
|
async (params) => {
|
|
1014
1172
|
await conn2.removeManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1021,9 +1179,9 @@ function registerApproveManualTest(server2, conn2) {
|
|
|
1021
1179
|
"approve_manual_test",
|
|
1022
1180
|
"Sign off on (approve) a manual test step on a task on behalf of your authenticated user. Pass projectId to target a specific project; otherwise the configured default project is used. Identify the test by its title (case-insensitive). Use after you have verified the step passes.",
|
|
1023
1181
|
{
|
|
1024
|
-
projectId:
|
|
1025
|
-
taskId:
|
|
1026
|
-
title:
|
|
1182
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1183
|
+
taskId: z10.string().describe("The task ID or slug"),
|
|
1184
|
+
title: z10.string().min(1).describe("The title of the manual test to approve")
|
|
1027
1185
|
},
|
|
1028
1186
|
async (params) => {
|
|
1029
1187
|
await conn2.approveManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1036,10 +1194,10 @@ function registerRejectManualTest(server2, conn2) {
|
|
|
1036
1194
|
"reject_manual_test",
|
|
1037
1195
|
"Flag an issue with (reject) a manual test step on a task on behalf of your authenticated user, recording the reason. Pass projectId to target a specific project; otherwise the configured default project is used. Identify the test by its title (case-insensitive). Use when the step fails verification.",
|
|
1038
1196
|
{
|
|
1039
|
-
projectId:
|
|
1040
|
-
taskId:
|
|
1041
|
-
title:
|
|
1042
|
-
reason:
|
|
1197
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1198
|
+
taskId: z10.string().describe("The task ID or slug"),
|
|
1199
|
+
title: z10.string().min(1).describe("The title of the manual test to reject"),
|
|
1200
|
+
reason: z10.string().min(1).max(2e3).describe("Why the test failed \u2014 what went wrong, shown to the team")
|
|
1043
1201
|
},
|
|
1044
1202
|
async (params) => {
|
|
1045
1203
|
await conn2.rejectManualTest(params.taskId, params.title, params.reason, params.projectId);
|
|
@@ -1059,9 +1217,9 @@ function registerQueryManualTests(server2, conn2) {
|
|
|
1059
1217
|
"query_manual_tests",
|
|
1060
1218
|
"Query manual tests across many tasks in a project, grouped by task. Filter by card status (e.g. ReviewDev, ReviewLive, Complete) and/or test status (open | approved | rejected). Use to answer questions like 'show all OPEN manual tests in ReviewDev' or 'show all REJECTED manual tests in ReviewDev/ReviewLive with the failing reason'. With no filters it defaults to the needs-attention view: open+rejected tests on ReviewDev/ReviewLive cards. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
1061
1219
|
{
|
|
1062
|
-
projectId:
|
|
1063
|
-
cardStatuses:
|
|
1064
|
-
testStatuses:
|
|
1220
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1221
|
+
cardStatuses: z10.array(z10.string()).optional().describe('Filter tasks by card/column status, e.g. ["ReviewDev", "ReviewLive"]'),
|
|
1222
|
+
testStatuses: z10.array(z10.enum(["open", "approved", "rejected"])).optional().describe("Filter tests by status: open | approved | rejected")
|
|
1065
1223
|
},
|
|
1066
1224
|
async (params) => {
|
|
1067
1225
|
const groups = await conn2.queryManualTests({
|
|
@@ -1087,7 +1245,7 @@ function registerChecklistTools(server2, conn2) {
|
|
|
1087
1245
|
}
|
|
1088
1246
|
|
|
1089
1247
|
// src/tools/workspace.ts
|
|
1090
|
-
import { z as
|
|
1248
|
+
import { z as z11 } from "zod";
|
|
1091
1249
|
|
|
1092
1250
|
// src/workspace-ssh-tunnel.ts
|
|
1093
1251
|
import net from "net";
|
|
@@ -1206,8 +1364,8 @@ function registerAttachInfoTool(server2, conn2) {
|
|
|
1206
1364
|
"workspace_attach_info",
|
|
1207
1365
|
"Return SSH/SFTP attach metadata for a running task Claudespace, plus hosted preview URLs and configured preview ports. Optionally installs an OpenSSH public key for this attach session.",
|
|
1208
1366
|
{
|
|
1209
|
-
taskId:
|
|
1210
|
-
sshPublicKey:
|
|
1367
|
+
taskId: z11.string().describe("The task ID"),
|
|
1368
|
+
sshPublicKey: z11.string().optional().describe("Optional OpenSSH public key to install into the workspace")
|
|
1211
1369
|
},
|
|
1212
1370
|
async ({ taskId, sshPublicKey }) => {
|
|
1213
1371
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1220,7 +1378,7 @@ function registerPreviewUrlsTool(server2, conn2) {
|
|
|
1220
1378
|
"workspace_preview_urls",
|
|
1221
1379
|
"Return the hosted preview URLs and preview ports for a running task Claudespace. This mirrors the web UI preview link metadata.",
|
|
1222
1380
|
{
|
|
1223
|
-
taskId:
|
|
1381
|
+
taskId: z11.string().describe("The task ID")
|
|
1224
1382
|
},
|
|
1225
1383
|
async ({ taskId }) => {
|
|
1226
1384
|
const info = await conn2.getWorkspaceAttachInfo(taskId);
|
|
@@ -1249,10 +1407,10 @@ function registerStartTunnelTool(server2, conn2, startTunnel) {
|
|
|
1249
1407
|
"workspace_start_tunnel",
|
|
1250
1408
|
"Start a local loopback tunnel through the MCP server to a running task Claudespace port. Use port 2222 for SSH/SFTP, or one of previewPorts for app access.",
|
|
1251
1409
|
{
|
|
1252
|
-
taskId:
|
|
1253
|
-
port:
|
|
1254
|
-
preferredLocalPort:
|
|
1255
|
-
sshPublicKey:
|
|
1410
|
+
taskId: z11.string().describe("The task ID"),
|
|
1411
|
+
port: z11.number().optional().describe("Remote Claudespace port. Defaults to SSH port 2222."),
|
|
1412
|
+
preferredLocalPort: z11.number().optional().describe("Preferred local loopback port. If omitted, the OS chooses one."),
|
|
1413
|
+
sshPublicKey: z11.string().optional().describe("Optional OpenSSH public key to install before opening the tunnel")
|
|
1256
1414
|
},
|
|
1257
1415
|
async ({ taskId, port, preferredLocalPort, sshPublicKey }) => {
|
|
1258
1416
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1305,7 +1463,7 @@ function registerStopTunnelTool(server2) {
|
|
|
1305
1463
|
"workspace_stop_tunnel",
|
|
1306
1464
|
"Stop a local workspace tunnel previously opened by workspace_start_tunnel.",
|
|
1307
1465
|
{
|
|
1308
|
-
tunnelId:
|
|
1466
|
+
tunnelId: z11.string().describe("Tunnel id returned by workspace_start_tunnel")
|
|
1309
1467
|
},
|
|
1310
1468
|
async ({ tunnelId }) => {
|
|
1311
1469
|
const tunnel = activeTunnels.get(tunnelId);
|
|
@@ -1324,7 +1482,7 @@ function registerWorkspaceTools(server2, conn2, deps = {}) {
|
|
|
1324
1482
|
}
|
|
1325
1483
|
|
|
1326
1484
|
// src/tools/logs.ts
|
|
1327
|
-
import { z as
|
|
1485
|
+
import { z as z12 } from "zod";
|
|
1328
1486
|
var SEVERITY_ENUM = [
|
|
1329
1487
|
"DEBUG",
|
|
1330
1488
|
"INFO",
|
|
@@ -1346,10 +1504,47 @@ function truncateLine(text) {
|
|
|
1346
1504
|
function entrySource(entry) {
|
|
1347
1505
|
return entry.resource.service_name ?? entry.resource.pod_name ?? entry.resource.database_id ?? entry.resourceType ?? "-";
|
|
1348
1506
|
}
|
|
1507
|
+
var PAYLOAD_SKIP_KEYS = /* @__PURE__ */ new Set(["message", "severity", "timestamp", "level", "stack"]);
|
|
1508
|
+
var PAYLOAD_PRIORITY = [
|
|
1509
|
+
"error",
|
|
1510
|
+
"outcome",
|
|
1511
|
+
"serviceName",
|
|
1512
|
+
"methodName",
|
|
1513
|
+
"userId",
|
|
1514
|
+
"taskId",
|
|
1515
|
+
"sessionId",
|
|
1516
|
+
"workspaceId",
|
|
1517
|
+
"projectId",
|
|
1518
|
+
"durationMs"
|
|
1519
|
+
];
|
|
1520
|
+
var PAYLOAD_VALUE_MAX_CHARS = 160;
|
|
1521
|
+
function compactPayloadValue(value) {
|
|
1522
|
+
const raw = typeof value === "string" ? value : JSON.stringify(value);
|
|
1523
|
+
const flat = (raw ?? "undefined").replace(/\s+/g, " ");
|
|
1524
|
+
const quoted = typeof value === "string" && /[\s"]/.test(flat) ? JSON.stringify(flat) : flat;
|
|
1525
|
+
return quoted.length > PAYLOAD_VALUE_MAX_CHARS ? `${quoted.slice(0, PAYLOAD_VALUE_MAX_CHARS)}\u2026` : quoted;
|
|
1526
|
+
}
|
|
1527
|
+
function formatPayloadSuffix(payloadJson) {
|
|
1528
|
+
if (!payloadJson) return "";
|
|
1529
|
+
let parsed;
|
|
1530
|
+
try {
|
|
1531
|
+
parsed = JSON.parse(payloadJson);
|
|
1532
|
+
} catch {
|
|
1533
|
+
return "";
|
|
1534
|
+
}
|
|
1535
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "";
|
|
1536
|
+
const obj = parsed;
|
|
1537
|
+
const rank = (key) => {
|
|
1538
|
+
const i = PAYLOAD_PRIORITY.indexOf(key);
|
|
1539
|
+
return i === -1 ? PAYLOAD_PRIORITY.length : i;
|
|
1540
|
+
};
|
|
1541
|
+
const parts = Object.keys(obj).filter((k) => !PAYLOAD_SKIP_KEYS.has(k) && obj[k] !== void 0 && obj[k] !== null).sort((a, b) => rank(a) - rank(b) || a.localeCompare(b)).map((k) => `${k}=${compactPayloadValue(obj[k])}`);
|
|
1542
|
+
return parts.length > 0 ? ` | ${parts.join(" ")}` : "";
|
|
1543
|
+
}
|
|
1349
1544
|
function formatLogEntryLine(entry) {
|
|
1350
1545
|
const httpPrefix = entry.httpRequest?.status ? `http ${entry.httpRequest.status} ${entry.httpRequest.method ?? ""} ${entry.httpRequest.url ?? ""}`.trim() + " \u2014 " : "";
|
|
1351
1546
|
return `${entry.timestamp} ${entry.severity.padEnd(7)} [${entrySource(entry)}] ${truncateLine(
|
|
1352
|
-
`${httpPrefix}${entry.message}`
|
|
1547
|
+
`${httpPrefix}${entry.message}${formatPayloadSuffix(entry.payload)}`
|
|
1353
1548
|
)}`;
|
|
1354
1549
|
}
|
|
1355
1550
|
async function runQueryGcpLogs(conn2, params, now = Date.now) {
|
|
@@ -1389,27 +1584,27 @@ async function runQueryGcpLogs(conn2, params, now = Date.now) {
|
|
|
1389
1584
|
function registerLogTools(server2, conn2) {
|
|
1390
1585
|
server2.tool(
|
|
1391
1586
|
"query_gcp_logs",
|
|
1392
|
-
"Query Google Cloud Logging for a project's linked GCP environments \u2014 use this to investigate production or dev issues directly ('something broke on prod'). Envs: 'prod' and 'dev' are the project's Cloud Run apps + Cloud SQL databases (scoped by default to the resources linked in project settings); 'claudespace' is the project's GKE agent-pod namespace. Start broad (severity=ERROR, sinceMinutes=60), then narrow with services/search. Returns compact lines: '<time> <SEVERITY> [<source>] <message>'. When the response ends with a pageToken line, pass that token back as pageToken for the next page. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
1587
|
+
"Query Google Cloud Logging for a project's linked GCP environments \u2014 use this to investigate production or dev issues directly ('something broke on prod'). Envs: 'prod' and 'dev' are the project's Cloud Run apps + Cloud SQL databases (scoped by default to the resources linked in project settings); 'claudespace' is the project's GKE agent-pod namespace. Start broad (severity=ERROR, sinceMinutes=60), then narrow with services/search. Returns compact lines: '<time> <SEVERITY> [<source>] <message> | key=value \u2026' (the key=value tail is the entry's structured payload \u2014 error details, service/method, actor and entity ids). When the response ends with a pageToken line, pass that token back as pageToken for the next page. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
1393
1588
|
{
|
|
1394
|
-
projectId:
|
|
1395
|
-
env:
|
|
1396
|
-
sinceMinutes:
|
|
1589
|
+
projectId: z12.string().optional().describe("Target Conveyor project ID"),
|
|
1590
|
+
env: z12.enum(["prod", "dev", "claudespace"]).optional().describe("GCP environment slot to query (default prod)"),
|
|
1591
|
+
sinceMinutes: z12.number().int().min(1).max(10080).optional().describe(
|
|
1397
1592
|
"Relative time window ending now, in minutes (default 60). Ignored if startTime is set."
|
|
1398
1593
|
),
|
|
1399
|
-
startTime:
|
|
1400
|
-
endTime:
|
|
1401
|
-
severity:
|
|
1402
|
-
services:
|
|
1594
|
+
startTime: z12.string().optional().describe("ISO 8601 lower bound (overrides sinceMinutes)"),
|
|
1595
|
+
endTime: z12.string().optional().describe("ISO 8601 upper bound (default now)"),
|
|
1596
|
+
severity: z12.enum(SEVERITY_ENUM).optional().describe("Minimum severity, inclusive \u2014 ERROR returns ERROR and above"),
|
|
1597
|
+
services: z12.array(z12.string()).optional().describe(
|
|
1403
1598
|
"Restrict to these Cloud Run service names (prod/dev only). Defaults to all services linked in project settings."
|
|
1404
1599
|
),
|
|
1405
|
-
sqlInstances:
|
|
1406
|
-
allServices:
|
|
1600
|
+
sqlInstances: z12.array(z12.string()).optional().describe("Restrict to these Cloud SQL instance names (prod/dev only)"),
|
|
1601
|
+
allServices: z12.boolean().optional().describe(
|
|
1407
1602
|
"Set true to search ALL logs in the GCP project, ignoring the linked-resource scope"
|
|
1408
1603
|
),
|
|
1409
|
-
search:
|
|
1410
|
-
filter:
|
|
1411
|
-
limit:
|
|
1412
|
-
pageToken:
|
|
1604
|
+
search: z12.string().max(256).optional().describe("Free-text search across all log fields (exact substring, not regex)"),
|
|
1605
|
+
filter: z12.string().max(1e3).optional().describe("Advanced: raw Cloud Logging filter expression, ANDed with the scope"),
|
|
1606
|
+
limit: z12.number().int().min(1).max(200).optional().describe("Max entries per page (default 50)"),
|
|
1607
|
+
pageToken: z12.string().optional().describe("Opaque token from a previous response to fetch the next page")
|
|
1413
1608
|
},
|
|
1414
1609
|
async (params) => {
|
|
1415
1610
|
const text = await runQueryGcpLogs(conn2, params);
|
|
@@ -1421,6 +1616,7 @@ function registerLogTools(server2, conn2) {
|
|
|
1421
1616
|
// src/tools/index.ts
|
|
1422
1617
|
function registerAllTools(server2, conn2) {
|
|
1423
1618
|
registerProjectTools(server2, conn2);
|
|
1619
|
+
registerProjectConfigTools(server2, conn2);
|
|
1424
1620
|
registerTaskTools(server2, conn2);
|
|
1425
1621
|
registerBuildTools(server2, conn2);
|
|
1426
1622
|
registerAttachmentTools(server2, conn2);
|