@rallycry/conveyor-mcp 4.3.7 → 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-JSQLLIYJ.js → chunk-KOYKRWVY.js} +66 -7
- package/dist/chunk-KOYKRWVY.js.map +1 -0
- package/dist/cli.js +326 -219
- 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 +118 -3
- package/package.json +3 -3
- package/dist/chunk-JSQLLIYJ.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
|
);
|
|
@@ -93,16 +135,18 @@ function registerGetConnectUrls(server2, conn2) {
|
|
|
93
135
|
function registerUpdateProjectSettings(server2, conn2) {
|
|
94
136
|
server2.tool(
|
|
95
137
|
"update_project_settings",
|
|
96
|
-
"Update project configuration: name, description, default agent assignments, or a
|
|
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:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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(
|
|
144
|
+
"Deep-merged patch of the project settings JSON (JSON Merge Patch semantics: null deletes a key; advanced)"
|
|
145
|
+
),
|
|
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")
|
|
106
150
|
},
|
|
107
151
|
async (params) => {
|
|
108
152
|
const { projectId: projectId2, name, description, settings, ...agents } = params;
|
|
@@ -131,12 +175,12 @@ function registerManageTags(server2, conn2) {
|
|
|
131
175
|
"manage_tags",
|
|
132
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.",
|
|
133
177
|
{
|
|
134
|
-
action:
|
|
135
|
-
projectId:
|
|
136
|
-
id:
|
|
137
|
-
name:
|
|
138
|
-
color:
|
|
139
|
-
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")
|
|
140
184
|
},
|
|
141
185
|
async (params) => {
|
|
142
186
|
const { action, projectId: projectId2, id, name, color, description } = params;
|
|
@@ -170,13 +214,13 @@ function registerManagePriorities(server2, conn2) {
|
|
|
170
214
|
"manage_priorities",
|
|
171
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.",
|
|
172
216
|
{
|
|
173
|
-
action:
|
|
174
|
-
projectId:
|
|
175
|
-
id:
|
|
176
|
-
value:
|
|
177
|
-
name:
|
|
178
|
-
color:
|
|
179
|
-
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")
|
|
180
224
|
},
|
|
181
225
|
async (params) => {
|
|
182
226
|
const { action, projectId: projectId2, id, value, name, color, description } = params;
|
|
@@ -217,7 +261,7 @@ function registerProjectConfigTools(server2, conn2) {
|
|
|
217
261
|
}
|
|
218
262
|
|
|
219
263
|
// src/tools/tasks.ts
|
|
220
|
-
import { z as
|
|
264
|
+
import { z as z4 } from "zod";
|
|
221
265
|
var CLI_EVENT_FORMATTERS = {
|
|
222
266
|
thinking: (data) => String(data.message ?? ""),
|
|
223
267
|
tool_use: (data) => `${data.tool}: ${String(data.input ?? "").slice(0, 1e3)}`,
|
|
@@ -287,22 +331,26 @@ var STATUS_ENUM = [
|
|
|
287
331
|
];
|
|
288
332
|
var CARD_TYPE_ENUM = ["task", "incident", "suggestion"];
|
|
289
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
|
+
);
|
|
290
340
|
function registerListTasks(server2, conn2) {
|
|
291
341
|
server2.tool(
|
|
292
342
|
"list_tasks",
|
|
293
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.",
|
|
294
344
|
{
|
|
295
|
-
projectId:
|
|
296
|
-
status:
|
|
297
|
-
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(
|
|
298
348
|
'Card types to include, e.g. ["incident"] or ["task", "incident"]. Omit for tasks only.'
|
|
299
349
|
),
|
|
300
|
-
assigneeId:
|
|
301
|
-
unassigned:
|
|
302
|
-
subProjectId:
|
|
303
|
-
|
|
304
|
-
),
|
|
305
|
-
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)")
|
|
306
354
|
},
|
|
307
355
|
async (params) => {
|
|
308
356
|
const tasks = await conn2.listTasks(params);
|
|
@@ -317,8 +365,8 @@ function registerGetTask(server2, conn2) {
|
|
|
317
365
|
"get_task",
|
|
318
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.",
|
|
319
367
|
{
|
|
320
|
-
projectId:
|
|
321
|
-
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>)")
|
|
322
370
|
},
|
|
323
371
|
async (params) => {
|
|
324
372
|
const task = await conn2.getTask(params.taskId, params.projectId);
|
|
@@ -331,8 +379,8 @@ function registerGetCardBySlug(server2, conn2) {
|
|
|
331
379
|
"get_card_by_slug",
|
|
332
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.",
|
|
333
381
|
{
|
|
334
|
-
projectId:
|
|
335
|
-
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'")
|
|
336
384
|
},
|
|
337
385
|
async (params) => {
|
|
338
386
|
const task = await conn2.getCardBySlug(params.slug, params.projectId);
|
|
@@ -345,19 +393,22 @@ function registerCreateTask(server2, conn2) {
|
|
|
345
393
|
"create_task",
|
|
346
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.",
|
|
347
395
|
{
|
|
348
|
-
projectId:
|
|
349
|
-
title:
|
|
350
|
-
description:
|
|
351
|
-
plan:
|
|
352
|
-
status:
|
|
353
|
-
subProjectId:
|
|
354
|
-
"Scope to a sub-project board (list/search: filter; create/update: assign). Omit for the whole project."
|
|
355
|
-
)
|
|
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
|
|
356
402
|
},
|
|
357
403
|
async (params) => {
|
|
358
404
|
const task = await conn2.createTask(params);
|
|
359
405
|
return {
|
|
360
|
-
content: [
|
|
406
|
+
content: [
|
|
407
|
+
{
|
|
408
|
+
type: "text",
|
|
409
|
+
text: `Task created: ${task.id} (slug: ${task.slug}). effectiveScope: ${JSON.stringify(task.effectiveScope)}`
|
|
410
|
+
}
|
|
411
|
+
]
|
|
361
412
|
};
|
|
362
413
|
}
|
|
363
414
|
);
|
|
@@ -367,17 +418,17 @@ function registerUpdateTask(server2, conn2) {
|
|
|
367
418
|
"update_task",
|
|
368
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.",
|
|
369
420
|
{
|
|
370
|
-
projectId:
|
|
371
|
-
taskId:
|
|
372
|
-
title:
|
|
373
|
-
description:
|
|
374
|
-
plan:
|
|
375
|
-
status:
|
|
376
|
-
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(
|
|
377
428
|
"Risk level \u2014 how much important surface the task touches (critical/high/medium/low). Pass null to clear."
|
|
378
429
|
),
|
|
379
|
-
assignedUserId:
|
|
380
|
-
subProjectId:
|
|
430
|
+
assignedUserId: z4.string().nullable().optional().describe("User ID to assign, or null"),
|
|
431
|
+
subProjectId: z4.string().nullable().optional().describe(
|
|
381
432
|
"Assign the task to a sub-project board; null moves it back to the parent board. Omit to leave unchanged."
|
|
382
433
|
)
|
|
383
434
|
},
|
|
@@ -394,9 +445,9 @@ function registerMoveCard(server2, conn2) {
|
|
|
394
445
|
"move_card",
|
|
395
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.",
|
|
396
447
|
{
|
|
397
|
-
projectId:
|
|
398
|
-
taskId:
|
|
399
|
-
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")
|
|
400
451
|
},
|
|
401
452
|
async (params) => {
|
|
402
453
|
const result = await conn2.moveCard(params);
|
|
@@ -417,9 +468,9 @@ function registerChatTools(server2, conn2) {
|
|
|
417
468
|
"read_task_chat",
|
|
418
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.",
|
|
419
470
|
{
|
|
420
|
-
projectId:
|
|
421
|
-
taskId:
|
|
422
|
-
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)")
|
|
423
474
|
},
|
|
424
475
|
async (params) => {
|
|
425
476
|
const messages = await conn2.getTaskChat(params.taskId, params.limit, params.projectId);
|
|
@@ -430,9 +481,9 @@ function registerChatTools(server2, conn2) {
|
|
|
430
481
|
"post_to_chat",
|
|
431
482
|
"Post a message to a task's chat. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
432
483
|
{
|
|
433
|
-
projectId:
|
|
434
|
-
taskId:
|
|
435
|
-
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")
|
|
436
487
|
},
|
|
437
488
|
async (params) => {
|
|
438
489
|
await conn2.postToTaskChat(params.taskId, params.content, params.projectId);
|
|
@@ -445,12 +496,12 @@ function registerGetTaskCli(server2, conn2) {
|
|
|
445
496
|
"get_task_logs",
|
|
446
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.",
|
|
447
498
|
{
|
|
448
|
-
projectId:
|
|
449
|
-
taskId:
|
|
450
|
-
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(
|
|
451
502
|
"Filter by log source: 'agent' for reasoning/tool calls, 'application' for setup/dev-server output"
|
|
452
503
|
),
|
|
453
|
-
limit:
|
|
504
|
+
limit: z4.number().optional().describe("Max entries to return (default 50, max 500)")
|
|
454
505
|
},
|
|
455
506
|
async ({ taskId, source, limit, projectId: projectId2 }) => {
|
|
456
507
|
const effectiveLimit = Math.min(limit ?? 50, 500);
|
|
@@ -469,8 +520,8 @@ function registerGetTaskSessions(server2, conn2) {
|
|
|
469
520
|
"get_task_sessions",
|
|
470
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.",
|
|
471
522
|
{
|
|
472
|
-
projectId:
|
|
473
|
-
taskId:
|
|
523
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID"),
|
|
524
|
+
taskId: z4.string().describe("The task ID or slug")
|
|
474
525
|
},
|
|
475
526
|
async ({ taskId, projectId: projectId2 }) => {
|
|
476
527
|
const tasks = await conn2.getTaskSessions(taskId, projectId2);
|
|
@@ -488,19 +539,17 @@ function registerSearchTasks(server2, conn2) {
|
|
|
488
539
|
"search_tasks",
|
|
489
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.",
|
|
490
541
|
{
|
|
491
|
-
projectId:
|
|
492
|
-
tagNames:
|
|
493
|
-
searchQuery:
|
|
494
|
-
statusFilters:
|
|
495
|
-
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(
|
|
496
547
|
'Card types to include (default ["task"]). Pass e.g. ["incident"] or list several to search across types.'
|
|
497
548
|
),
|
|
498
|
-
assigneeId:
|
|
499
|
-
unassigned:
|
|
500
|
-
subProjectId:
|
|
501
|
-
|
|
502
|
-
),
|
|
503
|
-
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)")
|
|
504
553
|
},
|
|
505
554
|
async (params) => {
|
|
506
555
|
const tasks = await conn2.searchTasks(params);
|
|
@@ -515,7 +564,7 @@ function registerListTags(server2, conn2) {
|
|
|
515
564
|
"list_tags",
|
|
516
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.",
|
|
517
566
|
{
|
|
518
|
-
projectId:
|
|
567
|
+
projectId: z4.string().optional().describe("Target Conveyor project ID")
|
|
519
568
|
},
|
|
520
569
|
async (params) => {
|
|
521
570
|
const tags = await conn2.listTags(params.projectId);
|
|
@@ -528,9 +577,9 @@ function registerReviewTools(server2, conn2) {
|
|
|
528
577
|
"approve_task",
|
|
529
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.",
|
|
530
579
|
{
|
|
531
|
-
projectId:
|
|
532
|
-
taskId:
|
|
533
|
-
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.")
|
|
534
583
|
},
|
|
535
584
|
async (params) => {
|
|
536
585
|
const result = await conn2.approveTask(params.taskId, params.projectId, params.risk);
|
|
@@ -543,8 +592,8 @@ function registerReviewTools(server2, conn2) {
|
|
|
543
592
|
"approve_and_merge_pr",
|
|
544
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.",
|
|
545
594
|
{
|
|
546
|
-
projectId:
|
|
547
|
-
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")
|
|
548
597
|
},
|
|
549
598
|
async (params) => {
|
|
550
599
|
const result = await conn2.approveAndMergePR(params.childTaskId, params.projectId);
|
|
@@ -562,10 +611,10 @@ function registerReviewTools(server2, conn2) {
|
|
|
562
611
|
"request_changes",
|
|
563
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.",
|
|
564
613
|
{
|
|
565
|
-
projectId:
|
|
566
|
-
taskId:
|
|
567
|
-
feedback:
|
|
568
|
-
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.")
|
|
569
618
|
},
|
|
570
619
|
async (params) => {
|
|
571
620
|
await conn2.requestChanges(params.taskId, params.feedback, params.projectId, params.risk);
|
|
@@ -582,9 +631,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
582
631
|
"add_reviewer",
|
|
583
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.",
|
|
584
633
|
{
|
|
585
|
-
projectId:
|
|
586
|
-
taskId:
|
|
587
|
-
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)")
|
|
588
637
|
},
|
|
589
638
|
async (params) => {
|
|
590
639
|
const result = await conn2.addReviewer(params);
|
|
@@ -602,9 +651,9 @@ function registerReviewerTools(server2, conn2) {
|
|
|
602
651
|
"remove_reviewer",
|
|
603
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.",
|
|
604
653
|
{
|
|
605
|
-
projectId:
|
|
606
|
-
taskId:
|
|
607
|
-
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")
|
|
608
657
|
},
|
|
609
658
|
async (params) => {
|
|
610
659
|
const result = await conn2.removeReviewer(params);
|
|
@@ -636,7 +685,7 @@ function registerTaskTools(server2, conn2) {
|
|
|
636
685
|
}
|
|
637
686
|
|
|
638
687
|
// src/tools/builds.ts
|
|
639
|
-
import { z as
|
|
688
|
+
import { z as z5 } from "zod";
|
|
640
689
|
function textResult2(result) {
|
|
641
690
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
642
691
|
}
|
|
@@ -645,8 +694,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
645
694
|
"stop_task",
|
|
646
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.",
|
|
647
696
|
{
|
|
648
|
-
projectId:
|
|
649
|
-
taskId:
|
|
697
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
698
|
+
taskId: z5.string().describe("The task ID")
|
|
650
699
|
},
|
|
651
700
|
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
652
701
|
);
|
|
@@ -654,8 +703,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
654
703
|
"sleep_task",
|
|
655
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.",
|
|
656
705
|
{
|
|
657
|
-
projectId:
|
|
658
|
-
taskId:
|
|
706
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
707
|
+
taskId: z5.string().describe("The task ID")
|
|
659
708
|
},
|
|
660
709
|
async (params) => textResult2(await conn2.sleepTask(params.taskId, params.projectId))
|
|
661
710
|
);
|
|
@@ -663,8 +712,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
663
712
|
"resume_task",
|
|
664
713
|
"Resume a sleeping task Claudespace. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
665
714
|
{
|
|
666
|
-
projectId:
|
|
667
|
-
taskId:
|
|
715
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
716
|
+
taskId: z5.string().describe("The task ID")
|
|
668
717
|
},
|
|
669
718
|
async (params) => textResult2(await conn2.resumeTask(params.taskId, params.projectId))
|
|
670
719
|
);
|
|
@@ -672,8 +721,8 @@ function registerTaskLifecycleTools(server2, conn2) {
|
|
|
672
721
|
"delete_task_environment",
|
|
673
722
|
"Delete a task environment, including durable Claudespace state. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
674
723
|
{
|
|
675
|
-
projectId:
|
|
676
|
-
taskId:
|
|
724
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
725
|
+
taskId: z5.string().describe("The task ID")
|
|
677
726
|
},
|
|
678
727
|
async (params) => textResult2(await conn2.deleteTaskEnvironment(params.taskId, params.projectId))
|
|
679
728
|
);
|
|
@@ -683,8 +732,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
683
732
|
"start_task",
|
|
684
733
|
"Start a cloud build (codespace) for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
685
734
|
{
|
|
686
|
-
projectId:
|
|
687
|
-
taskId:
|
|
735
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
736
|
+
taskId: z5.string().describe("The task ID")
|
|
688
737
|
},
|
|
689
738
|
async (params) => {
|
|
690
739
|
const result = await conn2.startBuild(params.taskId, params.projectId);
|
|
@@ -696,8 +745,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
696
745
|
"create_release",
|
|
697
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).",
|
|
698
747
|
{
|
|
699
|
-
projectId:
|
|
700
|
-
taskIds:
|
|
748
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
749
|
+
taskIds: z5.array(z5.string()).optional().describe(
|
|
701
750
|
"Task IDs in Review (Dev) to cherry-pick into the release. Omit to release all of them."
|
|
702
751
|
)
|
|
703
752
|
},
|
|
@@ -710,8 +759,8 @@ function registerBuildTools(server2, conn2) {
|
|
|
710
759
|
"get_build_status",
|
|
711
760
|
"Check codespace and agent status for a task. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
712
761
|
{
|
|
713
|
-
projectId:
|
|
714
|
-
taskId:
|
|
762
|
+
projectId: z5.string().optional().describe("Target Conveyor project ID"),
|
|
763
|
+
taskId: z5.string().describe("The task ID")
|
|
715
764
|
},
|
|
716
765
|
async (params) => {
|
|
717
766
|
const status = await conn2.getBuildStatus(params.taskId, params.projectId);
|
|
@@ -723,7 +772,7 @@ function registerBuildTools(server2, conn2) {
|
|
|
723
772
|
// src/tools/attachments.ts
|
|
724
773
|
import { readFile, stat } from "fs/promises";
|
|
725
774
|
import { basename, extname } from "path";
|
|
726
|
-
import { z as
|
|
775
|
+
import { z as z6 } from "zod";
|
|
727
776
|
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
728
777
|
var MIME_BY_EXT = {
|
|
729
778
|
".png": "image/png",
|
|
@@ -760,8 +809,8 @@ function registerListTaskFiles(server2, conn2) {
|
|
|
760
809
|
"list_task_files",
|
|
761
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.",
|
|
762
811
|
{
|
|
763
|
-
projectId:
|
|
764
|
-
taskId:
|
|
812
|
+
projectId: z6.string().optional().describe("Target Conveyor project ID"),
|
|
813
|
+
taskId: z6.string().describe("The task ID or slug")
|
|
765
814
|
},
|
|
766
815
|
async (params) => {
|
|
767
816
|
const files = await conn2.listTaskFiles(params.taskId, params.projectId);
|
|
@@ -803,11 +852,11 @@ function registerGetAttachment(server2, conn2) {
|
|
|
803
852
|
"get_attachment",
|
|
804
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.",
|
|
805
854
|
{
|
|
806
|
-
projectId:
|
|
807
|
-
taskId:
|
|
808
|
-
fileId:
|
|
809
|
-
offset:
|
|
810
|
-
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.")
|
|
811
860
|
},
|
|
812
861
|
async (params) => {
|
|
813
862
|
const file = await conn2.getAttachment(params.taskId, params.fileId, {
|
|
@@ -824,11 +873,11 @@ function registerUploadAttachment(server2, conn2) {
|
|
|
824
873
|
"upload_attachment",
|
|
825
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.",
|
|
826
875
|
{
|
|
827
|
-
projectId:
|
|
828
|
-
taskId:
|
|
829
|
-
path:
|
|
830
|
-
comment:
|
|
831
|
-
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")
|
|
832
881
|
},
|
|
833
882
|
async (params) => {
|
|
834
883
|
const info = await stat(params.path).catch(() => null);
|
|
@@ -891,18 +940,18 @@ function registerAttachmentTools(server2, conn2) {
|
|
|
891
940
|
}
|
|
892
941
|
|
|
893
942
|
// src/tools/pull-request.ts
|
|
894
|
-
import { z as
|
|
943
|
+
import { z as z7 } from "zod";
|
|
895
944
|
function registerPullRequestTools(server2, conn2) {
|
|
896
945
|
server2.tool(
|
|
897
946
|
"create_pull_request",
|
|
898
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.",
|
|
899
948
|
{
|
|
900
|
-
projectId:
|
|
901
|
-
taskId:
|
|
902
|
-
title:
|
|
903
|
-
body:
|
|
904
|
-
head:
|
|
905
|
-
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)")
|
|
906
955
|
},
|
|
907
956
|
async (params) => {
|
|
908
957
|
const result = await conn2.createPullRequest(params);
|
|
@@ -914,7 +963,7 @@ function registerPullRequestTools(server2, conn2) {
|
|
|
914
963
|
}
|
|
915
964
|
|
|
916
965
|
// src/tools/subtasks.ts
|
|
917
|
-
import { z as
|
|
966
|
+
import { z as z8 } from "zod";
|
|
918
967
|
var STATUS_ENUM2 = [
|
|
919
968
|
"Planning",
|
|
920
969
|
"Open",
|
|
@@ -932,15 +981,15 @@ function registerCreateSubtask(server2, conn2) {
|
|
|
932
981
|
"create_subtask",
|
|
933
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.",
|
|
934
983
|
{
|
|
935
|
-
projectId:
|
|
936
|
-
parentTaskId:
|
|
937
|
-
title:
|
|
938
|
-
description:
|
|
939
|
-
plan:
|
|
940
|
-
ordinal:
|
|
941
|
-
storyPointValue:
|
|
942
|
-
followParentStatus:
|
|
943
|
-
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(
|
|
944
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."
|
|
945
994
|
)
|
|
946
995
|
},
|
|
@@ -957,16 +1006,16 @@ function registerUpdateSubtask(server2, conn2) {
|
|
|
957
1006
|
"update_subtask",
|
|
958
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.",
|
|
959
1008
|
{
|
|
960
|
-
projectId:
|
|
961
|
-
subtaskId:
|
|
962
|
-
title:
|
|
963
|
-
description:
|
|
964
|
-
plan:
|
|
965
|
-
status:
|
|
966
|
-
ordinal:
|
|
967
|
-
storyPointValue:
|
|
968
|
-
followParentStatus:
|
|
969
|
-
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(
|
|
970
1019
|
"Replace the sibling subtask ids/slugs this subtask blocks on (pass [] to clear). Omit to leave dependencies unchanged."
|
|
971
1020
|
)
|
|
972
1021
|
},
|
|
@@ -985,8 +1034,8 @@ function registerListSubtasks(server2, conn2) {
|
|
|
985
1034
|
"list_subtasks",
|
|
986
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.",
|
|
987
1036
|
{
|
|
988
|
-
projectId:
|
|
989
|
-
taskId:
|
|
1037
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1038
|
+
taskId: z8.string().describe("The parent task ID")
|
|
990
1039
|
},
|
|
991
1040
|
async (params) => {
|
|
992
1041
|
const subtasks = await conn2.listSubtasks(params.taskId, params.projectId);
|
|
@@ -999,8 +1048,8 @@ function registerDeleteSubtask(server2, conn2) {
|
|
|
999
1048
|
"delete_subtask",
|
|
1000
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.",
|
|
1001
1050
|
{
|
|
1002
|
-
projectId:
|
|
1003
|
-
subtaskId:
|
|
1051
|
+
projectId: z8.string().optional().describe("Target Conveyor project ID"),
|
|
1052
|
+
subtaskId: z8.string().describe("The subtask ID to delete")
|
|
1004
1053
|
},
|
|
1005
1054
|
async (params) => {
|
|
1006
1055
|
const result = await conn2.deleteSubtask(params.subtaskId, params.projectId);
|
|
@@ -1020,14 +1069,14 @@ function registerSubtaskTools(server2, conn2) {
|
|
|
1020
1069
|
}
|
|
1021
1070
|
|
|
1022
1071
|
// src/tools/dependencies.ts
|
|
1023
|
-
import { z as
|
|
1072
|
+
import { z as z9 } from "zod";
|
|
1024
1073
|
function registerGetDependencies(server2, conn2) {
|
|
1025
1074
|
server2.tool(
|
|
1026
1075
|
"get_dependencies",
|
|
1027
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.",
|
|
1028
1077
|
{
|
|
1029
|
-
projectId:
|
|
1030
|
-
taskId:
|
|
1078
|
+
projectId: z9.string().optional().describe("Target Conveyor project ID"),
|
|
1079
|
+
taskId: z9.string().describe("The task ID")
|
|
1031
1080
|
},
|
|
1032
1081
|
async (params) => {
|
|
1033
1082
|
const deps = await conn2.getDependencies(params.taskId, params.projectId);
|
|
@@ -1040,9 +1089,9 @@ function registerAddDependency(server2, conn2) {
|
|
|
1040
1089
|
"add_dependency",
|
|
1041
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.",
|
|
1042
1091
|
{
|
|
1043
|
-
projectId:
|
|
1044
|
-
taskId:
|
|
1045
|
-
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")
|
|
1046
1095
|
},
|
|
1047
1096
|
async (params) => {
|
|
1048
1097
|
await conn2.addDependency(params);
|
|
@@ -1055,9 +1104,9 @@ function registerRemoveDependency(server2, conn2) {
|
|
|
1055
1104
|
"remove_dependency",
|
|
1056
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.",
|
|
1057
1106
|
{
|
|
1058
|
-
projectId:
|
|
1059
|
-
taskId:
|
|
1060
|
-
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")
|
|
1061
1110
|
},
|
|
1062
1111
|
async (params) => {
|
|
1063
1112
|
await conn2.removeDependency(params);
|
|
@@ -1072,16 +1121,16 @@ function registerDependencyTools(server2, conn2) {
|
|
|
1072
1121
|
}
|
|
1073
1122
|
|
|
1074
1123
|
// src/tools/suggestions.ts
|
|
1075
|
-
import { z as
|
|
1124
|
+
import { z as z10 } from "zod";
|
|
1076
1125
|
function registerSuggestionTools(server2, conn2) {
|
|
1077
1126
|
server2.tool(
|
|
1078
1127
|
"create_suggestion",
|
|
1079
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.",
|
|
1080
1129
|
{
|
|
1081
|
-
projectId:
|
|
1082
|
-
title:
|
|
1083
|
-
description:
|
|
1084
|
-
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"])')
|
|
1085
1134
|
},
|
|
1086
1135
|
async (params) => {
|
|
1087
1136
|
const result = await conn2.createSuggestion(params);
|
|
@@ -1092,7 +1141,7 @@ function registerSuggestionTools(server2, conn2) {
|
|
|
1092
1141
|
}
|
|
1093
1142
|
|
|
1094
1143
|
// src/tools/checklists.ts
|
|
1095
|
-
import { z as
|
|
1144
|
+
import { z as z11 } from "zod";
|
|
1096
1145
|
function renderManualTestGroups(groups) {
|
|
1097
1146
|
const lines = [];
|
|
1098
1147
|
for (const g of groups) {
|
|
@@ -1115,8 +1164,8 @@ function registerListManualTests(server2, conn2) {
|
|
|
1115
1164
|
"list_manual_tests",
|
|
1116
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.",
|
|
1117
1166
|
{
|
|
1118
|
-
projectId:
|
|
1119
|
-
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>)")
|
|
1120
1169
|
},
|
|
1121
1170
|
async (params) => {
|
|
1122
1171
|
const items = await conn2.listManualTests(params.taskId, params.projectId);
|
|
@@ -1142,9 +1191,9 @@ function registerSetManualTests(server2, conn2) {
|
|
|
1142
1191
|
"set_manual_tests",
|
|
1143
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.",
|
|
1144
1193
|
{
|
|
1145
|
-
projectId:
|
|
1146
|
-
taskId:
|
|
1147
|
-
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")
|
|
1148
1197
|
},
|
|
1149
1198
|
async (params) => {
|
|
1150
1199
|
const result = await conn2.setManualTests(params.taskId, params.items, params.projectId);
|
|
@@ -1159,10 +1208,10 @@ function registerEditManualTest(server2, conn2) {
|
|
|
1159
1208
|
"edit_manual_test",
|
|
1160
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.",
|
|
1161
1210
|
{
|
|
1162
|
-
projectId:
|
|
1163
|
-
taskId:
|
|
1164
|
-
title:
|
|
1165
|
-
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")
|
|
1166
1215
|
},
|
|
1167
1216
|
async (params) => {
|
|
1168
1217
|
await conn2.editManualTest(params.taskId, params.title, params.newTitle, params.projectId);
|
|
@@ -1175,9 +1224,9 @@ function registerRemoveManualTest(server2, conn2) {
|
|
|
1175
1224
|
"remove_manual_test",
|
|
1176
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).",
|
|
1177
1226
|
{
|
|
1178
|
-
projectId:
|
|
1179
|
-
taskId:
|
|
1180
|
-
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")
|
|
1181
1230
|
},
|
|
1182
1231
|
async (params) => {
|
|
1183
1232
|
await conn2.removeManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1190,9 +1239,9 @@ function registerApproveManualTest(server2, conn2) {
|
|
|
1190
1239
|
"approve_manual_test",
|
|
1191
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.",
|
|
1192
1241
|
{
|
|
1193
|
-
projectId:
|
|
1194
|
-
taskId:
|
|
1195
|
-
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")
|
|
1196
1245
|
},
|
|
1197
1246
|
async (params) => {
|
|
1198
1247
|
await conn2.approveManualTest(params.taskId, params.title, params.projectId);
|
|
@@ -1205,10 +1254,10 @@ function registerRejectManualTest(server2, conn2) {
|
|
|
1205
1254
|
"reject_manual_test",
|
|
1206
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.",
|
|
1207
1256
|
{
|
|
1208
|
-
projectId:
|
|
1209
|
-
taskId:
|
|
1210
|
-
title:
|
|
1211
|
-
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")
|
|
1212
1261
|
},
|
|
1213
1262
|
async (params) => {
|
|
1214
1263
|
await conn2.rejectManualTest(params.taskId, params.title, params.reason, params.projectId);
|
|
@@ -1228,9 +1277,9 @@ function registerQueryManualTests(server2, conn2) {
|
|
|
1228
1277
|
"query_manual_tests",
|
|
1229
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.",
|
|
1230
1279
|
{
|
|
1231
|
-
projectId:
|
|
1232
|
-
cardStatuses:
|
|
1233
|
-
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")
|
|
1234
1283
|
},
|
|
1235
1284
|
async (params) => {
|
|
1236
1285
|
const groups = await conn2.queryManualTests({
|
|
@@ -1256,7 +1305,7 @@ function registerChecklistTools(server2, conn2) {
|
|
|
1256
1305
|
}
|
|
1257
1306
|
|
|
1258
1307
|
// src/tools/workspace.ts
|
|
1259
|
-
import { z as
|
|
1308
|
+
import { z as z12 } from "zod";
|
|
1260
1309
|
|
|
1261
1310
|
// src/workspace-ssh-tunnel.ts
|
|
1262
1311
|
import net from "net";
|
|
@@ -1375,8 +1424,8 @@ function registerAttachInfoTool(server2, conn2) {
|
|
|
1375
1424
|
"workspace_attach_info",
|
|
1376
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.",
|
|
1377
1426
|
{
|
|
1378
|
-
taskId:
|
|
1379
|
-
sshPublicKey:
|
|
1427
|
+
taskId: z12.string().describe("The task ID"),
|
|
1428
|
+
sshPublicKey: z12.string().optional().describe("Optional OpenSSH public key to install into the workspace")
|
|
1380
1429
|
},
|
|
1381
1430
|
async ({ taskId, sshPublicKey }) => {
|
|
1382
1431
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1389,7 +1438,7 @@ function registerPreviewUrlsTool(server2, conn2) {
|
|
|
1389
1438
|
"workspace_preview_urls",
|
|
1390
1439
|
"Return the hosted preview URLs and preview ports for a running task Claudespace. This mirrors the web UI preview link metadata.",
|
|
1391
1440
|
{
|
|
1392
|
-
taskId:
|
|
1441
|
+
taskId: z12.string().describe("The task ID")
|
|
1393
1442
|
},
|
|
1394
1443
|
async ({ taskId }) => {
|
|
1395
1444
|
const info = await conn2.getWorkspaceAttachInfo(taskId);
|
|
@@ -1418,10 +1467,10 @@ function registerStartTunnelTool(server2, conn2, startTunnel) {
|
|
|
1418
1467
|
"workspace_start_tunnel",
|
|
1419
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.",
|
|
1420
1469
|
{
|
|
1421
|
-
taskId:
|
|
1422
|
-
port:
|
|
1423
|
-
preferredLocalPort:
|
|
1424
|
-
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")
|
|
1425
1474
|
},
|
|
1426
1475
|
async ({ taskId, port, preferredLocalPort, sshPublicKey }) => {
|
|
1427
1476
|
const info = await conn2.getWorkspaceAttachInfo(taskId, sshPublicKey);
|
|
@@ -1474,7 +1523,7 @@ function registerStopTunnelTool(server2) {
|
|
|
1474
1523
|
"workspace_stop_tunnel",
|
|
1475
1524
|
"Stop a local workspace tunnel previously opened by workspace_start_tunnel.",
|
|
1476
1525
|
{
|
|
1477
|
-
tunnelId:
|
|
1526
|
+
tunnelId: z12.string().describe("Tunnel id returned by workspace_start_tunnel")
|
|
1478
1527
|
},
|
|
1479
1528
|
async ({ tunnelId }) => {
|
|
1480
1529
|
const tunnel = activeTunnels.get(tunnelId);
|
|
@@ -1493,7 +1542,7 @@ function registerWorkspaceTools(server2, conn2, deps = {}) {
|
|
|
1493
1542
|
}
|
|
1494
1543
|
|
|
1495
1544
|
// src/tools/logs.ts
|
|
1496
|
-
import { z as
|
|
1545
|
+
import { z as z13 } from "zod";
|
|
1497
1546
|
var SEVERITY_ENUM = [
|
|
1498
1547
|
"DEBUG",
|
|
1499
1548
|
"INFO",
|
|
@@ -1592,41 +1641,98 @@ async function runQueryGcpLogs(conn2, params, now = Date.now) {
|
|
|
1592
1641
|
}
|
|
1593
1642
|
return [header, ...lines, ...footer].join("\n");
|
|
1594
1643
|
}
|
|
1644
|
+
async function runQueryGrafanaLogs(conn2, params, now = Date.now) {
|
|
1645
|
+
const startTime = params.startTime ?? new Date(now() - (params.sinceMinutes ?? DEFAULT_SINCE_MINUTES) * 6e4).toISOString();
|
|
1646
|
+
const result = await conn2.queryGrafanaLogs({
|
|
1647
|
+
projectId: params.projectId,
|
|
1648
|
+
env: params.env,
|
|
1649
|
+
level: params.level,
|
|
1650
|
+
services: params.services,
|
|
1651
|
+
search: params.search,
|
|
1652
|
+
logql: params.logql,
|
|
1653
|
+
startTime,
|
|
1654
|
+
endTime: params.endTime,
|
|
1655
|
+
limit: params.limit
|
|
1656
|
+
});
|
|
1657
|
+
if (result.error) return result.error;
|
|
1658
|
+
const header = [
|
|
1659
|
+
`env=${params.env ?? "prod"}`,
|
|
1660
|
+
`window=${startTime}\u2192${params.endTime ?? "now"}`,
|
|
1661
|
+
...params.level ? [`minLevel=${params.level}`] : [],
|
|
1662
|
+
...result.logql ? [`logql=${truncateLine(result.logql)}`] : [],
|
|
1663
|
+
`entries=${result.entries.length}`
|
|
1664
|
+
].join(" ");
|
|
1665
|
+
const lines = result.entries.map(formatLogEntryLine);
|
|
1666
|
+
const footer = result.hasMore ? ["-- hit the limit: narrow the window (startTime/endTime) for older lines"] : [];
|
|
1667
|
+
if (lines.length === 0) {
|
|
1668
|
+
return [
|
|
1669
|
+
header,
|
|
1670
|
+
"(no matching log entries \u2014 widen the window, lower minLevel, or drop filters)"
|
|
1671
|
+
].join("\n");
|
|
1672
|
+
}
|
|
1673
|
+
return [header, ...lines, ...footer].join("\n");
|
|
1674
|
+
}
|
|
1675
|
+
function registerGrafanaLogTool(server2, conn2) {
|
|
1676
|
+
server2.tool(
|
|
1677
|
+
"query_grafana_logs",
|
|
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>'.",
|
|
1679
|
+
{
|
|
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(
|
|
1683
|
+
"Relative time window ending now, in minutes (default 60). Ignored if startTime is set."
|
|
1684
|
+
),
|
|
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)")
|
|
1692
|
+
},
|
|
1693
|
+
async (params) => {
|
|
1694
|
+
const text = await runQueryGrafanaLogs(conn2, params);
|
|
1695
|
+
return { content: [{ type: "text", text }] };
|
|
1696
|
+
}
|
|
1697
|
+
);
|
|
1698
|
+
}
|
|
1595
1699
|
function registerLogTools(server2, conn2) {
|
|
1596
1700
|
server2.tool(
|
|
1597
1701
|
"query_gcp_logs",
|
|
1598
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.",
|
|
1599
1703
|
{
|
|
1600
|
-
projectId:
|
|
1601
|
-
env:
|
|
1602
|
-
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(
|
|
1603
1707
|
"Relative time window ending now, in minutes (default 60). Ignored if startTime is set."
|
|
1604
1708
|
),
|
|
1605
|
-
startTime:
|
|
1606
|
-
endTime:
|
|
1607
|
-
severity:
|
|
1608
|
-
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(
|
|
1609
1713
|
"Restrict to these Cloud Run service names (prod/dev only). Defaults to all services linked in project settings."
|
|
1610
1714
|
),
|
|
1611
|
-
sqlInstances:
|
|
1612
|
-
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(
|
|
1613
1717
|
"Set true to search ALL logs in the GCP project, ignoring the linked-resource scope"
|
|
1614
1718
|
),
|
|
1615
|
-
search:
|
|
1616
|
-
filter:
|
|
1617
|
-
limit:
|
|
1618
|
-
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")
|
|
1619
1723
|
},
|
|
1620
1724
|
async (params) => {
|
|
1621
1725
|
const text = await runQueryGcpLogs(conn2, params);
|
|
1622
1726
|
return { content: [{ type: "text", text }] };
|
|
1623
1727
|
}
|
|
1624
1728
|
);
|
|
1729
|
+
registerGrafanaLogTool(server2, conn2);
|
|
1625
1730
|
}
|
|
1626
1731
|
|
|
1627
1732
|
// src/tools/index.ts
|
|
1628
1733
|
function registerAllTools(server2, conn2) {
|
|
1629
1734
|
registerProjectTools(server2, conn2);
|
|
1735
|
+
registerConnectionTools(server2, conn2);
|
|
1630
1736
|
registerProjectConfigTools(server2, conn2);
|
|
1631
1737
|
registerTaskTools(server2, conn2);
|
|
1632
1738
|
registerBuildTools(server2, conn2);
|
|
@@ -1645,13 +1751,14 @@ var { version } = createRequire(import.meta.url)("../package.json");
|
|
|
1645
1751
|
var apiUrl = process.env.CONVEYOR_API_URL;
|
|
1646
1752
|
var projectToken = process.env.CONVEYOR_USER_TOKEN ?? process.env.CONVEYOR_PROJECT_TOKEN;
|
|
1647
1753
|
var projectId = process.env.CONVEYOR_PROJECT_ID;
|
|
1754
|
+
var subProjectId = process.env.CONVEYOR_SUBPROJECT_ID;
|
|
1648
1755
|
if (!apiUrl || !projectToken) {
|
|
1649
1756
|
process.stderr.write(
|
|
1650
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"
|
|
1651
1758
|
);
|
|
1652
1759
|
process.exit(1);
|
|
1653
1760
|
}
|
|
1654
|
-
var conn = new ConveyorConnection({ apiUrl, projectToken, projectId });
|
|
1761
|
+
var conn = new ConveyorConnection({ apiUrl, projectToken, projectId, subProjectId });
|
|
1655
1762
|
try {
|
|
1656
1763
|
await conn.connect();
|
|
1657
1764
|
process.stderr.write("Connected to Conveyor API\n");
|