@rallycry/conveyor-mcp 4.3.8 → 4.3.9
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-NQWURJDR.js → chunk-KOYKRWVY.js} +57 -7
- package/dist/chunk-KOYKRWVY.js.map +1 -0
- package/dist/cli.js +277 -228
- 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 +99 -3
- package/package.json +3 -3
- package/dist/chunk-NQWURJDR.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-KOYKRWVY.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { createRequire } from "module";
|
|
@@ -66,8 +66,50 @@ function registerProjectTools(server2, conn2) {
|
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
// src/tools/
|
|
69
|
+
// src/tools/connection.ts
|
|
70
70
|
import { z as z2 } from "zod";
|
|
71
|
+
var CAPABILITY_ENUM = ["read", "create", "update", "chat", "files", "build"];
|
|
72
|
+
function registerConnectionTools(server2, conn2) {
|
|
73
|
+
server2.tool(
|
|
74
|
+
"get_connection_context",
|
|
75
|
+
"Resolve WHO this connection is and WHAT project/board it points at \u2014 call this FIRST, before inferring anything from names. Returns the effective account, project, and board (sub-project) each with BOTH its immutable ID and its human-readable name/slug, the granted capabilities (read/create/update/chat/files/build), management URLs, and a one-line summary. Removes the ambiguity between a project's canonical name and a board label. 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) => {
|
|
80
|
+
const ctx = await conn2.getConnectionContext(params.projectId);
|
|
81
|
+
return { content: [{ type: "text", text: JSON.stringify(ctx, null, 2) }] };
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
server2.tool(
|
|
85
|
+
"verify_connection",
|
|
86
|
+
"Prove the connection is correct AND that you can actually write to the intended board \u2014 not just that auth works. Runs layered checks (auth \u2192 account \u2192 project \u2192 target board \u2192 capabilities \u2192 read) and returns a plain pass/fail with, on failure, the exact failing layer and ONE next action. Use this instead of get_project_summary to confirm setup: a summary that returns data proves auth, not scope. Pass intendedActions to verify specific capabilities (defaults to read+create+update). Pass projectId to target a specific project; otherwise the configured default project is used. The board scope comes from CONVEYOR_SUBPROJECT_ID.",
|
|
87
|
+
{
|
|
88
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID"),
|
|
89
|
+
intendedActions: z2.array(z2.enum(CAPABILITY_ENUM)).optional().describe(
|
|
90
|
+
"Capabilities to verify the connection can perform (default: read, create, update)."
|
|
91
|
+
)
|
|
92
|
+
},
|
|
93
|
+
async (params) => {
|
|
94
|
+
const result = await conn2.verifyConnection(params);
|
|
95
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
server2.tool(
|
|
99
|
+
"list_accessible_subprojects",
|
|
100
|
+
"List the boards (sub-projects) under the connected project \u2014 each with its ID, name, slug, board URL, owned root path, and the role/capabilities this token has on it. Use this to discover which board to create or list cards on (pass a returned id as subProjectId, or set CONVEYOR_SUBPROJECT_ID) instead of asking the human for one. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
101
|
+
{
|
|
102
|
+
projectId: z2.string().optional().describe("Target Conveyor project ID")
|
|
103
|
+
},
|
|
104
|
+
async (params) => {
|
|
105
|
+
const subprojects = await conn2.listAccessibleSubprojects(params.projectId);
|
|
106
|
+
return { content: [{ type: "text", text: JSON.stringify(subprojects, null, 2) }] };
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/tools/project-config.ts
|
|
112
|
+
import { z as z3 } from "zod";
|
|
71
113
|
function jsonResult(data) {
|
|
72
114
|
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
73
115
|
}
|
|
@@ -85,7 +127,7 @@ function registerGetConnectUrls(server2, conn2) {
|
|
|
85
127
|
"get_connect_urls",
|
|
86
128
|
"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.",
|
|
87
129
|
{
|
|
88
|
-
projectId:
|
|
130
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID")
|
|
89
131
|
},
|
|
90
132
|
async (params) => jsonResult(await conn2.getConnectUrls(params.projectId))
|
|
91
133
|
);
|
|
@@ -95,16 +137,16 @@ function registerUpdateProjectSettings(server2, conn2) {
|
|
|
95
137
|
"update_project_settings",
|
|
96
138
|
"Update project configuration: name, description, default agent assignments, or a deep-merged patch of the project settings JSON (JSON Merge Patch: nested objects merge recursively, null deletes a key, arrays replace \u2014 a partial patch never wipes sibling keys). Requires a Moderate project role. Does NOT touch repositories or branches \u2014 those are configured in the Conveyor UI.",
|
|
97
139
|
{
|
|
98
|
-
projectId:
|
|
99
|
-
name:
|
|
100
|
-
description:
|
|
101
|
-
settings:
|
|
140
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID"),
|
|
141
|
+
name: z3.string().optional().describe("New project name"),
|
|
142
|
+
description: z3.string().optional().describe("New project description"),
|
|
143
|
+
settings: z3.record(z3.unknown()).optional().describe(
|
|
102
144
|
"Deep-merged patch of the project settings JSON (JSON Merge Patch semantics: null deletes a key; advanced)"
|
|
103
145
|
),
|
|
104
|
-
defaultPmAgentId:
|
|
105
|
-
defaultTaskAgentId:
|
|
106
|
-
defaultReviewerAgentId:
|
|
107
|
-
helperAgentId:
|
|
146
|
+
defaultPmAgentId: z3.string().nullable().optional().describe("Default PM agent ID"),
|
|
147
|
+
defaultTaskAgentId: z3.string().nullable().optional().describe("Default task agent ID"),
|
|
148
|
+
defaultReviewerAgentId: z3.string().nullable().optional().describe("Default reviewer agent ID"),
|
|
149
|
+
helperAgentId: z3.string().nullable().optional().describe("Helper agent ID")
|
|
108
150
|
},
|
|
109
151
|
async (params) => {
|
|
110
152
|
const { projectId: projectId2, name, description, settings, ...agents } = params;
|
|
@@ -133,12 +175,12 @@ function registerManageTags(server2, conn2) {
|
|
|
133
175
|
"manage_tags",
|
|
134
176
|
"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.",
|
|
135
177
|
{
|
|
136
|
-
action:
|
|
137
|
-
projectId:
|
|
138
|
-
id:
|
|
139
|
-
name:
|
|
140
|
-
color:
|
|
141
|
-
description:
|
|
178
|
+
action: z3.enum(["list", "create", "update", "delete"]).describe("Operation to perform"),
|
|
179
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID (list/create)"),
|
|
180
|
+
id: z3.string().optional().describe("Tag ID (update/delete)"),
|
|
181
|
+
name: z3.string().optional().describe("Tag name"),
|
|
182
|
+
color: z3.string().optional().describe("Hex color, e.g. #ff0000"),
|
|
183
|
+
description: z3.string().optional().describe("Tag description")
|
|
142
184
|
},
|
|
143
185
|
async (params) => {
|
|
144
186
|
const { action, projectId: projectId2, id, name, color, description } = params;
|
|
@@ -172,13 +214,13 @@ function registerManagePriorities(server2, conn2) {
|
|
|
172
214
|
"manage_priorities",
|
|
173
215
|
"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.",
|
|
174
216
|
{
|
|
175
|
-
action:
|
|
176
|
-
projectId:
|
|
177
|
-
id:
|
|
178
|
-
value:
|
|
179
|
-
name:
|
|
180
|
-
color:
|
|
181
|
-
description:
|
|
217
|
+
action: z3.enum(["list", "create", "update", "delete"]).describe("Operation to perform"),
|
|
218
|
+
projectId: z3.string().optional().describe("Target Conveyor project ID (list/create)"),
|
|
219
|
+
id: z3.string().optional().describe("Priority ID (update/delete)"),
|
|
220
|
+
value: z3.number().int().min(1).max(100).optional().describe("Priority value (1 = highest urgency scale point)"),
|
|
221
|
+
name: z3.string().optional().describe("Priority name"),
|
|
222
|
+
color: z3.string().optional().describe("Hex color, e.g. #ff0000"),
|
|
223
|
+
description: z3.string().optional().describe("Priority description")
|
|
182
224
|
},
|
|
183
225
|
async (params) => {
|
|
184
226
|
const { action, projectId: projectId2, id, value, name, color, description } = params;
|
|
@@ -219,7 +261,7 @@ function registerProjectConfigTools(server2, conn2) {
|
|
|
219
261
|
}
|
|
220
262
|
|
|
221
263
|
// src/tools/tasks.ts
|
|
222
|
-
import { z as
|
|
264
|
+
import { z as z4 } from "zod";
|
|
223
265
|
var CLI_EVENT_FORMATTERS = {
|
|
224
266
|
thinking: (data) => String(data.message ?? ""),
|
|
225
267
|
tool_use: (data) => `${data.tool}: ${String(data.input ?? "").slice(0, 1e3)}`,
|
|
@@ -289,22 +331,26 @@ var STATUS_ENUM = [
|
|
|
289
331
|
];
|
|
290
332
|
var CARD_TYPE_ENUM = ["task", "incident", "suggestion"];
|
|
291
333
|
var RISK_ENUM = ["critical", "high", "medium", "low"];
|
|
334
|
+
var BOARD_FILTER = z4.string().nullable().optional().describe(
|
|
335
|
+
"Filter to a sub-project board. Omit to use the connection's default board (CONVEYOR_SUBPROJECT_ID) when set, else the whole project; pass null to force the whole project. Use list_accessible_subprojects to find board IDs."
|
|
336
|
+
);
|
|
337
|
+
var BOARD_ASSIGN = z4.string().nullable().optional().describe(
|
|
338
|
+
"Assign the card to a sub-project board. Omit to use the connection's default board (CONVEYOR_SUBPROJECT_ID) when set, else the parent project; pass null to force the parent project. Use list_accessible_subprojects to find board IDs."
|
|
339
|
+
);
|
|
292
340
|
function registerListTasks(server2, conn2) {
|
|
293
341
|
server2.tool(
|
|
294
342
|
"list_tasks",
|
|
295
343
|
"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.",
|
|
296
344
|
{
|
|
297
|
-
projectId:
|
|
298
|
-
status:
|
|
299
|
-
typeFilters:
|
|
345
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
346
|
+
status: z4.enum(STATUS_ENUM).optional().describe("Filter by task status"),
|
|
347
|
+
typeFilters: z4.array(z4.enum(CARD_TYPE_ENUM)).optional().describe(
|
|
300
348
|
'Card types to include, e.g. ["incident"] or ["task", "incident"]. Omit for tasks only.'
|
|
301
349
|
),
|
|
302
|
-
assigneeId:
|
|
303
|
-
unassigned:
|
|
304
|
-
subProjectId:
|
|
305
|
-
|
|
306
|
-
),
|
|
307
|
-
limit: z3.number().optional().describe("Max tasks to return (default 50)")
|
|
350
|
+
assigneeId: z4.string().optional().describe("Filter by assigned user ID"),
|
|
351
|
+
unassigned: z4.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
352
|
+
subProjectId: BOARD_FILTER,
|
|
353
|
+
limit: z4.number().optional().describe("Max tasks to return (default 50)")
|
|
308
354
|
},
|
|
309
355
|
async (params) => {
|
|
310
356
|
const tasks = await conn2.listTasks(params);
|
|
@@ -319,8 +365,8 @@ function registerGetTask(server2, conn2) {
|
|
|
319
365
|
"get_task",
|
|
320
366
|
"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.",
|
|
321
367
|
{
|
|
322
|
-
projectId:
|
|
323
|
-
taskId:
|
|
368
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
369
|
+
taskId: z4.string().describe("The task ID or slug (the value in a card URL, /cards/<slug>)")
|
|
324
370
|
},
|
|
325
371
|
async (params) => {
|
|
326
372
|
const task = await conn2.getTask(params.taskId, params.projectId);
|
|
@@ -333,8 +379,8 @@ function registerGetCardBySlug(server2, conn2) {
|
|
|
333
379
|
"get_card_by_slug",
|
|
334
380
|
"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.",
|
|
335
381
|
{
|
|
336
|
-
projectId:
|
|
337
|
-
slug:
|
|
382
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
383
|
+
slug: z4.string().describe("The card slug from a Conveyor card URL, e.g. 'ship-it'")
|
|
338
384
|
},
|
|
339
385
|
async (params) => {
|
|
340
386
|
const task = await conn2.getCardBySlug(params.slug, params.projectId);
|
|
@@ -347,19 +393,22 @@ function registerCreateTask(server2, conn2) {
|
|
|
347
393
|
"create_task",
|
|
348
394
|
"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.",
|
|
349
395
|
{
|
|
350
|
-
projectId:
|
|
351
|
-
title:
|
|
352
|
-
description:
|
|
353
|
-
plan:
|
|
354
|
-
status:
|
|
355
|
-
subProjectId:
|
|
356
|
-
"Scope to a sub-project board (list/search: filter; create/update: assign). Omit for the whole project."
|
|
357
|
-
)
|
|
396
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
397
|
+
title: z4.string().describe("Task title"),
|
|
398
|
+
description: z4.string().optional().describe("Task description"),
|
|
399
|
+
plan: z4.string().optional().describe("Task implementation plan (markdown)"),
|
|
400
|
+
status: z4.enum(["Planning", "Open"]).optional().describe("Initial status (default: Planning)"),
|
|
401
|
+
subProjectId: BOARD_ASSIGN
|
|
358
402
|
},
|
|
359
403
|
async (params) => {
|
|
360
404
|
const task = await conn2.createTask(params);
|
|
361
405
|
return {
|
|
362
|
-
content: [
|
|
406
|
+
content: [
|
|
407
|
+
{
|
|
408
|
+
type: "text",
|
|
409
|
+
text: `Task created: ${task.id} (slug: ${task.slug}). effectiveScope: ${JSON.stringify(task.effectiveScope)}`
|
|
410
|
+
}
|
|
411
|
+
]
|
|
363
412
|
};
|
|
364
413
|
}
|
|
365
414
|
);
|
|
@@ -369,17 +418,17 @@ function registerUpdateTask(server2, conn2) {
|
|
|
369
418
|
"update_task",
|
|
370
419
|
"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.",
|
|
371
420
|
{
|
|
372
|
-
projectId:
|
|
373
|
-
taskId:
|
|
374
|
-
title:
|
|
375
|
-
description:
|
|
376
|
-
plan:
|
|
377
|
-
status:
|
|
378
|
-
risk:
|
|
421
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
422
|
+
taskId: z4.string().describe("The task ID"),
|
|
423
|
+
title: z4.string().optional().describe("New title"),
|
|
424
|
+
description: z4.string().optional().describe("New description"),
|
|
425
|
+
plan: z4.string().optional().describe("New plan (markdown)"),
|
|
426
|
+
status: z4.enum(STATUS_ENUM).optional().describe("New status"),
|
|
427
|
+
risk: z4.enum(RISK_ENUM).nullable().optional().describe(
|
|
379
428
|
"Risk level \u2014 how much important surface the task touches (critical/high/medium/low). Pass null to clear."
|
|
380
429
|
),
|
|
381
|
-
assignedUserId:
|
|
382
|
-
subProjectId:
|
|
430
|
+
assignedUserId: z4.string().nullable().optional().describe("User ID to assign, or null"),
|
|
431
|
+
subProjectId: z4.string().nullable().optional().describe(
|
|
383
432
|
"Assign the task to a sub-project board; null moves it back to the parent board. Omit to leave unchanged."
|
|
384
433
|
)
|
|
385
434
|
},
|
|
@@ -396,9 +445,9 @@ function registerMoveCard(server2, conn2) {
|
|
|
396
445
|
"move_card",
|
|
397
446
|
"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.",
|
|
398
447
|
{
|
|
399
|
-
projectId:
|
|
400
|
-
taskId:
|
|
401
|
-
destinationProjectId:
|
|
448
|
+
projectId: z4.string().optional().describe("Source Conveyor project ID"),
|
|
449
|
+
taskId: z4.string().describe("Card ID or slug"),
|
|
450
|
+
destinationProjectId: z4.string().describe("Destination Conveyor project ID")
|
|
402
451
|
},
|
|
403
452
|
async (params) => {
|
|
404
453
|
const result = await conn2.moveCard(params);
|
|
@@ -419,9 +468,9 @@ function registerChatTools(server2, conn2) {
|
|
|
419
468
|
"read_task_chat",
|
|
420
469
|
"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.",
|
|
421
470
|
{
|
|
422
|
-
projectId:
|
|
423
|
-
taskId:
|
|
424
|
-
limit:
|
|
471
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
472
|
+
taskId: z4.string().describe("The task ID"),
|
|
473
|
+
limit: z4.number().optional().describe("Max messages to return (default 50)")
|
|
425
474
|
},
|
|
426
475
|
async (params) => {
|
|
427
476
|
const messages = await conn2.getTaskChat(params.taskId, params.limit, params.projectId);
|
|
@@ -432,9 +481,9 @@ function registerChatTools(server2, conn2) {
|
|
|
432
481
|
"post_to_chat",
|
|
433
482
|
"Post a message to a task's chat. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
434
483
|
{
|
|
435
|
-
projectId:
|
|
436
|
-
taskId:
|
|
437
|
-
content:
|
|
484
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
485
|
+
taskId: z4.string().describe("The task ID"),
|
|
486
|
+
content: z4.string().describe("Message content")
|
|
438
487
|
},
|
|
439
488
|
async (params) => {
|
|
440
489
|
await conn2.postToTaskChat(params.taskId, params.content, params.projectId);
|
|
@@ -447,12 +496,12 @@ function registerGetTaskCli(server2, conn2) {
|
|
|
447
496
|
"get_task_logs",
|
|
448
497
|
"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.",
|
|
449
498
|
{
|
|
450
|
-
projectId:
|
|
451
|
-
taskId:
|
|
452
|
-
source:
|
|
499
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
500
|
+
taskId: z4.string().describe("The task ID or slug"),
|
|
501
|
+
source: z4.enum(["agent", "application"]).optional().describe(
|
|
453
502
|
"Filter by log source: 'agent' for reasoning/tool calls, 'application' for setup/dev-server output"
|
|
454
503
|
),
|
|
455
|
-
limit:
|
|
504
|
+
limit: z4.number().optional().describe("Max entries to return (default 50, max 500)")
|
|
456
505
|
},
|
|
457
506
|
async ({ taskId, source, limit, projectId: projectId2 }) => {
|
|
458
507
|
const effectiveLimit = Math.min(limit ?? 50, 500);
|
|
@@ -471,8 +520,8 @@ function registerGetTaskSessions(server2, conn2) {
|
|
|
471
520
|
"get_task_sessions",
|
|
472
521
|
"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.",
|
|
473
522
|
{
|
|
474
|
-
projectId:
|
|
475
|
-
taskId:
|
|
523
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
524
|
+
taskId: z4.string().describe("The task ID or slug")
|
|
476
525
|
},
|
|
477
526
|
async ({ taskId, projectId: projectId2 }) => {
|
|
478
527
|
const tasks = await conn2.getTaskSessions(taskId, projectId2);
|
|
@@ -490,19 +539,17 @@ function registerSearchTasks(server2, conn2) {
|
|
|
490
539
|
"search_tasks",
|
|
491
540
|
"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.",
|
|
492
541
|
{
|
|
493
|
-
projectId:
|
|
494
|
-
tagNames:
|
|
495
|
-
searchQuery:
|
|
496
|
-
statusFilters:
|
|
497
|
-
typeFilters:
|
|
542
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
543
|
+
tagNames: z4.array(z4.string()).optional().describe('Tag names to filter by (e.g., ["agent-runner", "chat"])'),
|
|
544
|
+
searchQuery: z4.string().optional().describe("Text search on title and description"),
|
|
545
|
+
statusFilters: z4.array(z4.enum(STATUS_ENUM)).optional().describe("Filter by one or more statuses"),
|
|
546
|
+
typeFilters: z4.array(z4.enum(CARD_TYPE_ENUM)).optional().describe(
|
|
498
547
|
'Card types to include (default ["task"]). Pass e.g. ["incident"] or list several to search across types.'
|
|
499
548
|
),
|
|
500
|
-
assigneeId:
|
|
501
|
-
unassigned:
|
|
502
|
-
subProjectId:
|
|
503
|
-
|
|
504
|
-
),
|
|
505
|
-
limit: z3.number().optional().describe("Max results to return (default 20)")
|
|
549
|
+
assigneeId: z4.string().optional().describe("Filter by assigned user ID"),
|
|
550
|
+
unassigned: z4.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
551
|
+
subProjectId: BOARD_FILTER,
|
|
552
|
+
limit: z4.number().optional().describe("Max results to return (default 20)")
|
|
506
553
|
},
|
|
507
554
|
async (params) => {
|
|
508
555
|
const tasks = await conn2.searchTasks(params);
|
|
@@ -517,7 +564,7 @@ function registerListTags(server2, conn2) {
|
|
|
517
564
|
"list_tags",
|
|
518
565
|
"List all project tags with their names, IDs, and colors. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
519
566
|
{
|
|
520
|
-
projectId:
|
|
567
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID")
|
|
521
568
|
},
|
|
522
569
|
async (params) => {
|
|
523
570
|
const tags = await conn2.listTags(params.projectId);
|
|
@@ -530,9 +577,9 @@ function registerReviewTools(server2, conn2) {
|
|
|
530
577
|
"approve_task",
|
|
531
578
|
"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.",
|
|
532
579
|
{
|
|
533
|
-
projectId:
|
|
534
|
-
taskId:
|
|
535
|
-
risk:
|
|
580
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
581
|
+
taskId: z4.string().describe("The task ID"),
|
|
582
|
+
risk: z4.enum(RISK_ENUM).optional().describe("Optional risk level to record; defaults to a raise-only 'low' on approval.")
|
|
536
583
|
},
|
|
537
584
|
async (params) => {
|
|
538
585
|
const result = await conn2.approveTask(params.taskId, params.projectId, params.risk);
|
|
@@ -545,8 +592,8 @@ function registerReviewTools(server2, conn2) {
|
|
|
545
592
|
"approve_and_merge_pr",
|
|
546
593
|
"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.",
|
|
547
594
|
{
|
|
548
|
-
projectId:
|
|
549
|
-
childTaskId:
|
|
595
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
596
|
+
childTaskId: z4.string().describe("The child task ID whose PR should be approved and merged")
|
|
550
597
|
},
|
|
551
598
|
async (params) => {
|
|
552
599
|
const result = await conn2.approveAndMergePR(params.childTaskId, params.projectId);
|
|
@@ -564,10 +611,10 @@ function registerReviewTools(server2, conn2) {
|
|
|
564
611
|
"request_changes",
|
|
565
612
|
"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.",
|
|
566
613
|
{
|
|
567
|
-
projectId:
|
|
568
|
-
taskId:
|
|
569
|
-
feedback:
|
|
570
|
-
risk:
|
|
614
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
615
|
+
taskId: z4.string().describe("The task ID"),
|
|
616
|
+
feedback: z4.string().describe("Feedback message describing requested changes"),
|
|
617
|
+
risk: z4.enum(RISK_ENUM).optional().describe("Optional risk level to record; defaults to a raise-only 'medium' on changes.")
|
|
571
618
|
},
|
|
572
619
|
async (params) => {
|
|
573
620
|
await conn2.requestChanges(params.taskId, params.feedback, params.projectId, params.risk);
|
|
@@ -584,9 +631,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
584
631
|
"add_reviewer",
|
|
585
632
|
"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.",
|
|
586
633
|
{
|
|
587
|
-
projectId:
|
|
588
|
-
taskId:
|
|
589
|
-
userId:
|
|
634
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
635
|
+
taskId: z4.string().describe("The task ID or slug"),
|
|
636
|
+
userId: z4.string().describe("User ID of the reviewer (use list_project_members to resolve a name or email)")
|
|
590
637
|
},
|
|
591
638
|
async (params) => {
|
|
592
639
|
const result = await conn2.addReviewer(params);
|
|
@@ -604,9 +651,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
604
651
|
"remove_reviewer",
|
|
605
652
|
"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.",
|
|
606
653
|
{
|
|
607
|
-
projectId:
|
|
608
|
-
taskId:
|
|
609
|
-
userId:
|
|
654
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
655
|
+
taskId: z4.string().describe("The task ID or slug"),
|
|
656
|
+
userId: z4.string().describe("User ID of the reviewer to remove")
|
|
610
657
|
},
|
|
611
658
|
async (params) => {
|
|
612
659
|
const result = await conn2.removeReviewer(params);
|
|
@@ -638,7 +685,7 @@ function registerTaskTools(server2, conn2) {
|
|
|
638
685
|
}
|
|
639
686
|
|
|
640
687
|
// src/tools/builds.ts
|
|
641
|
-
import { z as
|
|
688
|
+
import { z as z5 } from "zod";
|
|
642
689
|
function textResult2(result) {
|
|
643
690
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
644
691
|
}
|
|
@@ -647,8 +694,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
647
694
|
"stop_task",
|
|
648
695
|
"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.",
|
|
649
696
|
{
|
|
650
|
-
projectId:
|
|
651
|
-
taskId:
|
|
697
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
698
|
+
taskId: z5.string().describe("The task ID")
|
|
652
699
|
},
|
|
653
700
|
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
654
701
|
);
|
|
@@ -656,8 +703,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
656
703
|
"sleep_task",
|
|
657
704
|
"Sleep a task Claudespace, stopping compute while preserving durable state. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
658
705
|
{
|
|
659
|
-
projectId:
|
|
660
|
-
taskId:
|
|
706
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
707
|
+
taskId: z5.string().describe("The task ID")
|
|
661
708
|
},
|
|
662
709
|
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
663
710
|
);
|
|
@@ -665,8 +712,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
665
712
|
"resume_task",
|
|
666
713
|
"Resume a sleeping task Claudespace. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
667
714
|
{
|
|
668
|
-
projectId:
|
|
669
|
-
taskId:
|
|
715
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
716
|
+
taskId: z5.string().describe("The task ID")
|
|
670
717
|
},
|
|
671
718
|
async (params) => textResult2(await conn2.resumeTask(params.taskId, params.projectId))
|
|
672
719
|
);
|
|
@@ -674,8 +721,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
674
721
|
"delete_task_environment",
|
|
675
722
|
"Delete a task environment, including durable Claudespace state. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
676
723
|
{
|
|
677
|
-
projectId:
|
|
678
|
-
taskId:
|
|
724
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
725
|
+
taskId: z5.string().describe("The task ID")
|
|
679
726
|
},
|
|
680
727
|
async (params) => textResult2(await conn2.deleteTaskEnvironment(params.taskId, params.projectId))
|
|
681
728
|
);
|
|
@@ -685,8 +732,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
685
732
|
"start_task",
|
|
686
733
|
"Start a cloud build (codespace) for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
687
734
|
{
|
|
688
|
-
projectId:
|
|
689
|
-
taskId:
|
|
735
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
736
|
+
taskId: z5.string().describe("The task ID")
|
|
690
737
|
},
|
|
691
738
|
async (params) => {
|
|
692
739
|
const result = await conn2.startBuild(params.taskId, params.projectId);
|
|
@@ -698,8 +745,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
698
745
|
"create_release",
|
|
699
746
|
"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).",
|
|
700
747
|
{
|
|
701
|
-
projectId:
|
|
702
|
-
taskIds:
|
|
748
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
749
|
+
taskIds: z5.array(z5.string()).optional().describe(
|
|
703
750
|
"Task IDs in Review (Dev) to cherry-pick into the release. Omit to release all of them."
|
|
704
751
|
)
|
|
705
752
|
},
|
|
@@ -712,8 +759,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
712
759
|
"get_build_status",
|
|
713
760
|
"Check codespace and agent status for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
714
761
|
{
|
|
715
|
-
projectId:
|
|
716
|
-
taskId:
|
|
762
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
763
|
+
taskId: z5.string().describe("The task ID")
|
|
717
764
|
},
|
|
718
765
|
async (params) => {
|
|
719
766
|
const status = await conn2.getBuildStatus(params.taskId, params.projectId);
|
|
@@ -725,7 +772,7 @@ function registerBuildTools(server2, conn2) {
|
|
|
725
772
|
// src/tools/attachments.ts
|
|
726
773
|
import { readFile, stat } from "fs/promises";
|
|
727
774
|
import { basename, extname } from "path";
|
|
728
|
-
import { z as
|
|
775
|
+
import { z as z6 } from "zod";
|
|
729
776
|
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
730
777
|
var MIME_BY_EXT = {
|
|
731
778
|
".png": "image/png",
|
|
@@ -762,8 +809,8 @@ function registerListTaskFiles(server2, conn2) {
|
|
|
762
809
|
"list_task_files",
|
|
763
810
|
"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.",
|
|
764
811
|
{
|
|
765
|
-
projectId:
|
|
766
|
-
taskId:
|
|
812
|
+
projectId: z6.string().optional().describe("Target Conveyor project ID"),
|
|
813
|
+
taskId: z6.string().describe("The task ID or slug")
|
|
767
814
|
},
|
|
768
815
|
async (params) => {
|
|
769
816
|
const files = await conn2.listTaskFiles(params.taskId, params.projectId);
|
|
@@ -805,11 +852,11 @@ function registerGetAttachment(server2, conn2) {
|
|
|
805
852
|
"get_attachment",
|
|
806
853
|
"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.",
|
|
807
854
|
{
|
|
808
|
-
projectId:
|
|
809
|
-
taskId:
|
|
810
|
-
fileId:
|
|
811
|
-
offset:
|
|
812
|
-
maxBytes:
|
|
855
|
+
projectId: z6.string().optional().describe("Target Conveyor project ID"),
|
|
856
|
+
taskId: z6.string().describe("The task ID or slug"),
|
|
857
|
+
fileId: z6.string().describe("The file ID to fetch"),
|
|
858
|
+
offset: z6.number().int().nonnegative().optional().describe("Byte offset into text content (paging). Default 0."),
|
|
859
|
+
maxBytes: z6.number().int().positive().optional().describe("Max bytes of text content to return from offset.")
|
|
813
860
|
},
|
|
814
861
|
async (params) => {
|
|
815
862
|
const file = await conn2.getAttachment(params.taskId, params.fileId, {
|
|
@@ -826,11 +873,11 @@ function registerUploadAttachment(server2, conn2) {
|
|
|
826
873
|
"upload_attachment",
|
|
827
874
|
"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.",
|
|
828
875
|
{
|
|
829
|
-
projectId:
|
|
830
|
-
taskId:
|
|
831
|
-
path:
|
|
832
|
-
comment:
|
|
833
|
-
mimeType:
|
|
876
|
+
projectId: z6.string().optional().describe("Target Conveyor project ID"),
|
|
877
|
+
taskId: z6.string().describe("The task ID or slug"),
|
|
878
|
+
path: z6.string().describe("Absolute path to the local file to upload"),
|
|
879
|
+
comment: z6.string().optional().describe("When set, also posts the attachment to the task chat with this text"),
|
|
880
|
+
mimeType: z6.string().optional().describe("Override the mime type inferred from the file extension")
|
|
834
881
|
},
|
|
835
882
|
async (params) => {
|
|
836
883
|
const info = await stat(params.path).catch(() => null);
|
|
@@ -893,18 +940,18 @@ function registerAttachmentTools(server2, conn2) {
|
|
|
893
940
|
}
|
|
894
941
|
|
|
895
942
|
// src/tools/pull-request.ts
|
|
896
|
-
import { z as
|
|
943
|
+
import { z as z7 } from "zod";
|
|
897
944
|
function registerPullRequestTools(server2, conn2) {
|
|
898
945
|
server2.tool(
|
|
899
946
|
"create_pull_request",
|
|
900
947
|
"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.",
|
|
901
948
|
{
|
|
902
|
-
projectId:
|
|
903
|
-
taskId:
|
|
904
|
-
title:
|
|
905
|
-
body:
|
|
906
|
-
head:
|
|
907
|
-
base:
|
|
949
|
+
projectId: z7.string().optional().describe("Target Conveyor project ID"),
|
|
950
|
+
taskId: z7.string().describe("The task ID whose branch should be opened as a PR"),
|
|
951
|
+
title: z7.string().describe("Pull request title"),
|
|
952
|
+
body: z7.string().describe("Pull request body (markdown)"),
|
|
953
|
+
head: z7.string().optional().describe("Source branch for the PR (defaults to the task's branch)"),
|
|
954
|
+
base: z7.string().optional().describe("Target branch for the PR (defaults to the repo default)")
|
|
908
955
|
},
|
|
909
956
|
async (params) => {
|
|
910
957
|
const result = await conn2.createPullRequest(params);
|
|
@@ -916,7 +963,7 @@ function registerPullRequestTools(server2, conn2) {
|
|
|
916
963
|
}
|
|
917
964
|
|
|
918
965
|
// src/tools/subtasks.ts
|
|
919
|
-
import { z as
|
|
966
|
+
import { z as z8 } from "zod";
|
|
920
967
|
var STATUS_ENUM2 = [
|
|
921
968
|
"Planning",
|
|
922
969
|
"Open",
|
|
@@ -934,15 +981,15 @@ function registerCreateSubtask(server2, conn2) {
|
|
|
934
981
|
"create_subtask",
|
|
935
982
|
"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.",
|
|
936
983
|
{
|
|
937
|
-
projectId:
|
|
938
|
-
parentTaskId:
|
|
939
|
-
title:
|
|
940
|
-
description:
|
|
941
|
-
plan:
|
|
942
|
-
ordinal:
|
|
943
|
-
storyPointValue:
|
|
944
|
-
followParentStatus:
|
|
945
|
-
dependsOn:
|
|
984
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
985
|
+
parentTaskId: z8.string().describe("The parent task ID"),
|
|
986
|
+
title: z8.string().describe("Subtask title"),
|
|
987
|
+
description: z8.string().optional().describe("Subtask description"),
|
|
988
|
+
plan: z8.string().optional().describe("Subtask implementation plan (markdown)"),
|
|
989
|
+
ordinal: z8.number().optional().describe("Ordering position among siblings"),
|
|
990
|
+
storyPointValue: z8.number().optional().describe(SP_DESCRIPTION),
|
|
991
|
+
followParentStatus: z8.boolean().optional().describe(FOLLOW_PARENT_STATUS_DESCRIPTION),
|
|
992
|
+
dependsOn: z8.array(z8.string()).optional().describe(
|
|
946
993
|
"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."
|
|
947
994
|
)
|
|
948
995
|
},
|
|
@@ -959,16 +1006,16 @@ function registerUpdateSubtask(server2, conn2) {
|
|
|
959
1006
|
"update_subtask",
|
|
960
1007
|
"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.",
|
|
961
1008
|
{
|
|
962
|
-
projectId:
|
|
963
|
-
subtaskId:
|
|
964
|
-
title:
|
|
965
|
-
description:
|
|
966
|
-
plan:
|
|
967
|
-
status:
|
|
968
|
-
ordinal:
|
|
969
|
-
storyPointValue:
|
|
970
|
-
followParentStatus:
|
|
971
|
-
dependsOn:
|
|
1009
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1010
|
+
subtaskId: z8.string().describe("The subtask ID"),
|
|
1011
|
+
title: z8.string().optional().describe("New title"),
|
|
1012
|
+
description: z8.string().optional().describe("New description"),
|
|
1013
|
+
plan: z8.string().optional().describe("New plan (markdown)"),
|
|
1014
|
+
status: z8.enum(STATUS_ENUM2).optional().describe("New status"),
|
|
1015
|
+
ordinal: z8.number().optional().describe("New ordering position among siblings"),
|
|
1016
|
+
storyPointValue: z8.number().optional().describe(SP_DESCRIPTION),
|
|
1017
|
+
followParentStatus: z8.boolean().optional().describe(FOLLOW_PARENT_STATUS_DESCRIPTION),
|
|
1018
|
+
dependsOn: z8.array(z8.string()).optional().describe(
|
|
972
1019
|
"Replace the sibling subtask ids/slugs this subtask blocks on (pass [] to clear). Omit to leave dependencies unchanged."
|
|
973
1020
|
)
|
|
974
1021
|
},
|
|
@@ -987,8 +1034,8 @@ function registerListSubtasks(server2, conn2) {
|
|
|
987
1034
|
"list_subtasks",
|
|
988
1035
|
"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.",
|
|
989
1036
|
{
|
|
990
|
-
projectId:
|
|
991
|
-
taskId:
|
|
1037
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1038
|
+
taskId: z8.string().describe("The parent task ID")
|
|
992
1039
|
},
|
|
993
1040
|
async (params) => {
|
|
994
1041
|
const subtasks = await conn2.listSubtasks(params.taskId, params.projectId);
|
|
@@ -1001,8 +1048,8 @@ function registerDeleteSubtask(server2, conn2) {
|
|
|
1001
1048
|
"delete_subtask",
|
|
1002
1049
|
"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.",
|
|
1003
1050
|
{
|
|
1004
|
-
projectId:
|
|
1005
|
-
subtaskId:
|
|
1051
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1052
|
+
subtaskId: z8.string().describe("The subtask ID to delete")
|
|
1006
1053
|
},
|
|
1007
1054
|
async (params) => {
|
|
1008
1055
|
const result = await conn2.deleteSubtask(params.subtaskId, params.projectId);
|
|
@@ -1022,14 +1069,14 @@ function registerSubtaskTools(server2, conn2) {
|
|
|
1022
1069
|
}
|
|
1023
1070
|
|
|
1024
1071
|
// src/tools/dependencies.ts
|
|
1025
|
-
import { z as
|
|
1072
|
+
import { z as z9 } from "zod";
|
|
1026
1073
|
function registerGetDependencies(server2, conn2) {
|
|
1027
1074
|
server2.tool(
|
|
1028
1075
|
"get_dependencies",
|
|
1029
1076
|
"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.",
|
|
1030
1077
|
{
|
|
1031
|
-
projectId:
|
|
1032
|
-
taskId:
|
|
1078
|
+
projectId: z9.string().optional().describe("Target Conveyor project ID"),
|
|
1079
|
+
taskId: z9.string().describe("The task ID")
|
|
1033
1080
|
},
|
|
1034
1081
|
async (params) => {
|
|
1035
1082
|
const deps = await conn2.getDependencies(params.taskId, params.projectId);
|
|
@@ -1042,9 +1089,9 @@ function registerAddDependency(server2, conn2) {
|
|
|
1042
1089
|
"add_dependency",
|
|
1043
1090
|
"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.",
|
|
1044
1091
|
{
|
|
1045
|
-
projectId:
|
|
1046
|
-
taskId:
|
|
1047
|
-
dependsOnSlugOrId:
|
|
1092
|
+
projectId: z9.string().optional().describe("Target Conveyor project ID"),
|
|
1093
|
+
taskId: z9.string().describe("The task ID that will be blocked"),
|
|
1094
|
+
dependsOnSlugOrId: z9.string().describe("Slug or ID of the task this one depends on")
|
|
1048
1095
|
},
|
|
1049
1096
|
async (params) => {
|
|
1050
1097
|
await conn2.addDependency(params);
|
|
@@ -1057,9 +1104,9 @@ function registerRemoveDependency(server2, conn2) {
|
|
|
1057
1104
|
"remove_dependency",
|
|
1058
1105
|
"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.",
|
|
1059
1106
|
{
|
|
1060
|
-
projectId:
|
|
1061
|
-
taskId:
|
|
1062
|
-
dependsOnSlugOrId:
|
|
1107
|
+
projectId: z9.string().optional().describe("Target Conveyor project ID"),
|
|
1108
|
+
taskId: z9.string().describe("The task ID to unblock"),
|
|
1109
|
+
dependsOnSlugOrId: z9.string().describe("Slug or ID of the dependency to remove")
|
|
1063
1110
|
},
|
|
1064
1111
|
async (params) => {
|
|
1065
1112
|
await conn2.removeDependency(params);
|
|
@@ -1074,16 +1121,16 @@ function registerDependencyTools(server2, conn2) {
|
|
|
1074
1121
|
}
|
|
1075
1122
|
|
|
1076
1123
|
// src/tools/suggestions.ts
|
|
1077
|
-
import { z as
|
|
1124
|
+
import { z as z10 } from "zod";
|
|
1078
1125
|
function registerSuggestionTools(server2, conn2) {
|
|
1079
1126
|
server2.tool(
|
|
1080
1127
|
"create_suggestion",
|
|
1081
1128
|
"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.",
|
|
1082
1129
|
{
|
|
1083
|
-
projectId:
|
|
1084
|
-
title:
|
|
1085
|
-
description:
|
|
1086
|
-
tagNames:
|
|
1130
|
+
projectId: z10.string().optional().describe("Target Conveyor project ID"),
|
|
1131
|
+
title: z10.string().describe("Suggestion title"),
|
|
1132
|
+
description: z10.string().optional().describe("Suggestion details (markdown)"),
|
|
1133
|
+
tagNames: z10.array(z10.string()).optional().describe('Tag names to categorize the suggestion (e.g., ["agent-runner"])')
|
|
1087
1134
|
},
|
|
1088
1135
|
async (params) => {
|
|
1089
1136
|
const result = await conn2.createSuggestion(params);
|
|
@@ -1094,7 +1141,7 @@ function registerSuggestionTools(server2, conn2) {
|
|
|
1094
1141
|
}
|
|
1095
1142
|
|
|
1096
1143
|
// src/tools/checklists.ts
|
|
1097
|
-
import { z as
|
|
1144
|
+
import { z as z11 } from "zod";
|
|
1098
1145
|
function renderManualTestGroups(groups) {
|
|
1099
1146
|
const lines = [];
|
|
1100
1147
|
for (const g of groups) {
|
|
@@ -1117,8 +1164,8 @@ function registerListManualTests(server2, conn2) {
|
|
|
1117
1164
|
"list_manual_tests",
|
|
1118
1165
|
"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.",
|
|
1119
1166
|
{
|
|
1120
|
-
projectId:
|
|
1121
|
-
taskId:
|
|
1167
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1168
|
+
taskId: z11.string().describe("The task ID or slug (the value in a card URL, /cards/<slug>)")
|
|
1122
1169
|
},
|
|
1123
1170
|
async (params) => {
|
|
1124
1171
|
const items = await conn2.listManualTests(params.taskId, params.projectId);
|
|
@@ -1144,9 +1191,9 @@ function registerSetManualTests(server2, conn2) {
|
|
|
1144
1191
|
"set_manual_tests",
|
|
1145
1192
|
"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.",
|
|
1146
1193
|
{
|
|
1147
|
-
projectId:
|
|
1148
|
-
taskId:
|
|
1149
|
-
items:
|
|
1194
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1195
|
+
taskId: z11.string().describe("The task ID or slug"),
|
|
1196
|
+
items: z11.array(z11.object({ title: z11.string().min(1).describe("A concise, actionable test step") })).min(1).describe("List of manual test steps to add")
|
|
1150
1197
|
},
|
|
1151
1198
|
async (params) => {
|
|
1152
1199
|
const result = await conn2.setManualTests(params.taskId, params.items, params.projectId);
|
|
@@ -1161,10 +1208,10 @@ function registerEditManualTest(server2, conn2) {
|
|
|
1161
1208
|
"edit_manual_test",
|
|
1162
1209
|
"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.",
|
|
1163
1210
|
{
|
|
1164
|
-
projectId:
|
|
1165
|
-
taskId:
|
|
1166
|
-
title:
|
|
1167
|
-
newTitle:
|
|
1211
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1212
|
+
taskId: z11.string().describe("The task ID or slug"),
|
|
1213
|
+
title: z11.string().min(1).describe("The current title of the manual test to edit"),
|
|
1214
|
+
newTitle: z11.string().min(1).describe("The new title for the manual test")
|
|
1168
1215
|
},
|
|
1169
1216
|
async (params) => {
|
|
1170
1217
|
await conn2.editManualTest(params.taskId, params.title, params.newTitle, params.projectId);
|
|
@@ -1177,9 +1224,9 @@ function registerRemoveManualTest(server2, conn2) {
|
|
|
1177
1224
|
"remove_manual_test",
|
|
1178
1225
|
"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).",
|
|
1179
1226
|
{
|
|
1180
|
-
projectId:
|
|
1181
|
-
taskId:
|
|
1182
|
-
title:
|
|
1227
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1228
|
+
taskId: z11.string().describe("The task ID or slug"),
|
|
1229
|
+
title: z11.string().min(1).describe("The title of the manual test to remove")
|
|
1183
1230
|
},
|
|
1184
1231
|
async (params) => {
|
|
1185
1232
|
await conn2.removeManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1192,9 +1239,9 @@ function registerApproveManualTest(server2, conn2) {
|
|
|
1192
1239
|
"approve_manual_test",
|
|
1193
1240
|
"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.",
|
|
1194
1241
|
{
|
|
1195
|
-
projectId:
|
|
1196
|
-
taskId:
|
|
1197
|
-
title:
|
|
1242
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1243
|
+
taskId: z11.string().describe("The task ID or slug"),
|
|
1244
|
+
title: z11.string().min(1).describe("The title of the manual test to approve")
|
|
1198
1245
|
},
|
|
1199
1246
|
async (params) => {
|
|
1200
1247
|
await conn2.approveManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1207,10 +1254,10 @@ function registerRejectManualTest(server2, conn2) {
|
|
|
1207
1254
|
"reject_manual_test",
|
|
1208
1255
|
"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.",
|
|
1209
1256
|
{
|
|
1210
|
-
projectId:
|
|
1211
|
-
taskId:
|
|
1212
|
-
title:
|
|
1213
|
-
reason:
|
|
1257
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1258
|
+
taskId: z11.string().describe("The task ID or slug"),
|
|
1259
|
+
title: z11.string().min(1).describe("The title of the manual test to reject"),
|
|
1260
|
+
reason: z11.string().min(1).max(2e3).describe("Why the test failed \u2014 what went wrong, shown to the team")
|
|
1214
1261
|
},
|
|
1215
1262
|
async (params) => {
|
|
1216
1263
|
await conn2.rejectManualTest(params.taskId, params.title, params.reason, params.projectId);
|
|
@@ -1230,9 +1277,9 @@ function registerQueryManualTests(server2, conn2) {
|
|
|
1230
1277
|
"query_manual_tests",
|
|
1231
1278
|
"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.",
|
|
1232
1279
|
{
|
|
1233
|
-
projectId:
|
|
1234
|
-
cardStatuses:
|
|
1235
|
-
testStatuses:
|
|
1280
|
+
projectId: z11.string().optional().describe("Target Conveyor project ID"),
|
|
1281
|
+
cardStatuses: z11.array(z11.string()).optional().describe('Filter tasks by card/column status, e.g. ["ReviewDev", "ReviewLive"]'),
|
|
1282
|
+
testStatuses: z11.array(z11.enum(["open", "approved", "rejected"])).optional().describe("Filter tests by status: open | approved | rejected")
|
|
1236
1283
|
},
|
|
1237
1284
|
async (params) => {
|
|
1238
1285
|
const groups = await conn2.queryManualTests({
|
|
@@ -1258,7 +1305,7 @@ function registerChecklistTools(server2, conn2) {
|
|
|
1258
1305
|
}
|
|
1259
1306
|
|
|
1260
1307
|
// src/tools/workspace.ts
|
|
1261
|
-
import { z as
|
|
1308
|
+
import { z as z12 } from "zod";
|
|
1262
1309
|
|
|
1263
1310
|
// src/workspace-ssh-tunnel.ts
|
|
1264
1311
|
import net from "net";
|
|
@@ -1377,8 +1424,8 @@ function registerAttachInfoTool(server2, conn2) {
|
|
|
1377
1424
|
"workspace_attach_info",
|
|
1378
1425
|
"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.",
|
|
1379
1426
|
{
|
|
1380
|
-
taskId:
|
|
1381
|
-
sshPublicKey:
|
|
1427
|
+
taskId: z12.string().describe("The task ID"),
|
|
1428
|
+
sshPublicKey: z12.string().optional().describe("Optional OpenSSH public key to install into the workspace")
|
|
1382
1429
|
},
|
|
1383
1430
|
async ({ taskId, sshPublicKey }) => {
|
|
1384
1431
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1391,7 +1438,7 @@ function registerPreviewUrlsTool(server2, conn2) {
|
|
|
1391
1438
|
"workspace_preview_urls",
|
|
1392
1439
|
"Return the hosted preview URLs and preview ports for a running task Claudespace. This mirrors the web UI preview link metadata.",
|
|
1393
1440
|
{
|
|
1394
|
-
taskId:
|
|
1441
|
+
taskId: z12.string().describe("The task ID")
|
|
1395
1442
|
},
|
|
1396
1443
|
async ({ taskId }) => {
|
|
1397
1444
|
const info = await conn2.getWorkspaceAttachInfo(taskId);
|
|
@@ -1420,10 +1467,10 @@ function registerStartTunnelTool(server2, conn2, startTunnel) {
|
|
|
1420
1467
|
"workspace_start_tunnel",
|
|
1421
1468
|
"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.",
|
|
1422
1469
|
{
|
|
1423
|
-
taskId:
|
|
1424
|
-
port:
|
|
1425
|
-
preferredLocalPort:
|
|
1426
|
-
sshPublicKey:
|
|
1470
|
+
taskId: z12.string().describe("The task ID"),
|
|
1471
|
+
port: z12.number().optional().describe("Remote Claudespace port. Defaults to SSH port 2222."),
|
|
1472
|
+
preferredLocalPort: z12.number().optional().describe("Preferred local loopback port. If omitted, the OS chooses one."),
|
|
1473
|
+
sshPublicKey: z12.string().optional().describe("Optional OpenSSH public key to install before opening the tunnel")
|
|
1427
1474
|
},
|
|
1428
1475
|
async ({ taskId, port, preferredLocalPort, sshPublicKey }) => {
|
|
1429
1476
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1476,7 +1523,7 @@ function registerStopTunnelTool(server2) {
|
|
|
1476
1523
|
"workspace_stop_tunnel",
|
|
1477
1524
|
"Stop a local workspace tunnel previously opened by workspace_start_tunnel.",
|
|
1478
1525
|
{
|
|
1479
|
-
tunnelId:
|
|
1526
|
+
tunnelId: z12.string().describe("Tunnel id returned by workspace_start_tunnel")
|
|
1480
1527
|
},
|
|
1481
1528
|
async ({ tunnelId }) => {
|
|
1482
1529
|
const tunnel = activeTunnels.get(tunnelId);
|
|
@@ -1495,7 +1542,7 @@ function registerWorkspaceTools(server2, conn2, deps = {}) {
|
|
|
1495
1542
|
}
|
|
1496
1543
|
|
|
1497
1544
|
// src/tools/logs.ts
|
|
1498
|
-
import { z as
|
|
1545
|
+
import { z as z13 } from "zod";
|
|
1499
1546
|
var SEVERITY_ENUM = [
|
|
1500
1547
|
"DEBUG",
|
|
1501
1548
|
"INFO",
|
|
@@ -1630,18 +1677,18 @@ function registerGrafanaLogTool(server2, conn2) {
|
|
|
1630
1677
|
"query_grafana_logs",
|
|
1631
1678
|
"Query the project's connected Grafana (Loki) logs \u2014 the application logs shipped to Grafana Cloud/Loki, complementing query_gcp_logs (GCP infrastructure logs). Start with structured filters (env, level=error, sinceMinutes=60, services), then narrow with search; pass raw LogQL via logql only when structured filters can't express the query (it REPLACES them). The response header echoes the composed LogQL \u2014 iterate on it. Returns compact lines: '<time> <SEVERITY> [<service>] <message>'.",
|
|
1632
1679
|
{
|
|
1633
|
-
projectId:
|
|
1634
|
-
env:
|
|
1635
|
-
sinceMinutes:
|
|
1680
|
+
projectId: z13.string().optional().describe("Target Conveyor project ID"),
|
|
1681
|
+
env: z13.enum(["prod", "dev"]).optional().describe("Configured Grafana env mapping to scope by (default prod)"),
|
|
1682
|
+
sinceMinutes: z13.number().int().min(1).max(10080).optional().describe(
|
|
1636
1683
|
"Relative time window ending now, in minutes (default 60). Ignored if startTime is set."
|
|
1637
1684
|
),
|
|
1638
|
-
startTime:
|
|
1639
|
-
endTime:
|
|
1640
|
-
level:
|
|
1641
|
-
services:
|
|
1642
|
-
search:
|
|
1643
|
-
logql:
|
|
1644
|
-
limit:
|
|
1685
|
+
startTime: z13.string().optional().describe("ISO 8601 lower bound (overrides sinceMinutes)"),
|
|
1686
|
+
endTime: z13.string().optional().describe("ISO 8601 upper bound (default now)"),
|
|
1687
|
+
level: z13.enum(["debug", "info", "warn", "error", "fatal"]).optional().describe("Minimum severity, inclusive \u2014 error returns error and above"),
|
|
1688
|
+
services: z13.array(z13.string()).optional().describe("Restrict to these service_name label values"),
|
|
1689
|
+
search: z13.string().max(256).optional().describe("Substring line filter (exact substring, not regex)"),
|
|
1690
|
+
logql: z13.string().max(2e3).optional().describe("Advanced: raw LogQL query \u2014 REPLACES env/services/level/search composition"),
|
|
1691
|
+
limit: z13.number().int().min(1).max(200).optional().describe("Max entries (default 50)")
|
|
1645
1692
|
},
|
|
1646
1693
|
async (params) => {
|
|
1647
1694
|
const text = await runQueryGrafanaLogs(conn2, params);
|
|
@@ -1654,25 +1701,25 @@ function registerLogTools(server2, conn2) {
|
|
|
1654
1701
|
"query_gcp_logs",
|
|
1655
1702
|
"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.",
|
|
1656
1703
|
{
|
|
1657
|
-
projectId:
|
|
1658
|
-
env:
|
|
1659
|
-
sinceMinutes:
|
|
1704
|
+
projectId: z13.string().optional().describe("Target Conveyor project ID"),
|
|
1705
|
+
env: z13.enum(["prod", "dev", "claudespace"]).optional().describe("GCP environment slot to query (default prod)"),
|
|
1706
|
+
sinceMinutes: z13.number().int().min(1).max(10080).optional().describe(
|
|
1660
1707
|
"Relative time window ending now, in minutes (default 60). Ignored if startTime is set."
|
|
1661
1708
|
),
|
|
1662
|
-
startTime:
|
|
1663
|
-
endTime:
|
|
1664
|
-
severity:
|
|
1665
|
-
services:
|
|
1709
|
+
startTime: z13.string().optional().describe("ISO 8601 lower bound (overrides sinceMinutes)"),
|
|
1710
|
+
endTime: z13.string().optional().describe("ISO 8601 upper bound (default now)"),
|
|
1711
|
+
severity: z13.enum(SEVERITY_ENUM).optional().describe("Minimum severity, inclusive \u2014 ERROR returns ERROR and above"),
|
|
1712
|
+
services: z13.array(z13.string()).optional().describe(
|
|
1666
1713
|
"Restrict to these Cloud Run service names (prod/dev only). Defaults to all services linked in project settings."
|
|
1667
1714
|
),
|
|
1668
|
-
sqlInstances:
|
|
1669
|
-
allServices:
|
|
1715
|
+
sqlInstances: z13.array(z13.string()).optional().describe("Restrict to these Cloud SQL instance names (prod/dev only)"),
|
|
1716
|
+
allServices: z13.boolean().optional().describe(
|
|
1670
1717
|
"Set true to search ALL logs in the GCP project, ignoring the linked-resource scope"
|
|
1671
1718
|
),
|
|
1672
|
-
search:
|
|
1673
|
-
filter:
|
|
1674
|
-
limit:
|
|
1675
|
-
pageToken:
|
|
1719
|
+
search: z13.string().max(256).optional().describe("Free-text search across all log fields (exact substring, not regex)"),
|
|
1720
|
+
filter: z13.string().max(1e3).optional().describe("Advanced: raw Cloud Logging filter expression, ANDed with the scope"),
|
|
1721
|
+
limit: z13.number().int().min(1).max(200).optional().describe("Max entries per page (default 50)"),
|
|
1722
|
+
pageToken: z13.string().optional().describe("Opaque token from a previous response to fetch the next page")
|
|
1676
1723
|
},
|
|
1677
1724
|
async (params) => {
|
|
1678
1725
|
const text = await runQueryGcpLogs(conn2, params);
|
|
@@ -1685,6 +1732,7 @@ function registerLogTools(server2, conn2) {
|
|
|
1685
1732
|
// src/tools/index.ts
|
|
1686
1733
|
function registerAllTools(server2, conn2) {
|
|
1687
1734
|
registerProjectTools(server2, conn2);
|
|
1735
|
+
registerConnectionTools(server2, conn2);
|
|
1688
1736
|
registerProjectConfigTools(server2, conn2);
|
|
1689
1737
|
registerTaskTools(server2, conn2);
|
|
1690
1738
|
registerBuildTools(server2, conn2);
|
|
@@ -1703,13 +1751,14 @@ var { version } = createRequire(import.meta.url)("../package.json");
|
|
|
1703
1751
|
var apiUrl = process.env.CONVEYOR_API_URL;
|
|
1704
1752
|
var projectToken = process.env.CONVEYOR_USER_TOKEN ?? process.env.CONVEYOR_PROJECT_TOKEN;
|
|
1705
1753
|
var projectId = process.env.CONVEYOR_PROJECT_ID;
|
|
1754
|
+
var subProjectId = process.env.CONVEYOR_SUBPROJECT_ID;
|
|
1706
1755
|
if (!apiUrl || !projectToken) {
|
|
1707
1756
|
process.stderr.write(
|
|
1708
1757
|
"Error: CONVEYOR_API_URL and CONVEYOR_USER_TOKEN or CONVEYOR_PROJECT_TOKEN environment variables are required. CONVEYOR_PROJECT_ID is optional and sets the default project.\n"
|
|
1709
1758
|
);
|
|
1710
1759
|
process.exit(1);
|
|
1711
1760
|
}
|
|
1712
|
-
var conn = new ConveyorConnection({ apiUrl, projectToken, projectId });
|
|
1761
|
+
var conn = new ConveyorConnection({ apiUrl, projectToken, projectId, subProjectId });
|
|
1713
1762
|
try {
|
|
1714
1763
|
await conn.connect();
|
|
1715
1764
|
process.stderr.write("Connected to Conveyor API\n");
|