@rallycry/conveyor-mcp 5.0.3 → 5.0.5
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/README.md +6 -0
- package/dist/chunk-5KU3QS6A.js +45 -0
- package/dist/{chunk-XLDG5QEX.js → chunk-77XLXIFP.js} +78 -3
- package/dist/cli.js +592 -125
- package/dist/{connection-B7CwszOV.d.ts → connection-DclP31lm.d.ts} +42 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/tunnel-cli.js +5 -3
- package/dist/tunnel.d.ts +2 -1
- package/dist/wait-cli.js +5 -3
- package/dist/wait-runner.d.ts +2 -1
- package/dist/wait.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,12 @@ CONVEYOR_PROJECT_ID = "<project-id>"
|
|
|
76
76
|
| `CONVEYOR_PROJECT_ID` | no | Default project for unqualified tools. Omit it for multi-project mode. |
|
|
77
77
|
| `CONVEYOR_SUBPROJECT_ID` | no | Default board. Unqualified `create_task`/`list_tasks`/`search_tasks` target it. |
|
|
78
78
|
|
|
79
|
+
## How the server exits
|
|
80
|
+
|
|
81
|
+
The server's lifetime is its stdin pipe. It exits when stdin reaches EOF, on
|
|
82
|
+
`SIGINT` or `SIGTERM`, and when its parent process changes — so a client that
|
|
83
|
+
force-quits, crashes, or is torn down never leaves a server behind.
|
|
84
|
+
|
|
79
85
|
## Why `npx -y …@latest`
|
|
80
86
|
|
|
81
87
|
Every form above launches the server through
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// src/lifecycle.ts
|
|
2
|
+
function watchForClientExit(onExit, deps = {}) {
|
|
3
|
+
const stdin = deps.stdin ?? process.stdin;
|
|
4
|
+
const signals = deps.signals ?? process;
|
|
5
|
+
const getPpid = deps.getPpid ?? (() => process.ppid);
|
|
6
|
+
const intervalMs = deps.intervalMs ?? 3e4;
|
|
7
|
+
const watchStdin = deps.watchStdin ?? true;
|
|
8
|
+
let fired = false;
|
|
9
|
+
const fire = () => {
|
|
10
|
+
if (fired) return;
|
|
11
|
+
fired = true;
|
|
12
|
+
onExit();
|
|
13
|
+
};
|
|
14
|
+
signals.on("SIGINT", fire);
|
|
15
|
+
signals.on("SIGTERM", fire);
|
|
16
|
+
signals.on("SIGHUP", fire);
|
|
17
|
+
if (watchStdin && stdin.isTTY !== true) {
|
|
18
|
+
if (deps.resumeStdin) stdin.resume?.();
|
|
19
|
+
stdin.on("end", fire);
|
|
20
|
+
stdin.on("close", fire);
|
|
21
|
+
}
|
|
22
|
+
const initialPpid = getPpid();
|
|
23
|
+
const orphanCheck = setInterval(() => {
|
|
24
|
+
if (getPpid() !== initialPpid) fire();
|
|
25
|
+
}, intervalMs);
|
|
26
|
+
orphanCheck.unref?.();
|
|
27
|
+
return fire;
|
|
28
|
+
}
|
|
29
|
+
function installLifecycle(conn, deps = {}) {
|
|
30
|
+
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
31
|
+
let stopping = false;
|
|
32
|
+
function stop(code = 0) {
|
|
33
|
+
if (stopping) return;
|
|
34
|
+
stopping = true;
|
|
35
|
+
conn.disconnect();
|
|
36
|
+
exit(code);
|
|
37
|
+
}
|
|
38
|
+
watchForClientExit(() => stop(), deps);
|
|
39
|
+
return stop;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
watchForClientExit,
|
|
44
|
+
installLifecycle
|
|
45
|
+
};
|
|
@@ -49,10 +49,14 @@ function enrichToolError(error, fallback) {
|
|
|
49
49
|
var ConveyorConnection = class {
|
|
50
50
|
socket = null;
|
|
51
51
|
config;
|
|
52
|
+
socketFactory;
|
|
52
53
|
/** project slug → id, for resolving `<project>/<card>` card paths. */
|
|
53
54
|
projectSlugIds = /* @__PURE__ */ new Map();
|
|
54
|
-
|
|
55
|
+
/** Session rooms this connection has joined, replayed after every reconnect. */
|
|
56
|
+
subscribedSessionIds = /* @__PURE__ */ new Set();
|
|
57
|
+
constructor(config, socketFactory = io) {
|
|
55
58
|
this.config = config;
|
|
59
|
+
this.socketFactory = socketFactory;
|
|
56
60
|
}
|
|
57
61
|
get projectId() {
|
|
58
62
|
return this.resolveProjectId();
|
|
@@ -86,12 +90,32 @@ var ConveyorConnection = class {
|
|
|
86
90
|
if (Array.isArray(record.data)) return record.data;
|
|
87
91
|
return [];
|
|
88
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Re-join every room this connection needs.
|
|
95
|
+
*
|
|
96
|
+
* Runs on the FIRST connect and on every reconnect. A socket.io reconnect
|
|
97
|
+
* starts a fresh server-side socket that belongs to no rooms, and Cloud Run
|
|
98
|
+
* cuts each websocket at its 60-minute request limit, so a subscribe sent
|
|
99
|
+
* only once left long-lived MCP connections silently outside the project room
|
|
100
|
+
* for the rest of the day.
|
|
101
|
+
*/
|
|
102
|
+
rejoinRooms() {
|
|
103
|
+
const socket = this.socket;
|
|
104
|
+
if (!socket) return;
|
|
105
|
+
socket.emit("projectService:subscribe", { id: this.config.projectId });
|
|
106
|
+
for (const sessionId of this.subscribedSessionIds) {
|
|
107
|
+
socket.emit("agentSessionService:subscribe", {
|
|
108
|
+
entryId: sessionId,
|
|
109
|
+
requiredLevel: "Read"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
89
113
|
connect() {
|
|
90
114
|
return new Promise((resolve, reject) => {
|
|
91
115
|
let settled = false;
|
|
92
116
|
let attempts = 0;
|
|
93
117
|
const maxAttempts = 15;
|
|
94
|
-
this.socket =
|
|
118
|
+
this.socket = this.socketFactory(
|
|
95
119
|
this.config.apiUrl,
|
|
96
120
|
buildConveyorSocketOptions({
|
|
97
121
|
projectToken: this.config.projectToken,
|
|
@@ -99,12 +123,15 @@ var ConveyorConnection = class {
|
|
|
99
123
|
})
|
|
100
124
|
);
|
|
101
125
|
this.socket.on("connect", () => {
|
|
126
|
+
this.rejoinRooms();
|
|
102
127
|
if (!settled) {
|
|
103
128
|
settled = true;
|
|
104
|
-
this.socket?.emit("projectService:subscribe", { id: this.config.projectId });
|
|
105
129
|
resolve();
|
|
106
130
|
}
|
|
107
131
|
});
|
|
132
|
+
this.socket.on("disconnect", (reason) => {
|
|
133
|
+
if (reason === "io server disconnect") this.socket?.connect();
|
|
134
|
+
});
|
|
108
135
|
this.socket.on("connect_error", (err) => {
|
|
109
136
|
const message = err?.message ?? "unknown error";
|
|
110
137
|
if (!settled && AUTH_ERROR_RE.test(message)) {
|
|
@@ -547,6 +574,52 @@ var ConveyorConnection = class {
|
|
|
547
574
|
...rest
|
|
548
575
|
});
|
|
549
576
|
}
|
|
577
|
+
// ── Decisions ───────────────────────────────────────────────────────
|
|
578
|
+
//
|
|
579
|
+
// Every method resolves the project the same way the rest of the surface
|
|
580
|
+
// does, so a caller with a configured default never has to pass one.
|
|
581
|
+
createDecision(params) {
|
|
582
|
+
const { projectId, ...rest } = params;
|
|
583
|
+
return this.call("createProjectDecision", {
|
|
584
|
+
projectId: this.resolveProjectId(projectId),
|
|
585
|
+
...rest
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
listDecisions(params) {
|
|
589
|
+
const { projectId, ...rest } = params;
|
|
590
|
+
return this.call("listProjectDecisions", {
|
|
591
|
+
projectId: this.resolveProjectId(projectId),
|
|
592
|
+
...rest
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
getDecision(params) {
|
|
596
|
+
const { projectId, ...rest } = params;
|
|
597
|
+
return this.call("getProjectDecision", {
|
|
598
|
+
projectId: this.resolveProjectId(projectId),
|
|
599
|
+
...rest
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
voteDecision(params) {
|
|
603
|
+
const { projectId, ...rest } = params;
|
|
604
|
+
return this.call("voteProjectDecision", {
|
|
605
|
+
projectId: this.resolveProjectId(projectId),
|
|
606
|
+
...rest
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
resolveDecision(params) {
|
|
610
|
+
const { projectId, ...rest } = params;
|
|
611
|
+
return this.call("resolveProjectDecision", {
|
|
612
|
+
projectId: this.resolveProjectId(projectId),
|
|
613
|
+
...rest
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
updateDecision(params) {
|
|
617
|
+
const { projectId, ...rest } = params;
|
|
618
|
+
return this.call("updateProjectDecision", {
|
|
619
|
+
projectId: this.resolveProjectId(projectId),
|
|
620
|
+
...rest
|
|
621
|
+
});
|
|
622
|
+
}
|
|
550
623
|
// ── Meetings ────────────────────────────────────────────────────────
|
|
551
624
|
listMeetings(params) {
|
|
552
625
|
const { projectId, ...rest } = params;
|
|
@@ -943,6 +1016,7 @@ var ConveyorConnection = class {
|
|
|
943
1016
|
subscribeToSession(sessionId) {
|
|
944
1017
|
const socket = this.socket;
|
|
945
1018
|
if (!socket) throw new Error("Not connected");
|
|
1019
|
+
this.subscribedSessionIds.add(sessionId);
|
|
946
1020
|
socket.emit("agentSessionService:subscribe", {
|
|
947
1021
|
entryId: sessionId,
|
|
948
1022
|
requiredLevel: "Read"
|
|
@@ -1013,6 +1087,7 @@ var ConveyorConnection = class {
|
|
|
1013
1087
|
disconnect() {
|
|
1014
1088
|
this.socket?.disconnect();
|
|
1015
1089
|
this.socket = null;
|
|
1090
|
+
this.subscribedSessionIds.clear();
|
|
1016
1091
|
}
|
|
1017
1092
|
};
|
|
1018
1093
|
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
installLifecycle
|
|
4
|
+
} from "./chunk-5KU3QS6A.js";
|
|
2
5
|
import {
|
|
3
6
|
ConveyorConnection
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-77XLXIFP.js";
|
|
5
8
|
|
|
6
9
|
// src/cli.ts
|
|
7
10
|
import { createRequire } from "module";
|
|
@@ -69,7 +72,7 @@ function registerProjectTools(server2, conn2) {
|
|
|
69
72
|
// src/tools/connection.ts
|
|
70
73
|
import { z as z4 } from "zod";
|
|
71
74
|
|
|
72
|
-
// ../shared/dist/chunk-
|
|
75
|
+
// ../shared/dist/chunk-6NPOGQPP.js
|
|
73
76
|
import { z as z2 } from "zod";
|
|
74
77
|
var DEFAULT_SONNET_MODEL = "claude-sonnet-5";
|
|
75
78
|
var DEFAULT_OPUS_MODEL = "claude-opus-5";
|
|
@@ -303,14 +306,14 @@ var f = {
|
|
|
303
306
|
return { kind: "nullable", inner };
|
|
304
307
|
}
|
|
305
308
|
};
|
|
306
|
-
function compileString(
|
|
307
|
-
let schema =
|
|
309
|
+
function compileString(z13, spec) {
|
|
310
|
+
let schema = z13.string();
|
|
308
311
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
309
312
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
310
313
|
return schema;
|
|
311
314
|
}
|
|
312
|
-
function compileNumber(
|
|
313
|
-
let schema =
|
|
315
|
+
function compileNumber(z13, spec) {
|
|
316
|
+
let schema = z13.number();
|
|
314
317
|
if (spec.int) schema = schema.int();
|
|
315
318
|
if (spec.positive) schema = schema.positive();
|
|
316
319
|
if (spec.nonnegative) schema = schema.nonnegative();
|
|
@@ -318,49 +321,49 @@ function compileNumber(z11, spec) {
|
|
|
318
321
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
319
322
|
return schema;
|
|
320
323
|
}
|
|
321
|
-
function compileArray(
|
|
322
|
-
let schema =
|
|
324
|
+
function compileArray(z13, spec) {
|
|
325
|
+
let schema = z13.array(compileField(z13, spec.item));
|
|
323
326
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
324
327
|
return schema;
|
|
325
328
|
}
|
|
326
|
-
function compileBase(
|
|
329
|
+
function compileBase(z13, spec) {
|
|
327
330
|
switch (spec.kind) {
|
|
328
331
|
case "string":
|
|
329
|
-
return compileString(
|
|
332
|
+
return compileString(z13, spec);
|
|
330
333
|
case "number":
|
|
331
|
-
return compileNumber(
|
|
334
|
+
return compileNumber(z13, spec);
|
|
332
335
|
case "boolean":
|
|
333
|
-
return
|
|
336
|
+
return z13.boolean();
|
|
334
337
|
case "enum":
|
|
335
|
-
return
|
|
338
|
+
return z13.enum([...spec.values]);
|
|
336
339
|
case "array":
|
|
337
|
-
return compileArray(
|
|
340
|
+
return compileArray(z13, spec);
|
|
338
341
|
case "object":
|
|
339
|
-
return
|
|
342
|
+
return z13.object(compileShape(z13, spec.fields));
|
|
340
343
|
}
|
|
341
344
|
}
|
|
342
345
|
function descriptionOf(spec) {
|
|
343
346
|
if (spec.kind === "optional" || spec.kind === "nullable") return descriptionOf(spec.inner);
|
|
344
347
|
return spec.desc;
|
|
345
348
|
}
|
|
346
|
-
function compileUndescribed(
|
|
349
|
+
function compileUndescribed(z13, spec) {
|
|
347
350
|
if (spec.kind === "optional") {
|
|
348
|
-
return compileUndescribed(
|
|
351
|
+
return compileUndescribed(z13, spec.inner).optional();
|
|
349
352
|
}
|
|
350
353
|
if (spec.kind === "nullable") {
|
|
351
|
-
return compileUndescribed(
|
|
354
|
+
return compileUndescribed(z13, spec.inner).nullable();
|
|
352
355
|
}
|
|
353
|
-
return compileBase(
|
|
356
|
+
return compileBase(z13, spec);
|
|
354
357
|
}
|
|
355
|
-
function compileField(
|
|
356
|
-
const schema = compileUndescribed(
|
|
358
|
+
function compileField(z13, spec) {
|
|
359
|
+
const schema = compileUndescribed(z13, spec);
|
|
357
360
|
const desc = descriptionOf(spec);
|
|
358
361
|
return desc === void 0 ? schema : schema.describe(desc);
|
|
359
362
|
}
|
|
360
|
-
function compileShape(
|
|
363
|
+
function compileShape(z13, fields) {
|
|
361
364
|
const shape = {};
|
|
362
365
|
for (const [key, spec] of Object.entries(fields)) {
|
|
363
|
-
shape[key] = compileField(
|
|
366
|
+
shape[key] = compileField(z13, spec);
|
|
364
367
|
}
|
|
365
368
|
return shape;
|
|
366
369
|
}
|
|
@@ -473,7 +476,7 @@ var SEARCH_STATUSES = [
|
|
|
473
476
|
"Complete",
|
|
474
477
|
"Cancelled"
|
|
475
478
|
];
|
|
476
|
-
var SEARCH_CARD_TYPES = ["task", "incident", "suggestion"];
|
|
479
|
+
var SEARCH_CARD_TYPES = ["task", "incident", "suggestion", "decision"];
|
|
477
480
|
var searchFilterFields = {
|
|
478
481
|
tagNames: f.optional(
|
|
479
482
|
f.array(f.string(), {
|
|
@@ -1166,6 +1169,235 @@ var createSuggestionContract = defineToolContract({
|
|
|
1166
1169
|
}
|
|
1167
1170
|
});
|
|
1168
1171
|
var suggestionsContracts = [createSuggestionContract];
|
|
1172
|
+
var OPTION_KINDS = ["current", "planned", "proposed"];
|
|
1173
|
+
var STATUS_LABELS = ["Open", "Decided", "Cancelled"];
|
|
1174
|
+
var optionDescription = "What this option means in the product, written as GIVEN / WHEN / THEN. Concrete enough that a reader six months from now can tell which behaviour was chosen.";
|
|
1175
|
+
var optionsDesc = "Two or three options. More than three means the question is not framed yet \u2014 narrow it or split it. Mark the option describing what the code does today as kind: current.";
|
|
1176
|
+
var defaultOptionDesc = "1-based position of the option that wins if nobody decides by the deadline. Required: silence has to become a decision, never a stall.";
|
|
1177
|
+
var agentOption = f.object(
|
|
1178
|
+
{
|
|
1179
|
+
label: f.string({ min: 1, desc: "Short name for the option, under 80 characters" }),
|
|
1180
|
+
description: f.string({ min: 1, desc: optionDescription }),
|
|
1181
|
+
kind: f.optional(
|
|
1182
|
+
f.enum(OPTION_KINDS, {
|
|
1183
|
+
desc: 'current = what the code does today, planned = already agreed but unbuilt, proposed = new. Defaults to "proposed".'
|
|
1184
|
+
})
|
|
1185
|
+
)
|
|
1186
|
+
},
|
|
1187
|
+
{ desc: "One option people can choose" }
|
|
1188
|
+
);
|
|
1189
|
+
var createDecisionContract = defineToolContract({
|
|
1190
|
+
name: "create_decision",
|
|
1191
|
+
agent: {
|
|
1192
|
+
description: `Raise a product decision: a fork the plan cannot be right without. Two or three options, one default, a deadline. Run list_decisions FIRST \u2014 an answered decision is the answer, and re-asking it wastes everybody's time. Do NOT file a decision for an assumption you can simply state: an assumed behaviour belongs in the plan as a GIVEN / WHEN / THEN line under "Assumed behaviours". Returns the decision's id, slug, and url.`,
|
|
1193
|
+
fields: {
|
|
1194
|
+
question: f.string({
|
|
1195
|
+
min: 1,
|
|
1196
|
+
desc: "The question, as one plain sentence ending in a question mark"
|
|
1197
|
+
}),
|
|
1198
|
+
summary: f.optional(
|
|
1199
|
+
f.string({
|
|
1200
|
+
desc: cardDescriptionDesc("One or two sentences of context for the card face")
|
|
1201
|
+
})
|
|
1202
|
+
),
|
|
1203
|
+
context: f.string({
|
|
1204
|
+
min: 1,
|
|
1205
|
+
desc: "Markdown background: why this is being asked now, and what breaks if it is answered wrongly"
|
|
1206
|
+
}),
|
|
1207
|
+
options: f.array(agentOption, { min: 2, desc: optionsDesc }),
|
|
1208
|
+
default_option: f.number({ int: true, min: 1, max: 3, desc: defaultOptionDesc }),
|
|
1209
|
+
deadline_hours: f.optional(
|
|
1210
|
+
f.number({ min: 1, max: 720, desc: "Hours until the default applies. Default 72." })
|
|
1211
|
+
),
|
|
1212
|
+
impacted_cards: f.optional(
|
|
1213
|
+
f.array(f.string(), {
|
|
1214
|
+
desc: "Slugs or ids of cards this decision blocks. They cannot start until it is settled, and they are un-blocked the moment it is. Blocking a card needs Moderate access: without it the decision is still raised and each ref comes back under refused."
|
|
1215
|
+
})
|
|
1216
|
+
),
|
|
1217
|
+
include_current_card: f.optional(
|
|
1218
|
+
f.boolean({
|
|
1219
|
+
desc: "Also block the card this session is working on. Defaults to true \u2014 you are raising this because your own plan is stuck on it. Pass false to raise the question without stopping your own work."
|
|
1220
|
+
})
|
|
1221
|
+
),
|
|
1222
|
+
tag_names: f.optional(
|
|
1223
|
+
f.array(f.string(), {
|
|
1224
|
+
desc: "Tag names. The settled decision is written into each tag's overview, which is how the next agent finds it."
|
|
1225
|
+
})
|
|
1226
|
+
),
|
|
1227
|
+
raised_by_pr: f.optional(
|
|
1228
|
+
f.number({ int: true, min: 1, desc: "PR number that surfaced the question" })
|
|
1229
|
+
)
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
mcp: {
|
|
1233
|
+
description: "Raise a product decision on a Conveyor project: a fork that has to be settled before the work can be planned correctly. Two or three options, one default that applies if nobody decides, and a deadline. Search list_decisions first \u2014 a Decided decision is the answer. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
1234
|
+
fields: {
|
|
1235
|
+
projectId: mcpProjectId,
|
|
1236
|
+
question: f.string({ desc: "The question, as one plain sentence" }),
|
|
1237
|
+
summary: f.optional(f.string({ desc: cardDescriptionDesc("Context for the card face") })),
|
|
1238
|
+
context: f.string({ desc: "Markdown background: why this is being asked now" }),
|
|
1239
|
+
options: f.array(agentOption, { min: 2, desc: optionsDesc }),
|
|
1240
|
+
defaultOption: f.number({ int: true, min: 1, max: 3, desc: defaultOptionDesc }),
|
|
1241
|
+
deadlineHours: f.optional(
|
|
1242
|
+
f.number({ min: 1, max: 720, desc: "Hours until the default applies. Default 72." })
|
|
1243
|
+
),
|
|
1244
|
+
impactedCards: f.optional(
|
|
1245
|
+
f.array(f.string(), {
|
|
1246
|
+
desc: "Slugs or ids of cards this decision blocks. Needs Moderate access; without it each ref comes back under refused and the decision is still raised."
|
|
1247
|
+
})
|
|
1248
|
+
),
|
|
1249
|
+
tagNames: f.optional(f.array(f.string(), { desc: "Tag names to categorize the decision" })),
|
|
1250
|
+
raisedByPr: f.optional(
|
|
1251
|
+
f.number({ int: true, min: 1, desc: "PR number that surfaced the question" })
|
|
1252
|
+
)
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
var listDecisionsContract = defineToolContract({
|
|
1257
|
+
name: "list_decisions",
|
|
1258
|
+
agent: {
|
|
1259
|
+
description: `Search this project's decisions. Run this BEFORE planning anything in an area: "have we already decided how X behaves?" Decided rows carry their resolution, so the list doubles as the decision log. Filter by card to see what is blocking a specific card.`,
|
|
1260
|
+
fields: {
|
|
1261
|
+
status: f.optional(
|
|
1262
|
+
f.enum(STATUS_LABELS, {
|
|
1263
|
+
desc: "Open = still being voted on, Decided = settled, Cancelled = dropped"
|
|
1264
|
+
})
|
|
1265
|
+
),
|
|
1266
|
+
tag: f.optional(f.string({ desc: 'Tag name, e.g. "slack"' })),
|
|
1267
|
+
card: f.optional(
|
|
1268
|
+
f.string({ desc: "Slug or id of a card \u2014 returns the decisions it is blocked by" })
|
|
1269
|
+
),
|
|
1270
|
+
query: f.optional(f.string({ desc: "Text search on the question" })),
|
|
1271
|
+
limit: f.optional(f.number({ desc: "Max rows to return (default 50, max 200)" }))
|
|
1272
|
+
}
|
|
1273
|
+
},
|
|
1274
|
+
mcp: {
|
|
1275
|
+
description: `List and search a Conveyor project's decisions. Decided rows include their resolution, so this is the fastest way to answer "did we already settle this?". Pass projectId to target a specific project; otherwise the configured default project is used.`,
|
|
1276
|
+
fields: {
|
|
1277
|
+
projectId: mcpProjectId,
|
|
1278
|
+
status: f.optional(f.enum(STATUS_LABELS, { desc: "Filter by state" })),
|
|
1279
|
+
tag: f.optional(f.string({ desc: "Tag name to filter by" })),
|
|
1280
|
+
card: f.optional(f.string({ desc: "Card slug or id \u2014 decisions blocking that card" })),
|
|
1281
|
+
query: f.optional(f.string({ desc: "Text search on the question" })),
|
|
1282
|
+
limit: f.optional(
|
|
1283
|
+
f.number({ int: true, min: 1, max: 200, desc: "Max rows to return (default 50)" })
|
|
1284
|
+
)
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
var getDecisionContract = defineToolContract({
|
|
1289
|
+
name: "get_decision",
|
|
1290
|
+
agent: {
|
|
1291
|
+
description: "Read one decision in full: its context, every option with its GIVEN / WHEN / THEN, every vote with who cast it and why, the running tally, the cards it blocks, and the resolution once there is one. Use read_task_chat with the same id for the discussion thread.",
|
|
1292
|
+
fields: {
|
|
1293
|
+
decision: f.string({ min: 1, desc: "Decision slug or id" })
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
mcp: {
|
|
1297
|
+
description: "Read one Conveyor decision in full \u2014 context, options, votes with reasons, tally, impacted cards, and the resolution. Pass projectId to disambiguate a slug; otherwise the configured default project is used.",
|
|
1298
|
+
fields: {
|
|
1299
|
+
projectId: mcpProjectId,
|
|
1300
|
+
decision: f.string({ desc: "Decision slug or id" })
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
var voteDecisionContract = defineToolContract({
|
|
1305
|
+
name: "vote_decision",
|
|
1306
|
+
agent: {
|
|
1307
|
+
description: "Vote on an open decision. One vote per voter: voting again replaces your previous one. Always give a reason \u2014 the resolution weighs reasons over counts, and a vote with no reason carries almost nothing.",
|
|
1308
|
+
fields: {
|
|
1309
|
+
decision: f.string({ min: 1, desc: "Decision slug or id" }),
|
|
1310
|
+
option: f.string({ min: 1, desc: "Option id, or its 1-based position" }),
|
|
1311
|
+
reason: f.optional(
|
|
1312
|
+
f.string({ desc: "Why this option, in one or two sentences (max 255 characters)" })
|
|
1313
|
+
)
|
|
1314
|
+
}
|
|
1315
|
+
},
|
|
1316
|
+
mcp: {
|
|
1317
|
+
description: "Vote on an open Conveyor decision, with a reason. One vote per voter \u2014 voting again replaces the previous one.",
|
|
1318
|
+
fields: {
|
|
1319
|
+
projectId: mcpProjectId,
|
|
1320
|
+
decision: f.string({ desc: "Decision slug or id" }),
|
|
1321
|
+
option: f.string({ desc: "Option id, or its 1-based position" }),
|
|
1322
|
+
reason: f.optional(f.string({ desc: "Why this option (max 255 characters)" }))
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
});
|
|
1326
|
+
var resolveDecisionContract = defineToolContract({
|
|
1327
|
+
name: "resolve_decision",
|
|
1328
|
+
agent: {
|
|
1329
|
+
description: "Settle a decision. This is not a formality: the resolution is written into the plan of every card the decision blocked, into each of their chats, and into the overview of every tag it carries, and those cards become startable. Say what was decided in one or two sentences \u2014 a reader months later should not need to open the thread.",
|
|
1330
|
+
fields: {
|
|
1331
|
+
decision: f.string({ min: 1, desc: "Decision slug or id" }),
|
|
1332
|
+
option: f.string({ min: 1, desc: "Winning option id, or its 1-based position" }),
|
|
1333
|
+
resolution: f.string({
|
|
1334
|
+
min: 1,
|
|
1335
|
+
desc: "What was decided, in one or two plain sentences (max 255 characters)"
|
|
1336
|
+
}),
|
|
1337
|
+
notes: f.optional(
|
|
1338
|
+
f.string({ desc: "Markdown reasoning. Link any verdict attachment here." })
|
|
1339
|
+
)
|
|
1340
|
+
}
|
|
1341
|
+
},
|
|
1342
|
+
mcp: {
|
|
1343
|
+
description: "Settle a Conveyor decision. The resolution is written into every impacted card's plan and chat and into its tags' overviews, and the impacted cards become startable.",
|
|
1344
|
+
fields: {
|
|
1345
|
+
projectId: mcpProjectId,
|
|
1346
|
+
decision: f.string({ desc: "Decision slug or id" }),
|
|
1347
|
+
option: f.string({ desc: "Winning option id, or its 1-based position" }),
|
|
1348
|
+
resolution: f.string({ desc: "What was decided (max 255 characters)" }),
|
|
1349
|
+
notes: f.optional(f.string({ desc: "Markdown reasoning" }))
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
var updateDecisionContract = defineToolContract({
|
|
1354
|
+
name: "update_decision",
|
|
1355
|
+
agent: {
|
|
1356
|
+
description: "Change an open decision: extend its deadline, link or unlink the cards it blocks, or cancel it. Cancelling un-blocks the impacted cards without answering the question, so only do it when the question stopped mattering.",
|
|
1357
|
+
fields: {
|
|
1358
|
+
decision: f.string({ min: 1, desc: "Decision slug or id" }),
|
|
1359
|
+
deadline_hours: f.optional(f.number({ desc: "New deadline, in hours from now. 1 to 720." })),
|
|
1360
|
+
add_impacted_cards: f.optional(
|
|
1361
|
+
f.array(f.string(), { desc: "Slugs or ids of cards to block on this decision" })
|
|
1362
|
+
),
|
|
1363
|
+
remove_impacted_cards: f.optional(
|
|
1364
|
+
f.array(f.string(), { desc: "Ids of cards to stop blocking" })
|
|
1365
|
+
),
|
|
1366
|
+
status: f.optional(
|
|
1367
|
+
f.enum(["Cancelled", "Open"], {
|
|
1368
|
+
desc: "Cancelled drops the question; Open reopens a settled one and clears its answer"
|
|
1369
|
+
})
|
|
1370
|
+
)
|
|
1371
|
+
}
|
|
1372
|
+
},
|
|
1373
|
+
mcp: {
|
|
1374
|
+
description: "Change an open Conveyor decision: extend the deadline, link or unlink impacted cards, cancel it, or reopen a settled one.",
|
|
1375
|
+
fields: {
|
|
1376
|
+
projectId: mcpProjectId,
|
|
1377
|
+
decision: f.string({ desc: "Decision slug or id" }),
|
|
1378
|
+
deadlineHours: f.optional(
|
|
1379
|
+
f.number({ min: 1, max: 720, desc: "New deadline, in hours from now" })
|
|
1380
|
+
),
|
|
1381
|
+
addImpactedCards: f.optional(
|
|
1382
|
+
f.array(f.string(), { desc: "Slugs or ids of cards to block on this decision" })
|
|
1383
|
+
),
|
|
1384
|
+
removeImpactedCards: f.optional(
|
|
1385
|
+
f.array(f.string(), { desc: "Ids of cards to stop blocking" })
|
|
1386
|
+
),
|
|
1387
|
+
status: f.optional(
|
|
1388
|
+
f.enum(["Cancelled", "Open"], { desc: "Cancel it, or reopen a settled one" })
|
|
1389
|
+
)
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
var decisionsContracts = [
|
|
1394
|
+
createDecisionContract,
|
|
1395
|
+
listDecisionsContract,
|
|
1396
|
+
getDecisionContract,
|
|
1397
|
+
voteDecisionContract,
|
|
1398
|
+
resolveDecisionContract,
|
|
1399
|
+
updateDecisionContract
|
|
1400
|
+
];
|
|
1169
1401
|
var createPullRequestContract = defineToolContract({
|
|
1170
1402
|
name: "create_pull_request",
|
|
1171
1403
|
agent: {
|
|
@@ -1826,6 +2058,7 @@ var TOOL_CONTRACTS = Object.fromEntries(
|
|
|
1826
2058
|
...subtasksContracts,
|
|
1827
2059
|
...attachmentsContracts,
|
|
1828
2060
|
...suggestionsContracts,
|
|
2061
|
+
...decisionsContracts,
|
|
1829
2062
|
...pullRequestContracts,
|
|
1830
2063
|
...integrationsContracts,
|
|
1831
2064
|
...driveContracts,
|
|
@@ -3309,6 +3542,8 @@ import { z as z72 } from "zod";
|
|
|
3309
3542
|
import { z as z82 } from "zod";
|
|
3310
3543
|
import { z as z92 } from "zod";
|
|
3311
3544
|
import { z as z102 } from "zod";
|
|
3545
|
+
import { z as z11 } from "zod";
|
|
3546
|
+
import { z as z12 } from "zod";
|
|
3312
3547
|
var ACHIEVEMENT_RARITIES = [
|
|
3313
3548
|
{
|
|
3314
3549
|
key: "common",
|
|
@@ -4797,135 +5032,291 @@ var DeleteTaskAuditRequestSchema = z92.object({
|
|
|
4797
5032
|
var MarkInitialPromptSubmittedRequestSchema = z92.object({
|
|
4798
5033
|
sessionId: z92.string()
|
|
4799
5034
|
});
|
|
5035
|
+
var DECISION_STATUS_LABELS = ["Open", "Decided", "Cancelled"];
|
|
5036
|
+
var DECISION_OPTION_KINDS = ["current", "planned", "proposed"];
|
|
5037
|
+
var DECISION_VOTE_SOURCES = ["web", "slack", "discord", "agent"];
|
|
5038
|
+
var DECISION_OPTIONS_MIN = 2;
|
|
5039
|
+
var DECISION_OPTIONS_MAX = 3;
|
|
5040
|
+
var DECISION_OPTION_LABEL_MAX = 80;
|
|
5041
|
+
var DECISION_QUESTION_MAX = 200;
|
|
5042
|
+
var DECISION_RESOLUTION_MAX = CARD_DESCRIPTION_MAX;
|
|
5043
|
+
var DECISION_VOTE_REASON_MAX = CARD_DESCRIPTION_MAX;
|
|
5044
|
+
var DECISION_DEADLINE_MIN_HOURS = 1;
|
|
5045
|
+
var DECISION_DEADLINE_MAX_DAYS = 30;
|
|
5046
|
+
var DECISION_DEADLINE_MAX_HOURS = DECISION_DEADLINE_MAX_DAYS * 24;
|
|
5047
|
+
var DECISION_LIST_MAX_LIMIT = 200;
|
|
5048
|
+
var decisionIdSchema = z102.string().cuid("Invalid decision ID");
|
|
5049
|
+
var optionInputSchema = z102.object({
|
|
5050
|
+
label: z102.string().min(1, "Option label is required").max(DECISION_OPTION_LABEL_MAX),
|
|
5051
|
+
description: z102.string().min(1, "Describe the option as GIVEN / WHEN / THEN"),
|
|
5052
|
+
kind: z102.enum(DECISION_OPTION_KINDS).optional()
|
|
5053
|
+
});
|
|
5054
|
+
var optionsArraySchema = z102.array(optionInputSchema).min(DECISION_OPTIONS_MIN, `A decision needs at least ${DECISION_OPTIONS_MIN} options`).max(
|
|
5055
|
+
DECISION_OPTIONS_MAX,
|
|
5056
|
+
`A decision takes at most ${DECISION_OPTIONS_MAX} options \u2014 more than that means the question is not framed yet`
|
|
5057
|
+
);
|
|
5058
|
+
var CreateDecisionRequestSchema = z102.object({
|
|
5059
|
+
projectId: z102.string().cuid("Invalid project ID"),
|
|
5060
|
+
/** The question, as one plain sentence. */
|
|
5061
|
+
title: z102.string().min(1, "A decision needs a question").max(DECISION_QUESTION_MAX),
|
|
5062
|
+
description: z102.string().max(CARD_DESCRIPTION_MAX).optional(),
|
|
5063
|
+
context: z102.string().min(1, "Context is required \u2014 say why this is being asked now"),
|
|
5064
|
+
options: optionsArraySchema,
|
|
5065
|
+
/** 1-based position of the option that wins on silence. */
|
|
5066
|
+
defaultOptionOrdinal: z102.number().int().min(1).max(DECISION_OPTIONS_MAX),
|
|
5067
|
+
deadlineHours: z102.number().min(DECISION_DEADLINE_MIN_HOURS).max(DECISION_DEADLINE_MAX_HOURS).optional(),
|
|
5068
|
+
/** Cards this decision blocks, by cuid or slug. */
|
|
5069
|
+
impactedCardRefs: z102.array(z102.string().min(1)).max(50).optional(),
|
|
5070
|
+
tagNames: z102.array(z102.string().min(1)).max(10).optional(),
|
|
5071
|
+
raisedByTaskId: z102.string().min(1).optional(),
|
|
5072
|
+
raisedByPrNumber: z102.number().int().positive().optional()
|
|
5073
|
+
});
|
|
5074
|
+
var VoteDecisionRequestSchema = z102.object({
|
|
5075
|
+
decisionId: decisionIdSchema,
|
|
5076
|
+
optionId: z102.string().cuid("Invalid option ID"),
|
|
5077
|
+
reason: z102.string().max(DECISION_VOTE_REASON_MAX).optional(),
|
|
5078
|
+
source: z102.enum(DECISION_VOTE_SOURCES).optional()
|
|
5079
|
+
});
|
|
5080
|
+
var RemoveDecisionVoteRequestSchema = z102.object({
|
|
5081
|
+
decisionId: decisionIdSchema
|
|
5082
|
+
});
|
|
5083
|
+
var ResolveDecisionRequestSchema = z102.object({
|
|
5084
|
+
decisionId: decisionIdSchema,
|
|
5085
|
+
chosenOptionId: z102.string().cuid("Invalid option ID"),
|
|
5086
|
+
resolution: z102.string().min(1, "A resolution is required \u2014 say what was decided").max(DECISION_RESOLUTION_MAX),
|
|
5087
|
+
resolutionNotes: z102.string().optional()
|
|
5088
|
+
});
|
|
5089
|
+
var CancelDecisionRequestSchema = z102.object({
|
|
5090
|
+
decisionId: decisionIdSchema,
|
|
5091
|
+
/** Why it is being dropped. Posted to the decision thread. */
|
|
5092
|
+
reason: z102.string().max(DECISION_RESOLUTION_MAX).optional()
|
|
5093
|
+
});
|
|
5094
|
+
var ReopenDecisionRequestSchema = z102.object({
|
|
5095
|
+
decisionId: decisionIdSchema,
|
|
5096
|
+
deadlineHours: z102.number().min(DECISION_DEADLINE_MIN_HOURS).max(DECISION_DEADLINE_MAX_HOURS).optional()
|
|
5097
|
+
});
|
|
5098
|
+
var UpdateDecisionRequestSchema = z102.object({
|
|
5099
|
+
decisionId: decisionIdSchema,
|
|
5100
|
+
title: z102.string().min(1).max(200).optional(),
|
|
5101
|
+
description: z102.string().max(CARD_DESCRIPTION_MAX).optional(),
|
|
5102
|
+
context: z102.string().min(1).optional(),
|
|
5103
|
+
deadlineAt: z102.string().datetime().optional(),
|
|
5104
|
+
/** Only accepted while the decision has zero votes. */
|
|
5105
|
+
options: optionsArraySchema.optional(),
|
|
5106
|
+
defaultOptionOrdinal: z102.number().int().min(1).max(DECISION_OPTIONS_MAX).optional(),
|
|
5107
|
+
addImpactedCardRefs: z102.array(z102.string().min(1)).max(50).optional(),
|
|
5108
|
+
removeImpactedCardIds: z102.array(z102.string().min(1)).max(50).optional()
|
|
5109
|
+
});
|
|
5110
|
+
var GetDecisionRequestSchema = z102.object({
|
|
5111
|
+
/** cuid or slug. A slug needs `projectId` to resolve unambiguously. */
|
|
5112
|
+
decisionId: z102.string().min(1),
|
|
5113
|
+
projectId: z102.string().cuid().optional()
|
|
5114
|
+
});
|
|
5115
|
+
var ListDecisionsRequestSchema = z102.object({
|
|
5116
|
+
projectId: z102.string().cuid("Invalid project ID"),
|
|
5117
|
+
status: z102.enum(DECISION_STATUS_LABELS).optional(),
|
|
5118
|
+
/** Tag name, not id — an agent knows the tag it is working under. */
|
|
5119
|
+
tag: z102.string().min(1).optional(),
|
|
5120
|
+
/** Decisions that this card is blocked by (cuid or slug). */
|
|
5121
|
+
cardId: z102.string().min(1).optional(),
|
|
5122
|
+
query: z102.string().min(1).optional(),
|
|
5123
|
+
limit: z102.number().int().min(1).max(DECISION_LIST_MAX_LIMIT).optional()
|
|
5124
|
+
});
|
|
5125
|
+
var optionInput = z11.object({
|
|
5126
|
+
label: z11.string().min(1).max(DECISION_OPTION_LABEL_MAX),
|
|
5127
|
+
description: z11.string().min(1),
|
|
5128
|
+
kind: z11.enum(DECISION_OPTION_KINDS).optional()
|
|
5129
|
+
});
|
|
5130
|
+
var optionsInput = z11.array(optionInput).min(DECISION_OPTIONS_MIN).max(DECISION_OPTIONS_MAX);
|
|
5131
|
+
var deadlineHours = z11.number().min(DECISION_DEADLINE_MIN_HOURS).max(DECISION_DEADLINE_MAX_HOURS).optional();
|
|
5132
|
+
var CreateProjectDecisionRequestSchema = z11.object({
|
|
5133
|
+
projectId: z11.string(),
|
|
5134
|
+
question: z11.string().min(1).max(200),
|
|
5135
|
+
summary: z11.string().max(CARD_DESCRIPTION_MAX).optional(),
|
|
5136
|
+
context: z11.string().min(1),
|
|
5137
|
+
options: optionsInput,
|
|
5138
|
+
defaultOption: z11.number().int().min(1).max(DECISION_OPTIONS_MAX),
|
|
5139
|
+
deadlineHours,
|
|
5140
|
+
impactedCards: z11.array(z11.string().min(1)).max(50).optional(),
|
|
5141
|
+
/**
|
|
5142
|
+
* Pod surface only: also block the card this session is working on. The
|
|
5143
|
+
* session's task id is resolved SERVER-side from `sessionId` — a
|
|
5144
|
+
* client-supplied card id would let a pod block any card in the project.
|
|
5145
|
+
*/
|
|
5146
|
+
includeCurrentCard: z11.boolean().optional(),
|
|
5147
|
+
sessionId: z11.string().optional(),
|
|
5148
|
+
tagNames: z11.array(z11.string().min(1)).max(10).optional(),
|
|
5149
|
+
raisedByPr: z11.number().int().positive().optional(),
|
|
5150
|
+
requestingUserId: z11.string().optional()
|
|
5151
|
+
});
|
|
5152
|
+
var ListProjectDecisionsRequestSchema = z11.object({
|
|
5153
|
+
projectId: z11.string(),
|
|
5154
|
+
status: z11.enum(DECISION_STATUS_LABELS).optional(),
|
|
5155
|
+
tag: z11.string().min(1).optional(),
|
|
5156
|
+
card: z11.string().min(1).optional(),
|
|
5157
|
+
query: z11.string().min(1).optional(),
|
|
5158
|
+
limit: z11.number().int().min(1).max(DECISION_LIST_MAX_LIMIT).optional(),
|
|
5159
|
+
requestingUserId: z11.string().optional()
|
|
5160
|
+
});
|
|
5161
|
+
var GetProjectDecisionRequestSchema = z11.object({
|
|
5162
|
+
projectId: z11.string(),
|
|
5163
|
+
decision: z11.string().min(1),
|
|
5164
|
+
requestingUserId: z11.string().optional()
|
|
5165
|
+
});
|
|
5166
|
+
var VoteProjectDecisionRequestSchema = z11.object({
|
|
5167
|
+
projectId: z11.string(),
|
|
5168
|
+
decision: z11.string().min(1),
|
|
5169
|
+
/** An option id, or its 1-based position. */
|
|
5170
|
+
option: z11.string().min(1),
|
|
5171
|
+
reason: z11.string().max(CARD_DESCRIPTION_MAX).optional(),
|
|
5172
|
+
requestingUserId: z11.string().optional()
|
|
5173
|
+
});
|
|
5174
|
+
var ResolveProjectDecisionRequestSchema = z11.object({
|
|
5175
|
+
projectId: z11.string(),
|
|
5176
|
+
decision: z11.string().min(1),
|
|
5177
|
+
option: z11.string().min(1),
|
|
5178
|
+
resolution: z11.string().min(1).max(DECISION_RESOLUTION_MAX),
|
|
5179
|
+
notes: z11.string().optional(),
|
|
5180
|
+
requestingUserId: z11.string().optional()
|
|
5181
|
+
});
|
|
5182
|
+
var UpdateProjectDecisionRequestSchema = z11.object({
|
|
5183
|
+
projectId: z11.string(),
|
|
5184
|
+
decision: z11.string().min(1),
|
|
5185
|
+
deadlineHours,
|
|
5186
|
+
addImpactedCards: z11.array(z11.string().min(1)).max(50).optional(),
|
|
5187
|
+
removeImpactedCards: z11.array(z11.string().min(1)).max(50).optional(),
|
|
5188
|
+
status: z11.enum(["Cancelled", "Open"]).optional(),
|
|
5189
|
+
requestingUserId: z11.string().optional()
|
|
5190
|
+
});
|
|
4800
5191
|
var MEETING_CHECKLIST_TITLE_MAX = 300;
|
|
4801
5192
|
var MEETING_TRANSCRIPT_MAX_CHARS = 2e6;
|
|
4802
5193
|
var MEETING_TITLE_MAX = 200;
|
|
4803
5194
|
var MEETING_OCCURRED_AT_MIN_YEAR = 2e3;
|
|
4804
5195
|
var MEETING_OCCURRED_AT_MAX_FUTURE_MS = 48 * 60 * 60 * 1e3;
|
|
4805
5196
|
var OCCURRED_AT_RANGE_MESSAGE = `occurredAt must be a real date: no earlier than ${MEETING_OCCURRED_AT_MIN_YEAR}, and no more than 48 hours in the future.`;
|
|
4806
|
-
var MeetingOccurredAtSchema =
|
|
5197
|
+
var MeetingOccurredAtSchema = z12.string().datetime().refine((value) => {
|
|
4807
5198
|
const ms = Date.parse(value);
|
|
4808
5199
|
if (Number.isNaN(ms)) return false;
|
|
4809
5200
|
if (ms > Date.now() + MEETING_OCCURRED_AT_MAX_FUTURE_MS) return false;
|
|
4810
5201
|
return new Date(ms).getUTCFullYear() >= MEETING_OCCURRED_AT_MIN_YEAR;
|
|
4811
5202
|
}, OCCURRED_AT_RANGE_MESSAGE);
|
|
4812
|
-
var CreateMeetingFromTranscriptRequestSchema =
|
|
4813
|
-
projectId:
|
|
4814
|
-
rawText:
|
|
4815
|
-
title:
|
|
5203
|
+
var CreateMeetingFromTranscriptRequestSchema = z12.object({
|
|
5204
|
+
projectId: z12.string().cuid(),
|
|
5205
|
+
rawText: z12.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
5206
|
+
title: z12.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
4816
5207
|
/** ISO 8601. Defaults to now when the source carries no date. */
|
|
4817
5208
|
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
4818
5209
|
/** Override auto-detection. Rarely needed; detection handles the three formats. */
|
|
4819
|
-
format:
|
|
4820
|
-
source:
|
|
5210
|
+
format: z12.enum(["text", "vtt", "srt"]).optional(),
|
|
5211
|
+
source: z12.enum(["manual", "slack"]).optional()
|
|
4821
5212
|
});
|
|
4822
|
-
var GetMeetingRequestSchema =
|
|
4823
|
-
projectId:
|
|
4824
|
-
meetingId:
|
|
5213
|
+
var GetMeetingRequestSchema = z12.object({
|
|
5214
|
+
projectId: z12.string().cuid(),
|
|
5215
|
+
meetingId: z12.string().cuid()
|
|
4825
5216
|
});
|
|
4826
|
-
var UpdateMeetingRequestSchema =
|
|
4827
|
-
projectId:
|
|
4828
|
-
meetingId:
|
|
4829
|
-
title:
|
|
5217
|
+
var UpdateMeetingRequestSchema = z12.object({
|
|
5218
|
+
projectId: z12.string().cuid(),
|
|
5219
|
+
meetingId: z12.string().cuid(),
|
|
5220
|
+
title: z12.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
4830
5221
|
occurredAt: MeetingOccurredAtSchema.optional()
|
|
4831
5222
|
});
|
|
4832
|
-
var RegenerateMeetingSummaryRequestSchema =
|
|
4833
|
-
projectId:
|
|
4834
|
-
meetingId:
|
|
5223
|
+
var RegenerateMeetingSummaryRequestSchema = z12.object({
|
|
5224
|
+
projectId: z12.string().cuid(),
|
|
5225
|
+
meetingId: z12.string().cuid()
|
|
4835
5226
|
});
|
|
4836
|
-
var DeleteMeetingRequestSchema =
|
|
4837
|
-
projectId:
|
|
4838
|
-
meetingId:
|
|
5227
|
+
var DeleteMeetingRequestSchema = z12.object({
|
|
5228
|
+
projectId: z12.string().cuid(),
|
|
5229
|
+
meetingId: z12.string().cuid()
|
|
4839
5230
|
});
|
|
4840
|
-
var checklistTitle =
|
|
4841
|
-
var ListMeetingChecklistRequestSchema =
|
|
4842
|
-
projectId:
|
|
4843
|
-
meetingId:
|
|
5231
|
+
var checklistTitle = z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX);
|
|
5232
|
+
var ListMeetingChecklistRequestSchema = z12.object({
|
|
5233
|
+
projectId: z12.string().cuid(),
|
|
5234
|
+
meetingId: z12.string().cuid()
|
|
4844
5235
|
});
|
|
4845
|
-
var AddMeetingChecklistItemsRequestSchema =
|
|
4846
|
-
projectId:
|
|
4847
|
-
meetingId:
|
|
4848
|
-
items:
|
|
5236
|
+
var AddMeetingChecklistItemsRequestSchema = z12.object({
|
|
5237
|
+
projectId: z12.string().cuid(),
|
|
5238
|
+
meetingId: z12.string().cuid(),
|
|
5239
|
+
items: z12.array(z12.object({ title: checklistTitle })).min(1).max(50)
|
|
4849
5240
|
});
|
|
4850
|
-
var UpdateMeetingChecklistItemRequestSchema =
|
|
4851
|
-
projectId:
|
|
4852
|
-
meetingId:
|
|
4853
|
-
itemId:
|
|
5241
|
+
var UpdateMeetingChecklistItemRequestSchema = z12.object({
|
|
5242
|
+
projectId: z12.string().cuid(),
|
|
5243
|
+
meetingId: z12.string().cuid(),
|
|
5244
|
+
itemId: z12.string().cuid(),
|
|
4854
5245
|
title: checklistTitle.optional(),
|
|
4855
|
-
ordinal:
|
|
5246
|
+
ordinal: z12.number().int().min(0).optional(),
|
|
4856
5247
|
/** Explicit null clears the link; undefined leaves it alone. */
|
|
4857
|
-
linkedTaskId:
|
|
5248
|
+
linkedTaskId: z12.string().cuid().nullable().optional()
|
|
4858
5249
|
}).refine(
|
|
4859
5250
|
(v) => v.title !== void 0 || v.ordinal !== void 0 || v.linkedTaskId !== void 0,
|
|
4860
5251
|
"Pass at least one of title, ordinal, or linkedTaskId."
|
|
4861
5252
|
);
|
|
4862
|
-
var DeleteMeetingChecklistItemRequestSchema =
|
|
4863
|
-
projectId:
|
|
4864
|
-
meetingId:
|
|
4865
|
-
itemId:
|
|
4866
|
-
});
|
|
4867
|
-
var SetMeetingChecklistItemCheckedRequestSchema =
|
|
4868
|
-
projectId:
|
|
4869
|
-
meetingId:
|
|
4870
|
-
itemId:
|
|
4871
|
-
checked:
|
|
5253
|
+
var DeleteMeetingChecklistItemRequestSchema = z12.object({
|
|
5254
|
+
projectId: z12.string().cuid(),
|
|
5255
|
+
meetingId: z12.string().cuid(),
|
|
5256
|
+
itemId: z12.string().cuid()
|
|
5257
|
+
});
|
|
5258
|
+
var SetMeetingChecklistItemCheckedRequestSchema = z12.object({
|
|
5259
|
+
projectId: z12.string().cuid(),
|
|
5260
|
+
meetingId: z12.string().cuid(),
|
|
5261
|
+
itemId: z12.string().cuid(),
|
|
5262
|
+
checked: z12.boolean(),
|
|
4872
5263
|
/** Attach the card in the same call that ticks the item. */
|
|
4873
|
-
linkedTaskId:
|
|
5264
|
+
linkedTaskId: z12.string().cuid().nullable().optional()
|
|
4874
5265
|
});
|
|
4875
|
-
var ListMeetingsRequestSchema =
|
|
4876
|
-
projectId:
|
|
4877
|
-
limit:
|
|
4878
|
-
search:
|
|
5266
|
+
var ListMeetingsRequestSchema = z12.object({
|
|
5267
|
+
projectId: z12.string().cuid(),
|
|
5268
|
+
limit: z12.number().int().min(1).max(50).optional(),
|
|
5269
|
+
search: z12.string().max(200).optional()
|
|
4879
5270
|
});
|
|
4880
|
-
var ReadMeetingTranscriptRequestSchema =
|
|
4881
|
-
projectId:
|
|
4882
|
-
meetingId:
|
|
4883
|
-
offset:
|
|
4884
|
-
limit:
|
|
5271
|
+
var ReadMeetingTranscriptRequestSchema = z12.object({
|
|
5272
|
+
projectId: z12.string().cuid(),
|
|
5273
|
+
meetingId: z12.string().cuid(),
|
|
5274
|
+
offset: z12.number().int().min(0).optional(),
|
|
5275
|
+
limit: z12.number().int().min(1).max(500).optional()
|
|
4885
5276
|
});
|
|
4886
5277
|
var MEETING_SUMMARY_MAX_CHARS = 5e4;
|
|
4887
|
-
var AddProjectMeetingChecklistItemsRequestSchema =
|
|
4888
|
-
projectId:
|
|
4889
|
-
meetingId:
|
|
4890
|
-
items:
|
|
4891
|
-
requestingUserId:
|
|
4892
|
-
});
|
|
4893
|
-
var CheckProjectMeetingChecklistItemRequestSchema =
|
|
4894
|
-
projectId:
|
|
4895
|
-
meetingId:
|
|
4896
|
-
title:
|
|
4897
|
-
checked:
|
|
5278
|
+
var AddProjectMeetingChecklistItemsRequestSchema = z12.object({
|
|
5279
|
+
projectId: z12.string().cuid(),
|
|
5280
|
+
meetingId: z12.string().cuid(),
|
|
5281
|
+
items: z12.array(z12.object({ title: z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX) })).min(1).max(50),
|
|
5282
|
+
requestingUserId: z12.string().optional()
|
|
5283
|
+
});
|
|
5284
|
+
var CheckProjectMeetingChecklistItemRequestSchema = z12.object({
|
|
5285
|
+
projectId: z12.string().cuid(),
|
|
5286
|
+
meetingId: z12.string().cuid(),
|
|
5287
|
+
title: z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
5288
|
+
checked: z12.boolean(),
|
|
4898
5289
|
/** Card id or slug. Resolved server-side and required to be in the project. */
|
|
4899
|
-
linkedTask:
|
|
4900
|
-
requestingUserId:
|
|
4901
|
-
});
|
|
4902
|
-
var EditProjectMeetingChecklistItemRequestSchema =
|
|
4903
|
-
projectId:
|
|
4904
|
-
meetingId:
|
|
4905
|
-
title:
|
|
4906
|
-
newTitle:
|
|
4907
|
-
requestingUserId:
|
|
4908
|
-
});
|
|
4909
|
-
var RemoveProjectMeetingChecklistItemRequestSchema =
|
|
4910
|
-
projectId:
|
|
4911
|
-
meetingId:
|
|
4912
|
-
title:
|
|
4913
|
-
requestingUserId:
|
|
4914
|
-
});
|
|
4915
|
-
var CreateProjectMeetingRequestSchema =
|
|
4916
|
-
projectId:
|
|
4917
|
-
rawText:
|
|
4918
|
-
title:
|
|
5290
|
+
linkedTask: z12.string().min(1).optional(),
|
|
5291
|
+
requestingUserId: z12.string().optional()
|
|
5292
|
+
});
|
|
5293
|
+
var EditProjectMeetingChecklistItemRequestSchema = z12.object({
|
|
5294
|
+
projectId: z12.string().cuid(),
|
|
5295
|
+
meetingId: z12.string().cuid(),
|
|
5296
|
+
title: z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
5297
|
+
newTitle: z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
5298
|
+
requestingUserId: z12.string().optional()
|
|
5299
|
+
});
|
|
5300
|
+
var RemoveProjectMeetingChecklistItemRequestSchema = z12.object({
|
|
5301
|
+
projectId: z12.string().cuid(),
|
|
5302
|
+
meetingId: z12.string().cuid(),
|
|
5303
|
+
title: z12.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
5304
|
+
requestingUserId: z12.string().optional()
|
|
5305
|
+
});
|
|
5306
|
+
var CreateProjectMeetingRequestSchema = z12.object({
|
|
5307
|
+
projectId: z12.string().cuid(),
|
|
5308
|
+
rawText: z12.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
5309
|
+
title: z12.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
4919
5310
|
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
4920
|
-
requestingUserId:
|
|
5311
|
+
requestingUserId: z12.string().optional()
|
|
4921
5312
|
});
|
|
4922
|
-
var UpdateProjectMeetingRequestSchema =
|
|
4923
|
-
projectId:
|
|
4924
|
-
meetingId:
|
|
4925
|
-
title:
|
|
5313
|
+
var UpdateProjectMeetingRequestSchema = z12.object({
|
|
5314
|
+
projectId: z12.string().cuid(),
|
|
5315
|
+
meetingId: z12.string().cuid(),
|
|
5316
|
+
title: z12.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
4926
5317
|
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
4927
|
-
summary:
|
|
4928
|
-
requestingUserId:
|
|
5318
|
+
summary: z12.string().min(1).max(MEETING_SUMMARY_MAX_CHARS).optional(),
|
|
5319
|
+
requestingUserId: z12.string().optional()
|
|
4929
5320
|
}).refine(
|
|
4930
5321
|
(v) => v.title !== void 0 || v.occurredAt !== void 0 || v.summary !== void 0,
|
|
4931
5322
|
"Pass at least one of title, occurredAt, or summary."
|
|
@@ -5262,13 +5653,17 @@ var CARD_TYPE_SURFACE = {
|
|
|
5262
5653
|
task: "board",
|
|
5263
5654
|
chat: "board",
|
|
5264
5655
|
incident: "report",
|
|
5265
|
-
suggestion: "report"
|
|
5656
|
+
suggestion: "report",
|
|
5657
|
+
// Decisions get their own surface: they are neither built on the board nor
|
|
5658
|
+
// triaged in the report feeds. Cards → Decisions is their only feed.
|
|
5659
|
+
decision: "decision"
|
|
5266
5660
|
};
|
|
5267
5661
|
var surfaceTypes = (surface) => Object.keys(CARD_TYPE_SURFACE).filter(
|
|
5268
5662
|
(type) => CARD_TYPE_SURFACE[type] === surface
|
|
5269
5663
|
);
|
|
5270
5664
|
var BOARD_CARD_TYPES = surfaceTypes("board");
|
|
5271
5665
|
var REPORT_CARD_TYPES = surfaceTypes("report");
|
|
5666
|
+
var DECISION_CARD_TYPES = surfaceTypes("decision");
|
|
5272
5667
|
|
|
5273
5668
|
// src/tools/logs.ts
|
|
5274
5669
|
function registerLogTools(server2, conn2) {
|
|
@@ -5449,6 +5844,83 @@ ${res.lines.join("\n")}${footer}` }] };
|
|
|
5449
5844
|
});
|
|
5450
5845
|
}
|
|
5451
5846
|
|
|
5847
|
+
// src/tools/decisions.ts
|
|
5848
|
+
function registerDecisionReads(server2, conn2) {
|
|
5849
|
+
registerContractTool(server2, listDecisionsContract, async (params) => {
|
|
5850
|
+
const res = await conn2.listDecisions(params);
|
|
5851
|
+
if (res.decisions.length === 0) {
|
|
5852
|
+
return {
|
|
5853
|
+
content: [
|
|
5854
|
+
{
|
|
5855
|
+
type: "text",
|
|
5856
|
+
text: "No decisions match. Nothing has been settled here, so the choice is open \u2014 state it as an assumption in the plan, or raise a decision with create_decision if the plan cannot be right without an answer."
|
|
5857
|
+
}
|
|
5858
|
+
]
|
|
5859
|
+
};
|
|
5860
|
+
}
|
|
5861
|
+
return { content: [{ type: "text", text: JSON.stringify(res.decisions, null, 2) }] };
|
|
5862
|
+
});
|
|
5863
|
+
registerContractTool(server2, getDecisionContract, async (params) => {
|
|
5864
|
+
const res = await conn2.getDecision(params);
|
|
5865
|
+
return { content: [{ type: "text", text: JSON.stringify(res, null, 2) }] };
|
|
5866
|
+
});
|
|
5867
|
+
}
|
|
5868
|
+
function registerDecisionWrites(server2, conn2) {
|
|
5869
|
+
registerContractTool(server2, createDecisionContract, async (params) => {
|
|
5870
|
+
const { defaultOption, deadlineHours: deadlineHours2, impactedCards, tagNames, raisedByPr, ...rest } = params;
|
|
5871
|
+
const res = await conn2.createDecision({
|
|
5872
|
+
...rest,
|
|
5873
|
+
defaultOption,
|
|
5874
|
+
deadlineHours: deadlineHours2,
|
|
5875
|
+
impactedCards,
|
|
5876
|
+
tagNames,
|
|
5877
|
+
raisedByPr
|
|
5878
|
+
});
|
|
5879
|
+
const refused = res.refused.length > 0 ? `
|
|
5880
|
+
Not linked: ${res.refused.map((r) => `${r.ref} (${r.reason})`).join("; ")}` : "";
|
|
5881
|
+
return {
|
|
5882
|
+
content: [
|
|
5883
|
+
{
|
|
5884
|
+
type: "text",
|
|
5885
|
+
text: `Raised decision ${res.slug} \u2014 ${res.url}
|
|
5886
|
+
Blocking ${res.impactedLinked.length} card(s).${refused}`
|
|
5887
|
+
}
|
|
5888
|
+
]
|
|
5889
|
+
};
|
|
5890
|
+
});
|
|
5891
|
+
registerContractTool(server2, voteDecisionContract, async (params) => {
|
|
5892
|
+
const res = await conn2.voteDecision(params);
|
|
5893
|
+
const tally = res.options.map((o) => `${o.label}: ${o.votes}`).join(", ");
|
|
5894
|
+
return { content: [{ type: "text", text: `Voted on ${res.slug}. Tally \u2014 ${tally}.` }] };
|
|
5895
|
+
});
|
|
5896
|
+
registerContractTool(server2, resolveDecisionContract, async (params) => {
|
|
5897
|
+
const res = await conn2.resolveDecision(params);
|
|
5898
|
+
return {
|
|
5899
|
+
content: [
|
|
5900
|
+
{
|
|
5901
|
+
type: "text",
|
|
5902
|
+
text: `Settled ${res.slug} as "${res.chosenOption}". ${res.impactedCount} card(s) were written back to and are no longer blocked.`
|
|
5903
|
+
}
|
|
5904
|
+
]
|
|
5905
|
+
};
|
|
5906
|
+
});
|
|
5907
|
+
registerContractTool(server2, updateDecisionContract, async (params) => {
|
|
5908
|
+
const res = await conn2.updateDecision(params);
|
|
5909
|
+
return {
|
|
5910
|
+
content: [
|
|
5911
|
+
{
|
|
5912
|
+
type: "text",
|
|
5913
|
+
text: `Updated ${res.slug} \u2014 ${res.status}, ${res.impactedCount} impacted card(s), deadline ${res.deadlineAt}.`
|
|
5914
|
+
}
|
|
5915
|
+
]
|
|
5916
|
+
};
|
|
5917
|
+
});
|
|
5918
|
+
}
|
|
5919
|
+
function registerDecisionTools(server2, conn2) {
|
|
5920
|
+
registerDecisionReads(server2, conn2);
|
|
5921
|
+
registerDecisionWrites(server2, conn2);
|
|
5922
|
+
}
|
|
5923
|
+
|
|
5452
5924
|
// src/tools/index.ts
|
|
5453
5925
|
function registerAllTools(server2, conn2) {
|
|
5454
5926
|
registerProjectTools(server2, conn2);
|
|
@@ -5467,6 +5939,7 @@ function registerAllTools(server2, conn2) {
|
|
|
5467
5939
|
registerIntegrationTools(server2, conn2);
|
|
5468
5940
|
registerDriveTools(server2, conn2);
|
|
5469
5941
|
registerMeetingTools(server2, conn2);
|
|
5942
|
+
registerDecisionTools(server2, conn2);
|
|
5470
5943
|
}
|
|
5471
5944
|
|
|
5472
5945
|
// src/cli.ts
|
|
@@ -5497,11 +5970,5 @@ var server = new McpServer({
|
|
|
5497
5970
|
registerAllTools(server, conn);
|
|
5498
5971
|
var transport = new StdioServerTransport();
|
|
5499
5972
|
await server.connect(transport);
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
process.exit(0);
|
|
5503
|
-
});
|
|
5504
|
-
process.on("SIGTERM", () => {
|
|
5505
|
-
conn.disconnect();
|
|
5506
|
-
process.exit(0);
|
|
5507
|
-
});
|
|
5973
|
+
var stop = installLifecycle(conn);
|
|
5974
|
+
server.server.onclose = () => stop();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { io, Socket } from 'socket.io-client';
|
|
2
|
+
import { ListDriveFilesResponse, ReadDriveFileResponse, DriveFileDTO, DeleteDriveFileResponse, ProjectIntegrationsSummary, GaAnalyticsSummaryDTO, ProjectChannelDTO, ReadChannelMessagesResponse, PostChannelMessageResponse, CreateProjectDecisionRequest, CreateProjectDecisionResponse, ListProjectDecisionsRequest, ProjectDecisionRow, ProjectDecisionDetail, VoteProjectDecisionRequest, ResolveProjectDecisionRequest, UpdateProjectDecisionRequest, ListMeetingsResponse, MeetingForAgent, ReadMeetingTranscriptResponse, MeetingChecklistItemForAgent } from '@project/shared';
|
|
2
3
|
|
|
3
4
|
interface ConveyorMcpConfig {
|
|
4
5
|
apiUrl: string;
|
|
@@ -310,12 +311,20 @@ interface PrioritySummary {
|
|
|
310
311
|
color: string;
|
|
311
312
|
description?: string | null;
|
|
312
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Creates the underlying socket. Defaults to socket.io's `io`; tests inject a
|
|
316
|
+
* fake so the reconnect wiring in `connect()` can be driven without a server.
|
|
317
|
+
*/
|
|
318
|
+
type ConveyorSocketFactory = (url: string, options: Parameters<typeof io>[1]) => Pick<Socket, "on" | "emit" | "close" | "connect" | "disconnect">;
|
|
313
319
|
declare class ConveyorConnection {
|
|
314
320
|
private socket;
|
|
315
321
|
private config;
|
|
322
|
+
private socketFactory;
|
|
316
323
|
/** project slug → id, for resolving `<project>/<card>` card paths. */
|
|
317
324
|
private projectSlugIds;
|
|
318
|
-
|
|
325
|
+
/** Session rooms this connection has joined, replayed after every reconnect. */
|
|
326
|
+
private subscribedSessionIds;
|
|
327
|
+
constructor(config: ConveyorMcpConfig, socketFactory?: ConveyorSocketFactory);
|
|
319
328
|
get projectId(): string;
|
|
320
329
|
private resolveProjectId;
|
|
321
330
|
/** The configured default board (CONVEYOR_SUBPROJECT_ID), if any. */
|
|
@@ -329,6 +338,16 @@ declare class ConveyorConnection {
|
|
|
329
338
|
*/
|
|
330
339
|
private resolveSubProjectId;
|
|
331
340
|
private normalizeProjectList;
|
|
341
|
+
/**
|
|
342
|
+
* Re-join every room this connection needs.
|
|
343
|
+
*
|
|
344
|
+
* Runs on the FIRST connect and on every reconnect. A socket.io reconnect
|
|
345
|
+
* starts a fresh server-side socket that belongs to no rooms, and Cloud Run
|
|
346
|
+
* cuts each websocket at its 60-minute request limit, so a subscribe sent
|
|
347
|
+
* only once left long-lived MCP connections silently outside the project room
|
|
348
|
+
* for the rest of the day.
|
|
349
|
+
*/
|
|
350
|
+
private rejoinRooms;
|
|
332
351
|
connect(): Promise<void>;
|
|
333
352
|
private call;
|
|
334
353
|
/**
|
|
@@ -670,6 +689,27 @@ declare class ConveyorConnection {
|
|
|
670
689
|
text: string;
|
|
671
690
|
threadTs?: string;
|
|
672
691
|
}): Promise<PostChannelMessageResponse>;
|
|
692
|
+
createDecision(params: Omit<CreateProjectDecisionRequest, "projectId"> & {
|
|
693
|
+
projectId?: string;
|
|
694
|
+
}): Promise<CreateProjectDecisionResponse>;
|
|
695
|
+
listDecisions(params: Omit<ListProjectDecisionsRequest, "projectId"> & {
|
|
696
|
+
projectId?: string;
|
|
697
|
+
}): Promise<{
|
|
698
|
+
decisions: ProjectDecisionRow[];
|
|
699
|
+
}>;
|
|
700
|
+
getDecision(params: {
|
|
701
|
+
projectId?: string;
|
|
702
|
+
decision: string;
|
|
703
|
+
}): Promise<ProjectDecisionDetail>;
|
|
704
|
+
voteDecision(params: Omit<VoteProjectDecisionRequest, "projectId"> & {
|
|
705
|
+
projectId?: string;
|
|
706
|
+
}): Promise<ProjectDecisionDetail>;
|
|
707
|
+
resolveDecision(params: Omit<ResolveProjectDecisionRequest, "projectId"> & {
|
|
708
|
+
projectId?: string;
|
|
709
|
+
}): Promise<ProjectDecisionDetail>;
|
|
710
|
+
updateDecision(params: Omit<UpdateProjectDecisionRequest, "projectId"> & {
|
|
711
|
+
projectId?: string;
|
|
712
|
+
}): Promise<ProjectDecisionDetail>;
|
|
673
713
|
listMeetings(params: {
|
|
674
714
|
projectId?: string;
|
|
675
715
|
limit?: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { A as ActivePtySession, d as ConveyorConnection, e as ConveyorMcpConfig, P as PtyAttachSnapshot, c as PtyDataChunk } from './connection-
|
|
1
|
+
export { A as ActivePtySession, d as ConveyorConnection, e as ConveyorMcpConfig, P as PtyAttachSnapshot, c as PtyDataChunk } from './connection-DclP31lm.js';
|
|
2
2
|
export { AttachTunnelOptions, ResolvedPtySession, RunTunnelOptions, TunnelConnection, TunnelHandle, TunnelSession, TunnelTty, WaitForPtySessionOptions, attachTunnel, runTunnel, waitForPtySession } from './tunnel.js';
|
|
3
|
+
import 'socket.io-client';
|
|
3
4
|
import '@project/shared';
|
package/dist/index.js
CHANGED
package/dist/tunnel-cli.js
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runTunnel
|
|
4
4
|
} from "./chunk-HIVOGGE3.js";
|
|
5
|
+
import {
|
|
6
|
+
watchForClientExit
|
|
7
|
+
} from "./chunk-5KU3QS6A.js";
|
|
5
8
|
import {
|
|
6
9
|
ConveyorConnection
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-77XLXIFP.js";
|
|
8
11
|
|
|
9
12
|
// src/tunnel-cli.ts
|
|
10
13
|
var HELP = `conveyor-tunnel \u2014 attach your local terminal to a cloud Claude Code session.
|
|
@@ -125,8 +128,7 @@ function cleanupAndExit(code) {
|
|
|
125
128
|
conn.disconnect();
|
|
126
129
|
process.exit(code);
|
|
127
130
|
}
|
|
128
|
-
|
|
129
|
-
process.on("SIGTERM", () => cleanupAndExit(0));
|
|
131
|
+
watchForClientExit(() => cleanupAndExit(0), { watchStdin: false });
|
|
130
132
|
try {
|
|
131
133
|
await conn.connect();
|
|
132
134
|
log("Connected to Conveyor API.");
|
package/dist/tunnel.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { A as ActivePtySession, P as PtyAttachSnapshot, c as PtyDataChunk } from './connection-
|
|
1
|
+
import { A as ActivePtySession, P as PtyAttachSnapshot, c as PtyDataChunk } from './connection-DclP31lm.js';
|
|
2
|
+
import 'socket.io-client';
|
|
2
3
|
import '@project/shared';
|
|
3
4
|
|
|
4
5
|
/**
|
package/dist/wait-cli.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
watchForClientExit
|
|
4
|
+
} from "./chunk-5KU3QS6A.js";
|
|
2
5
|
import {
|
|
3
6
|
ConveyorConnection
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-77XLXIFP.js";
|
|
5
8
|
import {
|
|
6
9
|
runWait
|
|
7
10
|
} from "./chunk-OPZL4NDT.js";
|
|
@@ -257,8 +260,7 @@ function interrupt() {
|
|
|
257
260
|
exiting = true;
|
|
258
261
|
emitResult({ reason: "interrupted" }, () => shutdown(0));
|
|
259
262
|
}
|
|
260
|
-
|
|
261
|
-
process.on("SIGTERM", interrupt);
|
|
263
|
+
watchForClientExit(interrupt, { resumeStdin: true });
|
|
262
264
|
try {
|
|
263
265
|
await conn.connect();
|
|
264
266
|
} catch (err) {
|
package/dist/wait-runner.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { C as CardCollectionPage, a as CardCollectionDelta } from './connection-
|
|
1
|
+
import { C as CardCollectionPage, a as CardCollectionDelta } from './connection-DclP31lm.js';
|
|
2
2
|
import { WaitFilter, WaitResult } from './wait.js';
|
|
3
|
+
import 'socket.io-client';
|
|
3
4
|
import '@project/shared';
|
|
4
5
|
|
|
5
6
|
/**
|
package/dist/wait.d.ts
CHANGED