@rallycry/conveyor-mcp 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-2DPMMT6S.js → chunk-Z566YAS7.js} +121 -73
- package/dist/chunk-Z566YAS7.js.map +1 -0
- package/dist/cli.js +233 -164
- 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 +40 -22
- package/package.json +1 -1
- package/dist/chunk-2DPMMT6S.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/connection.ts
|
|
2
2
|
import { io } from "socket.io-client";
|
|
3
|
+
var NO_PROJECT_SELECTED_MESSAGE = "No Conveyor project selected. Pass projectId to this tool or configure CONVEYOR_PROJECT_ID.";
|
|
3
4
|
var AUTH_ERROR_RE = /token|unauthor|forbidden|not authenticated|invalid auth/i;
|
|
4
5
|
function enrichToolError(error, fallback) {
|
|
5
6
|
const base = error ?? fallback ?? "Request failed";
|
|
@@ -15,7 +16,21 @@ var ConveyorConnection = class {
|
|
|
15
16
|
this.config = config;
|
|
16
17
|
}
|
|
17
18
|
get projectId() {
|
|
18
|
-
return this.
|
|
19
|
+
return this.resolveProjectId();
|
|
20
|
+
}
|
|
21
|
+
resolveProjectId(projectId) {
|
|
22
|
+
const resolved = projectId ?? this.config.projectId;
|
|
23
|
+
if (!resolved) throw new Error(NO_PROJECT_SELECTED_MESSAGE);
|
|
24
|
+
return resolved;
|
|
25
|
+
}
|
|
26
|
+
normalizeProjectList(response) {
|
|
27
|
+
if (Array.isArray(response)) return response;
|
|
28
|
+
if (typeof response !== "object" || response === null) return [];
|
|
29
|
+
const record = response;
|
|
30
|
+
if (Array.isArray(record.items)) return record.items;
|
|
31
|
+
if (Array.isArray(record.projects)) return record.projects;
|
|
32
|
+
if (Array.isArray(record.data)) return record.data;
|
|
33
|
+
return [];
|
|
19
34
|
}
|
|
20
35
|
connect() {
|
|
21
36
|
return new Promise((resolve, reject) => {
|
|
@@ -49,7 +64,7 @@ var ConveyorConnection = class {
|
|
|
49
64
|
this.socket?.close();
|
|
50
65
|
reject(
|
|
51
66
|
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.`
|
|
67
|
+
`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_USER_TOKEN (or legacy CONVEYOR_PROJECT_TOKEN).`
|
|
53
68
|
)
|
|
54
69
|
);
|
|
55
70
|
return;
|
|
@@ -118,70 +133,86 @@ var ConveyorConnection = class {
|
|
|
118
133
|
}
|
|
119
134
|
// ── Task Queries ────────────────────────────────────────────────────
|
|
120
135
|
listTasks(params) {
|
|
136
|
+
const { projectId, ...rest } = params;
|
|
121
137
|
return this.call("listProjectTasks", {
|
|
122
|
-
projectId: this.
|
|
123
|
-
...
|
|
138
|
+
projectId: this.resolveProjectId(projectId),
|
|
139
|
+
...rest
|
|
124
140
|
});
|
|
125
141
|
}
|
|
126
|
-
getTask(taskId) {
|
|
142
|
+
getTask(taskId, projectId) {
|
|
127
143
|
return this.call("getProjectTask", {
|
|
128
|
-
projectId: this.
|
|
144
|
+
projectId: this.resolveProjectId(projectId),
|
|
129
145
|
taskId
|
|
130
146
|
});
|
|
131
147
|
}
|
|
148
|
+
getCardBySlug(slug, projectId) {
|
|
149
|
+
return this.call("getProjectTask", {
|
|
150
|
+
projectId: this.resolveProjectId(projectId),
|
|
151
|
+
taskId: slug
|
|
152
|
+
});
|
|
153
|
+
}
|
|
132
154
|
searchTasks(params) {
|
|
155
|
+
const { projectId, ...rest } = params;
|
|
133
156
|
return this.call("searchProjectTasks", {
|
|
134
|
-
projectId: this.
|
|
135
|
-
...
|
|
157
|
+
projectId: this.resolveProjectId(projectId),
|
|
158
|
+
...rest
|
|
136
159
|
});
|
|
137
160
|
}
|
|
138
161
|
// ── Task Mutations ──────────────────────────────────────────────────
|
|
139
162
|
createTask(params) {
|
|
163
|
+
const { projectId, ...rest } = params;
|
|
140
164
|
return this.call("createProjectTask", {
|
|
141
|
-
projectId: this.
|
|
142
|
-
...
|
|
165
|
+
projectId: this.resolveProjectId(projectId),
|
|
166
|
+
...rest
|
|
143
167
|
});
|
|
144
168
|
}
|
|
145
169
|
updateTask(params) {
|
|
170
|
+
const { projectId, ...rest } = params;
|
|
146
171
|
return this.call("updateProjectTask", {
|
|
147
|
-
projectId: this.
|
|
148
|
-
...
|
|
172
|
+
projectId: this.resolveProjectId(projectId),
|
|
173
|
+
...rest
|
|
149
174
|
});
|
|
150
175
|
}
|
|
151
176
|
// ── Reviewers & Members ─────────────────────────────────────────────
|
|
152
177
|
addReviewer(params) {
|
|
178
|
+
const { projectId, ...rest } = params;
|
|
153
179
|
return this.call("addProjectTaskReviewer", {
|
|
154
|
-
projectId: this.
|
|
155
|
-
...
|
|
180
|
+
projectId: this.resolveProjectId(projectId),
|
|
181
|
+
...rest
|
|
156
182
|
});
|
|
157
183
|
}
|
|
158
184
|
removeReviewer(params) {
|
|
185
|
+
const { projectId, ...rest } = params;
|
|
159
186
|
return this.call("removeProjectTaskReviewer", {
|
|
160
|
-
projectId: this.
|
|
161
|
-
...
|
|
187
|
+
projectId: this.resolveProjectId(projectId),
|
|
188
|
+
...rest
|
|
162
189
|
});
|
|
163
190
|
}
|
|
164
|
-
listProjectMembers() {
|
|
191
|
+
listProjectMembers(projectId) {
|
|
165
192
|
return this.call("listProjectMembers", {
|
|
166
|
-
projectId: this.
|
|
193
|
+
projectId: this.resolveProjectId(projectId)
|
|
167
194
|
});
|
|
168
195
|
}
|
|
196
|
+
async listProjects() {
|
|
197
|
+
const response = await this.call("listAccessibleProjects", { pageSize: 100 });
|
|
198
|
+
return this.normalizeProjectList(response);
|
|
199
|
+
}
|
|
169
200
|
// ── Build Management ────────────────────────────────────────────────
|
|
170
|
-
startBuild(taskId) {
|
|
201
|
+
startBuild(taskId, projectId) {
|
|
171
202
|
return this.call("startProjectBuild", {
|
|
172
|
-
projectId: this.
|
|
203
|
+
projectId: this.resolveProjectId(projectId),
|
|
173
204
|
taskId
|
|
174
205
|
});
|
|
175
206
|
}
|
|
176
|
-
stopBuild(taskId) {
|
|
207
|
+
stopBuild(taskId, projectId) {
|
|
177
208
|
return this.call("stopProjectBuild", {
|
|
178
|
-
projectId: this.
|
|
209
|
+
projectId: this.resolveProjectId(projectId),
|
|
179
210
|
taskId
|
|
180
211
|
});
|
|
181
212
|
}
|
|
182
|
-
getBuildStatus(taskId) {
|
|
213
|
+
getBuildStatus(taskId, projectId) {
|
|
183
214
|
return this.call("getProjectTask", {
|
|
184
|
-
projectId: this.
|
|
215
|
+
projectId: this.resolveProjectId(projectId),
|
|
185
216
|
taskId
|
|
186
217
|
}).then((task) => ({
|
|
187
218
|
session: task?.session ?? null
|
|
@@ -194,73 +225,79 @@ var ConveyorConnection = class {
|
|
|
194
225
|
});
|
|
195
226
|
}
|
|
196
227
|
// ── Chat ────────────────────────────────────────────────────────────
|
|
197
|
-
getTaskChat(taskId, limit) {
|
|
228
|
+
getTaskChat(taskId, limit, projectId) {
|
|
198
229
|
return this.call("getProjectTask", {
|
|
199
|
-
projectId: this.
|
|
230
|
+
projectId: this.resolveProjectId(projectId),
|
|
200
231
|
taskId
|
|
201
232
|
}).then((task) => {
|
|
202
233
|
const messages = task?.chatMessages ?? [];
|
|
203
234
|
return limit ? messages.slice(-limit) : messages;
|
|
204
235
|
});
|
|
205
236
|
}
|
|
206
|
-
postToTaskChat(taskId, content) {
|
|
237
|
+
postToTaskChat(taskId, content, projectId) {
|
|
207
238
|
return this.call("postToProjectTaskChat", {
|
|
208
|
-
projectId: this.
|
|
239
|
+
projectId: this.resolveProjectId(projectId),
|
|
209
240
|
taskId,
|
|
210
241
|
content
|
|
211
242
|
});
|
|
212
243
|
}
|
|
213
244
|
// ── CLI History ─────────────────────────────────────────────────────
|
|
214
|
-
getTaskCli(taskId, limit, source) {
|
|
245
|
+
getTaskCli(taskId, limit, source, projectId) {
|
|
215
246
|
return this.call("getProjectTaskCli", {
|
|
216
|
-
projectId: this.
|
|
247
|
+
projectId: this.resolveProjectId(projectId),
|
|
217
248
|
taskId,
|
|
218
249
|
limit,
|
|
219
250
|
source
|
|
220
251
|
});
|
|
221
252
|
}
|
|
222
253
|
// ── Project Info ────────────────────────────────────────────────────
|
|
223
|
-
listTags() {
|
|
254
|
+
listTags(projectId) {
|
|
224
255
|
return this.call("listProjectTags", {
|
|
225
|
-
projectId: this.
|
|
256
|
+
projectId: this.resolveProjectId(projectId)
|
|
226
257
|
});
|
|
227
258
|
}
|
|
228
|
-
getProjectSummary() {
|
|
259
|
+
getProjectSummary(projectId) {
|
|
229
260
|
return this.call("getProjectSummary", {
|
|
230
|
-
projectId: this.
|
|
261
|
+
projectId: this.resolveProjectId(projectId)
|
|
231
262
|
});
|
|
232
263
|
}
|
|
233
264
|
// ── Review Flow ─────────────────────────────────────────────────────
|
|
234
|
-
async approveTask(taskId) {
|
|
265
|
+
async approveTask(taskId, projectId) {
|
|
266
|
+
const targetProjectId = this.resolveProjectId(projectId);
|
|
235
267
|
const task = await this.call("getProjectTask", {
|
|
236
|
-
projectId:
|
|
268
|
+
projectId: targetProjectId,
|
|
237
269
|
taskId
|
|
238
270
|
});
|
|
239
271
|
if (!task) throw new Error("Task not found");
|
|
240
272
|
const nextStatus = task.status === "ReviewPR" ? "ReviewDev" : "Complete";
|
|
241
|
-
const result = await this.updateTask({
|
|
273
|
+
const result = await this.updateTask({
|
|
274
|
+
projectId: targetProjectId,
|
|
275
|
+
taskId,
|
|
276
|
+
status: nextStatus
|
|
277
|
+
});
|
|
242
278
|
return { status: result.status };
|
|
243
279
|
}
|
|
244
|
-
async requestChanges(taskId, feedback) {
|
|
245
|
-
|
|
246
|
-
await this.
|
|
280
|
+
async requestChanges(taskId, feedback, projectId) {
|
|
281
|
+
const targetProjectId = this.resolveProjectId(projectId);
|
|
282
|
+
await this.postToTaskChat(taskId, feedback, targetProjectId);
|
|
283
|
+
await this.updateTask({ projectId: targetProjectId, taskId, status: "InProgress" });
|
|
247
284
|
}
|
|
248
|
-
approveAndMergePR(childTaskId) {
|
|
285
|
+
approveAndMergePR(childTaskId, projectId) {
|
|
249
286
|
return this.call("approveProjectMergePR", {
|
|
250
|
-
projectId: this.
|
|
287
|
+
projectId: this.resolveProjectId(projectId),
|
|
251
288
|
childTaskId
|
|
252
289
|
});
|
|
253
290
|
}
|
|
254
291
|
// ── File Attachments ────────────────────────────────────────────────
|
|
255
|
-
listTaskFiles(taskId) {
|
|
292
|
+
listTaskFiles(taskId, projectId) {
|
|
256
293
|
return this.call("listProjectTaskFiles", {
|
|
257
|
-
projectId: this.
|
|
294
|
+
projectId: this.resolveProjectId(projectId),
|
|
258
295
|
taskId
|
|
259
296
|
});
|
|
260
297
|
}
|
|
261
298
|
getAttachment(taskId, fileId, opts) {
|
|
262
299
|
const payload = {
|
|
263
|
-
projectId: this.
|
|
300
|
+
projectId: this.resolveProjectId(opts?.projectId),
|
|
264
301
|
taskId,
|
|
265
302
|
fileId
|
|
266
303
|
};
|
|
@@ -269,15 +306,16 @@ var ConveyorConnection = class {
|
|
|
269
306
|
return this.call("getProjectAttachment", payload);
|
|
270
307
|
}
|
|
271
308
|
requestFileUpload(taskId, params) {
|
|
309
|
+
const { projectId, ...rest } = params;
|
|
272
310
|
return this.call("requestProjectFileUpload", {
|
|
273
|
-
projectId: this.
|
|
311
|
+
projectId: this.resolveProjectId(projectId),
|
|
274
312
|
taskId,
|
|
275
|
-
...
|
|
313
|
+
...rest
|
|
276
314
|
});
|
|
277
315
|
}
|
|
278
|
-
confirmFileUpload(taskId, fileId, comment) {
|
|
316
|
+
confirmFileUpload(taskId, fileId, comment, projectId) {
|
|
279
317
|
const payload = {
|
|
280
|
-
projectId: this.
|
|
318
|
+
projectId: this.resolveProjectId(projectId),
|
|
281
319
|
taskId,
|
|
282
320
|
fileId
|
|
283
321
|
};
|
|
@@ -285,80 +323,90 @@ var ConveyorConnection = class {
|
|
|
285
323
|
return this.call("confirmProjectFileUpload", payload, 3e4);
|
|
286
324
|
}
|
|
287
325
|
// ── Releases ────────────────────────────────────────────────────────
|
|
288
|
-
createRelease(taskIds) {
|
|
289
|
-
return this.call(
|
|
326
|
+
createRelease(taskIds, projectId) {
|
|
327
|
+
return this.call(
|
|
328
|
+
"createProjectRelease",
|
|
329
|
+
{ projectId: this.resolveProjectId(projectId), taskIds },
|
|
330
|
+
45e3
|
|
331
|
+
);
|
|
290
332
|
}
|
|
291
333
|
// ── Pull Requests ───────────────────────────────────────────────────
|
|
292
334
|
createPullRequest(params) {
|
|
335
|
+
const { projectId, ...rest } = params;
|
|
293
336
|
return this.call(
|
|
294
337
|
"createProjectPullRequest",
|
|
295
|
-
{ projectId: this.
|
|
338
|
+
{ projectId: this.resolveProjectId(projectId), ...rest },
|
|
296
339
|
45e3
|
|
297
340
|
);
|
|
298
341
|
}
|
|
299
342
|
// ── Subtasks ────────────────────────────────────────────────────────
|
|
300
343
|
createSubtask(params) {
|
|
344
|
+
const { projectId, ...rest } = params;
|
|
301
345
|
return this.call("createProjectSubtask", {
|
|
302
|
-
projectId: this.
|
|
303
|
-
...
|
|
346
|
+
projectId: this.resolveProjectId(projectId),
|
|
347
|
+
...rest
|
|
304
348
|
});
|
|
305
349
|
}
|
|
306
350
|
updateSubtask(params) {
|
|
351
|
+
const { projectId, ...rest } = params;
|
|
307
352
|
return this.call("updateProjectSubtask", {
|
|
308
|
-
projectId: this.
|
|
309
|
-
...
|
|
353
|
+
projectId: this.resolveProjectId(projectId),
|
|
354
|
+
...rest
|
|
310
355
|
});
|
|
311
356
|
}
|
|
312
|
-
listSubtasks(taskId) {
|
|
357
|
+
listSubtasks(taskId, projectId) {
|
|
313
358
|
return this.call("listProjectSubtasks", {
|
|
314
|
-
projectId: this.
|
|
359
|
+
projectId: this.resolveProjectId(projectId),
|
|
315
360
|
taskId
|
|
316
361
|
});
|
|
317
362
|
}
|
|
318
|
-
deleteSubtask(subtaskId) {
|
|
363
|
+
deleteSubtask(subtaskId, projectId) {
|
|
319
364
|
return this.call("deleteProjectSubtask", {
|
|
320
|
-
projectId: this.
|
|
365
|
+
projectId: this.resolveProjectId(projectId),
|
|
321
366
|
subtaskId
|
|
322
367
|
});
|
|
323
368
|
}
|
|
324
369
|
// ── Dependencies ────────────────────────────────────────────────────
|
|
325
|
-
getDependencies(taskId) {
|
|
370
|
+
getDependencies(taskId, projectId) {
|
|
326
371
|
return this.call("getProjectTaskDependencies", {
|
|
327
|
-
projectId: this.
|
|
372
|
+
projectId: this.resolveProjectId(projectId),
|
|
328
373
|
taskId
|
|
329
374
|
});
|
|
330
375
|
}
|
|
331
376
|
addDependency(params) {
|
|
377
|
+
const { projectId, ...rest } = params;
|
|
332
378
|
return this.call("addProjectTaskDependency", {
|
|
333
|
-
projectId: this.
|
|
334
|
-
...
|
|
379
|
+
projectId: this.resolveProjectId(projectId),
|
|
380
|
+
...rest
|
|
335
381
|
});
|
|
336
382
|
}
|
|
337
383
|
removeDependency(params) {
|
|
384
|
+
const { projectId, ...rest } = params;
|
|
338
385
|
return this.call("removeProjectTaskDependency", {
|
|
339
|
-
projectId: this.
|
|
340
|
-
...
|
|
386
|
+
projectId: this.resolveProjectId(projectId),
|
|
387
|
+
...rest
|
|
341
388
|
});
|
|
342
389
|
}
|
|
343
390
|
// ── Manual Test Checklist ───────────────────────────────────────────
|
|
344
|
-
listManualTests(taskId) {
|
|
391
|
+
listManualTests(taskId, projectId) {
|
|
345
392
|
return this.call("listProjectManualTests", {
|
|
346
|
-
projectId: this.
|
|
393
|
+
projectId: this.resolveProjectId(projectId),
|
|
347
394
|
taskId
|
|
348
395
|
});
|
|
349
396
|
}
|
|
350
|
-
setManualTests(taskId, items) {
|
|
397
|
+
setManualTests(taskId, items, projectId) {
|
|
351
398
|
return this.call("setProjectManualTests", {
|
|
352
|
-
projectId: this.
|
|
399
|
+
projectId: this.resolveProjectId(projectId),
|
|
353
400
|
taskId,
|
|
354
401
|
items
|
|
355
402
|
});
|
|
356
403
|
}
|
|
357
404
|
// ── Suggestions ─────────────────────────────────────────────────────
|
|
358
405
|
createSuggestion(params) {
|
|
406
|
+
const { projectId, ...rest } = params;
|
|
359
407
|
return this.call("createProjectSuggestion", {
|
|
360
|
-
projectId: this.
|
|
361
|
-
...
|
|
408
|
+
projectId: this.resolveProjectId(projectId),
|
|
409
|
+
...rest
|
|
362
410
|
});
|
|
363
411
|
}
|
|
364
412
|
// ── PTY Tunnel Relay (reuses the S2 pty:* envelope) ─────────────────
|
|
@@ -413,4 +461,4 @@ var ConveyorConnection = class {
|
|
|
413
461
|
export {
|
|
414
462
|
ConveyorConnection
|
|
415
463
|
};
|
|
416
|
-
//# sourceMappingURL=chunk-
|
|
464
|
+
//# sourceMappingURL=chunk-Z566YAS7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/connection.ts"],"sourcesContent":["/* oxlint-disable max-lines -- central MCP socket client; split after service-call helpers are extracted */\nimport { 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\nexport interface WorkspaceAttachInfo {\n taskId: string;\n sessionId: string;\n workspaceRoot: string;\n tunnelUrl: string;\n attachToken: string;\n expiresAt: string;\n previewPorts: Array<{ port: number; label: string }>;\n previewUrls: Record<string, string>;\n ssh?: {\n remotePort: number;\n preferredLocalPort: number;\n username: string;\n };\n}\n\ntype SocketCallback = (response: { success: boolean; data?: unknown; error?: string }) => void;\n\nconst NO_PROJECT_SELECTED_MESSAGE =\n \"No Conveyor project selected. Pass projectId to this tool or configure CONVEYOR_PROJECT_ID.\";\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.resolveProjectId();\n }\n\n private resolveProjectId(projectId?: string): string {\n const resolved = projectId ?? this.config.projectId;\n if (!resolved) throw new Error(NO_PROJECT_SELECTED_MESSAGE);\n return resolved;\n }\n\n private normalizeProjectList(response: unknown): unknown[] {\n if (Array.isArray(response)) return response;\n if (typeof response !== \"object\" || response === null) return [];\n const record = response as Record<string, unknown>;\n if (Array.isArray(record.items)) return record.items;\n if (Array.isArray(record.projects)) return record.projects;\n if (Array.isArray(record.data)) return record.data;\n return [];\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_USER_TOKEN ` +\n `(or legacy 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, timeoutMs = 15_000): Promise<T> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n\n const TIMEOUT_MS = timeoutMs;\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 private callService<T>(\n serviceName: string,\n method: string,\n data: unknown,\n timeoutMs = 15_000,\n ): Promise<T> {\n const socket = this.socket;\n if (!socket) throw new Error(\"Not connected\");\n return Promise.race([\n new Promise<T>((resolve, reject) => {\n socket.emit(`${serviceName}:${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: ${serviceName}:${method}`));\n }, timeoutMs);\n }),\n ]);\n }\n\n // ── Task Queries ────────────────────────────────────────────────────\n\n listTasks(params: {\n projectId?: string;\n status?: string;\n assigneeId?: string;\n unassigned?: boolean;\n limit?: number;\n }): Promise<unknown[]> {\n const { projectId, ...rest } = params;\n return this.call(\"listProjectTasks\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n getTask(taskId: string, projectId?: string): Promise<unknown> {\n return this.call(\"getProjectTask\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n getCardBySlug(slug: string, projectId?: string): Promise<unknown> {\n return this.call(\"getProjectTask\", {\n projectId: this.resolveProjectId(projectId),\n taskId: slug,\n });\n }\n\n searchTasks(params: {\n projectId?: string;\n tagNames?: string[];\n searchQuery?: string;\n statusFilters?: string[];\n assigneeId?: string;\n unassigned?: boolean;\n limit?: number;\n }): Promise<unknown[]> {\n const { projectId, ...rest } = params;\n return this.call(\"searchProjectTasks\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n // ── Task Mutations ──────────────────────────────────────────────────\n\n createTask(params: {\n projectId?: string;\n title: string;\n description?: string;\n plan?: string;\n status?: string;\n }): Promise<{ id: string; slug: string }> {\n const { projectId, ...rest } = params;\n return this.call(\"createProjectTask\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n updateTask(params: {\n projectId?: string;\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 const { projectId, ...rest } = params;\n return this.call(\"updateProjectTask\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n // ── Reviewers & Members ─────────────────────────────────────────────\n\n addReviewer(params: {\n projectId?: string;\n taskId: string;\n userId: string;\n }): Promise<{ taskId: string; reviewers: Array<{ userId: string; name: string | null }> }> {\n const { projectId, ...rest } = params;\n return this.call(\"addProjectTaskReviewer\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n removeReviewer(params: {\n projectId?: string;\n taskId: string;\n userId: string;\n }): Promise<{ taskId: string; reviewers: Array<{ userId: string; name: string | null }> }> {\n const { projectId, ...rest } = params;\n return this.call(\"removeProjectTaskReviewer\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n listProjectMembers(\n projectId?: string,\n ): Promise<Array<{ userId: string; name: string | null; email: string; level: string }>> {\n return this.call(\"listProjectMembers\", {\n projectId: this.resolveProjectId(projectId),\n });\n }\n\n async listProjects(): Promise<unknown[]> {\n const response = await this.call(\"listAccessibleProjects\", { pageSize: 100 });\n return this.normalizeProjectList(response);\n }\n\n // ── Build Management ────────────────────────────────────────────────\n\n startBuild(taskId: string, projectId?: string): Promise<{ taskId: string; status: string }> {\n return this.call(\"startProjectBuild\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n stopBuild(taskId: string, projectId?: string): Promise<{ taskId: string; stopped: boolean }> {\n return this.call(\"stopProjectBuild\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n getBuildStatus(\n taskId: string,\n projectId?: string,\n ): 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.resolveProjectId(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 getWorkspaceAttachInfo(taskId: string, sshPublicKey?: string): Promise<WorkspaceAttachInfo> {\n return this.callService(\"cloudBuildService\", \"getWorkspaceAttachInfo\", {\n taskId,\n sshPublicKey,\n });\n }\n\n // ── Chat ────────────────────────────────────────────────────────────\n\n getTaskChat(taskId: string, limit?: number, projectId?: string): Promise<unknown[]> {\n // Uses getProjectTask and extracts chatMessages\n return this.call<Record<string, unknown>>(\"getProjectTask\", {\n projectId: this.resolveProjectId(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(\n taskId: string,\n content: string,\n projectId?: string,\n ): Promise<{ messageId: string }> {\n return this.call(\"postToProjectTaskChat\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n content,\n });\n }\n\n // ── CLI History ─────────────────────────────────────────────────────\n\n getTaskCli(\n taskId: string,\n limit?: number,\n source?: string,\n projectId?: string,\n ): Promise<{ type: string; data: Record<string, unknown>; timestamp: string }[]> {\n return this.call(\"getProjectTaskCli\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n limit,\n source,\n });\n }\n\n // ── Project Info ────────────────────────────────────────────────────\n\n listTags(projectId?: string): Promise<{ id: string; name: string; color: string }[]> {\n return this.call(\"listProjectTags\", {\n projectId: this.resolveProjectId(projectId),\n });\n }\n\n getProjectSummary(projectId?: string): Promise<unknown> {\n return this.call(\"getProjectSummary\", {\n projectId: this.resolveProjectId(projectId),\n });\n }\n\n // ── Review Flow ─────────────────────────────────────────────────────\n\n async approveTask(taskId: string, projectId?: string): Promise<{ status: string }> {\n const targetProjectId = this.resolveProjectId(projectId);\n // Determine next status based on current status\n const task = (await this.call(\"getProjectTask\", {\n projectId: targetProjectId,\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({\n projectId: targetProjectId,\n taskId,\n status: nextStatus,\n });\n return { status: result.status };\n }\n\n async requestChanges(taskId: string, feedback: string, projectId?: string): Promise<void> {\n const targetProjectId = this.resolveProjectId(projectId);\n // Post feedback to task chat then move to InProgress\n await this.postToTaskChat(taskId, feedback, targetProjectId);\n await this.updateTask({ projectId: targetProjectId, taskId, status: \"InProgress\" });\n }\n\n approveAndMergePR(\n childTaskId: string,\n projectId?: string,\n ): Promise<{ merged: boolean; childTaskId: string; prNumber: number }> {\n return this.call(\"approveProjectMergePR\", {\n projectId: this.resolveProjectId(projectId),\n childTaskId,\n });\n }\n\n // ── File Attachments ────────────────────────────────────────────────\n\n listTaskFiles(taskId: string, projectId?: string): Promise<unknown[]> {\n return this.call(\"listProjectTaskFiles\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n getAttachment(\n taskId: string,\n fileId: string,\n opts?: { offset?: number; maxBytes?: number; projectId?: string },\n ): Promise<unknown> {\n const payload: Record<string, unknown> = {\n projectId: this.resolveProjectId(opts?.projectId),\n taskId,\n fileId,\n };\n if (opts?.offset !== undefined) payload.offset = opts.offset;\n if (opts?.maxBytes !== undefined) payload.maxBytes = opts.maxBytes;\n return this.call(\"getProjectAttachment\", payload);\n }\n\n requestFileUpload(\n taskId: string,\n params: { fileName: string; mimeType: string; fileSize: number; projectId?: string },\n ): Promise<{ fileId: string; uploadUrl: string }> {\n const { projectId, ...rest } = params;\n return this.call(\"requestProjectFileUpload\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n ...rest,\n });\n }\n\n confirmFileUpload(\n taskId: string,\n fileId: string,\n comment?: string,\n projectId?: string,\n ): Promise<{ fileId: string; fileName: string; downloadUrl?: string; messageId?: string }> {\n const payload: Record<string, unknown> = {\n projectId: this.resolveProjectId(projectId),\n taskId,\n fileId,\n };\n if (comment !== undefined) payload.comment = comment;\n // Confirm verifies the object in GCS before marking it uploaded — allow\n // extra headroom for the storage round-trips.\n return this.call(\"confirmProjectFileUpload\", payload, 30_000);\n }\n\n // ── Releases ────────────────────────────────────────────────────────\n\n createRelease(\n taskIds?: string[],\n projectId?: string,\n ): Promise<{ taskId: string; version: string }> {\n // Full releases create the release branch + PR against GitHub synchronously;\n // allow the same headroom as createPullRequest.\n return this.call(\n \"createProjectRelease\",\n { projectId: this.resolveProjectId(projectId), taskIds },\n 45_000,\n );\n }\n\n // ── Pull Requests ───────────────────────────────────────────────────\n\n createPullRequest(params: {\n projectId?: string;\n taskId: string;\n title: string;\n body: string;\n head?: string;\n base?: string;\n }): Promise<{ prNumber: number; prUrl: string }> {\n const { projectId, ...rest } = params;\n // PR creation makes several sequential GitHub API calls (token, create,\n // existing-PR lookup); allow more headroom than the default request timeout.\n return this.call(\n \"createProjectPullRequest\",\n { projectId: this.resolveProjectId(projectId), ...rest },\n 45_000,\n );\n }\n\n // ── Subtasks ────────────────────────────────────────────────────────\n\n createSubtask(params: {\n projectId?: string;\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 const { projectId, ...rest } = params;\n return this.call(\"createProjectSubtask\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n updateSubtask(params: {\n projectId?: string;\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 const { projectId, ...rest } = params;\n return this.call(\"updateProjectSubtask\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n listSubtasks(taskId: string, projectId?: string): Promise<unknown[]> {\n return this.call(\"listProjectSubtasks\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n deleteSubtask(subtaskId: string, projectId?: string): Promise<{ deleted: boolean }> {\n return this.call(\"deleteProjectSubtask\", {\n projectId: this.resolveProjectId(projectId),\n subtaskId,\n });\n }\n\n // ── Dependencies ────────────────────────────────────────────────────\n\n getDependencies(taskId: string, projectId?: string): Promise<unknown[]> {\n return this.call(\"getProjectTaskDependencies\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n addDependency(params: {\n projectId?: string;\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n const { projectId, ...rest } = params;\n return this.call(\"addProjectTaskDependency\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n removeDependency(params: {\n projectId?: string;\n taskId: string;\n dependsOnSlugOrId: string;\n }): Promise<{ success: boolean }> {\n const { projectId, ...rest } = params;\n return this.call(\"removeProjectTaskDependency\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\n });\n }\n\n // ── Manual Test Checklist ───────────────────────────────────────────\n\n listManualTests(\n taskId: string,\n projectId?: string,\n ): Promise<\n Array<{\n id: string;\n type: string;\n title: string;\n ordinal: number;\n createdAt: string;\n checked: boolean;\n }>\n > {\n return this.call(\"listProjectManualTests\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n });\n }\n\n setManualTests(\n taskId: string,\n items: Array<{ title: string }>,\n projectId?: string,\n ): Promise<{ created: number; skipped: number }> {\n return this.call(\"setProjectManualTests\", {\n projectId: this.resolveProjectId(projectId),\n taskId,\n items,\n });\n }\n\n // ── Suggestions ─────────────────────────────────────────────────────\n\n createSuggestion(params: {\n projectId?: string;\n title: string;\n description?: string;\n tagNames?: string[];\n }): Promise<{ id: string; merged: boolean; mergedIntoId?: string }> {\n const { projectId, ...rest } = params;\n return this.call(\"createProjectSuggestion\", {\n projectId: this.resolveProjectId(projectId),\n ...rest,\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":[]}
|