@rallycry/conveyor-mcp 2.1.1 → 2.1.2
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.
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
// src/connection.ts
|
|
2
2
|
import { io } from "socket.io-client";
|
|
3
|
+
var AUTH_ERROR_RE = /token|unauthor|forbidden|not authenticated|invalid auth/i;
|
|
4
|
+
function enrichToolError(error, fallback) {
|
|
5
|
+
const base = error ?? fallback ?? "Request failed";
|
|
6
|
+
if (/insufficient permissions/i.test(base)) {
|
|
7
|
+
return `${base}: your Conveyor project role can't perform this action. Creating/updating tasks, builds, and PRs requires Moderate access or higher \u2014 ask a project admin to raise your role.`;
|
|
8
|
+
}
|
|
9
|
+
return base;
|
|
10
|
+
}
|
|
3
11
|
var ConveyorConnection = class {
|
|
4
12
|
socket = null;
|
|
5
13
|
config;
|
|
@@ -35,10 +43,21 @@ var ConveyorConnection = class {
|
|
|
35
43
|
}
|
|
36
44
|
});
|
|
37
45
|
this.socket.on("connect_error", (err) => {
|
|
46
|
+
const message = err?.message ?? "unknown error";
|
|
47
|
+
if (!settled && AUTH_ERROR_RE.test(message)) {
|
|
48
|
+
settled = true;
|
|
49
|
+
this.socket?.close();
|
|
50
|
+
reject(
|
|
51
|
+
new Error(
|
|
52
|
+
`Conveyor rejected the connection: ${message}. The project token is likely invalid or expired \u2014 regenerate it in the web app (User Settings \u2192 Connect Claude Code) and update CONVEYOR_PROJECT_TOKEN.`
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
38
57
|
attempts++;
|
|
39
58
|
if (!settled && attempts >= maxAttempts) {
|
|
40
59
|
settled = true;
|
|
41
|
-
reject(new Error(`Failed to connect: ${
|
|
60
|
+
reject(new Error(`Failed to connect to ${this.config.apiUrl}: ${message}`));
|
|
42
61
|
}
|
|
43
62
|
});
|
|
44
63
|
});
|
|
@@ -54,7 +73,7 @@ var ConveyorConnection = class {
|
|
|
54
73
|
if (response.success) {
|
|
55
74
|
resolve(response.data);
|
|
56
75
|
} else {
|
|
57
|
-
reject(new Error(response.error
|
|
76
|
+
reject(new Error(enrichToolError(response.error, `${method} failed`)));
|
|
58
77
|
}
|
|
59
78
|
}));
|
|
60
79
|
}),
|
|
@@ -312,4 +331,4 @@ var ConveyorConnection = class {
|
|
|
312
331
|
export {
|
|
313
332
|
ConveyorConnection
|
|
314
333
|
};
|
|
315
|
-
//# sourceMappingURL=chunk-
|
|
334
|
+
//# sourceMappingURL=chunk-X6SSUXWZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connection.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\n\nexport interface ConveyorMcpConfig {\n apiUrl: string;\n projectToken: string;\n projectId: string;\n}\n\n/** A single PTY output frame broadcast on the `pty:data` room event. */\nexport interface PtyDataChunk {\n sessionId: string;\n seq: number;\n data: string;\n cols?: number;\n rows?: number;\n}\n\n/** Ring-buffer snapshot returned by `ptyAttach` for catch-up replay. */\nexport interface PtyAttachSnapshot {\n sessionId: string;\n chunks: { seq: number; data: string }[];\n cols: number;\n rows: number;\n totalBytes: number;\n}\n\n/**\n * Result of `getActivePtySession`. `sessionId` is null until the cloud agent\n * has booted a PTY and produced at least one ring frame (readiness signal).\n */\nexport interface ActivePtySession {\n sessionId: string | null;\n cols?: number;\n rows?: number;\n}\n\ntype SocketCallback = (response: { success: boolean; data?: unknown; error?: string }) => void;\n\n/** Auth failures never recover on retry — match them to fail fast with guidance. */\nconst AUTH_ERROR_RE = /token|unauthor|forbidden|not authenticated|invalid auth/i;\n\n/**\n * Turn a raw server error into an actionable message. Most errors pass through\n * unchanged; the common-but-opaque \"Insufficient permissions\" gets the missing\n * context about why (project role too low) and how to fix it.\n */\nfunction enrichToolError(error?: string, fallback?: string): string {\n const base = error ?? fallback ?? \"Request failed\";\n if (/insufficient permissions/i.test(base)) {\n return (\n `${base}: your Conveyor project role can't perform this action. ` +\n `Creating/updating tasks, builds, and PRs requires Moderate access or higher — ` +\n `ask a project admin to raise your role.`\n );\n }\n return base;\n}\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: ConveyorMcpConfig;\n\n constructor(config: ConveyorMcpConfig) {\n this.config = config;\n }\n\n get projectId(): string {\n return this.config.projectId;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxAttempts = 15;\n\n this.socket = io(this.config.apiUrl, {\n auth: {\n projectToken: this.config.projectToken,\n runnerMode: \"project\",\n },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: { \"ngrok-skip-browser-warning\": \"true\" },\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n // Subscribe to project room for events\n this.socket?.emit(\"projectService:subscribe\", { id: this.config.projectId });\n resolve();\n }\n });\n\n this.socket.on(\"connect_error\", (err) => {\n const message = err?.message ?? \"unknown error\";\n // An auth rejection (e.g. \"Invalid project token\") will never succeed on\n // retry, so fail fast with an actionable message instead of silently\n // retrying for ~30s and then dying with a generic error.\n if (!settled && AUTH_ERROR_RE.test(message)) {\n settled = true;\n this.socket?.close();\n reject(\n new Error(\n `Conveyor rejected the connection: ${message}. The project token is ` +\n `likely invalid or expired — regenerate it in the web app ` +\n `(User Settings → Connect Claude Code) and update CONVEYOR_PROJECT_TOKEN.`,\n ),\n );\n return;\n }\n attempts++;\n if (!settled && attempts >= maxAttempts) {\n settled = true;\n reject(new Error(`Failed to connect to ${this.config.apiUrl}: ${message}`));\n }\n });\n });\n }\n\n // ── Service method call (agentSessionService:*) ─────────────────────\n\n private call<T>(method: string, data: unknown): Promise<T> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n const TIMEOUT_MS = 15_000;\n\n return Promise.race([\n new Promise<T>((resolve, reject) => {\n socket.emit(`agentSessionService:${method}`, data, ((response: {\n success: boolean;\n data?: T;\n error?: string;\n }) => {\n if (response.success) {\n resolve(response.data as T);\n } else {\n reject(new Error(enrichToolError(response.error, `${method} failed`)));\n }\n }) as SocketCallback);\n }),\n new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Request timed out: ${method}`));\n }, TIMEOUT_MS);\n }),\n ]);\n }\n\n /**\n * Fire-and-forget emit (no ack). The quickdraw-core server method handler\n * invokes the ack callback via optional chaining, so omitting it still runs\n * the full auth/schema/ACL pipeline — it just skips the response round-trip.\n * Used for high-frequency PTY input/resize so each keystroke does not arm a\n * 15s timeout timer.\n */\n private emit(method: string, data: unknown): void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.emit(`agentSessionService:${method}`, data);\n }\n\n // ── Task Queries ────────────────────────────────────────────────────\n\n listTasks(params: { status?: string; assigneeId?: string; limit?: number }): Promise<unknown[]> {\n return this.call(\"listProjectTasks\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n getTask(taskId: string): Promise<unknown> {\n return this.call(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n searchTasks(params: {\n tagNames?: string[];\n searchQuery?: string;\n statusFilters?: string[];\n limit?: number;\n }): Promise<unknown[]> {\n return this.call(\"searchProjectTasks\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Task Mutations ──────────────────────────────────────────────────\n\n createTask(params: {\n title: string;\n description?: string;\n plan?: string;\n status?: string;\n }): Promise<{ id: string; slug: string }> {\n return this.call(\"createProjectTask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n updateTask(params: {\n taskId: string;\n title?: string;\n description?: string;\n plan?: string;\n status?: string;\n assignedUserId?: string | null;\n }): Promise<{ id: string; status: string }> {\n return this.call(\"updateProjectTask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Build Management ────────────────────────────────────────────────\n\n startBuild(taskId: string): Promise<{ taskId: string; status: string }> {\n return this.call(\"startProjectBuild\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n stopBuild(taskId: string): Promise<{ taskId: string; stopped: boolean }> {\n return this.call(\"stopProjectBuild\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n getBuildStatus(taskId: string): Promise<{\n session: { status: string | null; agentRunnerStatus: string | null } | null;\n }> {\n // Uses getProjectTask and extracts the session field\n return this.call<Record<string, unknown>>(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n }).then((task) => ({\n session:\n (task?.session as {\n status: string | null;\n agentRunnerStatus: string | null;\n }) ?? null,\n }));\n }\n\n // ── Chat ────────────────────────────────────────────────────────────\n\n getTaskChat(taskId: string, limit?: number): Promise<unknown[]> {\n // Uses getProjectTask and extracts chatMessages\n return this.call<Record<string, unknown>>(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n }).then((task) => {\n const messages = (task?.chatMessages ?? []) as unknown[];\n return limit ? messages.slice(-limit) : messages;\n });\n }\n\n postToTaskChat(taskId: string, content: string): Promise<{ messageId: string }> {\n return this.call(\"postToProjectTaskChat\", {\n projectId: this.config.projectId,\n taskId,\n content,\n });\n }\n\n // ── CLI History ─────────────────────────────────────────────────────\n\n getTaskCli(\n taskId: string,\n limit?: number,\n source?: string,\n ): Promise<{ type: string; data: Record<string, unknown>; timestamp: string }[]> {\n return this.call(\"getProjectTaskCli\", {\n projectId: this.config.projectId,\n taskId,\n limit,\n source,\n });\n }\n\n // ── Project Info ────────────────────────────────────────────────────\n\n listTags(): Promise<{ id: string; name: string; color: string }[]> {\n return this.call(\"listProjectTags\", {\n projectId: this.config.projectId,\n });\n }\n\n getProjectSummary(): Promise<unknown> {\n return this.call(\"getProjectSummary\", {\n projectId: this.config.projectId,\n });\n }\n\n // ── Review Flow ─────────────────────────────────────────────────────\n\n async approveTask(taskId: string): Promise<{ status: string }> {\n // Determine next status based on current status\n const task = (await this.call(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n })) as { status: string } | null;\n\n if (!task) throw new Error(\"Task not found\");\n\n const nextStatus = task.status === \"ReviewPR\" ? \"ReviewDev\" : \"Complete\";\n\n const result = await this.updateTask({ taskId, status: nextStatus });\n return { status: result.status };\n }\n\n async requestChanges(taskId: string, feedback: string): Promise<void> {\n // Post feedback to task chat then move to InProgress\n await this.postToTaskChat(taskId, feedback);\n await this.updateTask({ taskId, status: \"InProgress\" });\n }\n\n approveAndMergePR(\n childTaskId: string,\n ): Promise<{ merged: boolean; childTaskId: string; prNumber: number }> {\n return this.call(\"approveProjectMergePR\", {\n projectId: this.config.projectId,\n childTaskId,\n });\n }\n\n // ── File Attachments ────────────────────────────────────────────────\n\n listTaskFiles(taskId: string): Promise<unknown[]> {\n return this.call(\"listProjectTaskFiles\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n getAttachment(taskId: string, fileId: string): Promise<unknown> {\n return this.call(\"getProjectAttachment\", {\n projectId: this.config.projectId,\n taskId,\n fileId,\n });\n }\n\n // ── Pull Requests ───────────────────────────────────────────────────\n\n createPullRequest(params: {\n taskId: string;\n title: string;\n body: string;\n head?: string;\n base?: string;\n }): Promise<{ prNumber: number; prUrl: string }> {\n return this.call(\"createProjectPullRequest\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Subtasks ────────────────────────────────────────────────────────\n\n createSubtask(params: {\n parentTaskId: string;\n title: string;\n description?: string;\n plan?: string;\n ordinal?: number;\n storyPointValue?: number;\n }): Promise<{ id: string; slug: string }> {\n return this.call(\"createProjectSubtask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n updateSubtask(params: {\n subtaskId: string;\n title?: string;\n description?: string;\n plan?: string;\n status?: string;\n ordinal?: number;\n storyPointValue?: number;\n }): Promise<{ id: string; status: string }> {\n return this.call(\"updateProjectSubtask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n listSubtasks(taskId: string): Promise<unknown[]> {\n return this.call(\"listProjectSubtasks\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n deleteSubtask(subtaskId: string): Promise<{ deleted: boolean }> {\n return this.call(\"deleteProjectSubtask\", {\n projectId: this.config.projectId,\n subtaskId,\n });\n }\n\n // ── Dependencies ────────────────────────────────────────────────────\n\n getDependencies(taskId: string): Promise<unknown[]> {\n return this.call(\"getProjectTaskDependencies\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n addDependency(params: {\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n return this.call(\"addProjectTaskDependency\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n removeDependency(params: {\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n return this.call(\"removeProjectTaskDependency\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Suggestions ─────────────────────────────────────────────────────\n\n createSuggestion(params: {\n title: string;\n description?: string;\n tagNames?: string[];\n }): Promise<{ id: string; merged: boolean; mergedIntoId?: string }> {\n return this.call(\"createProjectSuggestion\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── PTY Tunnel Relay (reuses the S2 pty:* envelope) ─────────────────\n\n /**\n * Poll target: returns the active cloud PTY session for a task once its ring\n * buffer has frames. `sessionId` is resolved server-side from `taskId` (never\n * accepted from the wire), preserving the one-active-session-per-task invariant.\n */\n getActivePtySession(taskId: string): Promise<ActivePtySession> {\n return this.call(\"getActivePtySession\", { taskId });\n }\n\n /** Fetch the ring-buffer snapshot for catch-up replay on (re)attach. */\n ptyAttach(sessionId: string): Promise<PtyAttachSnapshot> {\n return this.call(\"ptyAttach\", { sessionId });\n }\n\n /**\n * Join the session room so `pty:data` frames are delivered. Uses the standard\n * quickdraw-core subscribe envelope; \"Read\" is sufficient for output streaming.\n */\n subscribeToSession(sessionId: string): void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.emit(\"agentSessionService:subscribe\", {\n entryId: sessionId,\n requiredLevel: \"Read\",\n });\n }\n\n /** Relay a stdin chunk to the cloud PTY (raw utf8, fire-and-forget). */\n ptyInput(sessionId: string, data: string): void {\n this.emit(\"ptyInput\", { sessionId, data });\n }\n\n /** Relay a terminal resize to the cloud PTY (fire-and-forget). */\n ptyResize(sessionId: string, cols: number, rows: number): void {\n this.emit(\"ptyResize\", { sessionId, cols, rows });\n }\n\n /** Subscribe to raw PTY output frames. Returns an unsubscribe function. */\n onPtyData(handler: (chunk: PtyDataChunk) => void): () => void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.on(\"pty:data\", handler as (...args: unknown[]) => void);\n return () => {\n socket.off(\"pty:data\", handler as (...args: unknown[]) => void);\n };\n }\n\n // ── Connection lifecycle ────────────────────────────────────────────\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n"],"mappings":"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","names":[]}
|
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-X6SSUXWZ.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -534,7 +534,7 @@ try {
|
|
|
534
534
|
}
|
|
535
535
|
var server = new McpServer({
|
|
536
536
|
name: "conveyor",
|
|
537
|
-
version: "2.1.
|
|
537
|
+
version: "2.1.2"
|
|
538
538
|
});
|
|
539
539
|
registerAllTools(server, conn);
|
|
540
540
|
var transport = new StdioServerTransport();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/tools/project.ts","../src/tools/tasks.ts","../src/tools/builds.ts","../src/tools/attachments.ts","../src/tools/pull-request.ts","../src/tools/subtasks.ts","../src/tools/dependencies.ts","../src/tools/suggestions.ts","../src/tools/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { ConveyorConnection } from \"./connection.js\";\nimport { registerAllTools } from \"./tools/index.js\";\n\nconst apiUrl = process.env.CONVEYOR_API_URL;\nconst projectToken = process.env.CONVEYOR_PROJECT_TOKEN;\nconst projectId = process.env.CONVEYOR_PROJECT_ID;\n\nif (!apiUrl || !projectToken || !projectId) {\n process.stderr.write(\n \"Error: CONVEYOR_API_URL, CONVEYOR_PROJECT_TOKEN, and CONVEYOR_PROJECT_ID environment variables are required.\\n\",\n );\n process.exit(1);\n}\n\nconst conn = new ConveyorConnection({ apiUrl, projectToken, projectId });\n\ntry {\n await conn.connect();\n process.stderr.write(\"Connected to Conveyor API\\n\");\n} catch (err) {\n process.stderr.write(`Failed to connect to Conveyor API: ${err}\\n`);\n process.exit(1);\n}\n\nconst server = new McpServer({\n name: \"conveyor\",\n version: \"2.1.0\",\n});\n\nregisterAllTools(server, conn);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n\nprocess.on(\"SIGINT\", () => {\n conn.disconnect();\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n conn.disconnect();\n process.exit(0);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerProjectTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_project_summary\",\n \"Get overall project status: task counts by status, active builds, repo info\",\n {},\n async () => {\n const summary = await conn.getProjectSummary();\n return { content: [{ type: \"text\", text: JSON.stringify(summary, null, 2) }] };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nconst CLI_EVENT_FORMATTERS: Record<string, (data: Record<string, unknown>) => string> = {\n thinking: (data) => String(data.message ?? \"\"),\n tool_use: (data) => `${data.tool}: ${String(data.input ?? \"\").slice(0, 1000)}`,\n tool_result: (data) =>\n `${data.tool} → ${String(data.output ?? \"\").slice(0, 500)}${data.isError ? \" [ERROR]\" : \"\"}`,\n message: (data) => String(data.content ?? \"\"),\n error: (data) => `ERROR: ${String(data.message ?? \"\")}`,\n completed: (data) =>\n `Completed: ${data.summary ?? \"\"} (cost: $${data.costUsd ?? \"?\"}, duration: ${data.durationMs ?? \"?\"}ms)`,\n setup_output: (data) => `[${data.stream ?? \"stdout\"}] ${String(data.data ?? \"\")}`,\n start_command_output: (data) => `[${data.stream ?? \"stdout\"}] ${String(data.data ?? \"\")}`,\n turn_end: (data) =>\n `Turn complete (${Array.isArray(data.toolCalls) ? data.toolCalls.length : 0} tool calls)`,\n};\n\nfunction formatCliEventSummary(type: string, data: Record<string, unknown>): string {\n const formatter = CLI_EVENT_FORMATTERS[type];\n return formatter ? formatter(data) : JSON.stringify(data);\n}\n\nconst STATUS_ENUM = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\",\n] as const;\n\nfunction registerListTasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_tasks\",\n \"List project tasks, optionally filtered by status or assignee\",\n {\n status: z.enum(STATUS_ENUM).optional().describe(\"Filter by task status\"),\n assigneeId: z.string().optional().describe(\"Filter by assigned user ID\"),\n limit: z.number().optional().describe(\"Max tasks to return (default 50)\"),\n },\n async (params) => {\n const tasks = await conn.listTasks(params);\n return { content: [{ type: \"text\", text: JSON.stringify(tasks, null, 2) }] };\n },\n );\n}\n\nfunction registerGetTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task\",\n \"Get full task details including plan, chat history, PR info, subtasks, and build status\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const task = await conn.getTask(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(task, null, 2) }] };\n },\n );\n}\n\nfunction registerCreateTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_task\",\n \"Create a new task with title, description, and optional plan\",\n {\n title: z.string().describe(\"Task title\"),\n description: z.string().optional().describe(\"Task description\"),\n plan: z.string().optional().describe(\"Task implementation plan (markdown)\"),\n status: z\n .enum([\"Planning\", \"Open\"])\n .optional()\n .describe(\"Initial status (default: Planning)\"),\n },\n async (params) => {\n const task = await conn.createTask(params);\n return {\n content: [{ type: \"text\", text: `Task created: ${task.id} (slug: ${task.slug})` }],\n };\n },\n );\n}\n\nfunction registerUpdateTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"update_task\",\n \"Update task fields: title, description, plan, status, or assignment\",\n {\n taskId: z.string().describe(\"The task ID\"),\n title: z.string().optional().describe(\"New title\"),\n description: z.string().optional().describe(\"New description\"),\n plan: z.string().optional().describe(\"New plan (markdown)\"),\n status: z.enum(STATUS_ENUM).optional().describe(\"New status\"),\n assignedUserId: z.string().nullable().optional().describe(\"User ID to assign, or null\"),\n },\n async (params) => {\n const result = await conn.updateTask(params);\n return {\n content: [{ type: \"text\", text: `Task ${result.id} updated (status: ${result.status})` }],\n };\n },\n );\n}\n\nfunction registerChatTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task_chat\",\n \"Read messages from a task's chat\",\n {\n taskId: z.string().describe(\"The task ID\"),\n limit: z.number().optional().describe(\"Max messages to return (default 50)\"),\n },\n async (params) => {\n const messages = await conn.getTaskChat(params.taskId, params.limit);\n return { content: [{ type: \"text\", text: JSON.stringify(messages, null, 2) }] };\n },\n );\n\n server.tool(\n \"post_to_task_chat\",\n \"Post a message to a task's chat\",\n {\n taskId: z.string().describe(\"The task ID\"),\n content: z.string().describe(\"Message content\"),\n },\n async (params) => {\n await conn.postToTaskChat(params.taskId, params.content);\n return { content: [{ type: \"text\", text: \"Message posted\" }] };\n },\n );\n}\n\nfunction registerGetTaskCli(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task_cli\",\n \"Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n source: z\n .enum([\"agent\", \"application\"])\n .optional()\n .describe(\n \"Filter by log source: 'agent' for reasoning/tool calls, 'application' for setup/dev-server output\",\n ),\n limit: z.number().optional().describe(\"Max entries to return (default 50, max 500)\"),\n },\n async ({ taskId, source, limit }) => {\n const effectiveLimit = Math.min(limit ?? 50, 500);\n const logs = await conn.getTaskCli(taskId, effectiveLimit, source);\n const formatted = logs\n .map((log) => {\n return `[${log.timestamp}] [${log.type}] ${formatCliEventSummary(log.type, log.data)}`;\n })\n .join(\"\\n\");\n return {\n content: [{ type: \"text\" as const, text: formatted || \"No CLI logs found for this task.\" }],\n };\n },\n );\n}\n\nfunction registerSearchTasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"search_tasks\",\n \"Search tasks by tag name, text query, and/or status. Use tag names like 'agent-runner', not IDs.\",\n {\n tagNames: z\n .array(z.string())\n .optional()\n .describe('Tag names to filter by (e.g., [\"agent-runner\", \"chat\"])'),\n searchQuery: z.string().optional().describe(\"Text search on title and description\"),\n statusFilters: z\n .array(z.enum(STATUS_ENUM))\n .optional()\n .describe(\"Filter by one or more statuses\"),\n limit: z.number().optional().describe(\"Max results to return (default 20)\"),\n },\n async (params) => {\n const tasks = await conn.searchTasks(params);\n return { content: [{ type: \"text\", text: JSON.stringify(tasks, null, 2) }] };\n },\n );\n}\n\nfunction registerListTags(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_tags\",\n \"List all project tags with their names, IDs, and colors\",\n {},\n async () => {\n const tags = await conn.listTags();\n return { content: [{ type: \"text\", text: JSON.stringify(tags, null, 2) }] };\n },\n );\n}\n\nfunction registerReviewTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"approve_task\",\n \"Move a task forward in the review flow (ReviewPR -> ReviewDev, or -> Complete)\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.approveTask(params.taskId);\n return {\n content: [{ type: \"text\", text: `Task approved, new status: ${result.status}` }],\n };\n },\n );\n\n server.tool(\n \"approve_and_merge_pr\",\n \"Approve and merge a child task's pull request. Only succeeds if all CI/CD checks are passing. The child task must be in ReviewPR status with a PR.\",\n {\n childTaskId: z.string().describe(\"The child task ID whose PR should be approved and merged\"),\n },\n async (params) => {\n const result = await conn.approveAndMergePR(params.childTaskId);\n return {\n content: [\n {\n type: \"text\",\n text: `PR #${result.prNumber} approved and merged for task ${result.childTaskId}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"request_changes\",\n \"Post feedback and send task back to InProgress for more work\",\n {\n taskId: z.string().describe(\"The task ID\"),\n feedback: z.string().describe(\"Feedback message describing requested changes\"),\n },\n async (params) => {\n await conn.requestChanges(params.taskId, params.feedback);\n return { content: [{ type: \"text\", text: \"Changes requested, task moved to InProgress\" }] };\n },\n );\n}\n\nexport function registerTaskTools(server: McpServer, conn: ConveyorConnection): void {\n registerListTasks(server, conn);\n registerGetTask(server, conn);\n registerCreateTask(server, conn);\n registerUpdateTask(server, conn);\n registerChatTools(server, conn);\n registerGetTaskCli(server, conn);\n registerSearchTasks(server, conn);\n registerListTags(server, conn);\n registerReviewTools(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerBuildTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"start_build\",\n \"Start a cloud build (codespace) for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.startBuild(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }] };\n },\n );\n\n server.tool(\n \"stop_build\",\n \"Stop a running cloud build for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.stopBuild(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }] };\n },\n );\n\n server.tool(\n \"get_build_status\",\n \"Check codespace and agent status for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const status = await conn.getBuildStatus(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(status, null, 2) }] };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nfunction registerListTaskFiles(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_task_files\",\n \"List all files attached to a task with metadata. Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const files = await conn.listTaskFiles(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(files, null, 2) }] };\n },\n );\n}\n\nfunction registerGetAttachment(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_attachment\",\n \"Fetch one task file's content plus metadata by file ID. Call list_task_files first to discover IDs and check sizes — large binaries may be truncated by the service's size limit.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n fileId: z.string().describe(\"The file ID to fetch\"),\n },\n async (params) => {\n const file = await conn.getAttachment(params.taskId, params.fileId);\n return { content: [{ type: \"text\", text: JSON.stringify(file, null, 2) }] };\n },\n );\n}\n\nexport function registerAttachmentTools(server: McpServer, conn: ConveyorConnection): void {\n registerListTaskFiles(server, conn);\n registerGetAttachment(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerPullRequestTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_pull_request\",\n \"Open a GitHub pull request for a task's existing branch (the branch must already be pushed to origin). Moves the task to ReviewPR. Returns the PR number and URL.\",\n {\n taskId: z.string().describe(\"The task ID whose branch should be opened as a PR\"),\n title: z.string().describe(\"Pull request title\"),\n body: z.string().describe(\"Pull request body (markdown)\"),\n head: z\n .string()\n .optional()\n .describe(\"Source branch for the PR (defaults to the task's branch)\"),\n base: z\n .string()\n .optional()\n .describe(\"Target branch for the PR (defaults to the repo default)\"),\n },\n async (params) => {\n const result = await conn.createPullRequest(params);\n return {\n content: [{ type: \"text\", text: `PR #${result.prNumber} opened: ${result.prUrl}` }],\n };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nconst STATUS_ENUM = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\",\n] as const;\n\nconst SP_DESCRIPTION = \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n\nfunction registerCreateSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_subtask\",\n \"Create a subtask under a parent task. Subtasks break a larger task into independently buildable pieces.\",\n {\n parentTaskId: z.string().describe(\"The parent task ID\"),\n title: z.string().describe(\"Subtask title\"),\n description: z.string().optional().describe(\"Subtask description\"),\n plan: z.string().optional().describe(\"Subtask implementation plan (markdown)\"),\n ordinal: z.number().optional().describe(\"Ordering position among siblings\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async (params) => {\n const subtask = await conn.createSubtask(params);\n return {\n content: [{ type: \"text\", text: `Subtask created: ${subtask.id} (slug: ${subtask.slug})` }],\n };\n },\n );\n}\n\nfunction registerUpdateSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"update_subtask\",\n \"Update a subtask's fields: title, description, plan, status, ordering, or story points.\",\n {\n subtaskId: z.string().describe(\"The subtask ID\"),\n title: z.string().optional().describe(\"New title\"),\n description: z.string().optional().describe(\"New description\"),\n plan: z.string().optional().describe(\"New plan (markdown)\"),\n status: z.enum(STATUS_ENUM).optional().describe(\"New status\"),\n ordinal: z.number().optional().describe(\"New ordering position among siblings\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async (params) => {\n const result = await conn.updateSubtask(params);\n return {\n content: [\n { type: \"text\", text: `Subtask ${result.id} updated (status: ${result.status})` },\n ],\n };\n },\n );\n}\n\nfunction registerListSubtasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_subtasks\",\n \"List all subtasks of a parent task with their status and ordering.\",\n {\n taskId: z.string().describe(\"The parent task ID\"),\n },\n async (params) => {\n const subtasks = await conn.listSubtasks(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(subtasks, null, 2) }] };\n },\n );\n}\n\nfunction registerDeleteSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"delete_subtask\",\n \"Delete a subtask by ID. This is permanent — use update_subtask to set status to Cancelled if you only want to close it.\",\n {\n subtaskId: z.string().describe(\"The subtask ID to delete\"),\n },\n async (params) => {\n const result = await conn.deleteSubtask(params.subtaskId);\n return {\n content: [\n { type: \"text\", text: result.deleted ? \"Subtask deleted\" : \"Subtask not deleted\" },\n ],\n };\n },\n );\n}\n\nexport function registerSubtaskTools(server: McpServer, conn: ConveyorConnection): void {\n registerCreateSubtask(server, conn);\n registerUpdateSubtask(server, conn);\n registerListSubtasks(server, conn);\n registerDeleteSubtask(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nfunction registerGetDependencies(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_dependencies\",\n \"Get a task's dependencies and their met/unmet status (met = merged to dev). Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const deps = await conn.getDependencies(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(deps, null, 2) }] };\n },\n );\n}\n\nfunction registerAddDependency(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"add_dependency\",\n \"Add a blocking dependency — this task cannot start until the named task is merged to dev.\",\n {\n taskId: z.string().describe(\"The task ID that will be blocked\"),\n dependsOnSlugOrId: z.string().describe(\"Slug or ID of the task this one depends on\"),\n },\n async (params) => {\n await conn.addDependency(params);\n return { content: [{ type: \"text\", text: \"Dependency added\" }] };\n },\n );\n}\n\nfunction registerRemoveDependency(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"remove_dependency\",\n \"Remove a previously added dependency from a task. The task is no longer blocked by the named task. Returns: confirmation string.\",\n {\n taskId: z.string().describe(\"The task ID to unblock\"),\n dependsOnSlugOrId: z.string().describe(\"Slug or ID of the dependency to remove\"),\n },\n async (params) => {\n await conn.removeDependency(params);\n return { content: [{ type: \"text\", text: \"Dependency removed\" }] };\n },\n );\n}\n\nexport function registerDependencyTools(server: McpServer, conn: ConveyorConnection): void {\n registerGetDependencies(server, conn);\n registerAddDependency(server, conn);\n registerRemoveDependency(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerSuggestionTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_suggestion\",\n \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.\",\n {\n title: z.string().describe(\"Suggestion title\"),\n description: z.string().optional().describe(\"Suggestion details (markdown)\"),\n tagNames: z\n .array(z.string())\n .optional()\n .describe('Tag names to categorize the suggestion (e.g., [\"agent-runner\"])'),\n },\n async (params) => {\n const result = await conn.createSuggestion(params);\n const text = result.merged\n ? `Suggestion merged into existing suggestion ${result.mergedIntoId} (upvote recorded)`\n : `Suggestion created: ${result.id}`;\n return { content: [{ type: \"text\", text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\nimport { registerProjectTools } from \"./project.js\";\nimport { registerTaskTools } from \"./tasks.js\";\nimport { registerBuildTools } from \"./builds.js\";\nimport { registerAttachmentTools } from \"./attachments.js\";\nimport { registerPullRequestTools } from \"./pull-request.js\";\nimport { registerSubtaskTools } from \"./subtasks.js\";\nimport { registerDependencyTools } from \"./dependencies.js\";\nimport { registerSuggestionTools } from \"./suggestions.js\";\n\nexport function registerAllTools(server: McpServer, conn: ConveyorConnection): void {\n registerProjectTools(server, conn);\n registerTaskTools(server, conn);\n registerBuildTools(server, conn);\n registerAttachmentTools(server, conn);\n registerPullRequestTools(server, conn);\n registerSubtaskTools(server, conn);\n registerDependencyTools(server, conn);\n registerSuggestionTools(server, conn);\n}\n"],"mappings":"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","names":["server","conn","server","conn","z","server","conn","z","server","conn","z","server","conn","z","STATUS_ENUM","server","conn","z","server","conn","z","server","conn","server","conn"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/tools/project.ts","../src/tools/tasks.ts","../src/tools/builds.ts","../src/tools/attachments.ts","../src/tools/pull-request.ts","../src/tools/subtasks.ts","../src/tools/dependencies.ts","../src/tools/suggestions.ts","../src/tools/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { ConveyorConnection } from \"./connection.js\";\nimport { registerAllTools } from \"./tools/index.js\";\n\nconst apiUrl = process.env.CONVEYOR_API_URL;\nconst projectToken = process.env.CONVEYOR_PROJECT_TOKEN;\nconst projectId = process.env.CONVEYOR_PROJECT_ID;\n\nif (!apiUrl || !projectToken || !projectId) {\n process.stderr.write(\n \"Error: CONVEYOR_API_URL, CONVEYOR_PROJECT_TOKEN, and CONVEYOR_PROJECT_ID environment variables are required.\\n\",\n );\n process.exit(1);\n}\n\nconst conn = new ConveyorConnection({ apiUrl, projectToken, projectId });\n\ntry {\n await conn.connect();\n process.stderr.write(\"Connected to Conveyor API\\n\");\n} catch (err) {\n process.stderr.write(`Failed to connect to Conveyor API: ${err}\\n`);\n process.exit(1);\n}\n\nconst server = new McpServer({\n name: \"conveyor\",\n version: \"2.1.2\",\n});\n\nregisterAllTools(server, conn);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n\nprocess.on(\"SIGINT\", () => {\n conn.disconnect();\n process.exit(0);\n});\n\nprocess.on(\"SIGTERM\", () => {\n conn.disconnect();\n process.exit(0);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerProjectTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_project_summary\",\n \"Get overall project status: task counts by status, active builds, repo info\",\n {},\n async () => {\n const summary = await conn.getProjectSummary();\n return { content: [{ type: \"text\", text: JSON.stringify(summary, null, 2) }] };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nconst CLI_EVENT_FORMATTERS: Record<string, (data: Record<string, unknown>) => string> = {\n thinking: (data) => String(data.message ?? \"\"),\n tool_use: (data) => `${data.tool}: ${String(data.input ?? \"\").slice(0, 1000)}`,\n tool_result: (data) =>\n `${data.tool} → ${String(data.output ?? \"\").slice(0, 500)}${data.isError ? \" [ERROR]\" : \"\"}`,\n message: (data) => String(data.content ?? \"\"),\n error: (data) => `ERROR: ${String(data.message ?? \"\")}`,\n completed: (data) =>\n `Completed: ${data.summary ?? \"\"} (cost: $${data.costUsd ?? \"?\"}, duration: ${data.durationMs ?? \"?\"}ms)`,\n setup_output: (data) => `[${data.stream ?? \"stdout\"}] ${String(data.data ?? \"\")}`,\n start_command_output: (data) => `[${data.stream ?? \"stdout\"}] ${String(data.data ?? \"\")}`,\n turn_end: (data) =>\n `Turn complete (${Array.isArray(data.toolCalls) ? data.toolCalls.length : 0} tool calls)`,\n};\n\nfunction formatCliEventSummary(type: string, data: Record<string, unknown>): string {\n const formatter = CLI_EVENT_FORMATTERS[type];\n return formatter ? formatter(data) : JSON.stringify(data);\n}\n\nconst STATUS_ENUM = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\",\n] as const;\n\nfunction registerListTasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_tasks\",\n \"List project tasks, optionally filtered by status or assignee\",\n {\n status: z.enum(STATUS_ENUM).optional().describe(\"Filter by task status\"),\n assigneeId: z.string().optional().describe(\"Filter by assigned user ID\"),\n limit: z.number().optional().describe(\"Max tasks to return (default 50)\"),\n },\n async (params) => {\n const tasks = await conn.listTasks(params);\n return { content: [{ type: \"text\", text: JSON.stringify(tasks, null, 2) }] };\n },\n );\n}\n\nfunction registerGetTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task\",\n \"Get full task details including plan, chat history, PR info, subtasks, and build status\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const task = await conn.getTask(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(task, null, 2) }] };\n },\n );\n}\n\nfunction registerCreateTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_task\",\n \"Create a new task with title, description, and optional plan\",\n {\n title: z.string().describe(\"Task title\"),\n description: z.string().optional().describe(\"Task description\"),\n plan: z.string().optional().describe(\"Task implementation plan (markdown)\"),\n status: z\n .enum([\"Planning\", \"Open\"])\n .optional()\n .describe(\"Initial status (default: Planning)\"),\n },\n async (params) => {\n const task = await conn.createTask(params);\n return {\n content: [{ type: \"text\", text: `Task created: ${task.id} (slug: ${task.slug})` }],\n };\n },\n );\n}\n\nfunction registerUpdateTask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"update_task\",\n \"Update task fields: title, description, plan, status, or assignment\",\n {\n taskId: z.string().describe(\"The task ID\"),\n title: z.string().optional().describe(\"New title\"),\n description: z.string().optional().describe(\"New description\"),\n plan: z.string().optional().describe(\"New plan (markdown)\"),\n status: z.enum(STATUS_ENUM).optional().describe(\"New status\"),\n assignedUserId: z.string().nullable().optional().describe(\"User ID to assign, or null\"),\n },\n async (params) => {\n const result = await conn.updateTask(params);\n return {\n content: [{ type: \"text\", text: `Task ${result.id} updated (status: ${result.status})` }],\n };\n },\n );\n}\n\nfunction registerChatTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task_chat\",\n \"Read messages from a task's chat\",\n {\n taskId: z.string().describe(\"The task ID\"),\n limit: z.number().optional().describe(\"Max messages to return (default 50)\"),\n },\n async (params) => {\n const messages = await conn.getTaskChat(params.taskId, params.limit);\n return { content: [{ type: \"text\", text: JSON.stringify(messages, null, 2) }] };\n },\n );\n\n server.tool(\n \"post_to_task_chat\",\n \"Post a message to a task's chat\",\n {\n taskId: z.string().describe(\"The task ID\"),\n content: z.string().describe(\"Message content\"),\n },\n async (params) => {\n await conn.postToTaskChat(params.taskId, params.content);\n return { content: [{ type: \"text\", text: \"Message posted\" }] };\n },\n );\n}\n\nfunction registerGetTaskCli(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_task_cli\",\n \"Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n source: z\n .enum([\"agent\", \"application\"])\n .optional()\n .describe(\n \"Filter by log source: 'agent' for reasoning/tool calls, 'application' for setup/dev-server output\",\n ),\n limit: z.number().optional().describe(\"Max entries to return (default 50, max 500)\"),\n },\n async ({ taskId, source, limit }) => {\n const effectiveLimit = Math.min(limit ?? 50, 500);\n const logs = await conn.getTaskCli(taskId, effectiveLimit, source);\n const formatted = logs\n .map((log) => {\n return `[${log.timestamp}] [${log.type}] ${formatCliEventSummary(log.type, log.data)}`;\n })\n .join(\"\\n\");\n return {\n content: [{ type: \"text\" as const, text: formatted || \"No CLI logs found for this task.\" }],\n };\n },\n );\n}\n\nfunction registerSearchTasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"search_tasks\",\n \"Search tasks by tag name, text query, and/or status. Use tag names like 'agent-runner', not IDs.\",\n {\n tagNames: z\n .array(z.string())\n .optional()\n .describe('Tag names to filter by (e.g., [\"agent-runner\", \"chat\"])'),\n searchQuery: z.string().optional().describe(\"Text search on title and description\"),\n statusFilters: z\n .array(z.enum(STATUS_ENUM))\n .optional()\n .describe(\"Filter by one or more statuses\"),\n limit: z.number().optional().describe(\"Max results to return (default 20)\"),\n },\n async (params) => {\n const tasks = await conn.searchTasks(params);\n return { content: [{ type: \"text\", text: JSON.stringify(tasks, null, 2) }] };\n },\n );\n}\n\nfunction registerListTags(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_tags\",\n \"List all project tags with their names, IDs, and colors\",\n {},\n async () => {\n const tags = await conn.listTags();\n return { content: [{ type: \"text\", text: JSON.stringify(tags, null, 2) }] };\n },\n );\n}\n\nfunction registerReviewTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"approve_task\",\n \"Move a task forward in the review flow (ReviewPR -> ReviewDev, or -> Complete)\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.approveTask(params.taskId);\n return {\n content: [{ type: \"text\", text: `Task approved, new status: ${result.status}` }],\n };\n },\n );\n\n server.tool(\n \"approve_and_merge_pr\",\n \"Approve and merge a child task's pull request. Only succeeds if all CI/CD checks are passing. The child task must be in ReviewPR status with a PR.\",\n {\n childTaskId: z.string().describe(\"The child task ID whose PR should be approved and merged\"),\n },\n async (params) => {\n const result = await conn.approveAndMergePR(params.childTaskId);\n return {\n content: [\n {\n type: \"text\",\n text: `PR #${result.prNumber} approved and merged for task ${result.childTaskId}`,\n },\n ],\n };\n },\n );\n\n server.tool(\n \"request_changes\",\n \"Post feedback and send task back to InProgress for more work\",\n {\n taskId: z.string().describe(\"The task ID\"),\n feedback: z.string().describe(\"Feedback message describing requested changes\"),\n },\n async (params) => {\n await conn.requestChanges(params.taskId, params.feedback);\n return { content: [{ type: \"text\", text: \"Changes requested, task moved to InProgress\" }] };\n },\n );\n}\n\nexport function registerTaskTools(server: McpServer, conn: ConveyorConnection): void {\n registerListTasks(server, conn);\n registerGetTask(server, conn);\n registerCreateTask(server, conn);\n registerUpdateTask(server, conn);\n registerChatTools(server, conn);\n registerGetTaskCli(server, conn);\n registerSearchTasks(server, conn);\n registerListTags(server, conn);\n registerReviewTools(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerBuildTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"start_build\",\n \"Start a cloud build (codespace) for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.startBuild(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }] };\n },\n );\n\n server.tool(\n \"stop_build\",\n \"Stop a running cloud build for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const result = await conn.stopBuild(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }] };\n },\n );\n\n server.tool(\n \"get_build_status\",\n \"Check codespace and agent status for a task\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const status = await conn.getBuildStatus(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(status, null, 2) }] };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nfunction registerListTaskFiles(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_task_files\",\n \"List all files attached to a task with metadata. Use before fetching a specific file to see what is available and how large each is. For file contents use get_attachment.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const files = await conn.listTaskFiles(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(files, null, 2) }] };\n },\n );\n}\n\nfunction registerGetAttachment(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_attachment\",\n \"Fetch one task file's content plus metadata by file ID. Call list_task_files first to discover IDs and check sizes — large binaries may be truncated by the service's size limit.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n fileId: z.string().describe(\"The file ID to fetch\"),\n },\n async (params) => {\n const file = await conn.getAttachment(params.taskId, params.fileId);\n return { content: [{ type: \"text\", text: JSON.stringify(file, null, 2) }] };\n },\n );\n}\n\nexport function registerAttachmentTools(server: McpServer, conn: ConveyorConnection): void {\n registerListTaskFiles(server, conn);\n registerGetAttachment(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerPullRequestTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_pull_request\",\n \"Open a GitHub pull request for a task's existing branch (the branch must already be pushed to origin). Moves the task to ReviewPR. Returns the PR number and URL.\",\n {\n taskId: z.string().describe(\"The task ID whose branch should be opened as a PR\"),\n title: z.string().describe(\"Pull request title\"),\n body: z.string().describe(\"Pull request body (markdown)\"),\n head: z\n .string()\n .optional()\n .describe(\"Source branch for the PR (defaults to the task's branch)\"),\n base: z\n .string()\n .optional()\n .describe(\"Target branch for the PR (defaults to the repo default)\"),\n },\n async (params) => {\n const result = await conn.createPullRequest(params);\n return {\n content: [{ type: \"text\", text: `PR #${result.prNumber} opened: ${result.prUrl}` }],\n };\n },\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nconst STATUS_ENUM = [\n \"Planning\",\n \"Open\",\n \"InProgress\",\n \"ReviewPR\",\n \"ReviewDev\",\n \"ReviewLive\",\n \"Complete\",\n \"Cancelled\",\n] as const;\n\nconst SP_DESCRIPTION = \"Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)\";\n\nfunction registerCreateSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_subtask\",\n \"Create a subtask under a parent task. Subtasks break a larger task into independently buildable pieces.\",\n {\n parentTaskId: z.string().describe(\"The parent task ID\"),\n title: z.string().describe(\"Subtask title\"),\n description: z.string().optional().describe(\"Subtask description\"),\n plan: z.string().optional().describe(\"Subtask implementation plan (markdown)\"),\n ordinal: z.number().optional().describe(\"Ordering position among siblings\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async (params) => {\n const subtask = await conn.createSubtask(params);\n return {\n content: [{ type: \"text\", text: `Subtask created: ${subtask.id} (slug: ${subtask.slug})` }],\n };\n },\n );\n}\n\nfunction registerUpdateSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"update_subtask\",\n \"Update a subtask's fields: title, description, plan, status, ordering, or story points.\",\n {\n subtaskId: z.string().describe(\"The subtask ID\"),\n title: z.string().optional().describe(\"New title\"),\n description: z.string().optional().describe(\"New description\"),\n plan: z.string().optional().describe(\"New plan (markdown)\"),\n status: z.enum(STATUS_ENUM).optional().describe(\"New status\"),\n ordinal: z.number().optional().describe(\"New ordering position among siblings\"),\n storyPointValue: z.number().optional().describe(SP_DESCRIPTION),\n },\n async (params) => {\n const result = await conn.updateSubtask(params);\n return {\n content: [\n { type: \"text\", text: `Subtask ${result.id} updated (status: ${result.status})` },\n ],\n };\n },\n );\n}\n\nfunction registerListSubtasks(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"list_subtasks\",\n \"List all subtasks of a parent task with their status and ordering.\",\n {\n taskId: z.string().describe(\"The parent task ID\"),\n },\n async (params) => {\n const subtasks = await conn.listSubtasks(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(subtasks, null, 2) }] };\n },\n );\n}\n\nfunction registerDeleteSubtask(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"delete_subtask\",\n \"Delete a subtask by ID. This is permanent — use update_subtask to set status to Cancelled if you only want to close it.\",\n {\n subtaskId: z.string().describe(\"The subtask ID to delete\"),\n },\n async (params) => {\n const result = await conn.deleteSubtask(params.subtaskId);\n return {\n content: [\n { type: \"text\", text: result.deleted ? \"Subtask deleted\" : \"Subtask not deleted\" },\n ],\n };\n },\n );\n}\n\nexport function registerSubtaskTools(server: McpServer, conn: ConveyorConnection): void {\n registerCreateSubtask(server, conn);\n registerUpdateSubtask(server, conn);\n registerListSubtasks(server, conn);\n registerDeleteSubtask(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nfunction registerGetDependencies(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"get_dependencies\",\n \"Get a task's dependencies and their met/unmet status (met = merged to dev). Use to confirm blockers merged, or see why a task cannot start. For task state use get_task.\",\n {\n taskId: z.string().describe(\"The task ID\"),\n },\n async (params) => {\n const deps = await conn.getDependencies(params.taskId);\n return { content: [{ type: \"text\", text: JSON.stringify(deps, null, 2) }] };\n },\n );\n}\n\nfunction registerAddDependency(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"add_dependency\",\n \"Add a blocking dependency — this task cannot start until the named task is merged to dev.\",\n {\n taskId: z.string().describe(\"The task ID that will be blocked\"),\n dependsOnSlugOrId: z.string().describe(\"Slug or ID of the task this one depends on\"),\n },\n async (params) => {\n await conn.addDependency(params);\n return { content: [{ type: \"text\", text: \"Dependency added\" }] };\n },\n );\n}\n\nfunction registerRemoveDependency(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"remove_dependency\",\n \"Remove a previously added dependency from a task. The task is no longer blocked by the named task. Returns: confirmation string.\",\n {\n taskId: z.string().describe(\"The task ID to unblock\"),\n dependsOnSlugOrId: z.string().describe(\"Slug or ID of the dependency to remove\"),\n },\n async (params) => {\n await conn.removeDependency(params);\n return { content: [{ type: \"text\", text: \"Dependency removed\" }] };\n },\n );\n}\n\nexport function registerDependencyTools(server: McpServer, conn: ConveyorConnection): void {\n registerGetDependencies(server, conn);\n registerAddDependency(server, conn);\n registerRemoveDependency(server, conn);\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\n\nexport function registerSuggestionTools(server: McpServer, conn: ConveyorConnection): void {\n server.tool(\n \"create_suggestion\",\n \"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.\",\n {\n title: z.string().describe(\"Suggestion title\"),\n description: z.string().optional().describe(\"Suggestion details (markdown)\"),\n tagNames: z\n .array(z.string())\n .optional()\n .describe('Tag names to categorize the suggestion (e.g., [\"agent-runner\"])'),\n },\n async (params) => {\n const result = await conn.createSuggestion(params);\n const text = result.merged\n ? `Suggestion merged into existing suggestion ${result.mergedIntoId} (upvote recorded)`\n : `Suggestion created: ${result.id}`;\n return { content: [{ type: \"text\", text }] };\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ConveyorConnection } from \"../connection.js\";\nimport { registerProjectTools } from \"./project.js\";\nimport { registerTaskTools } from \"./tasks.js\";\nimport { registerBuildTools } from \"./builds.js\";\nimport { registerAttachmentTools } from \"./attachments.js\";\nimport { registerPullRequestTools } from \"./pull-request.js\";\nimport { registerSubtaskTools } from \"./subtasks.js\";\nimport { registerDependencyTools } from \"./dependencies.js\";\nimport { registerSuggestionTools } from \"./suggestions.js\";\n\nexport function registerAllTools(server: McpServer, conn: ConveyorConnection): void {\n registerProjectTools(server, conn);\n registerTaskTools(server, conn);\n registerBuildTools(server, conn);\n registerAttachmentTools(server, conn);\n registerPullRequestTools(server, conn);\n registerSubtaskTools(server, conn);\n registerDependencyTools(server, conn);\n registerSuggestionTools(server, conn);\n}\n"],"mappings":"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","names":["server","conn","server","conn","z","server","conn","z","server","conn","z","server","conn","z","STATUS_ENUM","server","conn","z","server","conn","z","server","conn","server","conn"]}
|
package/dist/index.js
CHANGED
package/dist/tunnel-cli.js
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/connection.ts"],"sourcesContent":["import { io, type Socket } from \"socket.io-client\";\n\nexport interface ConveyorMcpConfig {\n apiUrl: string;\n projectToken: string;\n projectId: string;\n}\n\n/** A single PTY output frame broadcast on the `pty:data` room event. */\nexport interface PtyDataChunk {\n sessionId: string;\n seq: number;\n data: string;\n cols?: number;\n rows?: number;\n}\n\n/** Ring-buffer snapshot returned by `ptyAttach` for catch-up replay. */\nexport interface PtyAttachSnapshot {\n sessionId: string;\n chunks: { seq: number; data: string }[];\n cols: number;\n rows: number;\n totalBytes: number;\n}\n\n/**\n * Result of `getActivePtySession`. `sessionId` is null until the cloud agent\n * has booted a PTY and produced at least one ring frame (readiness signal).\n */\nexport interface ActivePtySession {\n sessionId: string | null;\n cols?: number;\n rows?: number;\n}\n\ntype SocketCallback = (response: { success: boolean; data?: unknown; error?: string }) => void;\n\nexport class ConveyorConnection {\n private socket: Socket | null = null;\n private config: ConveyorMcpConfig;\n\n constructor(config: ConveyorMcpConfig) {\n this.config = config;\n }\n\n get projectId(): string {\n return this.config.projectId;\n }\n\n connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n let settled = false;\n let attempts = 0;\n const maxAttempts = 15;\n\n this.socket = io(this.config.apiUrl, {\n auth: {\n projectToken: this.config.projectToken,\n runnerMode: \"project\",\n },\n transports: [\"websocket\"],\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 2000,\n reconnectionDelayMax: 30000,\n randomizationFactor: 0.3,\n extraHeaders: { \"ngrok-skip-browser-warning\": \"true\" },\n });\n\n this.socket.on(\"connect\", () => {\n if (!settled) {\n settled = true;\n // Subscribe to project room for events\n this.socket?.emit(\"projectService:subscribe\", { id: this.config.projectId });\n resolve();\n }\n });\n\n this.socket.on(\"connect_error\", (err) => {\n attempts++;\n if (!settled && attempts >= maxAttempts) {\n settled = true;\n reject(new Error(`Failed to connect: ${err.message}`));\n }\n });\n });\n }\n\n // ── Service method call (agentSessionService:*) ─────────────────────\n\n private call<T>(method: string, data: unknown): Promise<T> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n const TIMEOUT_MS = 15_000;\n\n return Promise.race([\n new Promise<T>((resolve, reject) => {\n socket.emit(`agentSessionService:${method}`, data, ((response: {\n success: boolean;\n data?: T;\n error?: string;\n }) => {\n if (response.success) {\n resolve(response.data as T);\n } else {\n reject(new Error(response.error ?? `${method} failed`));\n }\n }) as SocketCallback);\n }),\n new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Request timed out: ${method}`));\n }, TIMEOUT_MS);\n }),\n ]);\n }\n\n /**\n * Fire-and-forget emit (no ack). The quickdraw-core server method handler\n * invokes the ack callback via optional chaining, so omitting it still runs\n * the full auth/schema/ACL pipeline — it just skips the response round-trip.\n * Used for high-frequency PTY input/resize so each keystroke does not arm a\n * 15s timeout timer.\n */\n private emit(method: string, data: unknown): void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.emit(`agentSessionService:${method}`, data);\n }\n\n // ── Task Queries ────────────────────────────────────────────────────\n\n listTasks(params: { status?: string; assigneeId?: string; limit?: number }): Promise<unknown[]> {\n return this.call(\"listProjectTasks\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n getTask(taskId: string): Promise<unknown> {\n return this.call(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n searchTasks(params: {\n tagNames?: string[];\n searchQuery?: string;\n statusFilters?: string[];\n limit?: number;\n }): Promise<unknown[]> {\n return this.call(\"searchProjectTasks\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Task Mutations ──────────────────────────────────────────────────\n\n createTask(params: {\n title: string;\n description?: string;\n plan?: string;\n status?: string;\n }): Promise<{ id: string; slug: string }> {\n return this.call(\"createProjectTask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n updateTask(params: {\n taskId: string;\n title?: string;\n description?: string;\n plan?: string;\n status?: string;\n assignedUserId?: string | null;\n }): Promise<{ id: string; status: string }> {\n return this.call(\"updateProjectTask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Build Management ────────────────────────────────────────────────\n\n startBuild(taskId: string): Promise<{ taskId: string; status: string }> {\n return this.call(\"startProjectBuild\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n stopBuild(taskId: string): Promise<{ taskId: string; stopped: boolean }> {\n return this.call(\"stopProjectBuild\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n getBuildStatus(taskId: string): Promise<{\n session: { status: string | null; agentRunnerStatus: string | null } | null;\n }> {\n // Uses getProjectTask and extracts the session field\n return this.call<Record<string, unknown>>(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n }).then((task) => ({\n session:\n (task?.session as {\n status: string | null;\n agentRunnerStatus: string | null;\n }) ?? null,\n }));\n }\n\n // ── Chat ────────────────────────────────────────────────────────────\n\n getTaskChat(taskId: string, limit?: number): Promise<unknown[]> {\n // Uses getProjectTask and extracts chatMessages\n return this.call<Record<string, unknown>>(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n }).then((task) => {\n const messages = (task?.chatMessages ?? []) as unknown[];\n return limit ? messages.slice(-limit) : messages;\n });\n }\n\n postToTaskChat(taskId: string, content: string): Promise<{ messageId: string }> {\n return this.call(\"postToProjectTaskChat\", {\n projectId: this.config.projectId,\n taskId,\n content,\n });\n }\n\n // ── CLI History ─────────────────────────────────────────────────────\n\n getTaskCli(\n taskId: string,\n limit?: number,\n source?: string,\n ): Promise<{ type: string; data: Record<string, unknown>; timestamp: string }[]> {\n return this.call(\"getProjectTaskCli\", {\n projectId: this.config.projectId,\n taskId,\n limit,\n source,\n });\n }\n\n // ── Project Info ────────────────────────────────────────────────────\n\n listTags(): Promise<{ id: string; name: string; color: string }[]> {\n return this.call(\"listProjectTags\", {\n projectId: this.config.projectId,\n });\n }\n\n getProjectSummary(): Promise<unknown> {\n return this.call(\"getProjectSummary\", {\n projectId: this.config.projectId,\n });\n }\n\n // ── Review Flow ─────────────────────────────────────────────────────\n\n async approveTask(taskId: string): Promise<{ status: string }> {\n // Determine next status based on current status\n const task = (await this.call(\"getProjectTask\", {\n projectId: this.config.projectId,\n taskId,\n })) as { status: string } | null;\n\n if (!task) throw new Error(\"Task not found\");\n\n const nextStatus = task.status === \"ReviewPR\" ? \"ReviewDev\" : \"Complete\";\n\n const result = await this.updateTask({ taskId, status: nextStatus });\n return { status: result.status };\n }\n\n async requestChanges(taskId: string, feedback: string): Promise<void> {\n // Post feedback to task chat then move to InProgress\n await this.postToTaskChat(taskId, feedback);\n await this.updateTask({ taskId, status: \"InProgress\" });\n }\n\n approveAndMergePR(\n childTaskId: string,\n ): Promise<{ merged: boolean; childTaskId: string; prNumber: number }> {\n return this.call(\"approveProjectMergePR\", {\n projectId: this.config.projectId,\n childTaskId,\n });\n }\n\n // ── File Attachments ────────────────────────────────────────────────\n\n listTaskFiles(taskId: string): Promise<unknown[]> {\n return this.call(\"listProjectTaskFiles\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n getAttachment(taskId: string, fileId: string): Promise<unknown> {\n return this.call(\"getProjectAttachment\", {\n projectId: this.config.projectId,\n taskId,\n fileId,\n });\n }\n\n // ── Pull Requests ───────────────────────────────────────────────────\n\n createPullRequest(params: {\n taskId: string;\n title: string;\n body: string;\n head?: string;\n base?: string;\n }): Promise<{ prNumber: number; prUrl: string }> {\n return this.call(\"createProjectPullRequest\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Subtasks ────────────────────────────────────────────────────────\n\n createSubtask(params: {\n parentTaskId: string;\n title: string;\n description?: string;\n plan?: string;\n ordinal?: number;\n storyPointValue?: number;\n }): Promise<{ id: string; slug: string }> {\n return this.call(\"createProjectSubtask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n updateSubtask(params: {\n subtaskId: string;\n title?: string;\n description?: string;\n plan?: string;\n status?: string;\n ordinal?: number;\n storyPointValue?: number;\n }): Promise<{ id: string; status: string }> {\n return this.call(\"updateProjectSubtask\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n listSubtasks(taskId: string): Promise<unknown[]> {\n return this.call(\"listProjectSubtasks\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n deleteSubtask(subtaskId: string): Promise<{ deleted: boolean }> {\n return this.call(\"deleteProjectSubtask\", {\n projectId: this.config.projectId,\n subtaskId,\n });\n }\n\n // ── Dependencies ────────────────────────────────────────────────────\n\n getDependencies(taskId: string): Promise<unknown[]> {\n return this.call(\"getProjectTaskDependencies\", {\n projectId: this.config.projectId,\n taskId,\n });\n }\n\n addDependency(params: {\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n return this.call(\"addProjectTaskDependency\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n removeDependency(params: {\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n return this.call(\"removeProjectTaskDependency\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── Suggestions ─────────────────────────────────────────────────────\n\n createSuggestion(params: {\n title: string;\n description?: string;\n tagNames?: string[];\n }): Promise<{ id: string; merged: boolean; mergedIntoId?: string }> {\n return this.call(\"createProjectSuggestion\", {\n projectId: this.config.projectId,\n ...params,\n });\n }\n\n // ── PTY Tunnel Relay (reuses the S2 pty:* envelope) ─────────────────\n\n /**\n * Poll target: returns the active cloud PTY session for a task once its ring\n * buffer has frames. `sessionId` is resolved server-side from `taskId` (never\n * accepted from the wire), preserving the one-active-session-per-task invariant.\n */\n getActivePtySession(taskId: string): Promise<ActivePtySession> {\n return this.call(\"getActivePtySession\", { taskId });\n }\n\n /** Fetch the ring-buffer snapshot for catch-up replay on (re)attach. */\n ptyAttach(sessionId: string): Promise<PtyAttachSnapshot> {\n return this.call(\"ptyAttach\", { sessionId });\n }\n\n /**\n * Join the session room so `pty:data` frames are delivered. Uses the standard\n * quickdraw-core subscribe envelope; \"Read\" is sufficient for output streaming.\n */\n subscribeToSession(sessionId: string): void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.emit(\"agentSessionService:subscribe\", {\n entryId: sessionId,\n requiredLevel: \"Read\",\n });\n }\n\n /** Relay a stdin chunk to the cloud PTY (raw utf8, fire-and-forget). */\n ptyInput(sessionId: string, data: string): void {\n this.emit(\"ptyInput\", { sessionId, data });\n }\n\n /** Relay a terminal resize to the cloud PTY (fire-and-forget). */\n ptyResize(sessionId: string, cols: number, rows: number): void {\n this.emit(\"ptyResize\", { sessionId, cols, rows });\n }\n\n /** Subscribe to raw PTY output frames. Returns an unsubscribe function. */\n onPtyData(handler: (chunk: PtyDataChunk) => void): () => void {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n socket.on(\"pty:data\", handler as (...args: unknown[]) => void);\n return () => {\n socket.off(\"pty:data\", handler as (...args: unknown[]) => void);\n };\n }\n\n // ── Connection lifecycle ────────────────────────────────────────────\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n}\n"],"mappings":";AAAA,SAAS,UAAuB;AAsCzB,IAAM,qBAAN,MAAyB;AAAA,EACtB,SAAwB;AAAA,EACxB;AAAA,EAER,YAAY,QAA2B;AACrC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,UAAyB;AACvB,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI,UAAU;AACd,UAAI,WAAW;AACf,YAAM,cAAc;AAEpB,WAAK,SAAS,GAAG,KAAK,OAAO,QAAQ;AAAA,QACnC,MAAM;AAAA,UACJ,cAAc,KAAK,OAAO;AAAA,UAC1B,YAAY;AAAA,QACd;AAAA,QACA,YAAY,CAAC,WAAW;AAAA,QACxB,cAAc;AAAA,QACd,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,QACnB,sBAAsB;AAAA,QACtB,qBAAqB;AAAA,QACrB,cAAc,EAAE,8BAA8B,OAAO;AAAA,MACvD,CAAC;AAED,WAAK,OAAO,GAAG,WAAW,MAAM;AAC9B,YAAI,CAAC,SAAS;AACZ,oBAAU;AAEV,eAAK,QAAQ,KAAK,4BAA4B,EAAE,IAAI,KAAK,OAAO,UAAU,CAAC;AAC3E,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,iBAAiB,CAAC,QAAQ;AACvC;AACA,YAAI,CAAC,WAAW,YAAY,aAAa;AACvC,oBAAU;AACV,iBAAO,IAAI,MAAM,sBAAsB,IAAI,OAAO,EAAE,CAAC;AAAA,QACvD;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA,EAIQ,KAAQ,QAAgB,MAA2B;AACzD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAE5C,UAAM,aAAa;AAEnB,WAAO,QAAQ,KAAK;AAAA,MAClB,IAAI,QAAW,CAAC,SAAS,WAAW;AAClC,eAAO,KAAK,uBAAuB,MAAM,IAAI,OAAO,CAAC,aAI/C;AACJ,cAAI,SAAS,SAAS;AACpB,oBAAQ,SAAS,IAAS;AAAA,UAC5B,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,GAAG,MAAM,SAAS,CAAC;AAAA,UACxD;AAAA,QACF,EAAoB;AAAA,MACtB,CAAC;AAAA,MACD,IAAI,QAAe,CAAC,GAAG,WAAW;AAChC,mBAAW,MAAM;AACf,iBAAO,IAAI,MAAM,sBAAsB,MAAM,EAAE,CAAC;AAAA,QAClD,GAAG,UAAU;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,KAAK,QAAgB,MAAqB;AAChD,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,KAAK,uBAAuB,MAAM,IAAI,IAAI;AAAA,EACnD;AAAA;AAAA,EAIA,UAAU,QAAsF;AAC9F,WAAO,KAAK,KAAK,oBAAoB;AAAA,MACnC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,QAAQ,QAAkC;AACxC,WAAO,KAAK,KAAK,kBAAkB;AAAA,MACjC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,QAKW;AACrB,WAAO,KAAK,KAAK,sBAAsB;AAAA,MACrC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,WAAW,QAK+B;AACxC,WAAO,KAAK,KAAK,qBAAqB;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,WAAW,QAOiC;AAC1C,WAAO,KAAK,KAAK,qBAAqB;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,WAAW,QAA6D;AACtE,WAAO,KAAK,KAAK,qBAAqB;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,QAA+D;AACvE,WAAO,KAAK,KAAK,oBAAoB;AAAA,MACnC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,QAEZ;AAED,WAAO,KAAK,KAA8B,kBAAkB;AAAA,MAC1D,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,UAAU;AAAA,MACjB,SACG,MAAM,WAGD;AAAA,IACV,EAAE;AAAA,EACJ;AAAA;AAAA,EAIA,YAAY,QAAgB,OAAoC;AAE9D,WAAO,KAAK,KAA8B,kBAAkB;AAAA,MAC1D,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,SAAS;AAChB,YAAM,WAAY,MAAM,gBAAgB,CAAC;AACzC,aAAO,QAAQ,SAAS,MAAM,CAAC,KAAK,IAAI;AAAA,IAC1C,CAAC;AAAA,EACH;AAAA,EAEA,eAAe,QAAgB,SAAiD;AAC9E,WAAO,KAAK,KAAK,yBAAyB;AAAA,MACxC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,WACE,QACA,OACA,QAC+E;AAC/E,WAAO,KAAK,KAAK,qBAAqB;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,WAAmE;AACjE,WAAO,KAAK,KAAK,mBAAmB;AAAA,MAClC,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,oBAAsC;AACpC,WAAO,KAAK,KAAK,qBAAqB;AAAA,MACpC,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,MAAM,YAAY,QAA6C;AAE7D,UAAM,OAAQ,MAAM,KAAK,KAAK,kBAAkB;AAAA,MAC9C,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAED,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,gBAAgB;AAE3C,UAAM,aAAa,KAAK,WAAW,aAAa,cAAc;AAE9D,UAAM,SAAS,MAAM,KAAK,WAAW,EAAE,QAAQ,QAAQ,WAAW,CAAC;AACnE,WAAO,EAAE,QAAQ,OAAO,OAAO;AAAA,EACjC;AAAA,EAEA,MAAM,eAAe,QAAgB,UAAiC;AAEpE,UAAM,KAAK,eAAe,QAAQ,QAAQ;AAC1C,UAAM,KAAK,WAAW,EAAE,QAAQ,QAAQ,aAAa,CAAC;AAAA,EACxD;AAAA,EAEA,kBACE,aACqE;AACrE,WAAO,KAAK,KAAK,yBAAyB;AAAA,MACxC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,cAAc,QAAoC;AAChD,WAAO,KAAK,KAAK,wBAAwB;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAAgB,QAAkC;AAC9D,WAAO,KAAK,KAAK,wBAAwB;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,kBAAkB,QAM+B;AAC/C,WAAO,KAAK,KAAK,4BAA4B;AAAA,MAC3C,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,cAAc,QAO4B;AACxC,WAAO,KAAK,KAAK,wBAAwB;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAQ8B;AAC1C,WAAO,KAAK,KAAK,wBAAwB;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,aAAa,QAAoC;AAC/C,WAAO,KAAK,KAAK,uBAAuB;AAAA,MACtC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,WAAkD;AAC9D,WAAO,KAAK,KAAK,wBAAwB;AAAA,MACvC,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,gBAAgB,QAAoC;AAClD,WAAO,KAAK,KAAK,8BAA8B;AAAA,MAC7C,WAAW,KAAK,OAAO;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,QAGoB;AAChC,WAAO,KAAK,KAAK,4BAA4B;AAAA,MAC3C,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,QAGiB;AAChC,WAAO,KAAK,KAAK,+BAA+B;AAAA,MAC9C,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA,EAIA,iBAAiB,QAImD;AAClE,WAAO,KAAK,KAAK,2BAA2B;AAAA,MAC1C,WAAW,KAAK,OAAO;AAAA,MACvB,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,oBAAoB,QAA2C;AAC7D,WAAO,KAAK,KAAK,uBAAuB,EAAE,OAAO,CAAC;AAAA,EACpD;AAAA;AAAA,EAGA,UAAU,WAA+C;AACvD,WAAO,KAAK,KAAK,aAAa,EAAE,UAAU,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,WAAyB;AAC1C,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,KAAK,iCAAiC;AAAA,MAC3C,SAAS;AAAA,MACT,eAAe;AAAA,IACjB,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,SAAS,WAAmB,MAAoB;AAC9C,SAAK,KAAK,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGA,UAAU,WAAmB,MAAc,MAAoB;AAC7D,SAAK,KAAK,aAAa,EAAE,WAAW,MAAM,KAAK,CAAC;AAAA,EAClD;AAAA;AAAA,EAGA,UAAU,SAAoD;AAC5D,UAAM,SAAS,KAAK;AACpB,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,eAAe;AAC5C,WAAO,GAAG,YAAY,OAAuC;AAC7D,WAAO,MAAM;AACX,aAAO,IAAI,YAAY,OAAuC;AAAA,IAChE;AAAA,EACF;AAAA;AAAA,EAIA,aAAmB;AACjB,SAAK,QAAQ,WAAW;AACxB,SAAK,SAAS;AAAA,EAChB;AACF;","names":[]}
|