@rallycry/conveyor-agent 11.0.20 → 11.0.22
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-OMD77OIJ.js +4926 -0
- package/dist/{chunk-POK3QCGN.js → chunk-RW6V7KCE.js} +669 -3166
- package/dist/{chunk-SKTNJNXQ.js → chunk-WNSX5ZEQ.js} +15 -1
- package/dist/cli.js +6 -11
- package/dist/index.d.ts +2 -15
- package/dist/index.js +2 -2
- package/dist/{serve-boot-4BUN4U44.js → serve-boot-4O5NJ77J.js} +2 -2
- package/package.json +1 -1
- package/skills/conveyor-build/SKILL.md +3 -4
- package/skills/conveyor-build/references/pack-path.md +13 -7
- package/skills/conveyor-review/SKILL.md +15 -2
- package/dist/chunk-JBGPARLG.js +0 -2590
|
@@ -31,2349 +31,93 @@ import {
|
|
|
31
31
|
turnOptionsFrom
|
|
32
32
|
} from "./chunk-W5INK3NE.js";
|
|
33
33
|
import {
|
|
34
|
+
AGENT_STATUS_REASON_USER_QUESTION,
|
|
34
35
|
AgentConnection,
|
|
36
|
+
CARD_DESCRIPTION_FIELD_HINT,
|
|
37
|
+
CONTEXT_LINK_LOCATOR_MAX,
|
|
38
|
+
CRITICAL_AUTOMATED_SOURCES,
|
|
35
39
|
CodespacePortVisibility,
|
|
40
|
+
DEFAULT_CI_WAIT_TIMEOUT_MINUTES,
|
|
41
|
+
DEFAULT_CODEX_CODING_MODEL,
|
|
36
42
|
DEFAULT_LIFECYCLE_CONFIG,
|
|
43
|
+
DEFAULT_SONNET_MODEL,
|
|
44
|
+
EXTERNAL_AGENT_MESSAGE_SOURCE,
|
|
45
|
+
FABLE_MODEL,
|
|
46
|
+
HUMAN_PROSE_WRITING_STYLE,
|
|
37
47
|
Lifecycle,
|
|
48
|
+
MAX_CI_WAIT_TIMEOUT_MINUTES,
|
|
49
|
+
MAX_FILE_SIZE_BYTES,
|
|
50
|
+
PM_CHAT_HISTORY_LIMIT,
|
|
51
|
+
PRE_BUILD_TASK_STATUSES,
|
|
52
|
+
PTY_STREAM_PORT_ATTEMPTS,
|
|
53
|
+
PTY_STREAM_PORT_BASE,
|
|
38
54
|
PortDiscovery,
|
|
55
|
+
PtyStreamFrameReader,
|
|
56
|
+
ReviewGuideContentSchema,
|
|
57
|
+
SEVERITY_ENUM,
|
|
58
|
+
TAG_DESCRIPTION_MAX,
|
|
59
|
+
TAG_OVERVIEW_MAX,
|
|
60
|
+
TAG_REASON_MAX,
|
|
61
|
+
TASK_CHAT_HISTORY_LIMIT,
|
|
62
|
+
TUI_KINDS,
|
|
39
63
|
awaitGitReady,
|
|
40
64
|
clearForceFreshCooldown,
|
|
41
65
|
createServiceLogger,
|
|
66
|
+
encodePtyStreamFrame,
|
|
42
67
|
ensureOnTaskBranch,
|
|
43
68
|
flushAllPendingWork,
|
|
44
69
|
flushPendingChanges,
|
|
45
70
|
forceFreshCooldownNotice,
|
|
46
71
|
forceFreshMintBlocked,
|
|
47
72
|
getCurrentBranch,
|
|
48
|
-
git,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} from "./chunk-
|
|
86
|
-
import {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"INFO",
|
|
97
|
-
"NOTICE",
|
|
98
|
-
"WARNING",
|
|
99
|
-
"ERROR",
|
|
100
|
-
"CRITICAL",
|
|
101
|
-
"ALERT",
|
|
102
|
-
"EMERGENCY"
|
|
103
|
-
];
|
|
104
|
-
var MAX_LINE_CHARS = 400;
|
|
105
|
-
var DEFAULT_SINCE_MINUTES = 60;
|
|
106
|
-
function truncateLine(text) {
|
|
107
|
-
const oneLine = text.replace(/\s*\n\s*/g, " \u23CE ");
|
|
108
|
-
if (oneLine.length <= MAX_LINE_CHARS) return oneLine;
|
|
109
|
-
const overflow = oneLine.length - MAX_LINE_CHARS;
|
|
110
|
-
return `${oneLine.slice(0, MAX_LINE_CHARS)}\u2026[+${overflow}c]`;
|
|
111
|
-
}
|
|
112
|
-
function entrySource(entry) {
|
|
113
|
-
return entry.resource.service_name ?? entry.resource.pod_name ?? entry.resource.database_id ?? entry.resourceType ?? "-";
|
|
114
|
-
}
|
|
115
|
-
var PAYLOAD_SKIP_KEYS = /* @__PURE__ */ new Set(["message", "severity", "timestamp", "level", "stack"]);
|
|
116
|
-
var PAYLOAD_PRIORITY = [
|
|
117
|
-
"error",
|
|
118
|
-
"outcome",
|
|
119
|
-
"serviceName",
|
|
120
|
-
"methodName",
|
|
121
|
-
"userId",
|
|
122
|
-
"taskId",
|
|
123
|
-
"sessionId",
|
|
124
|
-
"workspaceId",
|
|
125
|
-
"projectId",
|
|
126
|
-
"durationMs"
|
|
127
|
-
];
|
|
128
|
-
var PAYLOAD_VALUE_MAX_CHARS = 160;
|
|
129
|
-
function compactPayloadValue(value) {
|
|
130
|
-
const raw = typeof value === "string" ? value : JSON.stringify(value);
|
|
131
|
-
const flat = (raw ?? "undefined").replace(/\s+/g, " ");
|
|
132
|
-
const quoted = typeof value === "string" && /[\s"]/.test(flat) ? JSON.stringify(flat) : flat;
|
|
133
|
-
return quoted.length > PAYLOAD_VALUE_MAX_CHARS ? `${quoted.slice(0, PAYLOAD_VALUE_MAX_CHARS)}\u2026` : quoted;
|
|
134
|
-
}
|
|
135
|
-
function formatPayloadSuffix(payloadJson) {
|
|
136
|
-
if (!payloadJson) return "";
|
|
137
|
-
let parsed;
|
|
138
|
-
try {
|
|
139
|
-
parsed = JSON.parse(payloadJson);
|
|
140
|
-
} catch {
|
|
141
|
-
return "";
|
|
142
|
-
}
|
|
143
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "";
|
|
144
|
-
const obj = parsed;
|
|
145
|
-
const rank = (key) => {
|
|
146
|
-
const i = PAYLOAD_PRIORITY.indexOf(key);
|
|
147
|
-
return i === -1 ? PAYLOAD_PRIORITY.length : i;
|
|
148
|
-
};
|
|
149
|
-
const parts = Object.keys(obj).filter((k) => !PAYLOAD_SKIP_KEYS.has(k) && obj[k] !== void 0 && obj[k] !== null).sort((a, b) => rank(a) - rank(b) || a.localeCompare(b)).map((k) => `${k}=${compactPayloadValue(obj[k])}`);
|
|
150
|
-
return parts.length > 0 ? ` | ${parts.join(" ")}` : "";
|
|
151
|
-
}
|
|
152
|
-
function formatLogEntryLine(entry) {
|
|
153
|
-
const httpPrefix = entry.httpRequest?.status ? `http ${entry.httpRequest.status} ${entry.httpRequest.method ?? ""} ${entry.httpRequest.url ?? ""}`.trim() + " \u2014 " : "";
|
|
154
|
-
return `${entry.timestamp} ${entry.severity.padEnd(7)} [${entrySource(entry)}] ${truncateLine(
|
|
155
|
-
`${httpPrefix}${entry.message}${formatPayloadSuffix(entry.payload)}`
|
|
156
|
-
)}`;
|
|
157
|
-
}
|
|
158
|
-
async function runQueryGcpLogs(port, params, now = Date.now) {
|
|
159
|
-
const startTime = params.startTime ?? new Date(now() - (params.sinceMinutes ?? DEFAULT_SINCE_MINUTES) * 6e4).toISOString();
|
|
160
|
-
const result = await port.queryGcpLogs({
|
|
161
|
-
projectId: params.projectId,
|
|
162
|
-
env: params.env,
|
|
163
|
-
severity: params.severity,
|
|
164
|
-
services: params.services,
|
|
165
|
-
sqlInstances: params.sqlInstances,
|
|
166
|
-
allServices: params.allServices,
|
|
167
|
-
search: params.search,
|
|
168
|
-
filter: params.filter,
|
|
169
|
-
startTime,
|
|
170
|
-
endTime: params.endTime,
|
|
171
|
-
limit: params.limit,
|
|
172
|
-
pageToken: params.pageToken
|
|
173
|
-
});
|
|
174
|
-
if (result.error) return result.error;
|
|
175
|
-
const header = [
|
|
176
|
-
`env=${params.env ?? "prod"}`,
|
|
177
|
-
`window=${startTime}\u2192${params.endTime ?? "now"}`,
|
|
178
|
-
...params.severity ? [`minSeverity=${params.severity}`] : [],
|
|
179
|
-
`scope=${result.scopedServices ? `[${result.scopedServices.join(", ")}]` : "all"}`,
|
|
180
|
-
`entries=${result.entries.length}`
|
|
181
|
-
].join(" ");
|
|
182
|
-
const lines = result.entries.map(formatLogEntryLine);
|
|
183
|
-
const footer = result.nextPageToken ? [`-- more available: pass pageToken="${result.nextPageToken}" to continue`] : [];
|
|
184
|
-
if (lines.length === 0) {
|
|
185
|
-
return [
|
|
186
|
-
header,
|
|
187
|
-
"(no matching log entries \u2014 widen the window, lower minSeverity, or drop filters)"
|
|
188
|
-
].join("\n");
|
|
189
|
-
}
|
|
190
|
-
return [header, ...lines, ...footer].join("\n");
|
|
191
|
-
}
|
|
192
|
-
async function runQueryGrafanaLogs(port, params, now = Date.now) {
|
|
193
|
-
const startTime = params.startTime ?? new Date(now() - (params.sinceMinutes ?? DEFAULT_SINCE_MINUTES) * 6e4).toISOString();
|
|
194
|
-
const result = await port.queryGrafanaLogs({
|
|
195
|
-
projectId: params.projectId,
|
|
196
|
-
env: params.env,
|
|
197
|
-
level: params.level,
|
|
198
|
-
services: params.services,
|
|
199
|
-
search: params.search,
|
|
200
|
-
logql: params.logql,
|
|
201
|
-
startTime,
|
|
202
|
-
endTime: params.endTime,
|
|
203
|
-
limit: params.limit
|
|
204
|
-
});
|
|
205
|
-
if (result.error) return result.error;
|
|
206
|
-
const header = [
|
|
207
|
-
`env=${params.env ?? "prod"}`,
|
|
208
|
-
`window=${startTime}\u2192${params.endTime ?? "now"}`,
|
|
209
|
-
...params.level ? [`minLevel=${params.level}`] : [],
|
|
210
|
-
...result.logql ? [`logql=${truncateLine(result.logql)}`] : [],
|
|
211
|
-
`entries=${result.entries.length}`
|
|
212
|
-
].join(" ");
|
|
213
|
-
const lines = result.entries.map(formatLogEntryLine);
|
|
214
|
-
const oldest = result.entries.map((e) => e.timestamp).sort()[0];
|
|
215
|
-
const footer = result.hasMore ? [`-- hit the limit: older lines exist \u2014 pass endTime="${oldest}" to page further back`] : [];
|
|
216
|
-
if (lines.length === 0) {
|
|
217
|
-
return [
|
|
218
|
-
header,
|
|
219
|
-
"(no matching log entries \u2014 widen the window, lower minLevel, or drop filters)"
|
|
220
|
-
].join("\n");
|
|
221
|
-
}
|
|
222
|
-
return [header, ...lines, ...footer].join("\n");
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ../shared/dist/index.js
|
|
226
|
-
import { z } from "zod";
|
|
227
|
-
import { z as z2 } from "zod";
|
|
228
|
-
import { z as z3 } from "zod";
|
|
229
|
-
import { z as z4 } from "zod";
|
|
230
|
-
import { z as z5 } from "zod";
|
|
231
|
-
import { z as z6 } from "zod";
|
|
232
|
-
import { z as z7 } from "zod";
|
|
233
|
-
import { z as z8 } from "zod";
|
|
234
|
-
import { z as z9 } from "zod";
|
|
235
|
-
import { z as z10 } from "zod";
|
|
236
|
-
var EXTERNAL_AGENT_MESSAGE_SOURCE = "external_agent";
|
|
237
|
-
var DEFAULT_SONNET_MODEL = "claude-sonnet-5";
|
|
238
|
-
var DEFAULT_OPUS_MODEL = "claude-opus-5";
|
|
239
|
-
var DEFAULT_HAIKU_MODEL = "claude-haiku-4-5-20251001";
|
|
240
|
-
var FABLE_MODEL = "claude-fable-5-1";
|
|
241
|
-
var PREVIOUS_SONNET_MODEL = "claude-sonnet-4-6";
|
|
242
|
-
var PREVIOUS_OPUS_MODEL = "claude-opus-4-8";
|
|
243
|
-
var PTY_STREAM_PORT_BASE = 7420;
|
|
244
|
-
var PTY_STREAM_PORT_ATTEMPTS = 8;
|
|
245
|
-
function encodePtyStreamFrame(frame) {
|
|
246
|
-
return `${JSON.stringify(frame)}
|
|
247
|
-
`;
|
|
248
|
-
}
|
|
249
|
-
function isRecord(value) {
|
|
250
|
-
return typeof value === "object" && value !== null;
|
|
251
|
-
}
|
|
252
|
-
function parsePtyStreamFrame(line) {
|
|
253
|
-
if (!line) return null;
|
|
254
|
-
let parsed;
|
|
255
|
-
try {
|
|
256
|
-
parsed = JSON.parse(line);
|
|
257
|
-
} catch {
|
|
258
|
-
return null;
|
|
259
|
-
}
|
|
260
|
-
if (!isRecord(parsed) || typeof parsed.t !== "string") return null;
|
|
261
|
-
switch (parsed.t) {
|
|
262
|
-
case "hello":
|
|
263
|
-
case "data":
|
|
264
|
-
case "ended":
|
|
265
|
-
case "input":
|
|
266
|
-
case "resize":
|
|
267
|
-
return parsed;
|
|
268
|
-
default:
|
|
269
|
-
return null;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
var PtyStreamFrameReader = class {
|
|
273
|
-
constructor(onFrame) {
|
|
274
|
-
this.onFrame = onFrame;
|
|
275
|
-
}
|
|
276
|
-
onFrame;
|
|
277
|
-
buffer = "";
|
|
278
|
-
push(chunk) {
|
|
279
|
-
this.buffer += chunk;
|
|
280
|
-
let index = this.buffer.indexOf("\n");
|
|
281
|
-
while (index >= 0) {
|
|
282
|
-
const line = this.buffer.slice(0, index);
|
|
283
|
-
this.buffer = this.buffer.slice(index + 1);
|
|
284
|
-
const frame = parsePtyStreamFrame(line);
|
|
285
|
-
if (frame) this.onFrame(frame);
|
|
286
|
-
index = this.buffer.indexOf("\n");
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
var PREVIEW_PORT_DENY_LIST = [
|
|
291
|
-
5432,
|
|
292
|
-
6379,
|
|
293
|
-
9200,
|
|
294
|
-
...Array.from({ length: PTY_STREAM_PORT_ATTEMPTS }, (_, i) => PTY_STREAM_PORT_BASE + i)
|
|
295
|
-
];
|
|
296
|
-
function normalizeCheckpointPath(value) {
|
|
297
|
-
let normalized = value.trim().replace(/\/{2,}/g, "/");
|
|
298
|
-
normalized = normalized.split("/").filter((segment) => segment !== ".").join("/");
|
|
299
|
-
while (normalized.endsWith("/")) normalized = normalized.slice(0, -1);
|
|
300
|
-
return normalized;
|
|
301
|
-
}
|
|
302
|
-
var checkpointPathSchema = z.string().transform(normalizeCheckpointPath).pipe(
|
|
303
|
-
z.string().min(1).refine((value) => value !== ".", "Checkpoint paths must name a repository entry").refine((value) => !value.startsWith("/"), "Checkpoint paths must be repository-relative").refine(
|
|
304
|
-
(value) => !/^[A-Za-z]:[\\/]/.test(value) && !value.includes("\\"),
|
|
305
|
-
"Checkpoint paths must use repository-relative POSIX syntax"
|
|
306
|
-
).refine(
|
|
307
|
-
(value) => !value.split("/").includes(".."),
|
|
308
|
-
"Checkpoint paths must not traverse a parent directory"
|
|
309
|
-
)
|
|
310
|
-
);
|
|
311
|
-
var secretNameSchema = z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/);
|
|
312
|
-
var checkpointKeySchema = z.string().regex(/^[0-9a-f]{64}$/);
|
|
313
|
-
var checkpointDigestRefSchema = z.string().regex(/^[^\s@]+@sha256:[0-9a-f]{64}$/);
|
|
314
|
-
var ACTIONS_PREBAKE_REGISTRY_PATTERN = /^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?(?::(?:[1-9][0-9]{0,4}))?(?:\/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$/;
|
|
315
|
-
var actionsPrebakeRegistrySchema = z.string().trim().min(1).regex(
|
|
316
|
-
ACTIONS_PREBAKE_REGISTRY_PATTERN,
|
|
317
|
-
"Actions prebake registry must be a lowercase host[:port] with an optional path prefix"
|
|
318
|
-
).refine((value) => {
|
|
319
|
-
const port = /:([0-9]+)(?:\/|$)/.exec(value)?.[1];
|
|
320
|
-
return !port || Number(port) <= 65535;
|
|
321
|
-
}, "Actions prebake registry port must be between 1 and 65535");
|
|
322
|
-
function uniqueSortedArray(item, minimum = 0) {
|
|
323
|
-
return z.array(item).min(minimum).superRefine((values, ctx) => {
|
|
324
|
-
if (new Set(values).size !== values.length) {
|
|
325
|
-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Duplicate values are not allowed" });
|
|
326
|
-
}
|
|
327
|
-
}).transform((values) => [...values].sort());
|
|
328
|
-
}
|
|
329
|
-
var projectCheckpointSettingsSchema = z.object({
|
|
330
|
-
enabled: z.literal(true),
|
|
331
|
-
cacheCommand: z.string().trim().min(1),
|
|
332
|
-
cacheInputPaths: uniqueSortedArray(checkpointPathSchema, 1),
|
|
333
|
-
reusableArtifactPaths: uniqueSortedArray(checkpointPathSchema, 1),
|
|
334
|
-
finalizeCommand: z.string().trim().min(1),
|
|
335
|
-
credentialEpoch: z.string().trim().min(1),
|
|
336
|
-
requiredSecretNames: uniqueSortedArray(secretNameSchema).optional(),
|
|
337
|
-
optionalSecretNames: uniqueSortedArray(secretNameSchema).optional(),
|
|
338
|
-
bakeWebAppBuild: z.boolean().optional()
|
|
339
|
-
}).superRefine((checkpoint, ctx) => {
|
|
340
|
-
const required = new Set(checkpoint.requiredSecretNames ?? []);
|
|
341
|
-
for (const name of checkpoint.optionalSecretNames ?? []) {
|
|
342
|
-
if (required.has(name)) {
|
|
343
|
-
ctx.addIssue({
|
|
344
|
-
code: z.ZodIssueCode.custom,
|
|
345
|
-
path: ["optionalSecretNames"],
|
|
346
|
-
message: "A secret cannot be both required and optional"
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
var TUI_KINDS = ["claude-code", "opencode", "codex"];
|
|
352
|
-
var ACHIEVEMENT_RARITIES = [
|
|
353
|
-
{
|
|
354
|
-
key: "common",
|
|
355
|
-
name: "Common",
|
|
356
|
-
color: "#22c55e",
|
|
357
|
-
iconPath: "/storypoints/square-solid-full.svg"
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
key: "magic",
|
|
361
|
-
name: "Magic",
|
|
362
|
-
color: "#3b82f6",
|
|
363
|
-
iconPath: "/storypoints/diamond-solid-full.svg"
|
|
364
|
-
},
|
|
365
|
-
{ key: "rare", name: "Rare", color: "#eab308", iconPath: "/storypoints/gem-solid-full.svg" },
|
|
366
|
-
{
|
|
367
|
-
key: "unique",
|
|
368
|
-
name: "Unique",
|
|
369
|
-
color: "#f97316",
|
|
370
|
-
iconPath: "/storypoints/scroll-sharp-solid-full.svg"
|
|
371
|
-
},
|
|
372
|
-
{ key: "pack", name: "Pack", color: "#9c27b0", iconPath: "/storypoints/pack.svg" }
|
|
373
|
-
];
|
|
374
|
-
var RISK_LEVELS = ["critical", "high", "medium", "low"];
|
|
375
|
-
var riskLevelSchema = z2.enum(RISK_LEVELS);
|
|
376
|
-
var DEFAULT_RISK_LEVELS = [
|
|
377
|
-
{
|
|
378
|
-
level: "critical",
|
|
379
|
-
value: 4,
|
|
380
|
-
label: "Critical",
|
|
381
|
-
description: "Touches critical surface area; give it the closest review.",
|
|
382
|
-
color: "#dc2626",
|
|
383
|
-
ordinal: 0
|
|
384
|
-
},
|
|
385
|
-
{
|
|
386
|
-
level: "high",
|
|
387
|
-
value: 3,
|
|
388
|
-
label: "Elevated",
|
|
389
|
-
description: "Touches important surface area; review carefully.",
|
|
390
|
-
color: "#ea580c",
|
|
391
|
-
ordinal: 1
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
level: "medium",
|
|
395
|
-
value: 2,
|
|
396
|
-
label: "Moderate",
|
|
397
|
-
description: "Moderate surface area; normal review.",
|
|
398
|
-
color: "#d97706",
|
|
399
|
-
ordinal: 2
|
|
400
|
-
},
|
|
401
|
-
{
|
|
402
|
-
level: "low",
|
|
403
|
-
value: 1,
|
|
404
|
-
label: "Minimal",
|
|
405
|
-
description: "Small or isolated surface area.",
|
|
406
|
-
color: "#64748b",
|
|
407
|
-
ordinal: 3
|
|
408
|
-
}
|
|
409
|
-
];
|
|
410
|
-
var LEVEL_BY_VALUE = new Map(
|
|
411
|
-
DEFAULT_RISK_LEVELS.map((m) => [m.value, m.level])
|
|
412
|
-
);
|
|
413
|
-
var ACTIVE_WORK_STATUSES = [
|
|
414
|
-
"InProgress",
|
|
415
|
-
"ReviewPR",
|
|
416
|
-
"ReviewDev",
|
|
417
|
-
"ReviewLive",
|
|
418
|
-
"Complete"
|
|
419
|
-
];
|
|
420
|
-
var IDENTIFIED_WORK_STATUSES = ["Open", ...ACTIVE_WORK_STATUSES];
|
|
421
|
-
var DEFAULT_TASK_STATUS_COLOR = "#a8a29e";
|
|
422
|
-
var DEFAULT_TASK_STATUS_COLOR_INT = Number.parseInt(DEFAULT_TASK_STATUS_COLOR.slice(1), 16);
|
|
423
|
-
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
424
|
-
var MAX_FILE_TAGS = 5;
|
|
425
|
-
var MAX_FILE_TAG_LENGTH = 100;
|
|
426
|
-
var EMBED_THRESHOLD_IMAGES = 5 * 1024 * 1024;
|
|
427
|
-
var EMBED_THRESHOLD_TEXT = 2 * 1024 * 1024;
|
|
428
|
-
var IDLE_HEARTBEAT_MS = 90 * 1e3;
|
|
429
|
-
var RUNNER_MODES = [
|
|
430
|
-
"task",
|
|
431
|
-
"plan",
|
|
432
|
-
"pm",
|
|
433
|
-
"code-review",
|
|
434
|
-
"adhoc",
|
|
435
|
-
"pack",
|
|
436
|
-
"shell",
|
|
437
|
-
"serving"
|
|
438
|
-
];
|
|
439
|
-
var TurnEndToolCallSchema = z3.object({
|
|
440
|
-
tool: z3.string(),
|
|
441
|
-
input: z3.string().optional(),
|
|
442
|
-
output: z3.string().optional(),
|
|
443
|
-
timestamp: z3.string().optional()
|
|
444
|
-
}).passthrough();
|
|
445
|
-
var KnownAgentEventSchema = z3.discriminatedUnion("type", [
|
|
446
|
-
// ── Lifecycle / connection ────────────────────────────────────────────
|
|
447
|
-
z3.object({
|
|
448
|
-
type: z3.literal("connected"),
|
|
449
|
-
sessionId: z3.string(),
|
|
450
|
-
projectId: z3.string().optional()
|
|
451
|
-
}).passthrough(),
|
|
452
|
-
// Open-ended context snapshot spread from buildInitializationContext().
|
|
453
|
-
z3.object({ type: z3.literal("session_manifest") }).passthrough(),
|
|
454
|
-
z3.object({
|
|
455
|
-
type: z3.literal("agent_runner_status"),
|
|
456
|
-
reason: z3.string(),
|
|
457
|
-
attempt: z3.number().optional(),
|
|
458
|
-
attempts: z3.number().optional()
|
|
459
|
-
}).passthrough(),
|
|
460
|
-
z3.object({ type: z3.literal("shutdown"), reason: z3.string().optional() }).passthrough(),
|
|
461
|
-
z3.object({ type: z3.literal("mode_changed"), agentMode: z3.string() }).passthrough(),
|
|
462
|
-
z3.object({ type: z3.literal("mode_transition"), from: z3.string(), to: z3.string() }).passthrough(),
|
|
463
|
-
// ── Turn stream ───────────────────────────────────────────────────────
|
|
464
|
-
z3.object({ type: z3.literal("message"), content: z3.string() }).passthrough(),
|
|
465
|
-
z3.object({ type: z3.literal("thinking"), message: z3.string() }).passthrough(),
|
|
466
|
-
z3.object({
|
|
467
|
-
type: z3.literal("tool_use"),
|
|
468
|
-
tool: z3.string(),
|
|
469
|
-
// Producers send JSON.stringify(input); consumers defend against
|
|
470
|
-
// object inputs from older agents, so the wire stays permissive here.
|
|
471
|
-
input: z3.unknown().optional()
|
|
472
|
-
}).passthrough(),
|
|
473
|
-
z3.object({
|
|
474
|
-
type: z3.literal("tool_result"),
|
|
475
|
-
tool: z3.string(),
|
|
476
|
-
output: z3.unknown().optional(),
|
|
477
|
-
isError: z3.boolean().optional(),
|
|
478
|
-
redactedCount: z3.number().optional()
|
|
479
|
-
}).passthrough(),
|
|
480
|
-
z3.object({ type: z3.literal("turn_end"), toolCalls: z3.array(TurnEndToolCallSchema) }).passthrough(),
|
|
481
|
-
z3.object({
|
|
482
|
-
type: z3.literal("completed"),
|
|
483
|
-
summary: z3.string().optional(),
|
|
484
|
-
durationMs: z3.number().optional()
|
|
485
|
-
}).passthrough(),
|
|
486
|
-
z3.object({ type: z3.literal("error"), message: z3.string() }).passthrough(),
|
|
487
|
-
z3.object({ type: z3.literal("agent_typing_start") }).passthrough(),
|
|
488
|
-
z3.object({ type: z3.literal("agent_typing_stop") }).passthrough(),
|
|
489
|
-
// ── Telemetry ─────────────────────────────────────────────────────────
|
|
490
|
-
// heartbeat/typing: legacy telemetry the server still classifies as
|
|
491
|
-
// transient (TRANSIENT_EVENT_TYPES) — kept in the vocabulary.
|
|
492
|
-
z3.object({ type: z3.literal("heartbeat") }).passthrough(),
|
|
493
|
-
z3.object({ type: z3.literal("typing") }).passthrough(),
|
|
494
|
-
z3.object({
|
|
495
|
-
type: z3.literal("context_update"),
|
|
496
|
-
contextTokens: z3.number(),
|
|
497
|
-
contextWindow: z3.number(),
|
|
498
|
-
inputTokens: z3.number().optional(),
|
|
499
|
-
cacheReadInputTokens: z3.number().optional(),
|
|
500
|
-
cacheCreationInputTokens: z3.number().optional(),
|
|
501
|
-
totalTokensUsed: z3.number().optional()
|
|
502
|
-
}).passthrough(),
|
|
503
|
-
// Four producer shapes share this type: {rateLimitType, utilization, status}
|
|
504
|
-
// (SDK rate_limit_event), {resetsAt} (agent-connection resume notice), the
|
|
505
|
-
// usage-sampler ({rateLimitType, utilization, status, resetsAt, gauges}
|
|
506
|
-
// — resetsAt matches rateLimitType; gauges survives via .passthrough()), and
|
|
507
|
-
// {unmeasurable, reason} (the sampler reporting it cannot read this key).
|
|
508
|
-
z3.object({
|
|
509
|
-
type: z3.literal("rate_limit_update"),
|
|
510
|
-
rateLimitType: z3.string().optional(),
|
|
511
|
-
utilization: z3.number().optional(),
|
|
512
|
-
status: z3.string().optional(),
|
|
513
|
-
resetsAt: z3.string().optional(),
|
|
514
|
-
unmeasurable: z3.boolean().optional(),
|
|
515
|
-
reason: z3.string().optional()
|
|
516
|
-
}).passthrough(),
|
|
517
|
-
z3.object({
|
|
518
|
-
type: z3.literal("context_compacted"),
|
|
519
|
-
trigger: z3.string().optional(),
|
|
520
|
-
preTokens: z3.number().optional()
|
|
521
|
-
}).passthrough(),
|
|
522
|
-
z3.object({
|
|
523
|
-
type: z3.literal("tool_progress"),
|
|
524
|
-
toolName: z3.string().optional(),
|
|
525
|
-
elapsedSeconds: z3.number().optional()
|
|
526
|
-
}).passthrough(),
|
|
527
|
-
z3.object({
|
|
528
|
-
type: z3.literal("subagent_started"),
|
|
529
|
-
sdkTaskId: z3.string().optional(),
|
|
530
|
-
description: z3.string().optional()
|
|
531
|
-
}).passthrough(),
|
|
532
|
-
z3.object({
|
|
533
|
-
type: z3.literal("subagent_progress"),
|
|
534
|
-
sdkTaskId: z3.string().optional(),
|
|
535
|
-
description: z3.string().optional(),
|
|
536
|
-
toolUses: z3.number().optional(),
|
|
537
|
-
durationMs: z3.number().optional()
|
|
538
|
-
}).passthrough(),
|
|
539
|
-
// ── Work products ─────────────────────────────────────────────────────
|
|
540
|
-
z3.object({ type: z3.literal("pr_created"), url: z3.string(), number: z3.number() }).passthrough(),
|
|
541
|
-
z3.object({
|
|
542
|
-
type: z3.literal("code_review_complete"),
|
|
543
|
-
result: z3.enum(["approved", "changes_requested"]),
|
|
544
|
-
summary: z3.string().optional(),
|
|
545
|
-
issues: z3.array(
|
|
546
|
-
z3.object({
|
|
547
|
-
file: z3.string(),
|
|
548
|
-
line: z3.number().optional(),
|
|
549
|
-
severity: z3.string().optional(),
|
|
550
|
-
description: z3.string().optional()
|
|
551
|
-
}).passthrough()
|
|
552
|
-
).optional()
|
|
553
|
-
}).passthrough(),
|
|
554
|
-
// ── Environment setup / start command ─────────────────────────────────
|
|
555
|
-
z3.object({ type: z3.literal("setup_output"), stream: z3.string(), data: z3.string() }).passthrough(),
|
|
556
|
-
z3.object({
|
|
557
|
-
type: z3.literal("setup_complete"),
|
|
558
|
-
startCommandRunning: z3.boolean().optional(),
|
|
559
|
-
startCommandConfigured: z3.boolean().optional(),
|
|
560
|
-
// Sanitized server-side by sanitizeSessionPreviewPorts — stays unknown.
|
|
561
|
-
previewPorts: z3.unknown().optional()
|
|
562
|
-
}).passthrough(),
|
|
563
|
-
z3.object({ type: z3.literal("setup_error"), message: z3.string() }).passthrough(),
|
|
564
|
-
z3.object({ type: z3.literal("start_command_started") }).passthrough(),
|
|
565
|
-
z3.object({ type: z3.literal("start_command_output"), stream: z3.string(), data: z3.string() }).passthrough(),
|
|
566
|
-
z3.object({
|
|
567
|
-
type: z3.literal("start_command_exited"),
|
|
568
|
-
code: z3.number().nullable().optional(),
|
|
569
|
-
signal: z3.string().nullable().optional(),
|
|
570
|
-
message: z3.string().optional()
|
|
571
|
-
}).passthrough(),
|
|
572
|
-
z3.object({ type: z3.literal("start_command_error"), message: z3.string() }).passthrough()
|
|
573
|
-
]);
|
|
574
|
-
var AgentEventSchema = z3.union([
|
|
575
|
-
KnownAgentEventSchema,
|
|
576
|
-
z3.object({ type: z3.string().min(1) }).catchall(z3.unknown())
|
|
577
|
-
]);
|
|
578
|
-
var cardDescription = z4.string().max(CARD_DESCRIPTION_MAX, CARD_DESCRIPTION_LIMIT_MESSAGE).optional();
|
|
579
|
-
var AgentHeartbeatSchema = z4.object({
|
|
580
|
-
sessionId: z4.string().optional(),
|
|
581
|
-
timestamp: z4.string(),
|
|
582
|
-
status: z4.enum(["active", "idle", "building"]),
|
|
583
|
-
currentAction: z4.string().optional(),
|
|
584
|
-
/** Sender-observed main event-loop lag (ms) — see AgentHeartbeat.loopLagMs. */
|
|
585
|
-
loopLagMs: z4.number().nonnegative().optional()
|
|
586
|
-
});
|
|
587
|
-
var CreatePRInputSchema = z4.object({
|
|
588
|
-
title: z4.string().min(1),
|
|
589
|
-
body: z4.string(),
|
|
590
|
-
head: z4.string().optional(),
|
|
591
|
-
base: z4.string().optional()
|
|
592
|
-
});
|
|
593
|
-
var PostToChatInputSchema = z4.object({
|
|
594
|
-
message: z4.string().min(1),
|
|
595
|
-
type: z4.enum(["message", "question", "update"]).optional().default("message"),
|
|
596
|
-
milestone: z4.enum(["plan_ready", "implementation_complete", "blocked"]).optional()
|
|
597
|
-
});
|
|
598
|
-
var GetTaskContextRequestSchema = z4.object({
|
|
599
|
-
sessionId: z4.string(),
|
|
600
|
-
includeHistory: z4.boolean().optional().default(false),
|
|
601
|
-
/**
|
|
602
|
-
* Read the plan-revised marker WITHOUT consuming it. Bookkeeping fetches
|
|
603
|
-
* (the session-identity check, the branch refresh) pass true so they cannot
|
|
604
|
-
* race the boot fetch and swallow the notice before it reaches the prompt.
|
|
605
|
-
* Defaults to false — consuming — so a pod running an older agent build still
|
|
606
|
-
* clears the marker instead of showing the notice on every boot forever.
|
|
607
|
-
*/
|
|
608
|
-
peekPlanRevision: z4.boolean().optional().default(false)
|
|
609
|
-
});
|
|
610
|
-
var GetChatMessagesRequestSchema = z4.object({
|
|
611
|
-
sessionId: z4.string(),
|
|
612
|
-
limit: z4.number().int().positive().optional().default(50),
|
|
613
|
-
offset: z4.number().int().nonnegative().optional().default(0),
|
|
614
|
-
/** Task id or slug to read chat from. Omit for the session's own task. Only
|
|
615
|
-
* the session's own task or one of its children resolves — anything else is
|
|
616
|
-
* an error, never a silent fallback to the caller's own chat. */
|
|
617
|
-
taskId: z4.string().optional()
|
|
618
|
-
});
|
|
619
|
-
var GetTaskFilesRequestSchema = z4.object({
|
|
620
|
-
sessionId: z4.string()
|
|
621
|
-
});
|
|
622
|
-
var GetTaskFileRequestSchema = z4.object({
|
|
623
|
-
sessionId: z4.string(),
|
|
624
|
-
fileId: z4.string()
|
|
625
|
-
});
|
|
626
|
-
var GetTaskRequestSchema = z4.object({
|
|
627
|
-
sessionId: z4.string(),
|
|
628
|
-
taskSlugOrId: z4.string()
|
|
629
|
-
});
|
|
630
|
-
var GetCliHistoryRequestSchema = z4.object({
|
|
631
|
-
sessionId: z4.string(),
|
|
632
|
-
limit: z4.number().int().positive().optional().default(100),
|
|
633
|
-
source: z4.enum(["agent", "application"]).optional(),
|
|
634
|
-
/** Task id or slug to read logs from. Omit for the session's own task. Only
|
|
635
|
-
* the session's own task or one of its children resolves — anything else is
|
|
636
|
-
* an error, never a silent fallback to the caller's own logs. */
|
|
637
|
-
taskId: z4.string().optional()
|
|
638
|
-
});
|
|
639
|
-
var ListSubtasksRequestSchema = z4.object({
|
|
640
|
-
sessionId: z4.string(),
|
|
641
|
-
/** "compact" returns the slim orchestration view (ListSubtasksCompactResponse)
|
|
642
|
-
* with the pack build-slot picture; "full" (default — wire-compat with older
|
|
643
|
-
* agents) returns the verbose SubtaskSummaryDTO[] including description/plan. */
|
|
644
|
-
view: z4.enum(["compact", "full"]).optional()
|
|
645
|
-
});
|
|
646
|
-
var GetDependenciesRequestSchema = z4.object({
|
|
647
|
-
sessionId: z4.string()
|
|
648
|
-
});
|
|
649
|
-
var GetSuggestionsRequestSchema = z4.object({
|
|
650
|
-
sessionId: z4.string(),
|
|
651
|
-
status: z4.string().optional(),
|
|
652
|
-
limit: z4.number().int().min(1).max(100).optional()
|
|
653
|
-
});
|
|
654
|
-
var ListManualTestsRequestSchema = z4.object({
|
|
655
|
-
sessionId: z4.string()
|
|
656
|
-
});
|
|
657
|
-
var QueryManualTestsRequestSchema = z4.object({
|
|
658
|
-
sessionId: z4.string(),
|
|
659
|
-
cardStatuses: z4.array(z4.string()).optional(),
|
|
660
|
-
testStatuses: z4.array(z4.enum(["open", "approved", "rejected"])).optional()
|
|
661
|
-
});
|
|
662
|
-
var CreatePullRequestRequestSchema = CreatePRInputSchema.extend({ sessionId: z4.string() });
|
|
663
|
-
var RequestFileUploadRequestSchema = z4.object({
|
|
664
|
-
sessionId: z4.string(),
|
|
665
|
-
fileName: z4.string().min(1).max(255),
|
|
666
|
-
mimeType: z4.string().min(1).max(128),
|
|
667
|
-
fileSize: z4.number().int().positive().max(MAX_FILE_SIZE_BYTES)
|
|
668
|
-
});
|
|
669
|
-
var ConfirmFileUploadRequestSchema = z4.object({
|
|
670
|
-
sessionId: z4.string(),
|
|
671
|
-
fileId: z4.string(),
|
|
672
|
-
title: z4.string().max(500).optional(),
|
|
673
|
-
/** Glossary tag names (or ids) this file is an example of. */
|
|
674
|
-
tags: z4.array(z4.string().min(1).max(MAX_FILE_TAG_LENGTH)).max(MAX_FILE_TAGS).optional()
|
|
675
|
-
});
|
|
676
|
-
var UpdateTaskStatusRequestSchema = z4.object({
|
|
677
|
-
sessionId: z4.string(),
|
|
678
|
-
status: z4.string(),
|
|
679
|
-
force: z4.boolean().optional().default(false)
|
|
680
|
-
});
|
|
681
|
-
var StoreSessionIdRequestSchema = z4.object({
|
|
682
|
-
sessionId: z4.string(),
|
|
683
|
-
sdkSessionId: z4.string()
|
|
684
|
-
});
|
|
685
|
-
var SetManualTestsRequestSchema = z4.object({
|
|
686
|
-
sessionId: z4.string(),
|
|
687
|
-
items: z4.array(z4.object({ title: z4.string().min(1) })).min(1)
|
|
688
|
-
});
|
|
689
|
-
var EditManualTestRequestSchema = z4.object({
|
|
690
|
-
sessionId: z4.string(),
|
|
691
|
-
title: z4.string().min(1),
|
|
692
|
-
newTitle: z4.string().min(1)
|
|
693
|
-
});
|
|
694
|
-
var RemoveManualTestRequestSchema = z4.object({
|
|
695
|
-
sessionId: z4.string(),
|
|
696
|
-
title: z4.string().min(1)
|
|
697
|
-
});
|
|
698
|
-
var ApproveManualTestRequestSchema = z4.object({
|
|
699
|
-
sessionId: z4.string(),
|
|
700
|
-
title: z4.string().min(1)
|
|
701
|
-
});
|
|
702
|
-
var RejectManualTestRequestSchema = z4.object({
|
|
703
|
-
sessionId: z4.string(),
|
|
704
|
-
title: z4.string().min(1),
|
|
705
|
-
reason: z4.string().min(1).max(2e3)
|
|
706
|
-
});
|
|
707
|
-
var SessionStartRequestSchema = z4.object({
|
|
708
|
-
sessionId: z4.string(),
|
|
709
|
-
agentVersion: z4.string(),
|
|
710
|
-
capabilities: z4.array(z4.string())
|
|
711
|
-
});
|
|
712
|
-
var SessionStopRequestSchema = z4.object({
|
|
713
|
-
sessionId: z4.string(),
|
|
714
|
-
reason: z4.string().optional()
|
|
715
|
-
});
|
|
716
|
-
var EndReviewSessionRequestSchema = z4.object({
|
|
717
|
-
sessionId: z4.string(),
|
|
718
|
-
reason: z4.enum(["approved", "changes_requested", "finished"]).optional()
|
|
719
|
-
});
|
|
720
|
-
var ConnectAgentRequestSchema = z4.object({
|
|
721
|
-
sessionId: z4.string()
|
|
722
|
-
});
|
|
723
|
-
var ReportAgentStatusRequestSchema = z4.object({
|
|
724
|
-
sessionId: z4.string(),
|
|
725
|
-
status: z4.string(),
|
|
726
|
-
/** Why the agent reports this status (e.g. "user_question" while an AskUserQuestion questionnaire is pending in the TUI). */
|
|
727
|
-
reason: z4.string().optional(),
|
|
728
|
-
/**
|
|
729
|
-
* The pending question text, sent only alongside `reason: "user_question"`
|
|
730
|
-
* so the server can surface it in the user-question notification body (and
|
|
731
|
-
* thus the Attention feed) instead of a generic string. Optional: older
|
|
732
|
-
* agents omit it and the server falls back to the generic wording.
|
|
733
|
-
*/
|
|
734
|
-
questionText: z4.string().optional()
|
|
735
|
-
});
|
|
736
|
-
var NotifyAgentVersionRequestSchema = z4.object({
|
|
737
|
-
sessionId: z4.string(),
|
|
738
|
-
agentVersion: z4.string()
|
|
739
|
-
});
|
|
740
|
-
var DiscoveredPortSchema = z4.object({
|
|
741
|
-
port: z4.number().int().min(1).max(65535),
|
|
742
|
-
label: z4.string().min(1).max(64).optional(),
|
|
743
|
-
protocol: z4.enum(["http", "tcp"]).optional(),
|
|
744
|
-
detectedAt: z4.string()
|
|
745
|
-
});
|
|
746
|
-
var ReportDiscoveredPortsRequestSchema = z4.object({
|
|
747
|
-
sessionId: z4.string(),
|
|
748
|
-
ports: z4.array(DiscoveredPortSchema).max(64)
|
|
749
|
-
});
|
|
750
|
-
var ReportBootMilestoneRequestSchema = z4.object({
|
|
751
|
-
sessionId: z4.string(),
|
|
752
|
-
key: z4.string().max(64)
|
|
753
|
-
});
|
|
754
|
-
var CreateSubtaskRequestSchema = z4.object({
|
|
755
|
-
sessionId: z4.string(),
|
|
756
|
-
title: z4.string().min(1),
|
|
757
|
-
description: cardDescription,
|
|
758
|
-
plan: z4.string().optional(),
|
|
759
|
-
storyPointValue: z4.number().int().positive().optional(),
|
|
760
|
-
ordinal: z4.number().int().nonnegative().optional(),
|
|
761
|
-
followParentStatus: z4.boolean().optional(),
|
|
762
|
-
/** Sibling subtask ids or slugs this subtask blocks on (explicit dependency
|
|
763
|
-
* metadata — preferred over encoding order in plan text / ordinal). */
|
|
764
|
-
dependsOn: z4.array(z4.string().min(1)).max(32).optional(),
|
|
765
|
-
/** Glossary tag names to assign to the child. Unmatched names come back in
|
|
766
|
-
* the response rather than failing the create. */
|
|
767
|
-
tags: z4.array(z4.string().min(1)).max(10).optional()
|
|
768
|
-
});
|
|
769
|
-
var UpdateSubtaskRequestSchema = z4.object({
|
|
770
|
-
sessionId: z4.string(),
|
|
771
|
-
subtaskId: z4.string(),
|
|
772
|
-
title: z4.string().min(1).optional(),
|
|
773
|
-
description: cardDescription,
|
|
774
|
-
plan: z4.string().optional(),
|
|
775
|
-
/** Orchestration statuses only ("Planning" | "Open") — the pack parent's
|
|
776
|
-
* sanctioned promotion path. Execution statuses stay with the build
|
|
777
|
-
* pipeline / force_update_task_status. Enforced server-side. */
|
|
778
|
-
status: z4.string().optional(),
|
|
779
|
-
/** Assign a project agent to the child — accepts the agent's id or exact
|
|
780
|
-
* name; resolved against the parent task's project server-side. */
|
|
781
|
-
agentIdOrName: z4.string().min(1).optional(),
|
|
782
|
-
storyPointValue: z4.number().int().positive().optional(),
|
|
783
|
-
followParentStatus: z4.boolean().optional(),
|
|
784
|
-
/** Replace this subtask's dependency edges with these sibling ids/slugs.
|
|
785
|
-
* Empty array clears all. Omit to leave dependencies unchanged. */
|
|
786
|
-
dependsOn: z4.array(z4.string().min(1)).max(32).optional()
|
|
787
|
-
});
|
|
788
|
-
var DeleteSubtaskRequestSchema = z4.object({
|
|
789
|
-
sessionId: z4.string(),
|
|
790
|
-
subtaskId: z4.string()
|
|
791
|
-
});
|
|
792
|
-
var SetSubtaskParentRequestSchema = z4.object({
|
|
793
|
-
sessionId: z4.string(),
|
|
794
|
-
taskId: z4.string().min(1),
|
|
795
|
-
detach: z4.boolean().optional(),
|
|
796
|
-
ordinal: z4.number().int().nonnegative().optional(),
|
|
797
|
-
followParentStatus: z4.boolean().optional()
|
|
798
|
-
});
|
|
799
|
-
var GetTaskPropertiesRequestSchema = z4.object({
|
|
800
|
-
sessionId: z4.string()
|
|
801
|
-
});
|
|
802
|
-
var UpdateTaskFieldsRequestSchema = z4.object({
|
|
803
|
-
sessionId: z4.string(),
|
|
804
|
-
plan: z4.string().optional(),
|
|
805
|
-
description: cardDescription
|
|
806
|
-
});
|
|
807
|
-
var UpdateTaskPropertiesRequestSchema = z4.object({
|
|
808
|
-
sessionId: z4.string(),
|
|
809
|
-
title: z4.string().optional(),
|
|
810
|
-
storyPointValue: z4.number().int().positive().optional(),
|
|
811
|
-
tagIds: z4.array(z4.string()).optional(),
|
|
812
|
-
tagNames: z4.array(z4.string()).optional(),
|
|
813
|
-
githubPRUrl: z4.string().url().optional(),
|
|
814
|
-
githubBranch: z4.string().optional(),
|
|
815
|
-
// Canonical risk level, or null to clear — same semantics as the headless
|
|
816
|
-
// update_task boundary (resolved to the project's Risk row in the handler).
|
|
817
|
-
risk: riskLevelSchema.nullable().optional()
|
|
818
|
-
});
|
|
819
|
-
var ListIconsRequestSchema = z4.object({
|
|
820
|
-
sessionId: z4.string()
|
|
821
|
-
});
|
|
822
|
-
var GenerateTaskIconRequestSchema = z4.object({
|
|
823
|
-
sessionId: z4.string(),
|
|
824
|
-
prompt: z4.string().min(1),
|
|
825
|
-
aspectRatio: z4.string().optional()
|
|
826
|
-
});
|
|
827
|
-
var SearchFaIconsRequestSchema = z4.object({
|
|
828
|
-
sessionId: z4.string(),
|
|
829
|
-
query: z4.string().min(1),
|
|
830
|
-
first: z4.number().int().positive().optional()
|
|
831
|
-
});
|
|
832
|
-
var PickFaIconRequestSchema = z4.object({
|
|
833
|
-
sessionId: z4.string(),
|
|
834
|
-
fontAwesomeId: z4.string().min(1),
|
|
835
|
-
fontAwesomeStyle: z4.string().optional()
|
|
836
|
-
});
|
|
837
|
-
var CreateFollowUpTaskRequestSchema = z4.object({
|
|
838
|
-
sessionId: z4.string(),
|
|
839
|
-
title: z4.string().min(1),
|
|
840
|
-
description: cardDescription,
|
|
841
|
-
plan: z4.string().optional(),
|
|
842
|
-
storyPointValue: z4.number().int().positive().optional()
|
|
843
|
-
});
|
|
844
|
-
var AddDependencyRequestSchema = z4.object({
|
|
845
|
-
sessionId: z4.string(),
|
|
846
|
-
dependsOnSlugOrId: z4.string()
|
|
847
|
-
});
|
|
848
|
-
var RemoveDependencyRequestSchema = z4.object({
|
|
849
|
-
sessionId: z4.string(),
|
|
850
|
-
dependsOnSlugOrId: z4.string()
|
|
851
|
-
});
|
|
852
|
-
var CreateSuggestionRequestSchema = z4.object({
|
|
853
|
-
sessionId: z4.string(),
|
|
854
|
-
title: z4.string().min(1),
|
|
855
|
-
description: cardDescription,
|
|
856
|
-
tagNames: z4.array(z4.string()).optional()
|
|
857
|
-
});
|
|
858
|
-
var VoteSuggestionRequestSchema = z4.object({
|
|
859
|
-
sessionId: z4.string(),
|
|
860
|
-
suggestionId: z4.string(),
|
|
861
|
-
value: z4.union([z4.literal(1), z4.literal(-1)])
|
|
862
|
-
});
|
|
863
|
-
var TriggerIdentificationRequestSchema = z4.object({
|
|
864
|
-
sessionId: z4.string()
|
|
865
|
-
});
|
|
866
|
-
var HandoffToImplementerRequestSchema = z4.object({
|
|
867
|
-
sessionId: z4.string(),
|
|
868
|
-
// Optional difficulty sizing — sets the task's story points before resolving
|
|
869
|
-
// the matched implementer agent. Omit to hand off using the task's current
|
|
870
|
-
// story points (or the project's default task agent when unsized).
|
|
871
|
-
storyPoints: z4.number().int().positive().optional(),
|
|
872
|
-
// Optional kickoff note posted to the task chat alongside the handoff notice.
|
|
873
|
-
message: z4.string().optional()
|
|
874
|
-
});
|
|
875
|
-
var SubmitCodeReviewResultRequestSchema = z4.object({
|
|
876
|
-
sessionId: z4.string(),
|
|
877
|
-
approved: z4.boolean(),
|
|
878
|
-
content: z4.string(),
|
|
879
|
-
// Canonical risk level the reviewer assigned to this change. Required on every
|
|
880
|
-
// verdict — the reviewer must judge it. Applied authoritatively server-side
|
|
881
|
-
// (may raise OR lower an already-set value; the reviewer has that authority).
|
|
882
|
-
risk: riskLevelSchema,
|
|
883
|
-
// The commit SHA the reviewer actually reviewed. When present, the verdict is
|
|
884
|
-
// rejected unless the task is still at this SHA (guards against a late
|
|
885
|
-
// old-SHA verdict overwriting a newer review cycle).
|
|
886
|
-
reviewedSha: z4.string().optional()
|
|
887
|
-
});
|
|
888
|
-
var CycleCodingAgentKeyRequestSchema = z4.object({
|
|
889
|
-
sessionId: z4.string(),
|
|
890
|
-
rateLimitType: z4.string(),
|
|
891
|
-
resetsAt: z4.string().optional()
|
|
892
|
-
});
|
|
893
|
-
var StartChildCloudBuildRequestSchema = z4.object({
|
|
894
|
-
sessionId: z4.string(),
|
|
895
|
-
childTaskId: z4.string()
|
|
896
|
-
});
|
|
897
|
-
var StopChildBuildRequestSchema = z4.object({
|
|
898
|
-
sessionId: z4.string(),
|
|
899
|
-
childTaskId: z4.string()
|
|
900
|
-
});
|
|
901
|
-
var ApproveAndMergePRRequestSchema = z4.object({
|
|
902
|
-
sessionId: z4.string(),
|
|
903
|
-
childTaskId: z4.string()
|
|
904
|
-
});
|
|
905
|
-
var PostChildChatMessageRequestSchema = z4.object({
|
|
906
|
-
sessionId: z4.string(),
|
|
907
|
-
childTaskId: z4.string(),
|
|
908
|
-
message: z4.string().min(1)
|
|
909
|
-
});
|
|
910
|
-
var UpdateChildStatusRequestSchema = z4.object({
|
|
911
|
-
sessionId: z4.string(),
|
|
912
|
-
childTaskId: z4.string(),
|
|
913
|
-
status: z4.string()
|
|
914
|
-
});
|
|
915
|
-
var GetAgentStatusRequestSchema = z4.object({
|
|
916
|
-
taskId: z4.string()
|
|
917
|
-
});
|
|
918
|
-
var GetUiCliHistoryRequestSchema = z4.object({
|
|
919
|
-
taskId: z4.string()
|
|
920
|
-
});
|
|
921
|
-
var GetActivePtySessionRequestSchema = z4.object({
|
|
922
|
-
taskId: z4.string()
|
|
923
|
-
});
|
|
924
|
-
var ListActivePtySessionsRequestSchema = z4.object({
|
|
925
|
-
taskId: z4.string()
|
|
926
|
-
});
|
|
927
|
-
var SendSoftStopRequestSchema = z4.object({
|
|
928
|
-
taskId: z4.string()
|
|
929
|
-
});
|
|
930
|
-
var StopTaskSessionRequestSchema = z4.object({
|
|
931
|
-
taskId: z4.string(),
|
|
932
|
-
sessionId: z4.string()
|
|
933
|
-
});
|
|
934
|
-
var FlushTaskQueueRequestSchema = z4.object({
|
|
935
|
-
taskId: z4.string(),
|
|
936
|
-
softStop: z4.boolean().optional()
|
|
937
|
-
});
|
|
938
|
-
var CancelTaskQueuedMessageRequestSchema = z4.object({
|
|
939
|
-
taskId: z4.string(),
|
|
940
|
-
messageId: z4.string()
|
|
941
|
-
});
|
|
942
|
-
var FlushSingleQueuedMessageRequestSchema = z4.object({
|
|
943
|
-
taskId: z4.string(),
|
|
944
|
-
messageId: z4.string(),
|
|
945
|
-
softStop: z4.boolean().optional()
|
|
946
|
-
});
|
|
947
|
-
var AnswerAgentQuestionRequestSchema = z4.object({
|
|
948
|
-
taskId: z4.string(),
|
|
949
|
-
requestId: z4.string(),
|
|
950
|
-
answers: z4.record(z4.string(), z4.string())
|
|
951
|
-
});
|
|
952
|
-
var ClearAgentTodosRequestSchema = z4.object({
|
|
953
|
-
taskId: z4.string()
|
|
954
|
-
});
|
|
955
|
-
var AgentQuestionOptionSchema = z4.object({
|
|
956
|
-
label: z4.string(),
|
|
957
|
-
description: z4.string(),
|
|
958
|
-
preview: z4.string().optional()
|
|
959
|
-
});
|
|
960
|
-
var AgentQuestionSchema = z4.object({
|
|
961
|
-
question: z4.string(),
|
|
962
|
-
header: z4.string(),
|
|
963
|
-
options: z4.array(AgentQuestionOptionSchema),
|
|
964
|
-
multiSelect: z4.boolean().optional()
|
|
965
|
-
});
|
|
966
|
-
var AskUserQuestionRequestSchema = z4.object({
|
|
967
|
-
sessionId: z4.string(),
|
|
968
|
-
question: z4.string().min(1),
|
|
969
|
-
requestId: z4.string().min(1),
|
|
970
|
-
questions: z4.array(AgentQuestionSchema).min(1)
|
|
971
|
-
});
|
|
972
|
-
var PostAgentMessageRequestSchema = z4.object({
|
|
973
|
-
sessionId: z4.string().min(1),
|
|
974
|
-
content: z4.string(),
|
|
975
|
-
milestone: z4.enum(["plan_ready", "implementation_complete", "blocked"]).optional()
|
|
976
|
-
});
|
|
977
|
-
var EmitAgentEventRequestSchema = z4.object({
|
|
978
|
-
sessionId: z4.string(),
|
|
979
|
-
events: z4.array(AgentEventSchema).max(500)
|
|
980
|
-
});
|
|
981
|
-
var RefreshGithubTokenRequestSchema = z4.object({
|
|
982
|
-
sessionId: z4.string(),
|
|
983
|
-
forceFresh: z4.boolean().optional()
|
|
984
|
-
});
|
|
985
|
-
var ReportCredentialFailureRequestSchema = z4.object({
|
|
986
|
-
sessionId: z4.string(),
|
|
987
|
-
error: z4.string().max(2e3).optional(),
|
|
988
|
-
tokenShape: z4.string().max(500).optional(),
|
|
989
|
-
healed: z4.boolean().optional()
|
|
990
|
-
});
|
|
991
|
-
var ReportReviewSpawnFailureRequestSchema = z4.object({
|
|
992
|
-
sessionId: z4.string(),
|
|
993
|
-
reviewSessionId: z4.string(),
|
|
994
|
-
error: z4.string().max(2e3).optional()
|
|
995
|
-
});
|
|
996
|
-
var ReportBuilderSpawnFailureRequestSchema = ReportReviewSpawnFailureRequestSchema.omit({
|
|
997
|
-
reviewSessionId: true
|
|
998
|
-
}).extend({ buildSessionId: z4.string() });
|
|
999
|
-
var SpawnTaskSessionRequestSchema = z4.object({
|
|
1000
|
-
taskId: z4.string(),
|
|
1001
|
-
kind: z4.enum(["tui", "shell"])
|
|
1002
|
-
});
|
|
1003
|
-
var StartCodeReviewRequestSchema = z4.object({
|
|
1004
|
-
taskId: z4.string(),
|
|
1005
|
-
force: z4.boolean().optional()
|
|
1006
|
-
});
|
|
1007
|
-
var StopCodeReviewRequestSchema = z4.object({
|
|
1008
|
-
taskId: z4.string()
|
|
1009
|
-
});
|
|
1010
|
-
var ReportSessionSpawnFailureRequestSchema = z4.object({
|
|
1011
|
-
sessionId: z4.string(),
|
|
1012
|
-
spawnedSessionId: z4.string(),
|
|
1013
|
-
error: z4.string().max(2e3).optional()
|
|
1014
|
-
});
|
|
1015
|
-
var RefreshGithubTokenResponseSchema = z4.object({
|
|
1016
|
-
token: z4.string()
|
|
1017
|
-
});
|
|
1018
|
-
var PTY_FRAME_MAX_CHARS = 256 * 1024;
|
|
1019
|
-
var PTY_MAX_DIMENSION = 1e3;
|
|
1020
|
-
var PtyOutputRequestSchema = z4.object({
|
|
1021
|
-
sessionId: z4.string(),
|
|
1022
|
-
data: z4.string().max(PTY_FRAME_MAX_CHARS),
|
|
1023
|
-
cols: z4.number().int().positive().max(PTY_MAX_DIMENSION).optional(),
|
|
1024
|
-
rows: z4.number().int().positive().max(PTY_MAX_DIMENSION).optional()
|
|
1025
|
-
});
|
|
1026
|
-
var PtyEndedRequestSchema = z4.object({
|
|
1027
|
-
sessionId: z4.string()
|
|
1028
|
-
});
|
|
1029
|
-
var PtyInputRequestSchema = z4.object({
|
|
1030
|
-
sessionId: z4.string(),
|
|
1031
|
-
data: z4.string().max(PTY_FRAME_MAX_CHARS)
|
|
1032
|
-
});
|
|
1033
|
-
var PtyResizeRequestSchema = z4.object({
|
|
1034
|
-
sessionId: z4.string(),
|
|
1035
|
-
cols: z4.number().int().positive().max(PTY_MAX_DIMENSION),
|
|
1036
|
-
rows: z4.number().int().positive().max(PTY_MAX_DIMENSION)
|
|
1037
|
-
});
|
|
1038
|
-
var PtyAttachRequestSchema = z4.object({
|
|
1039
|
-
sessionId: z4.string()
|
|
1040
|
-
});
|
|
1041
|
-
var ReportPtyStreamRequestSchema = z4.object({
|
|
1042
|
-
sessionId: z4.string(),
|
|
1043
|
-
port: z4.number().int().positive().max(65535).nullable()
|
|
1044
|
-
});
|
|
1045
|
-
var GetPtyStreamEndpointRequestSchema = z4.object({
|
|
1046
|
-
sessionId: z4.string()
|
|
1047
|
-
});
|
|
1048
|
-
var PtyChatEventPayloadSchema = z4.discriminatedUnion("kind", [
|
|
1049
|
-
z4.object({
|
|
1050
|
-
kind: z4.literal("init"),
|
|
1051
|
-
model: z4.string().max(200),
|
|
1052
|
-
claudeSessionId: z4.string().max(100).optional()
|
|
1053
|
-
}),
|
|
1054
|
-
z4.object({
|
|
1055
|
-
kind: z4.literal("user_text"),
|
|
1056
|
-
text: z4.string().max(16384),
|
|
1057
|
-
// Set by the SERVER (never the agent) when this prompt was injected by
|
|
1058
|
-
// Conveyor rather than typed by a human — the routed message's `source`
|
|
1059
|
-
// (`ci_success`, `review_trigger`, `automated_feedback`, …). The agent
|
|
1060
|
-
// pastes automated messages into the TUI exactly like human prompts, so the
|
|
1061
|
-
// CLI records both as plain transcript `user` records; without this the
|
|
1062
|
-
// builder chat renders "All CI checks passed on your PR." as the human's
|
|
1063
|
-
// own bubble. Absent ⇒ a genuine human prompt.
|
|
1064
|
-
source: z4.string().max(60).optional()
|
|
1065
|
-
}),
|
|
1066
|
-
z4.object({ kind: z4.literal("assistant_text"), text: z4.string().max(16384) }),
|
|
1067
|
-
z4.object({
|
|
1068
|
-
kind: z4.literal("tool_use"),
|
|
1069
|
-
name: z4.string().max(200),
|
|
1070
|
-
// Compact preview: JSON.stringify(input) truncated agent-side. The cap
|
|
1071
|
-
// matches the text events because AskUserQuestion payloads ride this field
|
|
1072
|
-
// and the web lifts them into an interactive card — a tight cap forced
|
|
1073
|
-
// option descriptions down to 80 chars, making them unreadable. Every
|
|
1074
|
-
// other tool keeps a far smaller agent-side budget (`TOOL_INPUT_MAX` in
|
|
1075
|
-
// `chat-record-mapper.ts`), so the ring does not grow for normal calls.
|
|
1076
|
-
input: z4.string().max(16384),
|
|
1077
|
-
// Transcript tool_use block id — lets the client pair the tool_result.
|
|
1078
|
-
id: z4.string().max(100).optional()
|
|
1079
|
-
}),
|
|
1080
|
-
z4.object({
|
|
1081
|
-
kind: z4.literal("tool_result"),
|
|
1082
|
-
// tool_use block id this result answers (absent on malformed records).
|
|
1083
|
-
toolUseId: z4.string().max(100).optional(),
|
|
1084
|
-
// Compact output preview, truncated agent-side.
|
|
1085
|
-
output: z4.string().max(2e3),
|
|
1086
|
-
isError: z4.boolean().optional()
|
|
1087
|
-
}),
|
|
1088
|
-
z4.object({ kind: z4.literal("turn_end") })
|
|
1089
|
-
]);
|
|
1090
|
-
var PtyChatEventRequestSchema = z4.object({
|
|
1091
|
-
sessionId: z4.string(),
|
|
1092
|
-
event: PtyChatEventPayloadSchema
|
|
1093
|
-
});
|
|
1094
|
-
var PtyChatAttachRequestSchema = z4.object({
|
|
1095
|
-
sessionId: z4.string()
|
|
1096
|
-
});
|
|
1097
|
-
var CreatePRResponseSchema = z4.object({
|
|
1098
|
-
prNumber: z4.number().int().positive(),
|
|
1099
|
-
prUrl: z4.string().url(),
|
|
1100
|
-
/** Advisory glossary-upkeep note derived from the PR's changed files matched
|
|
1101
|
-
* against tag contextPaths — rendered into the tool result, never stored. */
|
|
1102
|
-
glossaryNote: z4.string().optional()
|
|
1103
|
-
});
|
|
1104
|
-
var PostToChatResponseSchema = z4.object({
|
|
1105
|
-
messageId: z4.string()
|
|
1106
|
-
});
|
|
1107
|
-
var UpdateTaskStatusResponseSchema = z4.object({
|
|
1108
|
-
taskId: z4.string(),
|
|
1109
|
-
status: z4.string()
|
|
1110
|
-
});
|
|
1111
|
-
var StoreSessionIdResponseSchema = z4.object({
|
|
1112
|
-
success: z4.boolean()
|
|
1113
|
-
});
|
|
1114
|
-
var HeartbeatResponseSchema = z4.object({
|
|
1115
|
-
acknowledged: z4.boolean()
|
|
1116
|
-
});
|
|
1117
|
-
var SessionStartResponseSchema = z4.object({
|
|
1118
|
-
sessionId: z4.string(),
|
|
1119
|
-
startedAt: z4.string()
|
|
1120
|
-
});
|
|
1121
|
-
var SessionStopResponseSchema = z4.object({
|
|
1122
|
-
sessionId: z4.string(),
|
|
1123
|
-
stoppedAt: z4.string()
|
|
1124
|
-
});
|
|
1125
|
-
var DeleteSubtaskResponseSchema = z4.object({
|
|
1126
|
-
deleted: z4.boolean()
|
|
1127
|
-
});
|
|
1128
|
-
var GIT_BRANCH_NAME_MAX = 255;
|
|
1129
|
-
var GIT_BRANCH_NAME_MESSAGE = "Invalid git branch name \u2014 use only letters, numbers, '.', '_', '/' and '-', starting with a letter or number, with no '..', '@{' or '//', and no trailing '/', '-', '.' or '.lock'";
|
|
1130
|
-
var ALLOWED_REF = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
|
|
1131
|
-
function isValidGitBranchName(name) {
|
|
1132
|
-
if (typeof name !== "string") return false;
|
|
1133
|
-
if (name.length === 0 || name.length > GIT_BRANCH_NAME_MAX) return false;
|
|
1134
|
-
if (!ALLOWED_REF.test(name)) return false;
|
|
1135
|
-
if (name.includes("..") || name.includes("@{") || name.includes("//")) return false;
|
|
1136
|
-
if (name.endsWith("/") || name.endsWith("-")) return false;
|
|
1137
|
-
if (name.endsWith(".") || name.endsWith(".lock")) return false;
|
|
1138
|
-
return true;
|
|
1139
|
-
}
|
|
1140
|
-
var cardDescription2 = z5.string().max(CARD_DESCRIPTION_MAX, CARD_DESCRIPTION_LIMIT_MESSAGE).optional();
|
|
1141
|
-
var ListAccessibleProjectsRequestSchema = z5.object({
|
|
1142
|
-
pageSize: z5.number().int().positive().max(100).optional().default(100)
|
|
1143
|
-
});
|
|
1144
|
-
var ListProjectTasksRequestSchema = z5.object({
|
|
1145
|
-
projectId: z5.string(),
|
|
1146
|
-
status: z5.string().optional(),
|
|
1147
|
-
// Card types to include. Omitted/empty → defaults to ["task"] in the handler
|
|
1148
|
-
// (mirrors searchProjectTasks) so listing doesn't surface incidents/suggestions
|
|
1149
|
-
// unless asked. Enum validation lives at the MCP tool layer.
|
|
1150
|
-
typeFilters: z5.array(z5.string()).optional(),
|
|
1151
|
-
assigneeId: z5.string().optional(),
|
|
1152
|
-
unassigned: z5.boolean().optional(),
|
|
1153
|
-
// Scope to a sub-project board when provided. Unlike the board layer's `?? null`
|
|
1154
|
-
// semantics, agents default to seeing the whole project when omitted.
|
|
1155
|
-
subProjectId: z5.string().nullable().optional(),
|
|
1156
|
-
limit: z5.number().int().positive().optional().default(50)
|
|
1157
|
-
}).refine((p) => !(p.unassigned && p.assigneeId), {
|
|
1158
|
-
message: "Pass either assigneeId or unassigned, not both"
|
|
1159
|
-
});
|
|
1160
|
-
var GetProjectTaskRequestSchema = z5.object({
|
|
1161
|
-
projectId: z5.string(),
|
|
1162
|
-
taskId: z5.string()
|
|
1163
|
-
});
|
|
1164
|
-
var SearchProjectTasksRequestSchema = z5.object({
|
|
1165
|
-
projectId: z5.string(),
|
|
1166
|
-
// Tag names, matched case-insensitively against the project glossary.
|
|
1167
|
-
tagNames: z5.array(z5.string()).optional(),
|
|
1168
|
-
// How to combine tagNames: "any" (default) = carries at least one,
|
|
1169
|
-
// "all" = carries every one.
|
|
1170
|
-
tagMatch: z5.enum(["any", "all"]).optional(),
|
|
1171
|
-
// Expand each named tag to its descendants in the tag DAG before matching,
|
|
1172
|
-
// so a parent tag sweeps its whole area. Default false.
|
|
1173
|
-
includeChildTags: z5.boolean().optional(),
|
|
1174
|
-
searchQuery: z5.string().optional(),
|
|
1175
|
-
statusFilters: z5.array(z5.string()).optional(),
|
|
1176
|
-
// Card types to include. Omitted/empty → defaults to ["task"] in the handler so
|
|
1177
|
-
// search doesn't surface incidents/suggestions unless asked. Enum validation lives
|
|
1178
|
-
// at the MCP tool layer (mirrors statusFilters).
|
|
1179
|
-
typeFilters: z5.array(z5.string()).optional(),
|
|
1180
|
-
assigneeId: z5.string().optional(),
|
|
1181
|
-
unassigned: z5.boolean().optional(),
|
|
1182
|
-
// Scope to a sub-project board when provided. Unlike the board layer's `?? null`
|
|
1183
|
-
// semantics, agents default to seeing the whole project when omitted.
|
|
1184
|
-
subProjectId: z5.string().nullable().optional(),
|
|
1185
|
-
limit: z5.number().int().positive().optional().default(20)
|
|
1186
|
-
}).refine((p) => !(p.unassigned && p.assigneeId), {
|
|
1187
|
-
message: "Pass either assigneeId or unassigned, not both"
|
|
1188
|
-
});
|
|
1189
|
-
var ListProjectTagsRequestSchema = z5.object({
|
|
1190
|
-
projectId: z5.string()
|
|
1191
|
-
});
|
|
1192
|
-
var GetProjectTagRequestSchema = z5.object({
|
|
1193
|
-
projectId: z5.string(),
|
|
1194
|
-
/** Tag id or exact (case-insensitive) tag name. */
|
|
1195
|
-
tag: z5.string().min(1).max(100)
|
|
1196
|
-
});
|
|
1197
|
-
var ListProjectTagAttachmentsRequestSchema = z5.object({
|
|
1198
|
-
projectId: z5.string(),
|
|
1199
|
-
/** Tag id or exact (case-insensitive) tag name. */
|
|
1200
|
-
tag: z5.string().min(1).max(100),
|
|
1201
|
-
limit: z5.number().int().min(1).max(60).optional(),
|
|
1202
|
-
offset: z5.number().int().min(0).optional()
|
|
1203
|
-
});
|
|
1204
|
-
var SetProjectFileTagsRequestSchema = z5.object({
|
|
1205
|
-
projectId: z5.string(),
|
|
1206
|
-
taskId: z5.string(),
|
|
1207
|
-
fileId: z5.string(),
|
|
1208
|
-
tags: z5.array(z5.string().min(1).max(MAX_FILE_TAG_LENGTH)).max(MAX_FILE_TAGS),
|
|
1209
|
-
requestingUserId: z5.string().optional()
|
|
1210
|
-
});
|
|
1211
|
-
var GetProjectSummaryRequestSchema = z5.object({
|
|
1212
|
-
projectId: z5.string()
|
|
1213
|
-
});
|
|
1214
|
-
var GetProjectOnboardingStatusRequestSchema = z5.object({
|
|
1215
|
-
projectId: z5.string()
|
|
1216
|
-
});
|
|
1217
|
-
var GetProjectOnboardingStepRequestSchema = z5.object({
|
|
1218
|
-
projectId: z5.string()
|
|
1219
|
-
});
|
|
1220
|
-
var GetProjectConnectUrlsRequestSchema = z5.object({
|
|
1221
|
-
projectId: z5.string()
|
|
1222
|
-
});
|
|
1223
|
-
var conveyorCapabilitySchema = z5.enum([
|
|
1224
|
-
"read",
|
|
1225
|
-
"create",
|
|
1226
|
-
"update",
|
|
1227
|
-
"chat",
|
|
1228
|
-
"files",
|
|
1229
|
-
"build"
|
|
1230
|
-
]);
|
|
1231
|
-
var GetConnectionContextRequestSchema = z5.object({
|
|
1232
|
-
projectId: z5.string(),
|
|
1233
|
-
// Optional board scope (CONVEYOR_SUBPROJECT_ID). Validated to belong to the
|
|
1234
|
-
// project in the handler; an invalid/foreign id is reported, not silently
|
|
1235
|
-
// dropped, so a mis-scoped connection is never presented as board-specific.
|
|
1236
|
-
subProjectId: z5.string().nullable().optional()
|
|
1237
|
-
});
|
|
1238
|
-
var VerifyConnectionRequestSchema = z5.object({
|
|
1239
|
-
projectId: z5.string(),
|
|
1240
|
-
subProjectId: z5.string().nullable().optional(),
|
|
1241
|
-
intendedActions: z5.array(conveyorCapabilitySchema).optional()
|
|
1242
|
-
});
|
|
1243
|
-
var ListAccessibleSubprojectsRequestSchema = z5.object({
|
|
1244
|
-
projectId: z5.string()
|
|
1245
|
-
});
|
|
1246
|
-
var CreateProjectTaskRequestSchema = z5.object({
|
|
1247
|
-
projectId: z5.string(),
|
|
1248
|
-
title: z5.string().min(1),
|
|
1249
|
-
description: cardDescription2,
|
|
1250
|
-
plan: z5.string().optional(),
|
|
1251
|
-
status: z5.string().optional(),
|
|
1252
|
-
// Assign to a sub-project board. Validated to belong to `projectId` in the handler.
|
|
1253
|
-
subProjectId: z5.string().nullable().optional(),
|
|
1254
|
-
requestingUserId: z5.string().optional()
|
|
1255
|
-
});
|
|
1256
|
-
var SetProjectTaskParentRequestSchema = z5.object({
|
|
1257
|
-
projectId: z5.string(),
|
|
1258
|
-
/** Card to move — id or slug. */
|
|
1259
|
-
taskId: z5.string().min(1),
|
|
1260
|
-
/** New parent (id or slug), or null to detach. */
|
|
1261
|
-
parentTaskId: z5.string().min(1).nullable(),
|
|
1262
|
-
ordinal: z5.number().int().nonnegative().optional(),
|
|
1263
|
-
followParentStatus: z5.boolean().optional(),
|
|
1264
|
-
requestingUserId: z5.string().optional()
|
|
1265
|
-
}).strict();
|
|
1266
|
-
var UpdateProjectTaskRequestSchema = z5.object({
|
|
1267
|
-
projectId: z5.string(),
|
|
1268
|
-
taskId: z5.string(),
|
|
1269
|
-
title: z5.string().optional(),
|
|
1270
|
-
description: cardDescription2,
|
|
1271
|
-
plan: z5.string().optional(),
|
|
1272
|
-
// Enum validation lives at the MCP tool layer (mirrors createProjectTask);
|
|
1273
|
-
// the handler routes through the shared updateStatus core (InProgress
|
|
1274
|
-
// dependency check + cleanup/board/Slack side effects), not the stricter
|
|
1275
|
-
// card-type-validating path the Socket.IO updateTaskStatus mutation uses.
|
|
1276
|
-
status: z5.string().optional(),
|
|
1277
|
-
// Canonical risk level, or null to clear. Resolved to the project's
|
|
1278
|
-
// configured Risk row (by rank) in the handler.
|
|
1279
|
-
risk: riskLevelSchema.nullable().optional(),
|
|
1280
|
-
// Story-point value, or null to clear. Resolved to the project's configured
|
|
1281
|
-
// StoryPoint row in the handler, which rejects an unconfigured value.
|
|
1282
|
-
storyPointValue: z5.number().int().positive().nullable().optional(),
|
|
1283
|
-
assignedUserId: z5.string().nullish(),
|
|
1284
|
-
// Move to a different sub-project board, or null to move to the parent board.
|
|
1285
|
-
// Validated to belong to `projectId` in the handler.
|
|
1286
|
-
subProjectId: z5.string().nullable().optional(),
|
|
1287
|
-
// Record the task's ACTUAL working branch (e.g. a locally-driven pack's
|
|
1288
|
-
// branch, so identification never mints a competing name and pack-child
|
|
1289
|
-
// merge handling matches reality), or null to detach. Guarded in the
|
|
1290
|
-
// handler: the ref must exist on origin and no live workspace may be bound
|
|
1291
|
-
// to a different branch.
|
|
1292
|
-
githubBranch: z5.string().min(1).max(GIT_BRANCH_NAME_MAX).refine(isValidGitBranchName, { message: GIT_BRANCH_NAME_MESSAGE }).nullable().optional(),
|
|
1293
|
-
requestingUserId: z5.string().optional()
|
|
1294
|
-
}).strict().refine(
|
|
1295
|
-
(v) => v.title !== void 0 || v.description !== void 0 || v.plan !== void 0 || v.status !== void 0 || v.risk !== void 0 || v.storyPointValue !== void 0 || v.assignedUserId !== void 0 || v.subProjectId !== void 0 || v.githubBranch !== void 0,
|
|
1296
|
-
{
|
|
1297
|
-
message: "update_task requires at least one field to change (title, description, plan, status, risk, storyPointValue, assignedUserId, subProjectId, or githubBranch)"
|
|
1298
|
-
}
|
|
1299
|
-
);
|
|
1300
|
-
var TransitionProjectTaskStatusRequestSchema = z5.object({
|
|
1301
|
-
projectId: z5.string(),
|
|
1302
|
-
taskId: z5.string(),
|
|
1303
|
-
toStatus: z5.string(),
|
|
1304
|
-
expectedFromStatus: z5.string().optional(),
|
|
1305
|
-
// Optional raise-only risk to attempt alongside the transition
|
|
1306
|
-
// (approve → low, request_changes → medium by default).
|
|
1307
|
-
risk: riskLevelSchema.optional(),
|
|
1308
|
-
requestingUserId: z5.string().optional()
|
|
1309
|
-
});
|
|
1310
|
-
var MoveProjectCardRequestSchema = z5.object({
|
|
1311
|
-
projectId: z5.string(),
|
|
1312
|
-
taskId: z5.string(),
|
|
1313
|
-
destinationProjectId: z5.string(),
|
|
1314
|
-
requestingUserId: z5.string().optional()
|
|
1315
|
-
});
|
|
1316
|
-
var PostToProjectTaskChatRequestSchema = z5.object({
|
|
1317
|
-
projectId: z5.string(),
|
|
1318
|
-
taskId: z5.string(),
|
|
1319
|
-
content: z5.string(),
|
|
1320
|
-
requestingUserId: z5.string().optional()
|
|
1321
|
-
});
|
|
1322
|
-
var GetProjectTaskCliRequestSchema = z5.object({
|
|
1323
|
-
projectId: z5.string(),
|
|
1324
|
-
taskId: z5.string(),
|
|
1325
|
-
limit: z5.number().int().positive().optional().default(50),
|
|
1326
|
-
source: z5.string().optional()
|
|
1327
|
-
});
|
|
1328
|
-
var GetProjectTaskSessionsRequestSchema = z5.object({
|
|
1329
|
-
projectId: z5.string(),
|
|
1330
|
-
taskId: z5.string()
|
|
1331
|
-
});
|
|
1332
|
-
var QueryProjectGcpLogsRequestSchema = z5.object({
|
|
1333
|
-
projectId: z5.string(),
|
|
1334
|
-
env: z5.enum(["prod", "dev", "claudespace"]).optional(),
|
|
1335
|
-
severity: z5.enum(["DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "CRITICAL", "ALERT", "EMERGENCY"]).optional(),
|
|
1336
|
-
services: z5.array(z5.string().min(1).max(200)).max(25).optional(),
|
|
1337
|
-
sqlInstances: z5.array(z5.string().min(1).max(200)).max(25).optional(),
|
|
1338
|
-
allServices: z5.boolean().optional(),
|
|
1339
|
-
search: z5.string().max(256).optional(),
|
|
1340
|
-
filter: z5.string().max(1e3).optional(),
|
|
1341
|
-
startTime: z5.string().optional(),
|
|
1342
|
-
endTime: z5.string().optional(),
|
|
1343
|
-
limit: z5.number().int().min(1).max(200).optional().default(50),
|
|
1344
|
-
pageToken: z5.string().max(4096).optional()
|
|
1345
|
-
});
|
|
1346
|
-
var QueryProjectGrafanaLogsRequestSchema = z5.object({
|
|
1347
|
-
projectId: z5.string(),
|
|
1348
|
-
env: z5.enum(["prod", "dev"]).optional(),
|
|
1349
|
-
services: z5.array(z5.string().min(1).max(200)).max(25).optional(),
|
|
1350
|
-
level: z5.enum(["debug", "info", "warn", "error", "fatal"]).optional(),
|
|
1351
|
-
search: z5.string().max(256).optional(),
|
|
1352
|
-
logql: z5.string().max(2e3).optional(),
|
|
1353
|
-
startTime: z5.string().optional(),
|
|
1354
|
-
endTime: z5.string().optional(),
|
|
1355
|
-
limit: z5.number().int().min(1).max(200).optional().default(50)
|
|
1356
|
-
});
|
|
1357
|
-
var driveFileNameSchema = z5.string().min(1).max(255).regex(/^[^/\\\r\n]+$/, "File names cannot contain slashes or line breaks");
|
|
1358
|
-
var DRIVE_MAX_CONTENT_CHARS = 1e6;
|
|
1359
|
-
var ListProjectDriveFilesRequestSchema = z5.object({
|
|
1360
|
-
projectId: z5.string(),
|
|
1361
|
-
folderId: z5.string().max(200).optional(),
|
|
1362
|
-
search: z5.string().max(200).optional(),
|
|
1363
|
-
limit: z5.number().int().min(1).max(200).optional()
|
|
1364
|
-
});
|
|
1365
|
-
var ReadProjectDriveFileRequestSchema = z5.object({
|
|
1366
|
-
projectId: z5.string(),
|
|
1367
|
-
fileId: z5.string().min(1).max(200)
|
|
1368
|
-
});
|
|
1369
|
-
var CreateProjectDriveFileRequestSchema = z5.object({
|
|
1370
|
-
projectId: z5.string(),
|
|
1371
|
-
name: driveFileNameSchema,
|
|
1372
|
-
content: z5.string().max(DRIVE_MAX_CONTENT_CHARS),
|
|
1373
|
-
mimeType: z5.string().max(200).optional(),
|
|
1374
|
-
folderId: z5.string().max(200).optional()
|
|
1375
|
-
});
|
|
1376
|
-
var UpdateProjectDriveFileRequestSchema = z5.object({
|
|
1377
|
-
projectId: z5.string(),
|
|
1378
|
-
fileId: z5.string().min(1).max(200),
|
|
1379
|
-
content: z5.string().max(DRIVE_MAX_CONTENT_CHARS),
|
|
1380
|
-
mimeType: z5.string().max(200).optional()
|
|
1381
|
-
});
|
|
1382
|
-
var DeleteProjectDriveFileRequestSchema = z5.object({
|
|
1383
|
-
projectId: z5.string(),
|
|
1384
|
-
fileId: z5.string().min(1).max(200)
|
|
1385
|
-
});
|
|
1386
|
-
var CreateProjectDriveFolderRequestSchema = z5.object({
|
|
1387
|
-
projectId: z5.string(),
|
|
1388
|
-
name: driveFileNameSchema,
|
|
1389
|
-
folderId: z5.string().max(200).optional()
|
|
1390
|
-
});
|
|
1391
|
-
var StartProjectBuildRequestSchema = z5.object({
|
|
1392
|
-
projectId: z5.string(),
|
|
1393
|
-
taskId: z5.string(),
|
|
1394
|
-
requestingUserId: z5.string().optional()
|
|
1395
|
-
});
|
|
1396
|
-
var StopProjectBuildRequestSchema = z5.object({
|
|
1397
|
-
projectId: z5.string(),
|
|
1398
|
-
taskId: z5.string(),
|
|
1399
|
-
requestingUserId: z5.string().optional()
|
|
1400
|
-
});
|
|
1401
|
-
var StartProjectWorkspaceRequestSchema = z5.object({
|
|
1402
|
-
projectId: z5.string(),
|
|
1403
|
-
requestingUserId: z5.string().optional()
|
|
1404
|
-
});
|
|
1405
|
-
var StopProjectWorkspaceRequestSchema = z5.object({
|
|
1406
|
-
projectId: z5.string(),
|
|
1407
|
-
destroy: z5.boolean().optional(),
|
|
1408
|
-
requestingUserId: z5.string().optional()
|
|
1409
|
-
});
|
|
1410
|
-
var ListMyLiveSessionsRequestSchema = z5.object({
|
|
1411
|
-
projectId: z5.string(),
|
|
1412
|
-
/** Admin-only: list another member's sessions instead of the caller's. */
|
|
1413
|
-
targetUserId: z5.string().optional()
|
|
1414
|
-
});
|
|
1415
|
-
var ListProjectSessionGroupsRequestSchema = z5.object({
|
|
1416
|
-
projectId: z5.string()
|
|
1417
|
-
});
|
|
1418
|
-
var ListMyLiveSessionsAcrossProjectsRequestSchema = z5.object({});
|
|
1419
|
-
var ListSessionGroupsAcrossProjectsRequestSchema = z5.object({});
|
|
1420
|
-
var GetProjectAvailableTuisRequestSchema = z5.object({
|
|
1421
|
-
projectId: z5.string()
|
|
1422
|
-
});
|
|
1423
|
-
var StartAdhocSessionRequestSchema = z5.object({
|
|
1424
|
-
projectId: z5.string(),
|
|
1425
|
-
label: z5.string().max(200).optional(),
|
|
1426
|
-
/** Coding-agent key to launch under — validated pick-time (ownership + TUI availability) in the handler. */
|
|
1427
|
-
codingAgentKeyId: z5.string().optional(),
|
|
1428
|
-
/** Model override (Claude model id) — overrides the launch key's own model. */
|
|
1429
|
-
model: z5.string().max(200).optional(),
|
|
1430
|
-
/**
|
|
1431
|
-
* Session role. Constrained: other task-less modes fall through to the pm
|
|
1432
|
-
* runner in the pod entrypoint, and "review" would crash without a task.
|
|
1433
|
-
*/
|
|
1434
|
-
mode: z5.enum(["adhoc", "pm"]).optional(),
|
|
1435
|
-
/** Base branch to check out (defaults to the project's dev branch). */
|
|
1436
|
-
branch: z5.string().max(300).optional(),
|
|
1437
|
-
/**
|
|
1438
|
-
* Server-assembled instructions the pod's TUI auto-submits once on first boot
|
|
1439
|
-
* (headless kickoff). Used by the onboarding "Set it up for me" flow to seed a
|
|
1440
|
-
* setup-driver prompt; the session stays watchable/interactive in the Sessions
|
|
1441
|
-
* view. `ensureAdhocWorkspace` persists it and clears it after first submit.
|
|
1442
|
-
*/
|
|
1443
|
-
initialPrompt: z5.string().max(2e4).optional(),
|
|
1444
|
-
requestingUserId: z5.string().optional()
|
|
1445
|
-
});
|
|
1446
|
-
var StopAdhocSessionRequestSchema = z5.object({
|
|
1447
|
-
projectId: z5.string(),
|
|
1448
|
-
workspaceId: z5.string(),
|
|
1449
|
-
destroy: z5.boolean().optional(),
|
|
1450
|
-
requestingUserId: z5.string().optional()
|
|
1451
|
-
});
|
|
1452
|
-
var ResumeAdhocSessionRequestSchema = z5.object({
|
|
1453
|
-
projectId: z5.string(),
|
|
1454
|
-
workspaceId: z5.string(),
|
|
1455
|
-
requestingUserId: z5.string().optional()
|
|
1456
|
-
});
|
|
1457
|
-
var RefreshCodingAgentKeyUsageRequestSchema = z5.object({
|
|
1458
|
-
projectId: z5.string(),
|
|
1459
|
-
keyId: z5.string().optional(),
|
|
1460
|
-
requestingUserId: z5.string().optional()
|
|
1461
|
-
});
|
|
1462
|
-
var ListKeysToProbeRequestSchema = z5.object({
|
|
1463
|
-
sessionId: z5.string()
|
|
1464
|
-
});
|
|
1465
|
-
var CreateProjectReleaseRequestSchema = z5.object({
|
|
1466
|
-
projectId: z5.string(),
|
|
1467
|
-
taskIds: z5.array(z5.string()).optional(),
|
|
1468
|
-
requestingUserId: z5.string().optional()
|
|
1469
|
-
});
|
|
1470
|
-
var AddTasksToProjectReleaseRequestSchema = z5.object({
|
|
1471
|
-
projectId: z5.string(),
|
|
1472
|
-
taskIds: z5.array(z5.string()).min(1),
|
|
1473
|
-
requestingUserId: z5.string().optional()
|
|
1474
|
-
});
|
|
1475
|
-
var ApproveProjectMergePRRequestSchema = z5.object({
|
|
1476
|
-
projectId: z5.string(),
|
|
1477
|
-
childTaskId: z5.string(),
|
|
1478
|
-
requestingUserId: z5.string().optional()
|
|
1479
|
-
});
|
|
1480
|
-
var ListProjectSubtasksRequestSchema = z5.object({
|
|
1481
|
-
projectId: z5.string(),
|
|
1482
|
-
taskId: z5.string()
|
|
1483
|
-
});
|
|
1484
|
-
var CreateProjectSubtaskRequestSchema = z5.object({
|
|
1485
|
-
projectId: z5.string(),
|
|
1486
|
-
parentTaskId: z5.string(),
|
|
1487
|
-
title: z5.string().min(1),
|
|
1488
|
-
description: cardDescription2,
|
|
1489
|
-
plan: z5.string().optional(),
|
|
1490
|
-
ordinal: z5.number().int().nonnegative().optional(),
|
|
1491
|
-
storyPointValue: z5.number().int().positive().optional(),
|
|
1492
|
-
followParentStatus: z5.boolean().optional(),
|
|
1493
|
-
/** Sibling subtask ids or slugs this subtask blocks on (explicit dependency
|
|
1494
|
-
* metadata — preferred over encoding order in plan text / ordinal). */
|
|
1495
|
-
dependsOn: z5.array(z5.string().min(1)).max(32).optional(),
|
|
1496
|
-
requestingUserId: z5.string().optional()
|
|
1497
|
-
});
|
|
1498
|
-
var UpdateProjectSubtaskRequestSchema = z5.object({
|
|
1499
|
-
projectId: z5.string(),
|
|
1500
|
-
subtaskId: z5.string(),
|
|
1501
|
-
title: z5.string().optional(),
|
|
1502
|
-
description: cardDescription2,
|
|
1503
|
-
plan: z5.string().optional(),
|
|
1504
|
-
status: z5.string().optional(),
|
|
1505
|
-
ordinal: z5.number().int().nonnegative().optional(),
|
|
1506
|
-
storyPointValue: z5.number().int().positive().optional(),
|
|
1507
|
-
followParentStatus: z5.boolean().optional(),
|
|
1508
|
-
/** Replace-set of sibling subtask ids/slugs this subtask blocks on ([] clears).
|
|
1509
|
-
* Mirrors the in-pod updateSubtask semantics. */
|
|
1510
|
-
dependsOn: z5.array(z5.string().min(1)).max(32).optional(),
|
|
1511
|
-
requestingUserId: z5.string().optional()
|
|
1512
|
-
});
|
|
1513
|
-
var DeleteProjectSubtaskRequestSchema = z5.object({
|
|
1514
|
-
projectId: z5.string(),
|
|
1515
|
-
subtaskId: z5.string(),
|
|
1516
|
-
requestingUserId: z5.string().optional()
|
|
1517
|
-
});
|
|
1518
|
-
var GetProjectTaskChatRequestSchema = z5.object({
|
|
1519
|
-
projectId: z5.string(),
|
|
1520
|
-
taskId: z5.string(),
|
|
1521
|
-
limit: z5.number().int().positive().optional().default(20)
|
|
1522
|
-
});
|
|
1523
|
-
var AddProjectTaskDependencyRequestSchema = z5.object({
|
|
1524
|
-
projectId: z5.string(),
|
|
1525
|
-
taskId: z5.string(),
|
|
1526
|
-
dependsOnSlugOrId: z5.string(),
|
|
1527
|
-
requestingUserId: z5.string().optional()
|
|
1528
|
-
});
|
|
1529
|
-
var RemoveProjectTaskDependencyRequestSchema = z5.object({
|
|
1530
|
-
projectId: z5.string(),
|
|
1531
|
-
taskId: z5.string(),
|
|
1532
|
-
dependsOnSlugOrId: z5.string(),
|
|
1533
|
-
requestingUserId: z5.string().optional()
|
|
1534
|
-
});
|
|
1535
|
-
var VoteProjectSuggestionRequestSchema = z5.object({
|
|
1536
|
-
projectId: z5.string(),
|
|
1537
|
-
suggestionId: z5.string(),
|
|
1538
|
-
value: z5.union([z5.literal(1), z5.literal(-1)]),
|
|
1539
|
-
requestingUserId: z5.string().optional()
|
|
1540
|
-
});
|
|
1541
|
-
var GetProjectTaskDependenciesRequestSchema = z5.object({
|
|
1542
|
-
projectId: z5.string(),
|
|
1543
|
-
taskId: z5.string()
|
|
1544
|
-
});
|
|
1545
|
-
var ListProjectTaskFilesRequestSchema = z5.object({
|
|
1546
|
-
projectId: z5.string(),
|
|
1547
|
-
taskId: z5.string()
|
|
1548
|
-
});
|
|
1549
|
-
var GetProjectAttachmentRequestSchema = z5.object({
|
|
1550
|
-
projectId: z5.string(),
|
|
1551
|
-
taskId: z5.string(),
|
|
1552
|
-
fileId: z5.string(),
|
|
1553
|
-
/** Byte offset into text content (paging large logs/JSON). Default 0. */
|
|
1554
|
-
offset: z5.number().int().nonnegative().optional(),
|
|
1555
|
-
/** Max bytes of text content to return from `offset`. Server default applies. */
|
|
1556
|
-
maxBytes: z5.number().int().positive().optional()
|
|
1557
|
-
});
|
|
1558
|
-
var RequestProjectFileUploadRequestSchema = z5.object({
|
|
1559
|
-
projectId: z5.string(),
|
|
1560
|
-
taskId: z5.string(),
|
|
1561
|
-
fileName: z5.string().min(1).max(255),
|
|
1562
|
-
mimeType: z5.string().min(1).max(128),
|
|
1563
|
-
fileSize: z5.number().int().positive().max(MAX_FILE_SIZE_BYTES),
|
|
1564
|
-
requestingUserId: z5.string().optional()
|
|
1565
|
-
});
|
|
1566
|
-
var ConfirmProjectFileUploadRequestSchema = z5.object({
|
|
1567
|
-
projectId: z5.string(),
|
|
1568
|
-
taskId: z5.string(),
|
|
1569
|
-
fileId: z5.string(),
|
|
1570
|
-
/** When set, the attachment is also posted to the task chat with this text. */
|
|
1571
|
-
comment: z5.string().max(2e3).optional(),
|
|
1572
|
-
/** Glossary tag names (or ids) this file is an example of. */
|
|
1573
|
-
tags: z5.array(z5.string().min(1).max(MAX_FILE_TAG_LENGTH)).max(MAX_FILE_TAGS).optional(),
|
|
1574
|
-
requestingUserId: z5.string().optional()
|
|
1575
|
-
});
|
|
1576
|
-
var CreateProjectPullRequestRequestSchema = z5.object({
|
|
1577
|
-
projectId: z5.string(),
|
|
1578
|
-
taskId: z5.string(),
|
|
1579
|
-
title: z5.string().min(1),
|
|
1580
|
-
body: z5.string(),
|
|
1581
|
-
head: z5.string().optional(),
|
|
1582
|
-
base: z5.string().optional(),
|
|
1583
|
-
requestingUserId: z5.string().optional()
|
|
1584
|
-
});
|
|
1585
|
-
var ListProjectMembersRequestSchema = z5.object({
|
|
1586
|
-
projectId: z5.string()
|
|
1587
|
-
});
|
|
1588
|
-
var AddProjectTaskReviewerRequestSchema = z5.object({
|
|
1589
|
-
projectId: z5.string(),
|
|
1590
|
-
taskId: z5.string(),
|
|
1591
|
-
userId: z5.string(),
|
|
1592
|
-
requestingUserId: z5.string().optional()
|
|
1593
|
-
});
|
|
1594
|
-
var RemoveProjectTaskReviewerRequestSchema = z5.object({
|
|
1595
|
-
projectId: z5.string(),
|
|
1596
|
-
taskId: z5.string(),
|
|
1597
|
-
userId: z5.string(),
|
|
1598
|
-
requestingUserId: z5.string().optional()
|
|
1599
|
-
});
|
|
1600
|
-
var ListProjectManualTestsRequestSchema = z5.object({
|
|
1601
|
-
projectId: z5.string(),
|
|
1602
|
-
taskId: z5.string()
|
|
1603
|
-
});
|
|
1604
|
-
var QueryProjectManualTestsRequestSchema = z5.object({
|
|
1605
|
-
projectId: z5.string(),
|
|
1606
|
-
cardStatuses: z5.array(z5.string()).optional(),
|
|
1607
|
-
testStatuses: z5.array(z5.enum(["open", "approved", "rejected"])).optional()
|
|
1608
|
-
});
|
|
1609
|
-
var SetProjectManualTestsRequestSchema = z5.object({
|
|
1610
|
-
projectId: z5.string(),
|
|
1611
|
-
taskId: z5.string(),
|
|
1612
|
-
items: z5.array(z5.object({ title: z5.string().min(1) })).min(1),
|
|
1613
|
-
requestingUserId: z5.string().optional()
|
|
1614
|
-
});
|
|
1615
|
-
var EditProjectManualTestRequestSchema = z5.object({
|
|
1616
|
-
projectId: z5.string(),
|
|
1617
|
-
taskId: z5.string(),
|
|
1618
|
-
title: z5.string().min(1),
|
|
1619
|
-
newTitle: z5.string().min(1),
|
|
1620
|
-
requestingUserId: z5.string().optional()
|
|
1621
|
-
});
|
|
1622
|
-
var RemoveProjectManualTestRequestSchema = z5.object({
|
|
1623
|
-
projectId: z5.string(),
|
|
1624
|
-
taskId: z5.string(),
|
|
1625
|
-
title: z5.string().min(1),
|
|
1626
|
-
requestingUserId: z5.string().optional()
|
|
1627
|
-
});
|
|
1628
|
-
var ApproveProjectManualTestRequestSchema = z5.object({
|
|
1629
|
-
projectId: z5.string(),
|
|
1630
|
-
taskId: z5.string(),
|
|
1631
|
-
title: z5.string().min(1),
|
|
1632
|
-
requestingUserId: z5.string().optional()
|
|
1633
|
-
});
|
|
1634
|
-
var RejectProjectManualTestRequestSchema = z5.object({
|
|
1635
|
-
projectId: z5.string(),
|
|
1636
|
-
taskId: z5.string(),
|
|
1637
|
-
title: z5.string().min(1),
|
|
1638
|
-
reason: z5.string().min(1).max(2e3),
|
|
1639
|
-
requestingUserId: z5.string().optional()
|
|
1640
|
-
});
|
|
1641
|
-
var CreateProjectSuggestionRequestSchema = z5.object({
|
|
1642
|
-
projectId: z5.string(),
|
|
1643
|
-
title: z5.string().min(1),
|
|
1644
|
-
description: cardDescription2,
|
|
1645
|
-
tagNames: z5.array(z5.string()).optional(),
|
|
1646
|
-
requestingUserId: z5.string().optional()
|
|
1647
|
-
});
|
|
1648
|
-
var ListProjectChannelsRequestSchema = z6.object({
|
|
1649
|
-
projectId: z6.string()
|
|
1650
|
-
});
|
|
1651
|
-
var READ_CHANNEL_MESSAGES_MAX_LIMIT = 50;
|
|
1652
|
-
var ReadChannelMessagesRequestSchema = z6.object({
|
|
1653
|
-
projectId: z6.string(),
|
|
1654
|
-
channelId: z6.string().min(1).max(200),
|
|
1655
|
-
limit: z6.number().int().min(1).max(READ_CHANNEL_MESSAGES_MAX_LIMIT).optional(),
|
|
1656
|
-
/** Provider-native cursor: return messages OLDER than this one. */
|
|
1657
|
-
before: z6.string().max(100).optional(),
|
|
1658
|
-
/** Provider-native cursor: return messages NEWER than this one. */
|
|
1659
|
-
after: z6.string().max(100).optional(),
|
|
1660
|
-
/**
|
|
1661
|
-
* Read one thread instead of the channel surface. Slack calls this a
|
|
1662
|
-
* `thread_ts`; on Discord it is the thread channel's id. One field for both,
|
|
1663
|
-
* because a caller holding a `threadTs` from a previous read should not have
|
|
1664
|
-
* to know which provider produced it.
|
|
1665
|
-
*/
|
|
1666
|
-
threadTs: z6.string().max(100).optional()
|
|
1667
|
-
});
|
|
1668
|
-
var POST_CHANNEL_MESSAGE_MAX_CHARS = 1800;
|
|
1669
|
-
var PostChannelMessageRequestSchema = z6.object({
|
|
1670
|
-
projectId: z6.string(),
|
|
1671
|
-
channelId: z6.string().min(1).max(200),
|
|
1672
|
-
text: z6.string().min(1).max(POST_CHANNEL_MESSAGE_MAX_CHARS),
|
|
1673
|
-
/** Reply inside a thread rather than to the channel. */
|
|
1674
|
-
threadTs: z6.string().max(100).optional()
|
|
1675
|
-
});
|
|
1676
|
-
var GET_ANALYTICS_SUMMARY_MAX_RANGE_DAYS = 90;
|
|
1677
|
-
var GetProjectAnalyticsSummaryRequestSchema = z6.object({
|
|
1678
|
-
projectId: z6.string(),
|
|
1679
|
-
rangeDays: z6.number().int().min(1).max(GET_ANALYTICS_SUMMARY_MAX_RANGE_DAYS).optional(),
|
|
1680
|
-
campaign: z6.string().max(200).optional()
|
|
1681
|
-
});
|
|
1682
|
-
var RequestWorkspaceRecycleRequestSchema = z7.object({
|
|
1683
|
-
sessionId: z7.string(),
|
|
1684
|
-
reason: z7.string().max(2e3)
|
|
1685
|
-
});
|
|
1686
|
-
var ReportApiOutageRequestSchema = z7.object({
|
|
1687
|
-
sessionId: z7.string(),
|
|
1688
|
-
detail: z7.string().max(2e3),
|
|
1689
|
-
attempts: z7.number().int().min(0).max(100)
|
|
1690
|
-
});
|
|
1691
|
-
var SHA_PATTERN = /^[0-9a-f]{40}$/i;
|
|
1692
|
-
var ReviewGuideFileReferenceSchema = z8.object({
|
|
1693
|
-
path: z8.string().min(1).max(500),
|
|
1694
|
-
startLine: z8.number().int().positive().max(1e6).optional(),
|
|
1695
|
-
endLine: z8.number().int().positive().max(1e6).optional(),
|
|
1696
|
-
hunkHeader: z8.string().min(1).max(300).optional()
|
|
1697
|
-
}).strict().superRefine((value, ctx) => {
|
|
1698
|
-
if (value.endLine !== void 0 && value.startLine === void 0) {
|
|
1699
|
-
ctx.addIssue({
|
|
1700
|
-
code: "custom",
|
|
1701
|
-
path: ["startLine"],
|
|
1702
|
-
message: "startLine is required when endLine is set"
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
if (value.startLine !== void 0 && value.endLine !== void 0 && value.endLine < value.startLine) {
|
|
1706
|
-
ctx.addIssue({
|
|
1707
|
-
code: "custom",
|
|
1708
|
-
path: ["endLine"],
|
|
1709
|
-
message: "endLine must be greater than or equal to startLine"
|
|
1710
|
-
});
|
|
1711
|
-
}
|
|
1712
|
-
});
|
|
1713
|
-
var ReviewGuideSectionSchema = z8.object({
|
|
1714
|
-
title: z8.string().min(1).max(160),
|
|
1715
|
-
explanation: z8.string().min(1).max(2e3),
|
|
1716
|
-
classification: z8.enum(["core", "supporting"]).optional(),
|
|
1717
|
-
files: z8.array(ReviewGuideFileReferenceSchema).min(1).max(20)
|
|
1718
|
-
}).strict();
|
|
1719
|
-
var ReviewGuideContentSchema = z8.object({
|
|
1720
|
-
overview: z8.string().min(1).max(3e3),
|
|
1721
|
-
sections: z8.array(ReviewGuideSectionSchema).min(1).max(12)
|
|
1722
|
-
}).strict();
|
|
1723
|
-
var PublishReviewGuideRequestSchema = ReviewGuideContentSchema.extend({
|
|
1724
|
-
sessionId: z8.string().min(1),
|
|
1725
|
-
reviewedSha: z8.string().regex(SHA_PATTERN, "reviewedSha must be a 40-character commit SHA")
|
|
1726
|
-
}).strict();
|
|
1727
|
-
var CONTEXT_LINK_LOCATOR_MAX = 300;
|
|
1728
|
-
var TEST_TITLE = /\b(?:it|test|describe)(?:\.\w+)?\s*\(\s*(['"`])((?:(?!\1)[\s\S])*)\1/g;
|
|
1729
|
-
function extractTestTitles(content) {
|
|
1730
|
-
return [...content.matchAll(TEST_TITLE)].map((m) => m[2]);
|
|
1731
|
-
}
|
|
1732
|
-
function isPlaceholderLocator(locator) {
|
|
1733
|
-
return locator.includes("<") || locator.includes(">");
|
|
1734
|
-
}
|
|
1735
|
-
function locatorMatchesContent(content, locatorType, locator) {
|
|
1736
|
-
if (locatorType === "code") return content.includes(locator);
|
|
1737
|
-
return extractTestTitles(content).some((title) => title.includes(locator));
|
|
1738
|
-
}
|
|
1739
|
-
var TAG_DESCRIPTION_MAX = CARD_DESCRIPTION_MAX;
|
|
1740
|
-
var TAG_OVERVIEW_MAX = 32e3;
|
|
1741
|
-
var TAG_REASON_MAX = 500;
|
|
1742
|
-
var ProjectTagContextPathSchema = z9.object({
|
|
1743
|
-
type: z9.enum(["rule", "doc", "file", "folder"]),
|
|
1744
|
-
path: z9.string().min(1).max(500),
|
|
1745
|
-
label: z9.string().max(100).optional(),
|
|
1746
|
-
/** Verified-link tether — text that must keep existing in the file. */
|
|
1747
|
-
locator: z9.string().min(1).max(CONTEXT_LINK_LOCATOR_MAX).regex(/^[^\r\n]*$/, "Locator cannot contain line breaks").optional(),
|
|
1748
|
-
/** test = must appear in a real test/describe title; code = any substring. */
|
|
1749
|
-
locatorType: z9.enum(["test", "code"]).optional()
|
|
1750
|
-
}).refine((link) => link.locator === void 0 === (link.locatorType === void 0), {
|
|
1751
|
-
message: "locator and locatorType must be provided together"
|
|
1752
|
-
}).refine((link) => link.locator === void 0 || link.type !== "folder", {
|
|
1753
|
-
message: "folder links cannot carry a locator"
|
|
1754
|
-
});
|
|
1755
|
-
var hexColor = z9.string().regex(/^#[0-9a-fA-F]{6}$/, "Expected #RRGGBB hex color");
|
|
1756
|
-
var overviewPathSchema = z9.string().min(1).max(500).regex(/^[^\r\n]*$/, "Overview path cannot contain line breaks");
|
|
1757
|
-
var CreateProjectTagRequestSchema = z9.object({
|
|
1758
|
-
projectId: z9.string(),
|
|
1759
|
-
name: z9.string().min(1).max(50),
|
|
1760
|
-
color: hexColor.optional(),
|
|
1761
|
-
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
1762
|
-
overview: z9.string().max(TAG_OVERVIEW_MAX).optional(),
|
|
1763
|
-
/** Source the overview from this repo file (stored overview stays as the pending fallback). */
|
|
1764
|
-
overviewPath: overviewPathSchema.optional(),
|
|
1765
|
-
contextPaths: z9.array(ProjectTagContextPathSchema).max(20).optional(),
|
|
1766
|
-
/** Parents to link at create time (multi-parent DAG). */
|
|
1767
|
-
parentTagIds: z9.array(z9.string()).max(25).optional(),
|
|
1768
|
-
requestingUserId: z9.string().optional()
|
|
1769
|
-
});
|
|
1770
|
-
var UpdateProjectTagRequestSchema = z9.object({
|
|
1771
|
-
projectId: z9.string(),
|
|
1772
|
-
tagId: z9.string(),
|
|
1773
|
-
name: z9.string().min(1).max(50).optional(),
|
|
1774
|
-
color: hexColor.optional(),
|
|
1775
|
-
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
1776
|
-
/** Full markdown glossary body; null clears it. Rejected while overviewPath is set. */
|
|
1777
|
-
overview: z9.string().max(TAG_OVERVIEW_MAX).nullable().optional(),
|
|
1778
|
-
/** Repo file to source the overview from; null clears back to the stored overview. */
|
|
1779
|
-
overviewPath: overviewPathSchema.nullable().optional(),
|
|
1780
|
-
/** Full replacement of the tag's context links when provided. */
|
|
1781
|
-
contextPaths: z9.array(ProjectTagContextPathSchema).max(20).optional(),
|
|
1782
|
-
/** Full-set replacement of the tag's parent tags (multi-parent DAG). */
|
|
1783
|
-
parentTagIds: z9.array(z9.string()).max(25).optional(),
|
|
1784
|
-
/** One-line revision provenance, recorded in the tag's history. */
|
|
1785
|
-
reason: z9.string().max(TAG_REASON_MAX).optional(),
|
|
1786
|
-
/** Card the caller was working in — stamped into the revision history. */
|
|
1787
|
-
taskId: z9.string().optional(),
|
|
1788
|
-
requestingUserId: z9.string().optional()
|
|
1789
|
-
});
|
|
1790
|
-
var PostToProjectChatRequestSchema = z9.object({
|
|
1791
|
-
projectId: z9.string(),
|
|
1792
|
-
content: z9.string().min(1).max(2e4),
|
|
1793
|
-
requestingUserId: z9.string().optional(),
|
|
1794
|
-
/** Marks the post so the server can persist it beyond chat (tag-audit summaries land in tag history). */
|
|
1795
|
-
kind: z9.enum(["tag_audit_summary"]).optional()
|
|
1796
|
-
});
|
|
1797
|
-
var StartTagAuditRequestSchema = z9.object({
|
|
1798
|
-
projectId: z9.string(),
|
|
1799
|
-
requestingUserId: z9.string().optional()
|
|
1800
|
-
});
|
|
1801
|
-
var StartTaskAuditRequestSchema = z9.object({
|
|
1802
|
-
projectId: z9.string(),
|
|
1803
|
-
taskIds: z9.array(z9.string()).min(1).max(20),
|
|
1804
|
-
requestingUserId: z9.string().optional()
|
|
1805
|
-
});
|
|
1806
|
-
var GetActiveAuditSessionsRequestSchema = z9.object({
|
|
1807
|
-
projectId: z9.string()
|
|
1808
|
-
});
|
|
1809
|
-
var ReportTaskAuditResultRequestSchema = z9.object({
|
|
1810
|
-
projectId: z9.string(),
|
|
1811
|
-
taskId: z9.string(),
|
|
1812
|
-
summary: z9.string(),
|
|
1813
|
-
turnGrades: z9.array(
|
|
1814
|
-
z9.object({
|
|
1815
|
-
turnIndex: z9.number(),
|
|
1816
|
-
phase: z9.enum(["planning", "building", "human"]),
|
|
1817
|
-
grade: z9.enum(["correct", "neutral", "blunder"]),
|
|
1818
|
-
reasoning: z9.string(),
|
|
1819
|
-
eventType: z9.string(),
|
|
1820
|
-
eventSummary: z9.string()
|
|
1821
|
-
})
|
|
1822
|
-
),
|
|
1823
|
-
planningAccuracy: z9.number().nullable(),
|
|
1824
|
-
buildingAccuracy: z9.number().nullable(),
|
|
1825
|
-
humanAccuracy: z9.number().nullable(),
|
|
1826
|
-
planningCorrect: z9.number(),
|
|
1827
|
-
planningNeutral: z9.number(),
|
|
1828
|
-
planningBlunder: z9.number(),
|
|
1829
|
-
buildingCorrect: z9.number(),
|
|
1830
|
-
buildingNeutral: z9.number(),
|
|
1831
|
-
buildingBlunder: z9.number(),
|
|
1832
|
-
humanCorrect: z9.number(),
|
|
1833
|
-
humanNeutral: z9.number(),
|
|
1834
|
-
humanBlunder: z9.number(),
|
|
1835
|
-
humanEvaluations: z9.array(
|
|
1836
|
-
z9.object({
|
|
1837
|
-
messageIndex: z9.number(),
|
|
1838
|
-
rating: z9.union([z9.literal(-1), z9.literal(0), z9.literal(1)]),
|
|
1839
|
-
reasoning: z9.string()
|
|
1840
|
-
})
|
|
1841
|
-
).optional(),
|
|
1842
|
-
suggestionIds: z9.array(z9.string()),
|
|
1843
|
-
auditCostUsd: z9.number().nullable(),
|
|
1844
|
-
model: z9.string().nullable(),
|
|
1845
|
-
/** When set, the audit is marked failed with this message instead. */
|
|
1846
|
-
error: z9.string().optional()
|
|
1847
|
-
});
|
|
1848
|
-
var GetTaskAuditsRequestSchema = z9.object({
|
|
1849
|
-
projectId: z9.string(),
|
|
1850
|
-
limit: z9.number().int().positive().max(200).optional().default(50)
|
|
1851
|
-
});
|
|
1852
|
-
var GetTaskAuditRequestSchema = z9.object({
|
|
1853
|
-
projectId: z9.string(),
|
|
1854
|
-
auditId: z9.string()
|
|
1855
|
-
});
|
|
1856
|
-
var GetTaskAuditAggregatesRequestSchema = z9.object({
|
|
1857
|
-
projectId: z9.string()
|
|
1858
|
-
});
|
|
1859
|
-
var DeleteTaskAuditRequestSchema = z9.object({
|
|
1860
|
-
projectId: z9.string(),
|
|
1861
|
-
auditId: z9.string(),
|
|
1862
|
-
requestingUserId: z9.string().optional()
|
|
1863
|
-
});
|
|
1864
|
-
var MarkInitialPromptSubmittedRequestSchema = z9.object({
|
|
1865
|
-
sessionId: z9.string()
|
|
1866
|
-
});
|
|
1867
|
-
var CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set([
|
|
1868
|
-
"ci_failure",
|
|
1869
|
-
"review_trigger",
|
|
1870
|
-
"merge_conflict",
|
|
1871
|
-
"merge_failed",
|
|
1872
|
-
"pull_branch",
|
|
1873
|
-
// Child-task events for pack parents: the orchestrator must act (merge the
|
|
1874
|
-
// child's PR, start unblocked siblings, finish the pack) even after it
|
|
1875
|
-
// reported completed for a prior turn. Only ever sent to parent tasks.
|
|
1876
|
-
"parent"
|
|
1877
|
-
]);
|
|
1878
|
-
var PACK_EXECUTIONS = ["single-pod", "fan-out"];
|
|
1879
|
-
var DEFAULT_PACK_EXECUTION = "single-pod";
|
|
1880
|
-
function parsePackExecution(value) {
|
|
1881
|
-
return PACK_EXECUTIONS.includes(value ?? "") ? value : DEFAULT_PACK_EXECUTION;
|
|
1882
|
-
}
|
|
1883
|
-
var MEETING_CHECKLIST_TITLE_MAX = 300;
|
|
1884
|
-
var MEETING_TRANSCRIPT_MAX_CHARS = 2e6;
|
|
1885
|
-
var MEETING_TITLE_MAX = 200;
|
|
1886
|
-
var MEETING_OCCURRED_AT_MIN_YEAR = 2e3;
|
|
1887
|
-
var MEETING_OCCURRED_AT_MAX_FUTURE_MS = 48 * 60 * 60 * 1e3;
|
|
1888
|
-
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.`;
|
|
1889
|
-
var MeetingOccurredAtSchema = z10.string().datetime().refine((value) => {
|
|
1890
|
-
const ms = Date.parse(value);
|
|
1891
|
-
if (Number.isNaN(ms)) return false;
|
|
1892
|
-
if (ms > Date.now() + MEETING_OCCURRED_AT_MAX_FUTURE_MS) return false;
|
|
1893
|
-
return new Date(ms).getUTCFullYear() >= MEETING_OCCURRED_AT_MIN_YEAR;
|
|
1894
|
-
}, OCCURRED_AT_RANGE_MESSAGE);
|
|
1895
|
-
var CreateMeetingFromTranscriptRequestSchema = z10.object({
|
|
1896
|
-
projectId: z10.string().cuid(),
|
|
1897
|
-
rawText: z10.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
1898
|
-
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
1899
|
-
/** ISO 8601. Defaults to now when the source carries no date. */
|
|
1900
|
-
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
1901
|
-
/** Override auto-detection. Rarely needed; detection handles the three formats. */
|
|
1902
|
-
format: z10.enum(["text", "vtt", "srt"]).optional(),
|
|
1903
|
-
source: z10.enum(["manual", "slack"]).optional()
|
|
1904
|
-
});
|
|
1905
|
-
var GetMeetingRequestSchema = z10.object({
|
|
1906
|
-
projectId: z10.string().cuid(),
|
|
1907
|
-
meetingId: z10.string().cuid()
|
|
1908
|
-
});
|
|
1909
|
-
var UpdateMeetingRequestSchema = z10.object({
|
|
1910
|
-
projectId: z10.string().cuid(),
|
|
1911
|
-
meetingId: z10.string().cuid(),
|
|
1912
|
-
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
1913
|
-
occurredAt: MeetingOccurredAtSchema.optional()
|
|
1914
|
-
});
|
|
1915
|
-
var RegenerateMeetingSummaryRequestSchema = z10.object({
|
|
1916
|
-
projectId: z10.string().cuid(),
|
|
1917
|
-
meetingId: z10.string().cuid()
|
|
1918
|
-
});
|
|
1919
|
-
var DeleteMeetingRequestSchema = z10.object({
|
|
1920
|
-
projectId: z10.string().cuid(),
|
|
1921
|
-
meetingId: z10.string().cuid()
|
|
1922
|
-
});
|
|
1923
|
-
var checklistTitle = z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX);
|
|
1924
|
-
var ListMeetingChecklistRequestSchema = z10.object({
|
|
1925
|
-
projectId: z10.string().cuid(),
|
|
1926
|
-
meetingId: z10.string().cuid()
|
|
1927
|
-
});
|
|
1928
|
-
var AddMeetingChecklistItemsRequestSchema = z10.object({
|
|
1929
|
-
projectId: z10.string().cuid(),
|
|
1930
|
-
meetingId: z10.string().cuid(),
|
|
1931
|
-
items: z10.array(z10.object({ title: checklistTitle })).min(1).max(50)
|
|
1932
|
-
});
|
|
1933
|
-
var UpdateMeetingChecklistItemRequestSchema = z10.object({
|
|
1934
|
-
projectId: z10.string().cuid(),
|
|
1935
|
-
meetingId: z10.string().cuid(),
|
|
1936
|
-
itemId: z10.string().cuid(),
|
|
1937
|
-
title: checklistTitle.optional(),
|
|
1938
|
-
ordinal: z10.number().int().min(0).optional(),
|
|
1939
|
-
/** Explicit null clears the link; undefined leaves it alone. */
|
|
1940
|
-
linkedTaskId: z10.string().cuid().nullable().optional()
|
|
1941
|
-
}).refine(
|
|
1942
|
-
(v) => v.title !== void 0 || v.ordinal !== void 0 || v.linkedTaskId !== void 0,
|
|
1943
|
-
"Pass at least one of title, ordinal, or linkedTaskId."
|
|
1944
|
-
);
|
|
1945
|
-
var DeleteMeetingChecklistItemRequestSchema = z10.object({
|
|
1946
|
-
projectId: z10.string().cuid(),
|
|
1947
|
-
meetingId: z10.string().cuid(),
|
|
1948
|
-
itemId: z10.string().cuid()
|
|
1949
|
-
});
|
|
1950
|
-
var SetMeetingChecklistItemCheckedRequestSchema = z10.object({
|
|
1951
|
-
projectId: z10.string().cuid(),
|
|
1952
|
-
meetingId: z10.string().cuid(),
|
|
1953
|
-
itemId: z10.string().cuid(),
|
|
1954
|
-
checked: z10.boolean(),
|
|
1955
|
-
/** Attach the card in the same call that ticks the item. */
|
|
1956
|
-
linkedTaskId: z10.string().cuid().nullable().optional()
|
|
1957
|
-
});
|
|
1958
|
-
var ListMeetingsRequestSchema = z10.object({
|
|
1959
|
-
projectId: z10.string().cuid(),
|
|
1960
|
-
limit: z10.number().int().min(1).max(50).optional(),
|
|
1961
|
-
search: z10.string().max(200).optional()
|
|
1962
|
-
});
|
|
1963
|
-
var ReadMeetingTranscriptRequestSchema = z10.object({
|
|
1964
|
-
projectId: z10.string().cuid(),
|
|
1965
|
-
meetingId: z10.string().cuid(),
|
|
1966
|
-
offset: z10.number().int().min(0).optional(),
|
|
1967
|
-
limit: z10.number().int().min(1).max(500).optional()
|
|
1968
|
-
});
|
|
1969
|
-
var MEETING_SUMMARY_MAX_CHARS = 5e4;
|
|
1970
|
-
var AddProjectMeetingChecklistItemsRequestSchema = z10.object({
|
|
1971
|
-
projectId: z10.string().cuid(),
|
|
1972
|
-
meetingId: z10.string().cuid(),
|
|
1973
|
-
items: z10.array(z10.object({ title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX) })).min(1).max(50),
|
|
1974
|
-
requestingUserId: z10.string().optional()
|
|
1975
|
-
});
|
|
1976
|
-
var CheckProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1977
|
-
projectId: z10.string().cuid(),
|
|
1978
|
-
meetingId: z10.string().cuid(),
|
|
1979
|
-
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1980
|
-
checked: z10.boolean(),
|
|
1981
|
-
/** Card id or slug. Resolved server-side and required to be in the project. */
|
|
1982
|
-
linkedTask: z10.string().min(1).optional(),
|
|
1983
|
-
requestingUserId: z10.string().optional()
|
|
1984
|
-
});
|
|
1985
|
-
var EditProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1986
|
-
projectId: z10.string().cuid(),
|
|
1987
|
-
meetingId: z10.string().cuid(),
|
|
1988
|
-
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1989
|
-
newTitle: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1990
|
-
requestingUserId: z10.string().optional()
|
|
1991
|
-
});
|
|
1992
|
-
var RemoveProjectMeetingChecklistItemRequestSchema = z10.object({
|
|
1993
|
-
projectId: z10.string().cuid(),
|
|
1994
|
-
meetingId: z10.string().cuid(),
|
|
1995
|
-
title: z10.string().min(1).max(MEETING_CHECKLIST_TITLE_MAX),
|
|
1996
|
-
requestingUserId: z10.string().optional()
|
|
1997
|
-
});
|
|
1998
|
-
var CreateProjectMeetingRequestSchema = z10.object({
|
|
1999
|
-
projectId: z10.string().cuid(),
|
|
2000
|
-
rawText: z10.string().min(1).max(MEETING_TRANSCRIPT_MAX_CHARS),
|
|
2001
|
-
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
2002
|
-
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
2003
|
-
requestingUserId: z10.string().optional()
|
|
2004
|
-
});
|
|
2005
|
-
var UpdateProjectMeetingRequestSchema = z10.object({
|
|
2006
|
-
projectId: z10.string().cuid(),
|
|
2007
|
-
meetingId: z10.string().cuid(),
|
|
2008
|
-
title: z10.string().min(1).max(MEETING_TITLE_MAX).optional(),
|
|
2009
|
-
occurredAt: MeetingOccurredAtSchema.optional(),
|
|
2010
|
-
summary: z10.string().min(1).max(MEETING_SUMMARY_MAX_CHARS).optional(),
|
|
2011
|
-
requestingUserId: z10.string().optional()
|
|
2012
|
-
}).refine(
|
|
2013
|
-
(v) => v.title !== void 0 || v.occurredAt !== void 0 || v.summary !== void 0,
|
|
2014
|
-
"Pass at least one of title, occurredAt, or summary."
|
|
2015
|
-
);
|
|
2016
|
-
var AGENT_STATUS_REASON_USER_QUESTION = "user_question";
|
|
2017
|
-
var TASK_CHAT_HISTORY_LIMIT = 20;
|
|
2018
|
-
var PM_CHAT_HISTORY_LIMIT = 40;
|
|
2019
|
-
var AGENT_CHAT_HISTORY_FETCH_LIMIT = Math.max(TASK_CHAT_HISTORY_LIMIT, PM_CHAT_HISTORY_LIMIT) + 10;
|
|
2020
|
-
function formatModelId(provider, model) {
|
|
2021
|
-
return `${provider}/${model}`;
|
|
2022
|
-
}
|
|
2023
|
-
function anthropicEntry(model, label, inputPerMillion, outputPerMillion, opts = {}) {
|
|
2024
|
-
return {
|
|
2025
|
-
provider: "anthropic",
|
|
2026
|
-
model,
|
|
2027
|
-
id: formatModelId("anthropic", model),
|
|
2028
|
-
label,
|
|
2029
|
-
format: "anthropic-messages",
|
|
2030
|
-
inputPrice: inputPerMillion / 1e6,
|
|
2031
|
-
outputPrice: outputPerMillion / 1e6,
|
|
2032
|
-
supportsTools: true,
|
|
2033
|
-
supportsEffort: opts.supportsEffort ?? true,
|
|
2034
|
-
...opts.experimental ? { experimental: true } : {}
|
|
2035
|
-
};
|
|
2036
|
-
}
|
|
2037
|
-
var ANTHROPIC_CATALOG = [
|
|
2038
|
-
anthropicEntry(DEFAULT_OPUS_MODEL, "Opus 5 Latest", 5, 25),
|
|
2039
|
-
anthropicEntry(PREVIOUS_OPUS_MODEL, "Opus 4.8", 5, 25),
|
|
2040
|
-
anthropicEntry(DEFAULT_SONNET_MODEL, "Sonnet 5 Latest", 3, 15),
|
|
2041
|
-
anthropicEntry(PREVIOUS_SONNET_MODEL, "Sonnet 4.6", 3, 15),
|
|
2042
|
-
// The Haiku line (4.5 and older) predates the tuning surface and 400s on it.
|
|
2043
|
-
anthropicEntry(DEFAULT_HAIKU_MODEL, "Haiku 4.5", 1, 5, { supportsEffort: false }),
|
|
2044
|
-
anthropicEntry(FABLE_MODEL, "Fable 5.1", 10, 50)
|
|
2045
|
-
];
|
|
2046
|
-
var CODEX_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
|
|
2047
|
-
var DEFAULT_CODEX_CODING_MODEL = "gpt-5.6-terra";
|
|
2048
|
-
function isCodexReasoningEffort(value) {
|
|
2049
|
-
return typeof value === "string" && CODEX_REASONING_EFFORTS.includes(value);
|
|
2050
|
-
}
|
|
2051
|
-
var HUMAN_PROSE_WRITING_STYLE = `## Writing style for humans
|
|
2052
|
-
When you write prose a person will read \u2014 chat messages, plan updates, PR titles and bodies, PR review guides (the \`publish_review_guide\` overview and section explanations), review comments \u2014 follow these rules (based on ASD-STE100 Simplified Technical English):
|
|
2053
|
-
- Use active voice. Say who does what ("The API rejects the request", not "the request is rejected").
|
|
2054
|
-
- Use simple tenses ("we received", not "we have received").
|
|
2055
|
-
- One instruction or fact per sentence. Keep sentences under ~20 words.
|
|
2056
|
-
- Pick one word for one thing and reuse it. Do not rotate synonyms (check/verify/confirm) for the same action.
|
|
2057
|
-
- Prefer the plain, common word ("use", not "utilize"; "start", not "initiate").
|
|
2058
|
-
- Do not stack more than 3 nouns in a row ("task queue handler" is the limit).
|
|
2059
|
-
- Use a numbered or bulleted list for 3+ steps or conditions instead of burying them in one sentence.
|
|
2060
|
-
- Define a technical term on first use when a non-engineer will read the message.
|
|
2061
|
-
- Never drop a condition, number, or scope qualifier to shorten a sentence. Precision beats brevity.
|
|
2062
|
-
These rules do NOT apply to code, code comments, commit messages, or quoted output.`;
|
|
2063
|
-
var CLAUDESPACE_WORKLOAD_LABEL = "rc-workload";
|
|
2064
|
-
var CLAUDESPACE_WORKLOAD_VALUE = "claudespace";
|
|
2065
|
-
var CONVEYOR_POD_SELECTOR = `${CLAUDESPACE_WORKLOAD_LABEL}=${CLAUDESPACE_WORKLOAD_VALUE}`;
|
|
2066
|
-
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
2067
|
-
var MENTION_TOKEN_REGEX = /@\[(\w+):([^\]]+)\]/g;
|
|
2068
|
-
function parseMentions(content) {
|
|
2069
|
-
const tokens = [];
|
|
2070
|
-
for (const match of content.matchAll(MENTION_TOKEN_REGEX)) {
|
|
2071
|
-
tokens.push({ type: match[1], id: match[2] });
|
|
2072
|
-
}
|
|
2073
|
-
return tokens;
|
|
2074
|
-
}
|
|
2075
|
-
var POSTGRES_ENV = {
|
|
2076
|
-
POSTGRES_HOST_AUTH_METHOD: "trust",
|
|
2077
|
-
POSTGRES_DB: "conveyor"
|
|
2078
|
-
};
|
|
2079
|
-
var FIREBASE_EMULATOR_COMMAND = [
|
|
2080
|
-
"sh",
|
|
2081
|
-
"-c",
|
|
2082
|
-
`set -e; mkdir -p /home/node && cd /home/node && cat > firebase.json <<'EOF'
|
|
2083
|
-
{"emulators":{"auth":{"host":"0.0.0.0","port":9099},"hub":{"host":"0.0.0.0","port":4400},"ui":{"enabled":false}}}
|
|
2084
|
-
EOF
|
|
2085
|
-
exec firebase emulators:start --only=auth --project=rally-cry-dev`
|
|
2086
|
-
];
|
|
2087
|
-
var FIREBASE_EMULATOR_ENV = {
|
|
2088
|
-
METADATA_SERVER_DETECTION: "none",
|
|
2089
|
-
GOOGLE_APPLICATION_CREDENTIALS: "/dev/null"
|
|
2090
|
-
};
|
|
2091
|
-
var CATALOG = {
|
|
2092
|
-
postgresql: {
|
|
2093
|
-
name: "postgresql",
|
|
2094
|
-
image: "postgres:16-alpine",
|
|
2095
|
-
command: [
|
|
2096
|
-
"sh",
|
|
2097
|
-
"-c",
|
|
2098
|
-
// Start postgres, wait for readiness, then create the test database.
|
|
2099
|
-
// Durability flags: service state is ephemeral by design (overlayfs, no
|
|
2100
|
-
// PVC; a crash re-seeds from pod-data), so commits must never wait on a
|
|
2101
|
-
// WAL flush. fsync=off + synchronous_commit=off + full_page_writes=off
|
|
2102
|
-
// remove all blocking storage I/O — without them, per-commit flushes on
|
|
2103
|
-
// the node's network boot disk dominated int-test wall time (~100ms/commit).
|
|
2104
|
-
"if [ ! -s /var/lib/postgresql/data/PG_VERSION ] && [ -d /var/lib/postgresql/pod-data ]; then cp -a /var/lib/postgresql/pod-data/. /var/lib/postgresql/data/; fi; chown -R postgres:postgres /var/lib/postgresql/data; docker-entrypoint.sh postgres -c fsync=off -c synchronous_commit=off -c full_page_writes=off & PID=$!; for i in $(seq 1 30); do pg_isready -U postgres && break; sleep 1; done; createdb -U postgres conveyor_test 2>/dev/null || true; wait $PID"
|
|
2105
|
-
],
|
|
2106
|
-
ports: [5432],
|
|
2107
|
-
livenessProbe: {
|
|
2108
|
-
exec: ["pg_isready", "-U", "postgres"],
|
|
2109
|
-
periodSeconds: 30,
|
|
2110
|
-
failureThreshold: 3,
|
|
2111
|
-
timeoutSeconds: 5,
|
|
2112
|
-
initialDelaySeconds: 60
|
|
2113
|
-
},
|
|
2114
|
-
env: { ...POSTGRES_ENV },
|
|
2115
|
-
resources: {
|
|
2116
|
-
// postgres runs from the baked seed at /var/lib/postgresql/pod-data via
|
|
2117
|
-
// overlayfs CoW (no emptyDir — see k8s-pod-spec.ts), so WAL + catalog +
|
|
2118
|
-
// re-seed churn charges the container's ephemeral-storage. It must exceed
|
|
2119
|
-
// the ~1Gi ceiling where pods evicted, but is bounded by TWO Autopilot rules:
|
|
2120
|
-
// 1) limit == request — Autopilot caps the limit DOWN to the request at
|
|
2121
|
-
// admission, so headroom must live on the REQUEST, not just the limit;
|
|
2122
|
-
// 2) the SUM of all container ephemeral requests in a pod must be ≤ 10Gi
|
|
2123
|
-
// (an emptyDir doesn't escape this: its usage still evicts against the
|
|
2124
|
-
// container limit, and raising the limit re-hits rule 1 → the cap).
|
|
2125
|
-
// The agent is trimmed to 4Gi (resource-tiers.ts) to free room: with
|
|
2126
|
-
// agent 4 + gcsfuse 1 + lgtm 1 + es/redis/firebase 0.75, postgres gets 3Gi
|
|
2127
|
-
// and the heaviest (URC) pod sits at 9.75Gi + 10Mi for GCS Fuse metadata
|
|
2128
|
-
// prefetch — under the 10Gi cap — while giving postgres 3x the ~1Gi
|
|
2129
|
-
// ceiling that evicted. Keep request == limit;
|
|
2130
|
-
// see the per-pod ephemeral budget guard test.
|
|
2131
|
-
// CPU: the request is the CFS floor; the old 50m starved postgres to 5ms
|
|
2132
|
-
// of CPU per 100ms period — every query burst hit throttle stalls, which
|
|
2133
|
-
// showed up as ~100ms floors on trivial statements and dominated the API
|
|
2134
|
-
// int suite even after the fsync flags above. 500m is paid for out of the
|
|
2135
|
-
// agent's derived share (resource-tiers.ts). The limit bursts to 2 for
|
|
2136
|
-
// spiky work — the first-boot pod-data seed copy and int-suite query
|
|
2137
|
-
// storms — borrowing idle node CPU without moving the request.
|
|
2138
|
-
requests: { cpuMillicores: 500, memoryMi: 512, ephemeralMi: 3 * 1024 },
|
|
2139
|
-
limits: { cpuMillicores: 2e3, memoryMi: 512, ephemeralMi: 3 * 1024 }
|
|
2140
|
-
},
|
|
2141
|
-
connectionEnv: {
|
|
2142
|
-
DATABASE_URL: "postgresql://postgres@postgresql:5432/conveyor",
|
|
2143
|
-
TEST_DATABASE_URL: "postgresql://postgres@postgresql:5432/conveyor_test"
|
|
2144
|
-
},
|
|
2145
|
-
statefulBake: true,
|
|
2146
|
-
bake: {
|
|
2147
|
-
// Start postgres, wait for readiness, then create the test database so
|
|
2148
|
-
// it's baked into the committed image. No pod-data restore (nothing is
|
|
2149
|
-
// seeded yet) and no durability flags (the bake's writes must land).
|
|
2150
|
-
// NOTE: docker-compose interpolates `$VAR`/`$(...)`, so every `$` that
|
|
2151
|
-
// must reach the shell is doubled.
|
|
2152
|
-
command: [
|
|
2153
|
-
"sh",
|
|
2154
|
-
"-c",
|
|
2155
|
-
"docker-entrypoint.sh postgres & PID=$$!; for i in $$(seq 1 30); do pg_isready -U postgres && break; sleep 1; done; createdb -U postgres conveyor_test 2>/dev/null || true; wait $$PID"
|
|
2156
|
-
],
|
|
2157
|
-
environment: { ...POSTGRES_ENV },
|
|
2158
|
-
healthcheck: {
|
|
2159
|
-
test: ["CMD-SHELL", "pg_isready -U postgres"],
|
|
2160
|
-
intervalSec: 2,
|
|
2161
|
-
timeoutSec: 5,
|
|
2162
|
-
retries: 15
|
|
2163
|
-
}
|
|
2164
|
-
}
|
|
2165
|
-
},
|
|
2166
|
-
redis: {
|
|
2167
|
-
name: "redis",
|
|
2168
|
-
image: "redis:7-alpine",
|
|
2169
|
-
command: ["redis-server", "--appendonly", "yes", "--dir", "/data"],
|
|
2170
|
-
ports: [6379],
|
|
2171
|
-
env: {},
|
|
2172
|
-
resources: {
|
|
2173
|
-
requests: { cpuMillicores: 25, memoryMi: 32, ephemeralMi: 256 },
|
|
2174
|
-
limits: { cpuMillicores: 50, memoryMi: 64, ephemeralMi: 256 }
|
|
2175
|
-
},
|
|
2176
|
-
connectionEnv: {
|
|
2177
|
-
REDIS_URL: "redis://redis:6379",
|
|
2178
|
-
AUTH_REDIS_URL: "redis://redis:6379"
|
|
2179
|
-
},
|
|
2180
|
-
statefulBake: false,
|
|
2181
|
-
// Redis holds no baked state, so the bake runs the stock image CMD.
|
|
2182
|
-
bake: {},
|
|
2183
|
-
mirror: { src: "redis:7-alpine", dest: "mirror-redis:7-alpine" }
|
|
2184
|
-
},
|
|
2185
|
-
elasticsearch: {
|
|
2186
|
-
name: "elasticsearch",
|
|
2187
|
-
// 9.4.0 matches universal-rally-cry's local compose + its v9 ES client —
|
|
2188
|
-
// the v9 client sends Accept: compatible-with=9, which an 8.x server
|
|
2189
|
-
// rejects (media_type_header_exception), breaking search/audit indexing
|
|
2190
|
-
// in pods. 512m heap matches the project compose sizing.
|
|
2191
|
-
image: "docker.elastic.co/elasticsearch/elasticsearch:9.4.0",
|
|
2192
|
-
mirror: {
|
|
2193
|
-
src: "docker.elastic.co/elasticsearch/elasticsearch:9.4.0",
|
|
2194
|
-
dest: "mirror-elasticsearch:9.4.0"
|
|
2195
|
-
},
|
|
2196
|
-
ports: [9200],
|
|
2197
|
-
// Baked service images are `docker commit`s of a recently-running ES, so
|
|
2198
|
-
// they carry a stale data-dir node.lock; ES 9 hard-fails on it at boot
|
|
2199
|
-
// ("Underlying file changed by an external force" → AlreadyClosedException).
|
|
2200
|
-
// Clear it before handing off to the stock entrypoint.
|
|
2201
|
-
command: [
|
|
2202
|
-
"sh",
|
|
2203
|
-
"-c",
|
|
2204
|
-
// ALL Lucene lock files, not just node.lock — the baked image also
|
|
2205
|
-
// carries per-index write.lock + snapshot_cache/write.lock, and ES 9
|
|
2206
|
-
// fail-fasts on any of them ("changed by an external force").
|
|
2207
|
-
"find /usr/share/elasticsearch/data -name '*.lock' -type f -delete 2>/dev/null; exec /usr/local/bin/docker-entrypoint.sh eswrapper"
|
|
2208
|
-
],
|
|
2209
|
-
env: {
|
|
2210
|
-
"discovery.type": "single-node",
|
|
2211
|
-
"xpack.security.enabled": "false",
|
|
2212
|
-
"xpack.ml.enabled": "false",
|
|
2213
|
-
"xpack.watcher.enabled": "false",
|
|
2214
|
-
"xpack.profiling.enabled": "false",
|
|
2215
|
-
"ingest.geoip.downloader.enabled": "false",
|
|
2216
|
-
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
|
|
2217
|
-
},
|
|
2218
|
-
resources: {
|
|
2219
|
-
// CPU limit 4x the request: ES cold-start is a CPU-bound JVM boot
|
|
2220
|
-
// (class loading + JIT + recovery of the docker-commit'ed data dir),
|
|
2221
|
-
// and the 500m hard cap put it at ~135s to yellow — past the sidecar
|
|
2222
|
-
// wait script's original 90s budget. Bursting to 2 cut it to ~40s on
|
|
2223
|
-
// the real cluster (A/B on identical nodes, 2 rounds). The burst only
|
|
2224
|
-
// borrows idle node CPU at boot; under contention CFS still floors ES
|
|
2225
|
-
// at its 500m request.
|
|
2226
|
-
requests: { cpuMillicores: 500, memoryMi: 1024, ephemeralMi: 256 },
|
|
2227
|
-
limits: { cpuMillicores: 2e3, memoryMi: 1024, ephemeralMi: 256 }
|
|
2228
|
-
},
|
|
2229
|
-
connectionEnv: {
|
|
2230
|
-
ELASTICSEARCH_URL: "http://elasticsearch:9200"
|
|
2231
|
-
},
|
|
2232
|
-
statefulBake: true,
|
|
2233
|
-
bake: {
|
|
2234
|
-
// No lock-clearing command at bake time: the bake starts from the stock
|
|
2235
|
-
// image, which has no committed data dir to unlock yet.
|
|
2236
|
-
environment: {
|
|
2237
|
-
"discovery.type": "single-node",
|
|
2238
|
-
"xpack.security.enabled": "false",
|
|
2239
|
-
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
},
|
|
2243
|
-
// All-in-one image bundling Grafana + Loki + Tempo + Mimir + an OTEL Collector.
|
|
2244
|
-
// Pinned tag (not :latest) so the image-builder content hash stays
|
|
2245
|
-
// deterministic across upstream releases — see image-builder.ts content-hash
|
|
2246
|
-
// dedup keyed on `deps.sorted()`.
|
|
2247
|
-
lgtm: {
|
|
2248
|
-
name: "lgtm",
|
|
2249
|
-
image: "grafana/otel-lgtm:0.11.6",
|
|
2250
|
-
// The otel-lgtm image's own CMD is ["/otel-lgtm/run-all.sh"] (WORKDIR
|
|
2251
|
-
// /otel-lgtm). Declaring it explicitly makes lgtm a command-based service so
|
|
2252
|
-
// the lazy start-file gate wraps it like the others — otherwise it launches
|
|
2253
|
-
// via image CMD at boot and can't be parked (which is why warm-booting it at
|
|
2254
|
-
// a minimal request OOMKilled it). getSidecarSpecs strips this command for a
|
|
2255
|
-
// baked lgtm image, so it only applies to the stock image whose launcher is
|
|
2256
|
-
// exactly this path.
|
|
2257
|
-
command: ["/otel-lgtm/run-all.sh"],
|
|
2258
|
-
ports: [
|
|
2259
|
-
// OTLP gRPC + HTTP — agents and user code emit telemetry here.
|
|
2260
|
-
4317,
|
|
2261
|
-
4318,
|
|
2262
|
-
// Grafana UI — reachable through the existing preview proxy on
|
|
2263
|
-
// https://3000-{sessionId}.preview.<PREVIEW_DOMAIN>/.
|
|
2264
|
-
3e3
|
|
2265
|
-
],
|
|
2266
|
-
env: {
|
|
2267
|
-
// The pod is per-task; the preview proxy authenticates the session
|
|
2268
|
-
// upstream, so anonymous in-pod admin is acceptable here.
|
|
2269
|
-
GF_AUTH_ANONYMOUS_ENABLED: "true",
|
|
2270
|
-
GF_AUTH_ANONYMOUS_ORG_ROLE: "Admin",
|
|
2271
|
-
GF_SECURITY_ALLOW_EMBEDDING: "true",
|
|
2272
|
-
ENABLE_LOGS_GRAFANA: "true",
|
|
2273
|
-
ENABLE_LOGS_OTELCOL: "true"
|
|
2274
|
-
},
|
|
2275
|
-
resources: {
|
|
2276
|
-
// Autopilot caps the ephemeral-storage limit to the request (see the
|
|
2277
|
-
// postgresql note), so the 1Gi headroom must be on the request too.
|
|
2278
|
-
requests: { cpuMillicores: 250, memoryMi: 1024, ephemeralMi: 1024 },
|
|
2279
|
-
limits: { cpuMillicores: 1e3, memoryMi: 2048, ephemeralMi: 1024 }
|
|
2280
|
-
},
|
|
2281
|
-
statefulBake: false,
|
|
2282
|
-
// No `bake` block: a BAKE produces traces nobody reads, so starting the
|
|
2283
|
-
// (heavy) collector image would only add a pull + boot to every build.
|
|
2284
|
-
// lgtm still runs for live pods, and is never committed regardless.
|
|
2285
|
-
mirror: { src: "grafana/otel-lgtm:0.11.6", dest: "mirror-otel-lgtm:0.11.6" }
|
|
2286
|
-
},
|
|
2287
|
-
"firebase-auth-emulator": {
|
|
2288
|
-
name: "firebase-auth-emulator",
|
|
2289
|
-
image: "andreysenov/firebase-tools:latest",
|
|
2290
|
-
command: FIREBASE_EMULATOR_COMMAND,
|
|
2291
|
-
ports: [9099, 4400],
|
|
2292
|
-
env: {
|
|
2293
|
-
// The emulator container inherits the pod's Workload Identity, so
|
|
2294
|
-
// firebase-tools finds GCP credentials and its `emulators:start` does an
|
|
2295
|
-
// online "auto auth" + project validation that stalls ~47s on the pod's
|
|
2296
|
-
// locked-down egress (the dominant service boot cost — measured live).
|
|
2297
|
-
// The emulator needs NO real credentials, so cut off credential discovery
|
|
2298
|
-
// for this container only: google-auth-library skips metadata detection
|
|
2299
|
-
// and finds no key file, firebase-tools logs "not authenticated" and
|
|
2300
|
-
// starts the emulator immediately. The agent container keeps its WI.
|
|
2301
|
-
...FIREBASE_EMULATOR_ENV
|
|
2302
|
-
},
|
|
2303
|
-
resources: {
|
|
2304
|
-
requests: { cpuMillicores: 100, memoryMi: 256, ephemeralMi: 256 },
|
|
2305
|
-
limits: { cpuMillicores: 500, memoryMi: 512, ephemeralMi: 256 }
|
|
2306
|
-
},
|
|
2307
|
-
connectionEnv: {
|
|
2308
|
-
// In docker-compose, services reach each other by service name — the
|
|
2309
|
-
// runtime pod equivalents use `localhost` because co-located services
|
|
2310
|
-
// share the pod's network namespace.
|
|
2311
|
-
FIREBASE_AUTH_EMULATOR_HOST: "firebase-auth-emulator:9099",
|
|
2312
|
-
NEXT_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST: "firebase-auth-emulator:9099"
|
|
2313
|
-
},
|
|
2314
|
-
statefulBake: false,
|
|
2315
|
-
mirror: {
|
|
2316
|
-
src: "andreysenov/firebase-tools:latest",
|
|
2317
|
-
dest: "mirror-firebase-tools:latest"
|
|
2318
|
-
},
|
|
2319
|
-
bake: {
|
|
2320
|
-
// The emulator writes its config at startup, so the bake needs the same
|
|
2321
|
-
// inline command the runtime uses.
|
|
2322
|
-
command: FIREBASE_EMULATOR_COMMAND,
|
|
2323
|
-
environment: FIREBASE_EMULATOR_ENV,
|
|
2324
|
-
healthcheck: {
|
|
2325
|
-
// Probe with node, the one runtime this image guarantees. The image
|
|
2326
|
-
// (`andreysenov/firebase-tools`) is a slim Node image that ships
|
|
2327
|
-
// NEITHER `wget` NOR `curl`, so the `wget -qO- …` probe this replaced
|
|
2328
|
-
// exited 127 on every attempt: a healthy emulator burned all 20 retries
|
|
2329
|
-
// and every bake reported it unhealthy. See the catalog invariant in
|
|
2330
|
-
// `service-definitions.test.ts`, which also executes this probe.
|
|
2331
|
-
test: [
|
|
2332
|
-
"CMD-SHELL",
|
|
2333
|
-
`node -e "fetch('http://localhost:9099/').then((response) => process.exit(response.ok ? 0 : 1)).catch(() => process.exit(1))"`
|
|
2334
|
-
],
|
|
2335
|
-
intervalSec: 3,
|
|
2336
|
-
timeoutSec: 5,
|
|
2337
|
-
retries: 20
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
}
|
|
2341
|
-
};
|
|
2342
|
-
var SERVICE_DEFINITIONS = CATALOG;
|
|
2343
|
-
var SUPPORTED_CLAUDESPACE_DEPS = Object.keys(CATALOG);
|
|
2344
|
-
var STATEFUL_BAKE_DEPS = new Set(
|
|
2345
|
-
SUPPORTED_CLAUDESPACE_DEPS.filter((dep) => SERVICE_DEFINITIONS[dep].statefulBake)
|
|
2346
|
-
);
|
|
2347
|
-
var MIRRORABLE_SIDECARS = Object.fromEntries(
|
|
2348
|
-
SUPPORTED_CLAUDESPACE_DEPS.flatMap((dep) => {
|
|
2349
|
-
const mirror = SERVICE_DEFINITIONS[dep].mirror;
|
|
2350
|
-
return mirror ? [[dep, mirror]] : [];
|
|
2351
|
-
})
|
|
2352
|
-
);
|
|
2353
|
-
var LEVELS_PER_BAND = 100;
|
|
2354
|
-
var PRESTIGE_TIERS = ACHIEVEMENT_RARITIES.map((rarity, index) => ({
|
|
2355
|
-
prestige: index + 1,
|
|
2356
|
-
name: rarity.name,
|
|
2357
|
-
color: rarity.color,
|
|
2358
|
-
iconPath: rarity.iconPath,
|
|
2359
|
-
minLevel: (index + 1) * LEVELS_PER_BAND
|
|
2360
|
-
}));
|
|
2361
|
-
var TOP_PRESTIGE_BAND = PRESTIGE_TIERS.length;
|
|
2362
|
-
var PRE_BUILD_TASK_STATUSES = /* @__PURE__ */ new Set(["Planning", "Open"]);
|
|
2363
|
-
function hasTaskPlan(plan) {
|
|
2364
|
-
return !!plan?.trim();
|
|
2365
|
-
}
|
|
2366
|
-
var CARD_TYPE_SURFACE = {
|
|
2367
|
-
task: "board",
|
|
2368
|
-
chat: "board",
|
|
2369
|
-
incident: "report",
|
|
2370
|
-
suggestion: "report"
|
|
2371
|
-
};
|
|
2372
|
-
var surfaceTypes = (surface) => Object.keys(CARD_TYPE_SURFACE).filter(
|
|
2373
|
-
(type) => CARD_TYPE_SURFACE[type] === surface
|
|
2374
|
-
);
|
|
2375
|
-
var BOARD_CARD_TYPES = surfaceTypes("board");
|
|
2376
|
-
var REPORT_CARD_TYPES = surfaceTypes("report");
|
|
73
|
+
git,
|
|
74
|
+
hasTaskPlan,
|
|
75
|
+
hasUncommittedChanges,
|
|
76
|
+
hasUnpushedCommits,
|
|
77
|
+
isCodexReasoningEffort,
|
|
78
|
+
isPlaceholderLocator,
|
|
79
|
+
locatorMatchesContent,
|
|
80
|
+
parseMentions,
|
|
81
|
+
pushToOrigin,
|
|
82
|
+
readWorkspaceBytes,
|
|
83
|
+
readWorkspaceDir,
|
|
84
|
+
readWorkspaceFile,
|
|
85
|
+
recordForceFreshFailure,
|
|
86
|
+
remoteMatchesLocalHead,
|
|
87
|
+
restoreWipSnapshot,
|
|
88
|
+
runQueryGcpLogs,
|
|
89
|
+
runQueryGrafanaLogs,
|
|
90
|
+
stageAndCommit,
|
|
91
|
+
statWorkspacePath,
|
|
92
|
+
updateRemoteToken,
|
|
93
|
+
verifyGitCredential
|
|
94
|
+
} from "./chunk-OMD77OIJ.js";
|
|
95
|
+
import {
|
|
96
|
+
registerBootMilestoneSocketFallback,
|
|
97
|
+
reportBootMilestone
|
|
98
|
+
} from "./chunk-Q4FQOJ7D.js";
|
|
99
|
+
import {
|
|
100
|
+
describeTokenFile,
|
|
101
|
+
ghHostsExternallyOwned,
|
|
102
|
+
githubTokenFilePath,
|
|
103
|
+
sleep
|
|
104
|
+
} from "./chunk-W4LZ7R6Z.js";
|
|
105
|
+
import {
|
|
106
|
+
isHeavyGateActive,
|
|
107
|
+
listAbandonedGateReceipts,
|
|
108
|
+
listGateExitSentinels,
|
|
109
|
+
refreshGenericGateStatus
|
|
110
|
+
} from "./chunk-372R6E4C.js";
|
|
111
|
+
import {
|
|
112
|
+
LoopLagMonitor,
|
|
113
|
+
loopStatusForRunnerStatus
|
|
114
|
+
} from "./chunk-IA45XHOA.js";
|
|
115
|
+
import {
|
|
116
|
+
getWorkbenchClient
|
|
117
|
+
} from "./chunk-SQM2BQ7H.js";
|
|
118
|
+
import {
|
|
119
|
+
workbenchEnabled
|
|
120
|
+
} from "./chunk-KMB3BU4S.js";
|
|
2377
121
|
|
|
2378
122
|
// src/connection/auth-errors.ts
|
|
2379
123
|
function isPermissionDeniedError(err) {
|
|
@@ -2608,7 +352,7 @@ function defineTool(name, description, schema, handler, options) {
|
|
|
2608
352
|
|
|
2609
353
|
// src/harness/claude-code/index.ts
|
|
2610
354
|
import { query, tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
2611
|
-
import { z
|
|
355
|
+
import { z } from "zod";
|
|
2612
356
|
var ClaudeCodeHarness = class {
|
|
2613
357
|
/** The SDK stream is itself the structured-event source. */
|
|
2614
358
|
emitsStructuredEvents = true;
|
|
@@ -2641,7 +385,7 @@ var ClaudeCodeHarness = class {
|
|
|
2641
385
|
}
|
|
2642
386
|
);
|
|
2643
387
|
if (t.strict) {
|
|
2644
|
-
sdkTool.inputSchema =
|
|
388
|
+
sdkTool.inputSchema = z.strictObject(t.schema);
|
|
2645
389
|
}
|
|
2646
390
|
return sdkTool;
|
|
2647
391
|
});
|
|
@@ -3038,7 +782,7 @@ function redact(input) {
|
|
|
3038
782
|
import { open } from "fs/promises";
|
|
3039
783
|
|
|
3040
784
|
// src/harness/pty/record-mapper.ts
|
|
3041
|
-
function
|
|
785
|
+
function isRecord(value) {
|
|
3042
786
|
return typeof value === "object" && value !== null;
|
|
3043
787
|
}
|
|
3044
788
|
function isUnknownArray(value) {
|
|
@@ -3084,7 +828,7 @@ function mapSystem(record) {
|
|
|
3084
828
|
}
|
|
3085
829
|
function mapUsage(message) {
|
|
3086
830
|
const usage = message.usage;
|
|
3087
|
-
if (!
|
|
831
|
+
if (!isRecord(usage)) return void 0;
|
|
3088
832
|
const result = {};
|
|
3089
833
|
const input = numberField(usage, "input_tokens");
|
|
3090
834
|
const cacheRead = numberField(usage, "cache_read_input_tokens");
|
|
@@ -3095,7 +839,7 @@ function mapUsage(message) {
|
|
|
3095
839
|
return result;
|
|
3096
840
|
}
|
|
3097
841
|
function mapContentBlock(raw) {
|
|
3098
|
-
if (!
|
|
842
|
+
if (!isRecord(raw)) return null;
|
|
3099
843
|
const type = stringField(raw, "type");
|
|
3100
844
|
if (type === void 0) return null;
|
|
3101
845
|
const block = { type };
|
|
@@ -3110,7 +854,7 @@ function mapContentBlock(raw) {
|
|
|
3110
854
|
}
|
|
3111
855
|
function mapAssistant(record) {
|
|
3112
856
|
const message = record.message;
|
|
3113
|
-
if (!
|
|
857
|
+
if (!isRecord(message)) return null;
|
|
3114
858
|
const rawContent = isUnknownArray(message.content) ? message.content : [];
|
|
3115
859
|
const content = [];
|
|
3116
860
|
for (const item of rawContent) {
|
|
@@ -3134,7 +878,7 @@ function mapResultSuccess(record) {
|
|
|
3134
878
|
total_cost_usd: numberField(record, "total_cost_usd", "totalCostUsd") ?? 0
|
|
3135
879
|
};
|
|
3136
880
|
const modelUsage = record.modelUsage;
|
|
3137
|
-
if (
|
|
881
|
+
if (isRecord(modelUsage)) event.modelUsage = modelUsage;
|
|
3138
882
|
const sessionId = stringField(record, "session_id", "sessionId");
|
|
3139
883
|
if (sessionId !== void 0) event.sessionId = sessionId;
|
|
3140
884
|
return event;
|
|
@@ -3153,7 +897,7 @@ function mapResult(record) {
|
|
|
3153
897
|
return null;
|
|
3154
898
|
}
|
|
3155
899
|
function mapTranscriptRecord(raw) {
|
|
3156
|
-
if (!
|
|
900
|
+
if (!isRecord(raw)) return null;
|
|
3157
901
|
switch (raw.type) {
|
|
3158
902
|
case "system":
|
|
3159
903
|
return mapSystem(raw);
|
|
@@ -3670,7 +1414,7 @@ var TEXT_MAX = 16e3;
|
|
|
3670
1414
|
var TOOL_INPUT_MAX = 1900;
|
|
3671
1415
|
var TOOL_OUTPUT_MAX = 1900;
|
|
3672
1416
|
var QUESTION_INPUT_MAX = 16e3;
|
|
3673
|
-
function
|
|
1417
|
+
function isRecord2(value) {
|
|
3674
1418
|
return typeof value === "object" && value !== null;
|
|
3675
1419
|
}
|
|
3676
1420
|
function isUnknownArray2(value) {
|
|
@@ -3701,7 +1445,7 @@ function compactQuestionsJson(questions) {
|
|
|
3701
1445
|
return serialize(withDescriptions(0)).slice(0, QUESTION_INPUT_MAX);
|
|
3702
1446
|
}
|
|
3703
1447
|
function compactToolInput(name, input) {
|
|
3704
|
-
if (name === "AskUserQuestion" &&
|
|
1448
|
+
if (name === "AskUserQuestion" && isRecord2(input)) {
|
|
3705
1449
|
const questions = parseUserQuestions(input);
|
|
3706
1450
|
if (questions.length > 0) return compactQuestionsJson(questions);
|
|
3707
1451
|
}
|
|
@@ -3714,15 +1458,15 @@ function isNonConversationText(text) {
|
|
|
3714
1458
|
}
|
|
3715
1459
|
function userRecordText(record) {
|
|
3716
1460
|
const message = record.message;
|
|
3717
|
-
if (!
|
|
1461
|
+
if (!isRecord2(message)) return void 0;
|
|
3718
1462
|
const content = message.content;
|
|
3719
1463
|
if (typeof content === "string") return content;
|
|
3720
1464
|
if (!isUnknownArray2(content)) return void 0;
|
|
3721
|
-
if (content.some((b) =>
|
|
3722
|
-
return content.filter((b) =>
|
|
1465
|
+
if (content.some((b) => isRecord2(b) && b.type === "tool_result")) return void 0;
|
|
1466
|
+
return content.filter((b) => isRecord2(b) && b.type === "text").map((b) => typeof b.text === "string" ? b.text : "").filter((t) => t.length > 0).join("\n");
|
|
3723
1467
|
}
|
|
3724
1468
|
function isBackgroundTaskNotificationRecord(raw) {
|
|
3725
|
-
if (!
|
|
1469
|
+
if (!isRecord2(raw) || raw.type !== "user") return false;
|
|
3726
1470
|
if (raw.isSidechain === true || raw.isMeta === true) return false;
|
|
3727
1471
|
const text = userRecordText(raw);
|
|
3728
1472
|
return text !== void 0 && text.trimStart().startsWith(TASK_NOTIFICATION_PREFIX);
|
|
@@ -3742,11 +1486,11 @@ function mapSystem2(record) {
|
|
|
3742
1486
|
}
|
|
3743
1487
|
function mapAssistant2(record) {
|
|
3744
1488
|
const message = record.message;
|
|
3745
|
-
if (!
|
|
1489
|
+
if (!isRecord2(message)) return [];
|
|
3746
1490
|
const content = isUnknownArray2(message.content) ? message.content : [];
|
|
3747
1491
|
const events = [];
|
|
3748
1492
|
for (const raw of content) {
|
|
3749
|
-
if (!
|
|
1493
|
+
if (!isRecord2(raw)) continue;
|
|
3750
1494
|
if (raw.type === "text") {
|
|
3751
1495
|
const text = stringField2(raw, "text");
|
|
3752
1496
|
if (text && text.length > 0) {
|
|
@@ -3773,14 +1517,14 @@ function toolResultText(block) {
|
|
|
3773
1517
|
const content = block.content;
|
|
3774
1518
|
if (typeof content === "string") return content;
|
|
3775
1519
|
if (isUnknownArray2(content)) {
|
|
3776
|
-
return content.filter((b) =>
|
|
1520
|
+
return content.filter((b) => isRecord2(b) && b.type === "text").map((b) => typeof b.text === "string" ? b.text : "").filter((t) => t.length > 0).join("\n");
|
|
3777
1521
|
}
|
|
3778
1522
|
return "";
|
|
3779
1523
|
}
|
|
3780
1524
|
function mapToolResults(content) {
|
|
3781
1525
|
const events = [];
|
|
3782
1526
|
for (const raw of content) {
|
|
3783
|
-
if (!
|
|
1527
|
+
if (!isRecord2(raw) || raw.type !== "tool_result") continue;
|
|
3784
1528
|
const event = {
|
|
3785
1529
|
kind: "tool_result",
|
|
3786
1530
|
output: truncate2(toolResultText(raw), TOOL_OUTPUT_MAX),
|
|
@@ -3794,9 +1538,9 @@ function mapToolResults(content) {
|
|
|
3794
1538
|
}
|
|
3795
1539
|
function mapUser(record) {
|
|
3796
1540
|
const message = record.message;
|
|
3797
|
-
if (!
|
|
1541
|
+
if (!isRecord2(message)) return [];
|
|
3798
1542
|
const content = message.content;
|
|
3799
|
-
if (isUnknownArray2(content) && content.some((b) =>
|
|
1543
|
+
if (isUnknownArray2(content) && content.some((b) => isRecord2(b) && b.type === "tool_result")) {
|
|
3800
1544
|
return mapToolResults(content);
|
|
3801
1545
|
}
|
|
3802
1546
|
const text = userRecordText(record);
|
|
@@ -3806,7 +1550,7 @@ function mapUser(record) {
|
|
|
3806
1550
|
return [{ kind: "user_text", text: truncate2(trimmed, TEXT_MAX) }];
|
|
3807
1551
|
}
|
|
3808
1552
|
function mapChatRecords(raw) {
|
|
3809
|
-
if (!
|
|
1553
|
+
if (!isRecord2(raw)) return [];
|
|
3810
1554
|
if (raw.isSidechain === true || raw.isMeta === true) return [];
|
|
3811
1555
|
switch (raw.type) {
|
|
3812
1556
|
case "system":
|
|
@@ -4134,7 +1878,7 @@ var PtyOutputCoalescer = class {
|
|
|
4134
1878
|
|
|
4135
1879
|
// src/harness/pty/tool-server.ts
|
|
4136
1880
|
import { createServer as createServer2 } from "http";
|
|
4137
|
-
import { z as
|
|
1881
|
+
import { z as z2 } from "zod";
|
|
4138
1882
|
import { writeFile as writeFile4 } from "fs/promises";
|
|
4139
1883
|
import { join as join4 } from "path";
|
|
4140
1884
|
import { randomBytes } from "crypto";
|
|
@@ -4191,7 +1935,7 @@ var PtyToolServer = class {
|
|
|
4191
1935
|
const mcp = new McpServer({ name: this.name, version: "1.0.0" });
|
|
4192
1936
|
const register = mcp.registerTool.bind(mcp);
|
|
4193
1937
|
for (const tool2 of this.tools) {
|
|
4194
|
-
const inputSchema = tool2.strict ?
|
|
1938
|
+
const inputSchema = tool2.strict ? z2.strictObject(tool2.schema) : tool2.schema;
|
|
4195
1939
|
register(
|
|
4196
1940
|
tool2.name,
|
|
4197
1941
|
{
|
|
@@ -7524,383 +5268,122 @@ var DirectStreamController = class {
|
|
|
7524
5268
|
const off = this.inner.onResize((cols, rows) => {
|
|
7525
5269
|
this.relayDims = { cols, rows };
|
|
7526
5270
|
this.applyDims();
|
|
7527
|
-
});
|
|
7528
|
-
return () => {
|
|
7529
|
-
if (this.resizeHandler === handler) this.resizeHandler = null;
|
|
7530
|
-
off();
|
|
7531
|
-
};
|
|
7532
|
-
}
|
|
7533
|
-
async dispose() {
|
|
7534
|
-
if (this.disposed) return;
|
|
7535
|
-
this.disposed = true;
|
|
7536
|
-
this.relayCoalescer.dispose();
|
|
7537
|
-
this.reporter.reportPtyStream(null);
|
|
7538
|
-
const current = this.server;
|
|
7539
|
-
this.server = null;
|
|
7540
|
-
if (current) await current.close();
|
|
7541
|
-
}
|
|
7542
|
-
};
|
|
7543
|
-
function wrapBridgeWithDirectStream(inner, reporter, options = {}) {
|
|
7544
|
-
const controller = new DirectStreamController(inner, reporter, options);
|
|
7545
|
-
return {
|
|
7546
|
-
bridge: {
|
|
7547
|
-
...inner,
|
|
7548
|
-
sendOutput: (data, dims) => controller.sendOutput(data, dims),
|
|
7549
|
-
sendEnded: () => controller.sendEnded(),
|
|
7550
|
-
onInput: (handler) => controller.onInput(handler),
|
|
7551
|
-
onResize: (handler) => controller.onResize(handler)
|
|
7552
|
-
},
|
|
7553
|
-
dispose: () => controller.dispose()
|
|
7554
|
-
};
|
|
7555
|
-
}
|
|
7556
|
-
|
|
7557
|
-
// src/execution/query-executor.ts
|
|
7558
|
-
import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
|
|
7559
|
-
import { existsSync, readFileSync as readFileSync3, renameSync as renameSync2, truncateSync } from "fs";
|
|
7560
|
-
|
|
7561
|
-
// src/execution/chat-instructions.ts
|
|
7562
|
-
function buildChatInstructions(context, scenario, newMessages) {
|
|
7563
|
-
const userMessages = newMessages.filter((m) => m.role === "user");
|
|
7564
|
-
const parts = [];
|
|
7565
|
-
if (scenario === "fresh") {
|
|
7566
|
-
parts.push(
|
|
7567
|
-
`The user's message is above. Do what it asks and reply with post_to_chat \u2014 your turn output is NOT shown in chat, so post_to_chat is the only way the user sees your answer.`
|
|
7568
|
-
);
|
|
7569
|
-
} else if (userMessages.length > 0) {
|
|
7570
|
-
parts.push(
|
|
7571
|
-
`You have new messages on this card.`,
|
|
7572
|
-
`
|
|
7573
|
-
New messages since your last run:`,
|
|
7574
|
-
...userMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
|
|
7575
|
-
`
|
|
7576
|
-
Respond to them with post_to_chat (your turn output is NOT shown in chat).`
|
|
7577
|
-
);
|
|
7578
|
-
} else {
|
|
7579
|
-
parts.push(
|
|
7580
|
-
`You were relaunched but no new messages have arrived since your last run.`,
|
|
7581
|
-
`Post a brief status update with post_to_chat if you still owe the team a response, then wait for them.`
|
|
7582
|
-
);
|
|
7583
|
-
}
|
|
7584
|
-
if (context.githubPRUrl) {
|
|
7585
|
-
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
7586
|
-
}
|
|
7587
|
-
return parts;
|
|
7588
|
-
}
|
|
7589
|
-
|
|
7590
|
-
// src/execution/relaunch-hold.ts
|
|
7591
|
-
function findLastAgentMessageIndex(history) {
|
|
7592
|
-
for (let i = history.length - 1; i >= 0; i--) {
|
|
7593
|
-
if (history[i].role === "assistant") return i;
|
|
7594
|
-
}
|
|
7595
|
-
return -1;
|
|
7596
|
-
}
|
|
7597
|
-
function messagesAfterCursor(history, lastSeenMessageId) {
|
|
7598
|
-
if (!lastSeenMessageId) return history;
|
|
7599
|
-
const idx = history.findIndex((m) => m.id === lastSeenMessageId);
|
|
7600
|
-
return idx === -1 ? history : history.slice(idx + 1);
|
|
7601
|
-
}
|
|
7602
|
-
function relaunchMessageBatch(context) {
|
|
7603
|
-
if (context.lastSeenMessageId) {
|
|
7604
|
-
return messagesAfterCursor(context.chatHistory, context.lastSeenMessageId);
|
|
7605
|
-
}
|
|
7606
|
-
return context.chatHistory.slice(findLastAgentMessageIndex(context.chatHistory) + 1);
|
|
7607
|
-
}
|
|
7608
|
-
function isCodeReviewRun(mode, agentMode) {
|
|
7609
|
-
return mode === "code-review" || mode !== "pm" && agentMode === "review";
|
|
7610
|
-
}
|
|
7611
|
-
function isActionableRelaunchMessage(m) {
|
|
7612
|
-
if (m.source && CRITICAL_AUTOMATED_SOURCES.has(m.source)) return true;
|
|
7613
|
-
return m.role === "user" && m.source !== EXTERNAL_AGENT_MESSAGE_SOURCE;
|
|
7614
|
-
}
|
|
7615
|
-
function isReviewHostHold(context, newMessages, isCodeReview) {
|
|
7616
|
-
if (isCodeReview) return false;
|
|
7617
|
-
if (context.status !== "ReviewPR" || !context.githubPRUrl) return false;
|
|
7618
|
-
return !newMessages.some((m) => isActionableRelaunchMessage(m));
|
|
7619
|
-
}
|
|
7620
|
-
function buildReviewHostHoldParts(context, newMessages) {
|
|
7621
|
-
const parts = [
|
|
7622
|
-
`You were relaunched while this task is in review, but nothing here asks you to change the code.`,
|
|
7623
|
-
`Most likely this workspace was woken to HOST the code review session, not to work.`,
|
|
7624
|
-
`Do NOT take a work turn: do not re-review your own diff, re-run gates, commit, or push. The PR is mid-review and moving the branch now would pull it out from under the reviewer.`,
|
|
7625
|
-
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`
|
|
7626
|
-
];
|
|
7627
|
-
if (newMessages.length > 0) {
|
|
7628
|
-
parts.push(
|
|
7629
|
-
`
|
|
7630
|
-
New messages since your last run:`,
|
|
7631
|
-
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`)
|
|
7632
|
-
);
|
|
7633
|
-
}
|
|
7634
|
-
parts.push(
|
|
7635
|
-
`
|
|
7636
|
-
Review these messages and wait for the team to provide instructions before taking action.`,
|
|
7637
|
-
`If the review requests changes, or CI fails, you will be woken again with that feedback \u2014 act then, not now.`
|
|
7638
|
-
);
|
|
7639
|
-
if (context.githubPRUrl) {
|
|
7640
|
-
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
7641
|
-
}
|
|
7642
|
-
return parts;
|
|
7643
|
-
}
|
|
7644
|
-
|
|
7645
|
-
// src/execution/pack-runner-prompt.ts
|
|
7646
|
-
function findLastAgentMessageIndex2(history) {
|
|
7647
|
-
for (let i = history.length - 1; i >= 0; i--) {
|
|
7648
|
-
if (history[i].role === "assistant") return i;
|
|
7649
|
-
}
|
|
7650
|
-
return -1;
|
|
7651
|
-
}
|
|
7652
|
-
function formatProjectAgents(agents) {
|
|
7653
|
-
const parts = [``, `## Project Agents`];
|
|
7654
|
-
for (const agent of agents) {
|
|
7655
|
-
const role = agent.role ? `role: ${agent.role}` : "role: unassigned";
|
|
7656
|
-
const sp = agent.storyPoints === null || agent.storyPoints === void 0 ? "" : `, story points: ${agent.storyPoints}`;
|
|
7657
|
-
parts.push(`- ${agent.name} (${role}${sp})`);
|
|
7658
|
-
}
|
|
7659
|
-
return parts;
|
|
7660
|
-
}
|
|
7661
|
-
function formatStoryPoints(storyPoints) {
|
|
7662
|
-
const parts = [``, `## Story Point Tiers`];
|
|
7663
|
-
for (const sp of storyPoints) {
|
|
7664
|
-
const desc = sp.description ? ` \u2014 ${sp.description}` : "";
|
|
7665
|
-
parts.push(`- Value ${sp.value}: "${sp.name}"${desc}`);
|
|
7666
|
-
}
|
|
7667
|
-
return parts;
|
|
7668
|
-
}
|
|
7669
|
-
var PACK_RUNNER_FOOTER = [
|
|
7670
|
-
``,
|
|
7671
|
-
`Your turn output appears ONLY in the live agent terminal \u2014 it is NOT posted to the task chat. The team does NOT see your replies unless you post them.`,
|
|
7672
|
-
`Use post_to_chat (omit task_id \u2192 this task's chat) to report which children you fired, status as you orchestrate, and any blocker or escalation the team needs to act on.`,
|
|
7673
|
-
`Pass task_id only to message a DIFFERENT task's chat (e.g. a child task).`,
|
|
7674
|
-
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,
|
|
7675
|
-
``,
|
|
7676
|
-
`If a Conveyor tool call fails or reports the MCP server is unavailable/disconnected, this is almost always a transient socket reconnect \u2014 RETRY the same call; it will succeed once the connection re-establishes. A tool error is NOT a reason to go idle or stop the loop. (Going idle is only correct when you are genuinely waiting on child-task status changes or CI \u2014 see the loop above.)`,
|
|
7677
|
-
``,
|
|
7678
|
-
HUMAN_PROSE_WRITING_STYLE
|
|
7679
|
-
];
|
|
7680
|
-
function formatBaseSync(packBranch, devBranch) {
|
|
7681
|
-
return [
|
|
7682
|
-
``,
|
|
7683
|
-
`## Pack Branch Base Sync`,
|
|
7684
|
-
`This is a feature-branch pack: children branch from \`${packBranch}\` and PR back into it, and the whole pack lands on \`${devBranch}\` in one final PR at the end.`,
|
|
7685
|
-
`YOU are the reviewer of record for child PRs \u2014 the automated code reviewer skips PRs that target \`${packBranch}\` (the full automated review runs on the pack's final PR into \`${devBranch}\`). Review each child diff properly before merging; a merged child advances to ReviewDev automatically.`,
|
|
7686
|
-
`Before each child launch the server merges \`${devBranch}\` into \`${packBranch}\` for you, so children start from a fresh base. You do not need to do this yourself.`,
|
|
7687
|
-
`When start_child_cloud_build reports a base-sync conflict, that merge could not be applied automatically. Fix it before firing more children:`,
|
|
7688
|
-
`1. \`git fetch origin ${devBranch} && git checkout ${packBranch} && git pull origin ${packBranch}\``,
|
|
7689
|
-
`2. \`git merge origin/${devBranch}\`, resolve the conflicts, commit, and push to \`${packBranch}\`.`,
|
|
7690
|
-
`3. Resume the loop.`,
|
|
7691
|
-
`Resolving this merge is git coordination, not code-writing \u2014 it does NOT violate the "Do NOT attempt to write code yourself" rule below. Keep the resolution to the conflict markers; if a conflict needs real code decisions, escalate to the team instead of authoring the fix.`,
|
|
7692
|
-
`The launch itself is never blocked by a conflict \u2014 the child was already started from the un-synced branch, so sync promptly.`
|
|
7693
|
-
];
|
|
7694
|
-
}
|
|
7695
|
-
function resolveMergedWorkBranch(context) {
|
|
7696
|
-
return context.featureBranch && context.githubBranch ? context.githubBranch : context.baseBranch;
|
|
7697
|
-
}
|
|
7698
|
-
function resolveSinglePodPackBranch(context) {
|
|
7699
|
-
return context.githubBranch || context.baseBranch;
|
|
7700
|
-
}
|
|
7701
|
-
function buildPackRunnerSystemPrompt(context, config, setupLog) {
|
|
7702
|
-
const mergedWorkBranch = resolveMergedWorkBranch(context);
|
|
7703
|
-
const parts = [
|
|
7704
|
-
`You are an autonomous Pack Runner managing child tasks for the "${context.title}" project.`,
|
|
7705
|
-
`You are running locally with full access to the repository and task management tools.`,
|
|
7706
|
-
`Your job is to execute child tasks by firing cloud builds, reviewing their PRs, and merging them \u2014 respecting dependency chains for parallel execution.`,
|
|
7707
|
-
``,
|
|
7708
|
-
`## Child Task Status Lifecycle`,
|
|
7709
|
-
`- "Planning" \u2014 Not ready for execution. If its plan is solid, promote it yourself: update_subtask with status "Open" (plus storyPointValue and agentIdOrName if unset \u2014 setting story points does NOT auto-promote). Otherwise skip it (or escalate if blocking).`,
|
|
7710
|
-
`- "Open" \u2014 Ready to execute (if dependencies are met). Use start_child_cloud_build to fire it.`,
|
|
7711
|
-
`- "InProgress" \u2014 Currently being worked on by a Task Runner. Wait \u2014 it will move to ReviewPR when done.`,
|
|
7712
|
-
`- "ReviewPR" \u2014 Task Runner finished and opened a PR. Review and merge it.`,
|
|
7713
|
-
`- "ReviewDev" \u2014 PR was merged (to dev, or into this pack's feature branch for feature-branch packs). This child is complete. Move on.`,
|
|
7714
|
-
`- "Complete" \u2014 Fully done. Move on.`,
|
|
7715
|
-
``,
|
|
7716
|
-
`## Autonomous Loop`,
|
|
7717
|
-
`Follow this loop each time you are launched or relaunched:`,
|
|
7718
|
-
``,
|
|
7719
|
-
`1. Call list_subtasks to see the current state of all child tasks.`,
|
|
7720
|
-
` The response includes PR info, agent assignment, **dependency info** (dependsOn array + allDependenciesMet flag), and the **packSlots** build-slot picture.`,
|
|
7721
|
-
` If list_subtasks returns NO children, this is a fresh parent card: break the work down now \u2014 explore the codebase, save a parent-level plan with update_task, then create child tasks with create_subtask, each with a detailed plan (file:line citations, verification steps) and dependsOn set for any child that blocks on another. Then fire the ready children and continue the loop.`,
|
|
7722
|
-
``,
|
|
7723
|
-
`2. Evaluate children by status and dependency readiness:`,
|
|
7724
|
-
` - "ReviewPR": Review and merge its PR with approve_and_merge_pr. (Highest priority)`,
|
|
7725
|
-
` - If merge fails due to pending CI: post a status update to chat, state you are going idle.`,
|
|
7726
|
-
` - If merge fails due to failed CI: use get_execution_logs(childTaskId) to check. Escalate to team.`,
|
|
7727
|
-
` - "InProgress": A Task Runner is actively working. Do nothing \u2014 wait.`,
|
|
7728
|
-
` - "Open" + allDependenciesMet=true: Ready to fire. Use start_child_cloud_build.`,
|
|
7729
|
-
` - "Open" + allDependenciesMet=false: Blocked \u2014 skip for now. Will be unblocked when deps complete.`,
|
|
7730
|
-
` - "ReviewDev" / "Complete": Already done. Skip.`,
|
|
7731
|
-
` - "Planning": Not ready. Promote it with update_subtask (status "Open" + story points + agent) once its plan is solid; if it genuinely isn't plannable, notify team.`,
|
|
7732
|
-
``,
|
|
7733
|
-
`3. Fire ALL ready "Open" tasks whose dependencies are met, not just one \u2014 independent tasks run in parallel. There is a concurrency limit: if start_child_cloud_build returns a PACK_CHILD_LIMIT error, that is backpressure, not a failure. Check list_subtasks' packSlots to see which children hold the in-flight slots \u2014 merge or wait on them (or stop_child_build a stale holder that isn't actually running), then start more as slots free up.`,
|
|
7734
|
-
` A successful start_child_cloud_build moves that child to "InProgress" \u2014 that status IS your confirmation the fire landed. Never re-fire a child that already reads "InProgress".`,
|
|
7735
|
-
``,
|
|
7736
|
-
`4. After merging a PR: run \`git pull origin ${mergedWorkBranch}\` then re-check list_subtasks \u2014 previously blocked tasks may now be ready.`,
|
|
7737
|
-
``,
|
|
7738
|
-
`5. After firing all ready tasks: report which tasks you fired to chat, then state you are going idle.`,
|
|
7739
|
-
``,
|
|
7740
|
-
`6. When ALL children are in "ReviewDev" or "Complete" (no "Open", "InProgress", or "ReviewPR" remaining): do a final review, summarize results in chat, and mark this parent task complete with force_update_task_status("Complete").`,
|
|
7741
|
-
``,
|
|
7742
|
-
`## Important Rules`,
|
|
7743
|
-
`- When dependencies are set on children, use them to determine execution order. Fire all ready tasks in parallel (up to the PACK_CHILD_LIMIT backpressure \u2014 see the loop above).`,
|
|
7744
|
-
`- Dependencies are explicit card metadata (set at creation via create_subtask's dependsOn, or rewired with update_subtask). Prefer them over reading order out of plan text. When NO dependencies are set on any children, fall back to ordinal order (one at a time) \u2014 this is legacy behavior; set dependsOn when a child truly blocks on another.`,
|
|
7745
|
-
`- After firing builds OR when waiting on CI, explicitly state you are going idle. Go idle when waiting \u2014 the system wakes you (or relaunches this environment) when a child changes status.`,
|
|
7746
|
-
`- Do NOT attempt to write code yourself. Your role is coordination only.`,
|
|
7747
|
-
`- If a child is stuck in "InProgress" for an unusually long time, use get_execution_logs(childTaskId) to check its logs and escalate to the team if it appears stuck.`,
|
|
7748
|
-
`- stop_child_build is a signal, not an immediate teardown: it tells the child's agent to stop, but the build slot stays held until that environment actually tears down. A slot still held right after a stop is normal, NOT a wedge \u2014 re-check list_subtasks' packSlots on a later turn instead of re-firing, stopping again, or escalating.`,
|
|
7749
|
-
`- You can use get_task(childTaskId) to get a child's full details including PR URL and branch.`,
|
|
7750
|
-
`- list_subtasks (compact view, the default) returns per child: status, agent assignment (agentId), story points, PR number/state, dependency info, and holdsBuildSlot \u2014 plus a packSlots summary of in-flight environments vs the cap. Use this to verify readiness before firing builds; pass verbose:true only if you need full plan/description text.`,
|
|
7751
|
-
`- You can use read_task_chat to check for team messages.`
|
|
7752
|
-
];
|
|
7753
|
-
if (context.featureBranch && context.githubBranch) {
|
|
7754
|
-
parts.push(...formatBaseSync(context.githubBranch, context.baseBranch));
|
|
7755
|
-
}
|
|
7756
|
-
if (context.storyPoints && context.storyPoints.length > 0) {
|
|
7757
|
-
parts.push(...formatStoryPoints(context.storyPoints));
|
|
7758
|
-
}
|
|
7759
|
-
if (context.agents && context.agents.length > 0) {
|
|
7760
|
-
parts.push(...formatProjectAgents(context.agents));
|
|
7761
|
-
}
|
|
7762
|
-
if (setupLog.length > 0) {
|
|
7763
|
-
parts.push(``, `## Environment setup log`, "```", ...setupLog, "```");
|
|
7764
|
-
}
|
|
7765
|
-
if (context.agentInstructions) {
|
|
7766
|
-
parts.push(``, `## Agent Instructions`, context.agentInstructions);
|
|
7767
|
-
}
|
|
7768
|
-
if (config.instructions) {
|
|
7769
|
-
parts.push(``, `## Additional Instructions`, config.instructions);
|
|
7770
|
-
}
|
|
7771
|
-
parts.push(...PACK_RUNNER_FOOTER);
|
|
7772
|
-
return parts.join("\n");
|
|
7773
|
-
}
|
|
7774
|
-
function buildSinglePodPackPrompt(context, config, setupLog) {
|
|
7775
|
-
const packBranch = resolveSinglePodPackBranch(context);
|
|
7776
|
-
const parts = [
|
|
7777
|
-
`You are an autonomous Pack Runner for the "${context.title}" pack, and you implement the work yourself.`,
|
|
7778
|
-
``,
|
|
7779
|
-
`Run the \`/conveyor-build\` skill and follow its PACK PATH. It is the source of truth for the loop \u2014 child selection, dependency order, the reviewer-of-record pass, the finale \u2014 and it carries the pod substitution this session runs under. Do not re-derive the workflow from memory.`,
|
|
7780
|
-
``,
|
|
7781
|
-
// Session-bound facts only. Everything the skill CAN know now lives there;
|
|
7782
|
-
// what stays is what is true of THIS pod and this card.
|
|
7783
|
-
`## This session`,
|
|
7784
|
-
`- You are ALREADY bound to this parent card. There is nothing to claim.`,
|
|
7785
|
-
`- One checkout, one branch: \`${packBranch}\`. Every child's work is commits on it.`,
|
|
7786
|
-
`- Children get NO branches and NO pull requests here. \`create_pull_request\` always opens the PR for the card you are bound to, so calling it mid-pack opens the PARENT's PR early and strands the remaining children. One PR, at the very end, for this parent.`,
|
|
7787
|
-
`- You move each child's status yourself: \`update_task(task_id: <child>, status: ...)\`. No per-child build fires, so a status you do not write is a board that silently lies. A child is "ReviewDev" once its commits are on \`${packBranch}\`.`,
|
|
7788
|
-
`- \`start_child_cloud_build\` and \`stop_child_build\` belong to the fan-out model and are not available to you \u2014 you are the implementer.`,
|
|
7789
|
-
`- Merge \`origin/${context.baseBranch}\` into \`${packBranch}\` after each child, never rebase: the branch is shared with WIP refs and rewriting it breaks them.`,
|
|
7790
|
-
`- Nothing will wake you to start the next child. Go idle only when genuinely blocked on something external.`,
|
|
7791
|
-
``
|
|
7792
|
-
];
|
|
7793
|
-
if (context.storyPoints && context.storyPoints.length > 0) {
|
|
7794
|
-
parts.push(...formatStoryPoints(context.storyPoints));
|
|
7795
|
-
}
|
|
7796
|
-
if (context.agents && context.agents.length > 0) {
|
|
7797
|
-
parts.push(...formatProjectAgents(context.agents));
|
|
7798
|
-
}
|
|
7799
|
-
if (setupLog.length > 0) {
|
|
7800
|
-
parts.push(``, `## Environment setup log`, "```", ...setupLog, "```");
|
|
7801
|
-
}
|
|
7802
|
-
if (context.agentInstructions) {
|
|
7803
|
-
parts.push(``, `## Agent Instructions`, context.agentInstructions);
|
|
5271
|
+
});
|
|
5272
|
+
return () => {
|
|
5273
|
+
if (this.resizeHandler === handler) this.resizeHandler = null;
|
|
5274
|
+
off();
|
|
5275
|
+
};
|
|
7804
5276
|
}
|
|
7805
|
-
|
|
7806
|
-
|
|
5277
|
+
async dispose() {
|
|
5278
|
+
if (this.disposed) return;
|
|
5279
|
+
this.disposed = true;
|
|
5280
|
+
this.relayCoalescer.dispose();
|
|
5281
|
+
this.reporter.reportPtyStream(null);
|
|
5282
|
+
const current = this.server;
|
|
5283
|
+
this.server = null;
|
|
5284
|
+
if (current) await current.close();
|
|
7807
5285
|
}
|
|
7808
|
-
|
|
7809
|
-
|
|
5286
|
+
};
|
|
5287
|
+
function wrapBridgeWithDirectStream(inner, reporter, options = {}) {
|
|
5288
|
+
const controller = new DirectStreamController(inner, reporter, options);
|
|
5289
|
+
return {
|
|
5290
|
+
bridge: {
|
|
5291
|
+
...inner,
|
|
5292
|
+
sendOutput: (data, dims) => controller.sendOutput(data, dims),
|
|
5293
|
+
sendEnded: () => controller.sendEnded(),
|
|
5294
|
+
onInput: (handler) => controller.onInput(handler),
|
|
5295
|
+
onResize: (handler) => controller.onResize(handler)
|
|
5296
|
+
},
|
|
5297
|
+
dispose: () => controller.dispose()
|
|
5298
|
+
};
|
|
7810
5299
|
}
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
5300
|
+
|
|
5301
|
+
// src/execution/query-executor.ts
|
|
5302
|
+
import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
|
|
5303
|
+
import { existsSync, readFileSync as readFileSync3, renameSync as renameSync2, truncateSync } from "fs";
|
|
5304
|
+
|
|
5305
|
+
// src/execution/chat-instructions.ts
|
|
5306
|
+
function buildChatInstructions(context, scenario, newMessages) {
|
|
5307
|
+
const userMessages = newMessages.filter((m) => m.role === "user");
|
|
5308
|
+
const parts = [];
|
|
7814
5309
|
if (scenario === "fresh") {
|
|
7815
5310
|
parts.push(
|
|
7816
|
-
`
|
|
7817
|
-
`Start now: call list_subtasks to see where the pack stands.`,
|
|
7818
|
-
`No children yet? Break the work down first \u2014 save a parent-level plan with update_task, then create_subtask each child with a detailed plan and dependsOn set where one blocks another.`,
|
|
7819
|
-
`Otherwise take the first "Open" child whose dependencies are met, claim it with update_task(task_id, status: "InProgress"), and implement it on this branch.`
|
|
7820
|
-
);
|
|
7821
|
-
} else if (scenario === "idle_relaunch") {
|
|
7822
|
-
parts.push(
|
|
7823
|
-
`You have been relaunched. Re-derive where the pack stands \u2014 call list_subtasks and check the branch, never rely on what you remember.`,
|
|
7824
|
-
`A child left "InProgress" is one YOU were implementing: check the working tree and the log for what already landed before redoing any of it.`,
|
|
7825
|
-
`Otherwise continue the loop: next ready child, or the finale if none remain.`
|
|
5311
|
+
`The user's message is above. Do what it asks and reply with post_to_chat \u2014 your turn output is NOT shown in chat, so post_to_chat is the only way the user sees your answer.`
|
|
7826
5312
|
);
|
|
7827
|
-
} else {
|
|
7828
|
-
const lastAgentIdx = findLastAgentMessageIndex2(context.chatHistory);
|
|
7829
|
-
const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
|
|
5313
|
+
} else if (userMessages.length > 0) {
|
|
7830
5314
|
parts.push(
|
|
7831
|
-
`You have
|
|
5315
|
+
`You have new messages on this card.`,
|
|
7832
5316
|
`
|
|
7833
5317
|
New messages since your last run:`,
|
|
7834
|
-
...
|
|
5318
|
+
...userMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
|
|
7835
5319
|
`
|
|
7836
|
-
|
|
7837
|
-
);
|
|
7838
|
-
}
|
|
7839
|
-
return parts;
|
|
7840
|
-
}
|
|
7841
|
-
function buildPackRunnerInstructions(context, scenario) {
|
|
7842
|
-
const parts = [`
|
|
7843
|
-
## Instructions`];
|
|
7844
|
-
if (scenario === "fresh") {
|
|
7845
|
-
parts.push(
|
|
7846
|
-
`You are the Pack Runner for this task and its subtasks.`,
|
|
7847
|
-
`Begin your autonomous loop immediately: call list_subtasks to assess the current state.`,
|
|
7848
|
-
`If there are no children yet, create them first \u2014 save a parent-level plan with update_task, then create child tasks with detailed plans and dependsOn set where one blocks on another. Then fire the ready ones.`,
|
|
7849
|
-
`If any child is in "ReviewPR" status, review and merge its PR first.`,
|
|
7850
|
-
`Then fire the next "Open" child task.`
|
|
7851
|
-
);
|
|
7852
|
-
} else if (scenario === "idle_relaunch") {
|
|
7853
|
-
parts.push(
|
|
7854
|
-
`You have been relaunched \u2014 a child task likely changed status.`,
|
|
7855
|
-
`Call list_subtasks to check the current state of all children.`,
|
|
7856
|
-
`Look for children in "ReviewPR" status first \u2014 review and merge their PRs.`,
|
|
7857
|
-
`Check if any previously blocked tasks now have allDependenciesMet=true \u2014 fire them.`,
|
|
7858
|
-
`If a child you previously fired is now in "ReviewDev", pull latest with \`git pull origin ${resolveMergedWorkBranch(context)}\`.`,
|
|
7859
|
-
`If no children need action, state you are going idle.`
|
|
5320
|
+
Respond to them with post_to_chat (your turn output is NOT shown in chat).`
|
|
7860
5321
|
);
|
|
7861
5322
|
} else {
|
|
7862
|
-
const lastAgentIdx = findLastAgentMessageIndex2(context.chatHistory);
|
|
7863
|
-
const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
|
|
7864
5323
|
parts.push(
|
|
7865
|
-
`You
|
|
7866
|
-
`
|
|
7867
|
-
New messages since your last run:`,
|
|
7868
|
-
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
|
|
7869
|
-
`
|
|
7870
|
-
After addressing the feedback, resume your autonomous loop: call list_subtasks and proceed accordingly.`
|
|
5324
|
+
`You were relaunched but no new messages have arrived since your last run.`,
|
|
5325
|
+
`Post a brief status update with post_to_chat if you still owe the team a response, then wait for them.`
|
|
7871
5326
|
);
|
|
7872
5327
|
}
|
|
5328
|
+
if (context.githubPRUrl) {
|
|
5329
|
+
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
5330
|
+
}
|
|
7873
5331
|
return parts;
|
|
7874
5332
|
}
|
|
7875
5333
|
|
|
7876
|
-
// src/execution/
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
if (Number.isNaN(at)) return "";
|
|
7883
|
-
const ago = now - at;
|
|
7884
|
-
if (ago < MINUTE_MS) return "just now";
|
|
7885
|
-
if (ago < HOUR_MS) return `${Math.round(ago / MINUTE_MS)} minutes ago`;
|
|
7886
|
-
if (ago < DAY_MS) return `${Math.round(ago / HOUR_MS)} hours ago`;
|
|
7887
|
-
return `${Math.round(ago / DAY_MS)} days ago`;
|
|
5334
|
+
// src/execution/relaunch-hold.ts
|
|
5335
|
+
function findLastAgentMessageIndex(history) {
|
|
5336
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
5337
|
+
if (history[i].role === "assistant") return i;
|
|
5338
|
+
}
|
|
5339
|
+
return -1;
|
|
7888
5340
|
}
|
|
7889
|
-
function
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
5341
|
+
function messagesAfterCursor(history, lastSeenMessageId) {
|
|
5342
|
+
if (!lastSeenMessageId) return history;
|
|
5343
|
+
const idx = history.findIndex((m) => m.id === lastSeenMessageId);
|
|
5344
|
+
return idx === -1 ? history : history.slice(idx + 1);
|
|
5345
|
+
}
|
|
5346
|
+
function relaunchMessageBatch(context) {
|
|
5347
|
+
if (context.lastSeenMessageId) {
|
|
5348
|
+
return messagesAfterCursor(context.chatHistory, context.lastSeenMessageId);
|
|
5349
|
+
}
|
|
5350
|
+
return context.chatHistory.slice(findLastAgentMessageIndex(context.chatHistory) + 1);
|
|
5351
|
+
}
|
|
5352
|
+
function isCodeReviewRun(mode, agentMode) {
|
|
5353
|
+
return mode === "code-review" || mode !== "pm" && agentMode === "review";
|
|
5354
|
+
}
|
|
5355
|
+
function isActionableRelaunchMessage(m) {
|
|
5356
|
+
if (m.source && CRITICAL_AUTOMATED_SOURCES.has(m.source)) return true;
|
|
5357
|
+
return m.role === "user" && m.source !== EXTERNAL_AGENT_MESSAGE_SOURCE;
|
|
5358
|
+
}
|
|
5359
|
+
function isReviewHostHold(context, newMessages, isCodeReview) {
|
|
5360
|
+
if (isCodeReview) return false;
|
|
5361
|
+
if (context.status !== "ReviewPR" || !context.githubPRUrl) return false;
|
|
5362
|
+
return !newMessages.some((m) => isActionableRelaunchMessage(m));
|
|
5363
|
+
}
|
|
5364
|
+
function buildReviewHostHoldParts(context, newMessages) {
|
|
5365
|
+
const parts = [
|
|
5366
|
+
`You were relaunched while this task is in review, but nothing here asks you to change the code.`,
|
|
5367
|
+
`Most likely this workspace was woken to HOST the code review session, not to work.`,
|
|
5368
|
+
`Do NOT take a work turn: do not re-review your own diff, re-run gates, commit, or push. The PR is mid-review and moving the branch now would pull it out from under the reviewer.`,
|
|
5369
|
+
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`
|
|
7903
5370
|
];
|
|
5371
|
+
if (newMessages.length > 0) {
|
|
5372
|
+
parts.push(
|
|
5373
|
+
`
|
|
5374
|
+
New messages since your last run:`,
|
|
5375
|
+
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`)
|
|
5376
|
+
);
|
|
5377
|
+
}
|
|
5378
|
+
parts.push(
|
|
5379
|
+
`
|
|
5380
|
+
Review these messages and wait for the team to provide instructions before taking action.`,
|
|
5381
|
+
`If the review requests changes, or CI fails, you will be woken again with that feedback \u2014 act then, not now.`
|
|
5382
|
+
);
|
|
5383
|
+
if (context.githubPRUrl) {
|
|
5384
|
+
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
5385
|
+
}
|
|
5386
|
+
return parts;
|
|
7904
5387
|
}
|
|
7905
5388
|
|
|
7906
5389
|
// src/execution/prompt-formatters.ts
|
|
@@ -8177,11 +5660,6 @@ function buildAutoPrompt(context, runnerMode) {
|
|
|
8177
5660
|
`You are in Auto mode \u2014 plan this card, then build it, without stopping for approval.`,
|
|
8178
5661
|
`Run \`/conveyor-plan\` FIRST to produce the plan and save it to the card, then run \`/conveyor-build\` to implement it. Both are sources of truth; do not re-derive them.`,
|
|
8179
5662
|
...buildSkillInvocation("/conveyor-build"),
|
|
8180
|
-
``,
|
|
8181
|
-
`### What "auto" changes`,
|
|
8182
|
-
`- There is no plan-approval step and no read-only phase. The plan is a RECORD for the team, not a gate \u2014 save it, then immediately write the code. A card whose only output is a plan (or a plan-only PR) has not been built.`,
|
|
8183
|
-
`- Decide independently. Escalate only when genuinely blocked: ambiguous requirements, missing access, conflicting instructions. Everything else is yours to call.`,
|
|
8184
|
-
`- Skip \`/conveyor-plan\` only if the card already carries a plan you are not materially diverging from.`,
|
|
8185
5663
|
...buildHarnessContracts(context)
|
|
8186
5664
|
];
|
|
8187
5665
|
if (context) parts.push(...buildPropertyInstructions(context, runnerMode));
|
|
@@ -8215,81 +5693,175 @@ function buildModePrompt(agentMode, context, runnerMode) {
|
|
|
8215
5693
|
return null;
|
|
8216
5694
|
}
|
|
8217
5695
|
}
|
|
8218
|
-
function buildChatPrompt(context) {
|
|
8219
|
-
const branch = context?.githubBranch?.trim();
|
|
8220
|
-
const gitScope = branch ? ` on branch \`${branch}\`` : "";
|
|
8221
|
-
return [
|
|
8222
|
-
`
|
|
8223
|
-
## Mode: Interactive`,
|
|
8224
|
-
`This is a direct Claude Code session on this card. The user drives it message by message; you have the same access you would have running Claude Code locally in this repo (full read/write, shell, git${gitScope}).`,
|
|
8225
|
-
`- Your turn output is NOT shown in chat \u2014 reply with \`post_to_chat\`.`,
|
|
8226
|
-
`- There is no required Conveyor workflow here. Do what the message asks: answer, investigate, write files, build, or open a PR. Skills such as \`/conveyor-plan\` and \`/conveyor-build\` are available if the user asks for them or they clearly help; nothing runs them for you.`,
|
|
8227
|
-
``,
|
|
8228
|
-
`### Card facts`,
|
|
8229
|
-
`- This card starts Unidentified and stays so until a plan is saved with \`update_task\`; that first plan identifies it and moves it to In Progress.`,
|
|
8230
|
-
`- Files the user should keep go on the card via \`upload_attachment\` (any file type, up to 25MB), not an off-platform link.`,
|
|
8231
|
-
`- \`create_pull_request\` opens the PR for this card and moves it to Review PR. Save a short plan first so the card is identified \u2014 a record, not an approval gate.`,
|
|
8232
|
-
`- When the user says they are done, call \`force_update_task_status\` with status \`"Complete"\`. Not if a PR is open \u2014 the review flow takes it from there.`
|
|
8233
|
-
].join("\n");
|
|
8234
|
-
}
|
|
8235
|
-
function buildReviewTagSection(context) {
|
|
8236
|
-
const assignedIds = new Set(context?.taskTagIds ?? []);
|
|
8237
|
-
const assigned = (context?.projectTags ?? []).filter((t) => assignedIds.has(t.id));
|
|
8238
|
-
if (assigned.length === 0) return [];
|
|
5696
|
+
function buildChatPrompt(context) {
|
|
5697
|
+
const branch = context?.githubBranch?.trim();
|
|
5698
|
+
const gitScope = branch ? ` on branch \`${branch}\`` : "";
|
|
5699
|
+
return [
|
|
5700
|
+
`
|
|
5701
|
+
## Mode: Interactive`,
|
|
5702
|
+
`This is a direct Claude Code session on this card. The user drives it message by message; you have the same access you would have running Claude Code locally in this repo (full read/write, shell, git${gitScope}).`,
|
|
5703
|
+
`- Your turn output is NOT shown in chat \u2014 reply with \`post_to_chat\`.`,
|
|
5704
|
+
`- There is no required Conveyor workflow here. Do what the message asks: answer, investigate, write files, build, or open a PR. Skills such as \`/conveyor-plan\` and \`/conveyor-build\` are available if the user asks for them or they clearly help; nothing runs them for you.`,
|
|
5705
|
+
``,
|
|
5706
|
+
`### Card facts`,
|
|
5707
|
+
`- This card starts Unidentified and stays so until a plan is saved with \`update_task\`; that first plan identifies it and moves it to In Progress.`,
|
|
5708
|
+
`- Files the user should keep go on the card via \`upload_attachment\` (any file type, up to 25MB), not an off-platform link.`,
|
|
5709
|
+
`- \`create_pull_request\` opens the PR for this card and moves it to Review PR. Save a short plan first so the card is identified \u2014 a record, not an approval gate.`,
|
|
5710
|
+
`- When the user says they are done, call \`force_update_task_status\` with status \`"Complete"\`. Not if a PR is open \u2014 the review flow takes it from there.`
|
|
5711
|
+
].join("\n");
|
|
5712
|
+
}
|
|
5713
|
+
function buildReviewTagSection(context) {
|
|
5714
|
+
const assignedIds = new Set(context?.taskTagIds ?? []);
|
|
5715
|
+
const assigned = (context?.projectTags ?? []).filter((t) => assignedIds.has(t.id));
|
|
5716
|
+
if (assigned.length === 0) return [];
|
|
5717
|
+
const parts = [
|
|
5718
|
+
`### Card Tags & Domain Context`,
|
|
5719
|
+
`This card carries these project glossary tags:`
|
|
5720
|
+
];
|
|
5721
|
+
for (const tag of assigned) parts.push(...formatTagWithContextPaths(tag));
|
|
5722
|
+
parts.push(
|
|
5723
|
+
``,
|
|
5724
|
+
`A tag's rules and overview define the conventions the code under review must follow. Use them when you judge Pattern Consistency:`,
|
|
5725
|
+
`- Read the tag entries that match the files in this diff. The "Reference Guides" section of the task brief lists the same tags with a one-line summary of each linked doc.`,
|
|
5726
|
+
`- Call get_tag("<name>") for a term's full spec (overview, linked files, hierarchy) when the linked docs are not enough.`,
|
|
5727
|
+
`- A change that contradicts a tagged system's documented conventions is a review finding, even when it reads fine on its own.`,
|
|
5728
|
+
`- Skip the tags this diff does not touch \u2014 do not read them all up front.`,
|
|
5729
|
+
`- If the diff changes how a tagged system behaves and the tag's overview is now wrong, say so in your review.`,
|
|
5730
|
+
``
|
|
5731
|
+
);
|
|
5732
|
+
return parts;
|
|
5733
|
+
}
|
|
5734
|
+
function buildReviewPrompt(context) {
|
|
5735
|
+
return [
|
|
5736
|
+
`
|
|
5737
|
+
## Mode: Review`,
|
|
5738
|
+
...buildSkillInvocation("/conveyor-review"),
|
|
5739
|
+
``,
|
|
5740
|
+
// Everything below is harness-bound: the skill cannot know this session's
|
|
5741
|
+
// resolved branch, and the verdict tool names differ per surface (the skill
|
|
5742
|
+
// documents both pairs; this names the one that exists here).
|
|
5743
|
+
`### This session`,
|
|
5744
|
+
`- The diff under review: \`${baseDiffCommand(context?.baseBranch)}\``,
|
|
5745
|
+
`- Your verdict tools on this pod are \`approve_code_review\` and \`request_code_changes\`. The local conveyor-mcp pair does not exist here.`,
|
|
5746
|
+
...buildEnforcedToolContracts(),
|
|
5747
|
+
...buildReviewTagSection(context)
|
|
5748
|
+
].join("\n");
|
|
5749
|
+
}
|
|
5750
|
+
|
|
5751
|
+
// src/execution/pack-runner-prompt.ts
|
|
5752
|
+
function formatProjectAgents(agents) {
|
|
5753
|
+
const parts = [``, `## Project Agents`];
|
|
5754
|
+
for (const agent of agents) {
|
|
5755
|
+
const role = agent.role ? `role: ${agent.role}` : "role: unassigned";
|
|
5756
|
+
const sp = agent.storyPoints === null || agent.storyPoints === void 0 ? "" : `, story points: ${agent.storyPoints}`;
|
|
5757
|
+
parts.push(`- ${agent.name} (${role}${sp})`);
|
|
5758
|
+
}
|
|
5759
|
+
return parts;
|
|
5760
|
+
}
|
|
5761
|
+
function formatStoryPoints(storyPoints) {
|
|
5762
|
+
const parts = [``, `## Story Point Tiers`];
|
|
5763
|
+
for (const sp of storyPoints) {
|
|
5764
|
+
const desc = sp.description ? ` \u2014 ${sp.description}` : "";
|
|
5765
|
+
parts.push(`- Value ${sp.value}: "${sp.name}"${desc}`);
|
|
5766
|
+
}
|
|
5767
|
+
return parts;
|
|
5768
|
+
}
|
|
5769
|
+
var PACK_RUNNER_FOOTER = [
|
|
5770
|
+
``,
|
|
5771
|
+
`Your turn output appears ONLY in the live agent terminal \u2014 it is NOT posted to the task chat. The team does NOT see your replies unless you post them.`,
|
|
5772
|
+
`Use post_to_chat (omit task_id \u2192 this task's chat) to report which child you are on, status as you work the pack, and any blocker or escalation the team needs to act on.`,
|
|
5773
|
+
`Pass task_id only to message a DIFFERENT task's chat (e.g. a child task).`,
|
|
5774
|
+
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,
|
|
5775
|
+
``,
|
|
5776
|
+
`If a Conveyor tool call fails or reports the MCP server is unavailable/disconnected, this is almost always a transient socket reconnect \u2014 RETRY the same call; it will succeed once the connection re-establishes. A tool error is NOT a reason to go idle or stop the pack. (When a turn may end is the pack path's call \u2014 see its goal and finish line.)`,
|
|
5777
|
+
``,
|
|
5778
|
+
HUMAN_PROSE_WRITING_STYLE
|
|
5779
|
+
];
|
|
5780
|
+
function resolveSinglePodPackBranch(context) {
|
|
5781
|
+
return context.githubBranch || context.baseBranch;
|
|
5782
|
+
}
|
|
5783
|
+
function isPackRunnerSession(mode, isAuto, isParentTask) {
|
|
5784
|
+
return mode === "pack" || mode === "pm" && !!isAuto && !!isParentTask;
|
|
5785
|
+
}
|
|
5786
|
+
function buildSinglePodPackPrompt(context, setupLog) {
|
|
5787
|
+
const packBranch = resolveSinglePodPackBranch(context);
|
|
5788
|
+
const parts = [
|
|
5789
|
+
`You are an autonomous Pack Runner for the "${context.title}" pack, and you implement the work yourself.`,
|
|
5790
|
+
``,
|
|
5791
|
+
`Run the \`/conveyor-build\` skill and follow its PACK PATH. It is the source of truth for the loop \u2014 child selection, dependency order, the reviewer-of-record pass, the finale \u2014 and it carries the pod substitution this session runs under. Do not re-derive the workflow from memory.`,
|
|
5792
|
+
``,
|
|
5793
|
+
// Session-bound facts only. Everything the skill CAN know now lives there;
|
|
5794
|
+
// what stays is what is true of THIS pod and this card.
|
|
5795
|
+
`## This session`,
|
|
5796
|
+
`- You are ALREADY bound to this parent card. There is nothing to claim.`,
|
|
5797
|
+
`- One checkout, one branch: \`${packBranch}\`. Every child's work is commits on it.`,
|
|
5798
|
+
`- Children get NO branches and NO pull requests here. \`create_pull_request\` always opens the PR for the card you are bound to, so calling it mid-pack opens the PARENT's PR early and strands the remaining children. One PR, at the very end, for this parent.`,
|
|
5799
|
+
`- This pack's base branch is \`${context.baseBranch}\`: sync \`origin/${context.baseBranch}\` into \`${packBranch}\` after each child (merge, never rebase \u2014 the branch carries WIP refs), and the finale PR targets it; pass it explicitly when you open the PR.`,
|
|
5800
|
+
`- Child status writes carry the child's id: \`update_task(task_id: <child>, status: ...)\`. Without \`task_id\` the write targets this parent card.`,
|
|
5801
|
+
``
|
|
5802
|
+
];
|
|
5803
|
+
if (context.storyPoints && context.storyPoints.length > 0) {
|
|
5804
|
+
parts.push(...formatStoryPoints(context.storyPoints));
|
|
5805
|
+
}
|
|
5806
|
+
if (context.agents && context.agents.length > 0) {
|
|
5807
|
+
parts.push(...formatProjectAgents(context.agents));
|
|
5808
|
+
}
|
|
5809
|
+
if (setupLog.length > 0) {
|
|
5810
|
+
parts.push(``, `## Environment setup log`, "```", ...setupLog, "```");
|
|
5811
|
+
}
|
|
5812
|
+
if (context.agentInstructions) {
|
|
5813
|
+
parts.push(``, `## Agent Instructions`, context.agentInstructions);
|
|
5814
|
+
}
|
|
5815
|
+
parts.push(...PACK_RUNNER_FOOTER);
|
|
5816
|
+
return parts.join("\n");
|
|
5817
|
+
}
|
|
5818
|
+
function buildSinglePodPackInstructions(scenario) {
|
|
8239
5819
|
const parts = [
|
|
8240
|
-
|
|
8241
|
-
|
|
5820
|
+
`
|
|
5821
|
+
## Instructions`,
|
|
5822
|
+
`You are the Pack Runner for this pack and you implement every child yourself, on this pod.`
|
|
8242
5823
|
];
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
);
|
|
5824
|
+
if (scenario === "idle_relaunch") {
|
|
5825
|
+
parts.push(
|
|
5826
|
+
`You were relaunched with no new messages \u2014 re-derive pack state from the card, never from memory.`
|
|
5827
|
+
);
|
|
5828
|
+
} else if (scenario === "feedback_relaunch") {
|
|
5829
|
+
parts.push(
|
|
5830
|
+
`You have been relaunched with the feedback in New Messages above \u2014 address it, then continue the pack.`
|
|
5831
|
+
);
|
|
5832
|
+
}
|
|
5833
|
+
parts.push(...buildSkillInvocation("/conveyor-build"));
|
|
8254
5834
|
return parts;
|
|
8255
5835
|
}
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
...buildEnforcedToolContracts(),
|
|
8270
|
-
...buildReviewTagSection(context)
|
|
8271
|
-
].join("\n");
|
|
5836
|
+
|
|
5837
|
+
// src/execution/plan-revision-notice.ts
|
|
5838
|
+
var MINUTE_MS = 60 * 1e3;
|
|
5839
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
5840
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
5841
|
+
function describeAge(revisedAt, now) {
|
|
5842
|
+
const at = Date.parse(revisedAt);
|
|
5843
|
+
if (Number.isNaN(at)) return "";
|
|
5844
|
+
const ago = now - at;
|
|
5845
|
+
if (ago < MINUTE_MS) return "just now";
|
|
5846
|
+
if (ago < HOUR_MS) return `${Math.round(ago / MINUTE_MS)} minutes ago`;
|
|
5847
|
+
if (ago < DAY_MS) return `${Math.round(ago / HOUR_MS)} hours ago`;
|
|
5848
|
+
return `${Math.round(ago / DAY_MS)} days ago`;
|
|
8272
5849
|
}
|
|
8273
|
-
function
|
|
5850
|
+
function buildPlanRevisionNotice(context, now = Date.now()) {
|
|
5851
|
+
const revisedAt = context.planRevisedAt;
|
|
5852
|
+
if (!revisedAt) return [];
|
|
5853
|
+
const age = describeAge(revisedAt, now);
|
|
5854
|
+
const when = age ? `${age} (${revisedAt})` : revisedAt;
|
|
8274
5855
|
return [
|
|
8275
5856
|
`
|
|
8276
|
-
##
|
|
8277
|
-
|
|
8278
|
-
`
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
``,
|
|
8285
|
-
`### Coordination Workflow`,
|
|
8286
|
-
`1. Check child task statuses with \`list_subtasks\``,
|
|
8287
|
-
`2. Review completed children \u2014 check PRs, run tests if needed`,
|
|
8288
|
-
`3. Approve and merge passing PRs`,
|
|
8289
|
-
`4. Fire builds for children that are ready`,
|
|
8290
|
-
`5. Create follow-up tasks for anything out of scope`,
|
|
8291
|
-
`6. As children complete, correct their story points with update_subtask (storyPointValue) when the actual work diverged from the estimate \u2014 either direction`
|
|
8292
|
-
].join("\n");
|
|
5857
|
+
## \u26A0\uFE0F The plan changed since this build was dispatched`,
|
|
5858
|
+
`Someone revised this card's plan ${when}. It was NOT you \u2014 an agent is never told about its own plan edit.`,
|
|
5859
|
+
`Before your next Write or Edit:`,
|
|
5860
|
+
`1. Call \`get_current_plan\` and read the current plan in full.`,
|
|
5861
|
+
`2. Compare it against the plan you were launched with. Treat the current plan as the truth.`,
|
|
5862
|
+
`3. Drop or redo any work the revision supersedes. Do NOT keep building the old plan.`,
|
|
5863
|
+
`If the revision invalidates work you already committed, say so with post_to_chat before you continue.`
|
|
5864
|
+
];
|
|
8293
5865
|
}
|
|
8294
5866
|
|
|
8295
5867
|
// src/execution/tag-context-resolver.ts
|
|
@@ -8618,15 +6190,17 @@ Your plan has been approved \u2014 you are the Builder on this card now.`,
|
|
|
8618
6190
|
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`
|
|
8619
6191
|
];
|
|
8620
6192
|
}
|
|
8621
|
-
function buildPmReviewRelaunchParts() {
|
|
8622
|
-
|
|
6193
|
+
function buildPmReviewRelaunchParts(context) {
|
|
6194
|
+
const parts = [
|
|
8623
6195
|
`
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
`Fire next child builds with start_child_cloud_build when ready.`,
|
|
8628
|
-
`Do not implement code directly or create a new PR from the PM review session.`
|
|
6196
|
+
You are the Reviewer on this card now.`,
|
|
6197
|
+
...buildSkillInvocation("/conveyor-review"),
|
|
6198
|
+
branchLine(context)
|
|
8629
6199
|
];
|
|
6200
|
+
if (context.githubPRUrl) {
|
|
6201
|
+
parts.push(`The PR under review is ${context.githubPRUrl}. Do not create a new PR.`);
|
|
6202
|
+
}
|
|
6203
|
+
return parts;
|
|
8630
6204
|
}
|
|
8631
6205
|
function buildPmAutoWithPlanRelaunchParts(context) {
|
|
8632
6206
|
return [
|
|
@@ -8657,7 +6231,7 @@ function buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode) {
|
|
|
8657
6231
|
const intent = resolvePmRelaunchIntent(context, isAuto, agentMode);
|
|
8658
6232
|
const intentPartsByIntent = {
|
|
8659
6233
|
["build" /* Build */]: () => buildPmBuildRelaunchParts(context),
|
|
8660
|
-
["review" /* Review */]: buildPmReviewRelaunchParts,
|
|
6234
|
+
["review" /* Review */]: () => buildPmReviewRelaunchParts(context),
|
|
8661
6235
|
["auto_with_plan" /* AutoWithPlan */]: () => buildPmAutoWithPlanRelaunchParts(context),
|
|
8662
6236
|
["auto_planning" /* AutoPlanning */]: () => buildPmAutoPlanningRelaunchParts(context),
|
|
8663
6237
|
["wait_for_team" /* WaitForTeam */]: buildPmWaitForTeamRelaunchParts
|
|
@@ -8700,15 +6274,6 @@ Workflow:`,
|
|
|
8700
6274
|
`- After saving the plan, call post_to_chat with a short summary for the team (your turn output is NOT posted to chat \u2014 they only see what you post), then end your turn. Do NOT attempt to execute the plan yourself.`,
|
|
8701
6275
|
`- A separate task agent will handle execution after the team reviews and approves your plan.`
|
|
8702
6276
|
];
|
|
8703
|
-
if (context.isParentTask) {
|
|
8704
|
-
parts.push(
|
|
8705
|
-
`
|
|
8706
|
-
You are the Project Manager for this set of tasks.`,
|
|
8707
|
-
`This task has child tasks (subtasks) that are tracked on the board.`,
|
|
8708
|
-
`Your role is to coordinate, plan, and manage the subtasks \u2014 not to write code directly.`,
|
|
8709
|
-
`Use the subtask tools (create_subtask, update_subtask, list_subtasks) to manage work breakdown.`
|
|
8710
|
-
);
|
|
8711
|
-
}
|
|
8712
6277
|
if (context.agents && context.agents.length > 0) {
|
|
8713
6278
|
parts.push(`
|
|
8714
6279
|
Project Agents:`);
|
|
@@ -8744,7 +6309,10 @@ Workflow:`,
|
|
|
8744
6309
|
`- If you toggled into active mode temporarily, mention when you're done so the team can switch you back to planning mode.`
|
|
8745
6310
|
].filter(Boolean);
|
|
8746
6311
|
}
|
|
8747
|
-
function
|
|
6312
|
+
function ciWaitRule(agentMode) {
|
|
6313
|
+
return agentMode === "review" ? `A review session has no \`wait_for_checks\`: after pushing a fix, read \`gh pr checks\` ONCE and decide on what it shows; never loop on it, and never end the turn expecting a CI wake.` : `Waiting on CI is never a \`gh pr checks\` loop, a pr-wait script, or a sleep: call \`wait_for_checks\` (mcp__conveyor__wait_for_checks) and END THE TURN. Conveyor wakes this session with the result; the pod sleeps in between instead of holding compute for a run it cannot influence.`;
|
|
6314
|
+
}
|
|
6315
|
+
function buildTaskAgentPreamble(context, workspaceDir, runtimeTui, agentMode) {
|
|
8748
6316
|
const managedStack = repoHasScript(workspaceDir, "web:rebuild");
|
|
8749
6317
|
const stackLines = managedStack ? [
|
|
8750
6318
|
`- The web app is served on port 3050, the API on port 7090.`,
|
|
@@ -8762,7 +6330,7 @@ Environment \u2014 already built${managedStack ? " and running" : ""}. These are
|
|
|
8762
6330
|
`- Browser automation is the Playwright CLI (\`playwright\`, pinned 1.62.1), NOT an MCP server \u2014 there are no \`mcp__playwright__*\` tools here. Only the headless shell is baked, so a launch must name it AND disable the sandbox: \`chromium.launch({ channel: "chromium-headless-shell", args: ["--no-sandbox"] })\`. A bare \`chromium.launch()\` FAILS: since playwright 1.49 that resolves to the full browser, which is deliberately not installed (pods have no display and cannot run Chromium's sandbox). Screenshots land wherever you write them \u2014 move or delete them before committing.`,
|
|
8763
6331
|
`- The clone is \`--single-branch\`, so a bare \`git fetch origin <branch>\` does NOT create \`origin/<branch>\`. To reference any other branch, use the explicit refspec: \`git fetch origin <branch>:refs/remotes/origin/<branch>\`.`,
|
|
8764
6332
|
`- The shell cwd resets between Bash calls, and so does every shell variable. A var you export in one call is EMPTY in the next, which silently redirects output to \`/\` and loses it. Write literal absolute paths (\`git -C\`, \`bun run --cwd\`), and \`mkdir -p\` a directory in the SAME call as the redirect that writes to it.`,
|
|
8765
|
-
`- The \`gh\` CLI is available for READ-ONLY PR and CI state (\`gh pr view\`, \`gh pr checks\`, \`gh pr diff\`). Use the mcp__conveyor__* tools for anything that mutates a PR or card.`,
|
|
6333
|
+
`- The \`gh\` CLI is available for READ-ONLY PR and CI state (\`gh pr view\`, \`gh pr checks\`, \`gh pr diff\`), one read at a time. ${ciWaitRule(agentMode)} Use the mcp__conveyor__* tools for anything that mutates a PR or card.`,
|
|
8766
6334
|
`- The core mcp__conveyor__* tools are preloaded \u2014 call them directly; do NOT spend a ToolSearch call on them. For any tool that IS still deferred (schema not loaded), load ALL the schemas you expect to need in ONE ToolSearch call using fully-qualified names (query "select:Monitor,mcp__conveyor__<name>" \u2014 bare MCP tool names without the mcp__<server>__ prefix do not match); never guess a deferred tool's parameters.`,
|
|
8767
6335
|
managedStack ? `Because the environment is already up, do not run installs, builds, database setup, dev-server starts, or exploratory \`pwd\`/\`ls\` probes to confirm any of the above. Run them only when a specific error demands it.` : `Do not run installs, database setup, or exploratory \`pwd\`/\`ls\` probes to confirm any of the above \u2014 they are done. If the task needs a running app, check whether one is already up before you start it, and use the repo's own scripts.`,
|
|
8768
6336
|
`
|
|
@@ -8770,25 +6338,22 @@ Working rules:`,
|
|
|
8770
6338
|
`- Read a file before your first Write/Edit to it, and batch multiple changes to the same file into a single call instead of many sequential edits.`,
|
|
8771
6339
|
`- To learn what calls a symbol or where it lives, query the prebuilt code graph before grepping: \`graphify query "<SymbolName>"\` from the repo root. Query a SYMBOL, never a sentence \u2014 \`graphify query "resolveTaskBaseBranch"\` returns the definition plus every call site, while "how does a task get its base branch" seeds unrelated start nodes and returns test files and loggers. Don't know the symbol yet? Grep for the name first, then query it: grep finds names, the graph finds relationships. \`No matching nodes found\` means "not in this graph" (it is prebuilt, so very recent code is absent), NOT "not in the codebase" \u2014 fall back to \`git grep\`. Skip all of this if \`graphify-out/graph.json\` is not present.`,
|
|
8772
6340
|
`- When a build/lint/test run fails, capture its output to a file once and grep the file \u2014 never re-run the suite just to re-filter the same output.`,
|
|
8773
|
-
|
|
8774
|
-
runtimeTui === "codex" ? `-
|
|
6341
|
+
`- App servers (including development and production servers) keep running after startup. Start them with the harness background/session facility, then run a separate bounded HTTP readiness check and continue verification. Never wait for server exit or a completion notification to mean the app is ready. If readiness times out, inspect build output and process/resource state before restarting.`,
|
|
6342
|
+
runtimeTui === "codex" ? `- Waiting on long-running commands: retain and resume the command session until it returns an exit result. Finish each required gate before ending the task. Never pretend a completion notification will resume you, and never start another gate while the current one is running.` : `- Waiting on long-running commands: if a gate finishes in under ~2 minutes, run it in the foreground with a timeout. For a longer one, launch it with run_in_background and STOP; a completion notification arrives when it finishes, and tracked background work holds the workspace awake for up to 45 minutes. Inspect any gate approaching that cap. For the final pre-PR gate a bounded foreground run (\`timeout 590 <gate>\` with Bash \`timeout: 600000\`) is still preferred as defense in depth. A pod restart loses both foreground and background processes. Never busy-wait with sleep/pgrep/tail loops, and never re-run the suite to escape a wait that looks stalled.`,
|
|
6343
|
+
runtimeTui === "codex" ? `- Do not end your turn to wait on a required gate. Resume its command session, inspect its exit result, and then continue the checklist.` : `- For a finite background gate, end your turn and its completion notification re-invokes you within the bounded liveness window. Never emit filler commands (\`echo waiting\`, \`true\`, \`sleep N; echo done\`) to "stay alive" \u2014 they are detected and blocked. The proven long-wait shape: start the job with run_in_background, then end the turn.${agentMode === "review" ? "" : " For CI on a pushed commit the shape is `wait_for_checks`, then end the turn (the pod may sleep; the GitHub result wakes it)."} Arm a ScheduleWakeup (delaySeconds 900-1500, prompt restating your next steps) only when nothing will notify you \u2014 a deploy, a remote queue \u2014 never for CI, and never as insurance against a background job's own notification, which does fire.`,
|
|
8775
6344
|
`
|
|
8776
6345
|
Git:`,
|
|
8777
6346
|
`- Stay on \`${context.githubBranch}\` for the whole task: do not check out another branch and do not create one. It was cut from \`${context.baseBranch}\`, and PRs target that automatically.`,
|
|
8778
6347
|
`- If \`git push\` is rejected as non-fast-forward, run \`git push --force-with-lease origin ${context.githubBranch}\`. This branch is exclusively yours, so force-with-lease is safe.`
|
|
8779
6348
|
];
|
|
8780
6349
|
}
|
|
8781
|
-
function buildPackPrompt(mode, context, config, setupLog) {
|
|
8782
|
-
return mode === "pack" && config.packExecution !== "fan-out" ? buildSinglePodPackPrompt(context, config, setupLog) : buildPackRunnerSystemPrompt(context, config, setupLog);
|
|
8783
|
-
}
|
|
8784
6350
|
function buildSystemPrompt(mode, context, config, setupLog, agentMode) {
|
|
8785
6351
|
const isPm = mode === "pm";
|
|
8786
6352
|
const isPmActive = isPm && agentMode === "building";
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
return buildPackPrompt(mode, context, config, setupLog);
|
|
6353
|
+
if (isPackRunnerSession(mode, config.isAuto, context.isParentTask)) {
|
|
6354
|
+
return buildSinglePodPackPrompt(context, setupLog);
|
|
8790
6355
|
}
|
|
8791
|
-
const parts = isPmActive ? buildActivePreamble(context, config.workspaceDir) : isPm ? buildPmPreamble(context) : buildTaskAgentPreamble(context, config.workspaceDir, config.runtimeTui);
|
|
6356
|
+
const parts = isPmActive ? buildActivePreamble(context, config.workspaceDir) : isPm ? buildPmPreamble(context) : buildTaskAgentPreamble(context, config.workspaceDir, config.runtimeTui, agentMode);
|
|
8792
6357
|
if (setupLog.length > 0) {
|
|
8793
6358
|
parts.push(
|
|
8794
6359
|
`
|
|
@@ -8802,11 +6367,6 @@ Environment setup log (already executed before you started \u2014 proof that set
|
|
|
8802
6367
|
parts.push(`
|
|
8803
6368
|
Agent Instructions:
|
|
8804
6369
|
${context.agentInstructions}`);
|
|
8805
|
-
}
|
|
8806
|
-
if (config.instructions) {
|
|
8807
|
-
parts.push(`
|
|
8808
|
-
Additional Instructions:
|
|
8809
|
-
${config.instructions}`);
|
|
8810
6370
|
}
|
|
8811
6371
|
parts.push(
|
|
8812
6372
|
`
|
|
@@ -8896,6 +6456,14 @@ function buildRelaunchWithSession(mode, context, agentMode, isAuto) {
|
|
|
8896
6456
|
allNew.filter((m) => m.role === "user")
|
|
8897
6457
|
).join("\n");
|
|
8898
6458
|
}
|
|
6459
|
+
if (isCodeReviewRun(mode, agentMode)) {
|
|
6460
|
+
parts.push(
|
|
6461
|
+
scenario === "feedback_relaunch" ? `You have been relaunched with new feedback.` : `You were relaunched but no new instructions have been given since your last run.`,
|
|
6462
|
+
...newMessagesBlock(allNew.filter((m) => m.role === "user")),
|
|
6463
|
+
...buildFreshCodeReviewInstructions(context)
|
|
6464
|
+
);
|
|
6465
|
+
return parts.join("\n");
|
|
6466
|
+
}
|
|
8899
6467
|
if (mode === "pm") {
|
|
8900
6468
|
parts.push(...buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode));
|
|
8901
6469
|
} else if (isPlanningSession(mode, agentMode, isAuto)) {
|
|
@@ -8911,23 +6479,10 @@ function buildRelaunchWithSession(mode, context, agentMode, isAuto) {
|
|
|
8911
6479
|
...builderKickoff(context, `You are the Builder on this card \u2014 address the feedback above.`)
|
|
8912
6480
|
);
|
|
8913
6481
|
} else {
|
|
8914
|
-
parts.push(
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
context,
|
|
8919
|
-
`You are the Builder on this card \u2014 pick up where you left off.`
|
|
8920
|
-
)
|
|
8921
|
-
);
|
|
8922
|
-
} else {
|
|
8923
|
-
parts.push(
|
|
8924
|
-
branchRule(context),
|
|
8925
|
-
`Post a brief status update with post_to_chat (your turn output is NOT shown in chat \u2014 post_to_chat is how the team sees it), then wait for further instructions.`
|
|
8926
|
-
);
|
|
8927
|
-
if (context.githubPRUrl) {
|
|
8928
|
-
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
8929
|
-
}
|
|
8930
|
-
}
|
|
6482
|
+
parts.push(
|
|
6483
|
+
`You were relaunched but no new instructions have been given since your last run.`,
|
|
6484
|
+
...builderKickoff(context, `You are the Builder on this card \u2014 pick up where you left off.`)
|
|
6485
|
+
);
|
|
8931
6486
|
}
|
|
8932
6487
|
return parts.join("\n");
|
|
8933
6488
|
}
|
|
@@ -9039,7 +6594,7 @@ function buildFeedbackInstructions(context, isPlanning) {
|
|
|
9039
6594
|
`You have been relaunched to address the feedback in New Messages above.`
|
|
9040
6595
|
);
|
|
9041
6596
|
}
|
|
9042
|
-
function buildIdleRelaunchInstructions(context, isPlanning
|
|
6597
|
+
function buildIdleRelaunchInstructions(context, isPlanning) {
|
|
9043
6598
|
const opener = `You were relaunched but no new instructions have been given since your last run.`;
|
|
9044
6599
|
if (isPlanning) {
|
|
9045
6600
|
return [
|
|
@@ -9047,28 +6602,16 @@ function buildIdleRelaunchInstructions(context, isPlanning, agentMode, isAuto) {
|
|
|
9047
6602
|
`You are the Planner on this card. Post a brief status update with post_to_chat (your turn output is NOT shown in chat \u2014 post_to_chat is how the team sees it), then wait for the team.`
|
|
9048
6603
|
];
|
|
9049
6604
|
}
|
|
9050
|
-
|
|
9051
|
-
return [
|
|
9052
|
-
opener,
|
|
9053
|
-
...builderKickoff(context, `You are the Builder on this card \u2014 pick up where you left off.`)
|
|
9054
|
-
];
|
|
9055
|
-
}
|
|
9056
|
-
const parts = [
|
|
6605
|
+
return [
|
|
9057
6606
|
opener,
|
|
9058
|
-
|
|
9059
|
-
`Post a brief status update summarizing where things stand with post_to_chat (your turn output is NOT shown in chat \u2014 post_to_chat is how the team sees it).`,
|
|
9060
|
-
`Then wait for further instructions \u2014 do NOT redo work that was already completed.`
|
|
6607
|
+
...builderKickoff(context, `You are the Builder on this card \u2014 pick up where you left off.`)
|
|
9061
6608
|
];
|
|
9062
|
-
if (context.githubPRUrl) {
|
|
9063
|
-
parts.push(`An existing PR is open at ${context.githubPRUrl}. Do not create a new PR.`);
|
|
9064
|
-
}
|
|
9065
|
-
return parts;
|
|
9066
6609
|
}
|
|
9067
6610
|
function buildInstructions(mode, context, scenario, agentMode, isAuto) {
|
|
9068
6611
|
const parts = [`
|
|
9069
6612
|
## Instructions`];
|
|
9070
6613
|
const isPm = mode === "pm";
|
|
9071
|
-
const isCodeReview = mode
|
|
6614
|
+
const isCodeReview = isCodeReviewRun(mode, agentMode);
|
|
9072
6615
|
const isPlanning = isPlanningSession(mode, agentMode, isAuto);
|
|
9073
6616
|
if (agentMode === "chat") {
|
|
9074
6617
|
parts.push(...buildChatInstructions(context, scenario, relaunchMessageBatch(context)));
|
|
@@ -9093,14 +6636,14 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
|
|
|
9093
6636
|
return parts;
|
|
9094
6637
|
}
|
|
9095
6638
|
if (scenario === "idle_relaunch") {
|
|
9096
|
-
parts.push(...buildIdleRelaunchInstructions(context, isPlanning
|
|
6639
|
+
parts.push(...buildIdleRelaunchInstructions(context, isPlanning));
|
|
9097
6640
|
return parts;
|
|
9098
6641
|
}
|
|
9099
6642
|
parts.push(...buildFeedbackInstructions(context, isPlanning));
|
|
9100
6643
|
return parts;
|
|
9101
6644
|
}
|
|
9102
|
-
async function buildInitialPrompt(mode, context, isAuto, agentMode
|
|
9103
|
-
const isPackRunner = mode
|
|
6645
|
+
async function buildInitialPrompt(mode, context, isAuto, agentMode) {
|
|
6646
|
+
const isPackRunner = isPackRunnerSession(mode, isAuto, context.isParentTask);
|
|
9104
6647
|
if (!isPackRunner) {
|
|
9105
6648
|
const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode, isAuto);
|
|
9106
6649
|
if (sessionRelaunch) {
|
|
@@ -9113,13 +6656,12 @@ async function buildInitialPrompt(mode, context, isAuto, agentMode, packExecutio
|
|
|
9113
6656
|
scenario = "fresh";
|
|
9114
6657
|
}
|
|
9115
6658
|
const body = await buildTaskBody(context, mode);
|
|
9116
|
-
const
|
|
9117
|
-
const instructions = isPackRunner ? singlePodPack ? buildSinglePodPackInstructions(context, scenario) : buildPackRunnerInstructions(context, scenario) : buildInstructions(mode, context, scenario, agentMode, isAuto);
|
|
6659
|
+
const instructions = isPackRunner ? buildSinglePodPackInstructions(scenario) : buildInstructions(mode, context, scenario, agentMode, isAuto);
|
|
9118
6660
|
return [...body, ...instructions].join("\n");
|
|
9119
6661
|
}
|
|
9120
6662
|
|
|
9121
6663
|
// src/tools/task-context-tools.ts
|
|
9122
|
-
import { z as
|
|
6664
|
+
import { z as z4 } from "zod";
|
|
9123
6665
|
|
|
9124
6666
|
// ../shared/dist/tool-contracts/index.js
|
|
9125
6667
|
var f = {
|
|
@@ -9148,14 +6690,14 @@ var f = {
|
|
|
9148
6690
|
return { kind: "nullable", inner };
|
|
9149
6691
|
}
|
|
9150
6692
|
};
|
|
9151
|
-
function compileString(
|
|
9152
|
-
let schema =
|
|
6693
|
+
function compileString(z11, spec) {
|
|
6694
|
+
let schema = z11.string();
|
|
9153
6695
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
9154
6696
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
9155
6697
|
return schema;
|
|
9156
6698
|
}
|
|
9157
|
-
function compileNumber(
|
|
9158
|
-
let schema =
|
|
6699
|
+
function compileNumber(z11, spec) {
|
|
6700
|
+
let schema = z11.number();
|
|
9159
6701
|
if (spec.int) schema = schema.int();
|
|
9160
6702
|
if (spec.positive) schema = schema.positive();
|
|
9161
6703
|
if (spec.nonnegative) schema = schema.nonnegative();
|
|
@@ -9163,49 +6705,49 @@ function compileNumber(z21, spec) {
|
|
|
9163
6705
|
if (spec.max !== void 0) schema = schema.max(spec.max);
|
|
9164
6706
|
return schema;
|
|
9165
6707
|
}
|
|
9166
|
-
function compileArray(
|
|
9167
|
-
let schema =
|
|
6708
|
+
function compileArray(z11, spec) {
|
|
6709
|
+
let schema = z11.array(compileField(z11, spec.item));
|
|
9168
6710
|
if (spec.min !== void 0) schema = schema.min(spec.min);
|
|
9169
6711
|
return schema;
|
|
9170
6712
|
}
|
|
9171
|
-
function compileBase(
|
|
6713
|
+
function compileBase(z11, spec) {
|
|
9172
6714
|
switch (spec.kind) {
|
|
9173
6715
|
case "string":
|
|
9174
|
-
return compileString(
|
|
6716
|
+
return compileString(z11, spec);
|
|
9175
6717
|
case "number":
|
|
9176
|
-
return compileNumber(
|
|
6718
|
+
return compileNumber(z11, spec);
|
|
9177
6719
|
case "boolean":
|
|
9178
|
-
return
|
|
6720
|
+
return z11.boolean();
|
|
9179
6721
|
case "enum":
|
|
9180
|
-
return
|
|
6722
|
+
return z11.enum([...spec.values]);
|
|
9181
6723
|
case "array":
|
|
9182
|
-
return compileArray(
|
|
6724
|
+
return compileArray(z11, spec);
|
|
9183
6725
|
case "object":
|
|
9184
|
-
return
|
|
6726
|
+
return z11.object(compileShape(z11, spec.fields));
|
|
9185
6727
|
}
|
|
9186
6728
|
}
|
|
9187
6729
|
function descriptionOf(spec) {
|
|
9188
6730
|
if (spec.kind === "optional" || spec.kind === "nullable") return descriptionOf(spec.inner);
|
|
9189
6731
|
return spec.desc;
|
|
9190
6732
|
}
|
|
9191
|
-
function compileUndescribed(
|
|
6733
|
+
function compileUndescribed(z11, spec) {
|
|
9192
6734
|
if (spec.kind === "optional") {
|
|
9193
|
-
return compileUndescribed(
|
|
6735
|
+
return compileUndescribed(z11, spec.inner).optional();
|
|
9194
6736
|
}
|
|
9195
6737
|
if (spec.kind === "nullable") {
|
|
9196
|
-
return compileUndescribed(
|
|
6738
|
+
return compileUndescribed(z11, spec.inner).nullable();
|
|
9197
6739
|
}
|
|
9198
|
-
return compileBase(
|
|
6740
|
+
return compileBase(z11, spec);
|
|
9199
6741
|
}
|
|
9200
|
-
function compileField(
|
|
9201
|
-
const schema = compileUndescribed(
|
|
6742
|
+
function compileField(z11, spec) {
|
|
6743
|
+
const schema = compileUndescribed(z11, spec);
|
|
9202
6744
|
const desc = descriptionOf(spec);
|
|
9203
6745
|
return desc === void 0 ? schema : schema.describe(desc);
|
|
9204
6746
|
}
|
|
9205
|
-
function compileShape(
|
|
6747
|
+
function compileShape(z11, fields) {
|
|
9206
6748
|
const shape = {};
|
|
9207
6749
|
for (const [key, spec] of Object.entries(fields)) {
|
|
9208
|
-
shape[key] = compileField(
|
|
6750
|
+
shape[key] = compileField(z11, spec);
|
|
9209
6751
|
}
|
|
9210
6752
|
return shape;
|
|
9211
6753
|
}
|
|
@@ -9374,25 +6916,6 @@ var searchTasksContract = defineToolContract({
|
|
|
9374
6916
|
}
|
|
9375
6917
|
}
|
|
9376
6918
|
});
|
|
9377
|
-
var childTaskIdForMerge = f.string({
|
|
9378
|
-
desc: "The child task ID whose PR should be approved and merged"
|
|
9379
|
-
});
|
|
9380
|
-
var approveAndMergePrContract = defineToolContract({
|
|
9381
|
-
name: "approve_and_merge_pr",
|
|
9382
|
-
agent: {
|
|
9383
|
-
description: "Approve and merge a child task's PR. Preconditions: child in ReviewPR. Returns { merged }: true = merged (status\u2192ReviewDev); false = automerge queued, wait for ReviewDev. Requires project Admin, or a sub-project merge grant covering every changed file; release PRs require Admin.",
|
|
9384
|
-
fields: {
|
|
9385
|
-
childTaskId: childTaskIdForMerge
|
|
9386
|
-
}
|
|
9387
|
-
},
|
|
9388
|
-
mcp: {
|
|
9389
|
-
description: "Approve a child task's pull request and QUEUE it for merge \u2014 the merge lands asynchronously (~30s sweep) once the CI and code-review gates pass; the response says whether it merged or was queued, so verify PR state before depending on it. Pass projectId to target a specific project; otherwise the configured default project is used. The child task must be in ReviewPR status with a PR. Requires project Admin, or a sub-project merge grant covering every changed file; release PRs require Admin.",
|
|
9390
|
-
fields: {
|
|
9391
|
-
projectId: mcpProjectId,
|
|
9392
|
-
childTaskId: childTaskIdForMerge
|
|
9393
|
-
}
|
|
9394
|
-
}
|
|
9395
|
-
});
|
|
9396
6919
|
var getConnectionContextContract = defineToolContract({
|
|
9397
6920
|
name: "get_connection_context",
|
|
9398
6921
|
agent: {
|
|
@@ -9412,7 +6935,6 @@ var tasksContracts = [
|
|
|
9412
6935
|
readTaskChatContract,
|
|
9413
6936
|
listTagsContract,
|
|
9414
6937
|
searchTasksContract,
|
|
9415
|
-
approveAndMergePrContract,
|
|
9416
6938
|
getConnectionContextContract
|
|
9417
6939
|
];
|
|
9418
6940
|
var STATUS_ENUM = [
|
|
@@ -9803,12 +7325,12 @@ var updateSubtaskContract = defineToolContract({
|
|
|
9803
7325
|
plan: f.optional(f.string()),
|
|
9804
7326
|
status: f.optional(
|
|
9805
7327
|
f.enum(["Planning", "Open"], {
|
|
9806
|
-
desc: 'Move the child between "Planning" and "Open". "Open" marks it ready to execute \u2014
|
|
7328
|
+
desc: 'Move the child between "Planning" and "Open". "Open" marks it ready to execute \u2014 the pack runner takes Open children in dependency order. Execution statuses transition automatically.'
|
|
9807
7329
|
})
|
|
9808
7330
|
),
|
|
9809
7331
|
agentIdOrName: f.optional(
|
|
9810
7332
|
f.string({
|
|
9811
|
-
desc: "Assign a project agent to the child (agent id or exact name from the Project Agents list).
|
|
7333
|
+
desc: "Assign a project agent to the child (agent id or exact name from the Project Agents list)."
|
|
9812
7334
|
})
|
|
9813
7335
|
),
|
|
9814
7336
|
ordinal: f.optional(f.number()),
|
|
@@ -9860,7 +7382,7 @@ var deleteSubtaskContract = defineToolContract({
|
|
|
9860
7382
|
var listSubtasksContract = defineToolContract({
|
|
9861
7383
|
name: "list_subtasks",
|
|
9862
7384
|
agent: {
|
|
9863
|
-
description: "List all subtasks under the current parent task. Default compact view returns per child: status, agent, story points, PR number/state, and dependencies
|
|
7385
|
+
description: "List all subtasks under the current parent task. Default compact view returns per child: status, agent, story points, PR number/state, and dependencies (dependsOn + allDependenciesMet). Use to pick the next ready child and record progress; pass verbose:true only when you need full description/plan text (large). For non-child tasks use get_task.",
|
|
9864
7386
|
fields: {
|
|
9865
7387
|
verbose: f.optional(
|
|
9866
7388
|
f.boolean({
|
|
@@ -10637,6 +8159,50 @@ var logsContracts = [
|
|
|
10637
8159
|
queryGcpLogsContract,
|
|
10638
8160
|
queryGrafanaLogsContract
|
|
10639
8161
|
];
|
|
8162
|
+
var SHA = f.optional(
|
|
8163
|
+
f.string({
|
|
8164
|
+
desc: "Commit sha to watch, full or abbreviated. Defaults to the head of prNumber, else this card's PR, else the tip of this card's branch.",
|
|
8165
|
+
min: 7,
|
|
8166
|
+
max: 40
|
|
8167
|
+
})
|
|
8168
|
+
);
|
|
8169
|
+
var PR_NUMBER = f.optional(
|
|
8170
|
+
f.number({
|
|
8171
|
+
desc: "PR number whose current head to watch. Use this for a child's PR when orchestrating a pack.",
|
|
8172
|
+
int: true,
|
|
8173
|
+
positive: true
|
|
8174
|
+
})
|
|
8175
|
+
);
|
|
8176
|
+
var TIMEOUT_MINUTES = f.optional(
|
|
8177
|
+
f.number({
|
|
8178
|
+
desc: `Give up after this many minutes (default ${DEFAULT_CI_WAIT_TIMEOUT_MINUTES}, max ${MAX_CI_WAIT_TIMEOUT_MINUTES}); you are woken with timed_out.`,
|
|
8179
|
+
int: true,
|
|
8180
|
+
min: 1,
|
|
8181
|
+
max: MAX_CI_WAIT_TIMEOUT_MINUTES
|
|
8182
|
+
})
|
|
8183
|
+
);
|
|
8184
|
+
var waitForChecksContract = defineToolContract({
|
|
8185
|
+
name: "wait_for_checks",
|
|
8186
|
+
agent: {
|
|
8187
|
+
description: "Wait for CI without holding the pod. Records the commit to watch on this session and returns immediately: if CI already finished you get the result now; otherwise the reply says `parked` and you must END YOUR TURN with no further tool calls. The pod idles out during the wait and Conveyor wakes this session with the result (success or failure with the failing job names and run URL, head_moved when the PR gets a new commit, timed_out at the deadline). Never poll `gh pr checks`, pr-wait scripts, or a sleep loop for CI. If something else wakes you before the result arrives, handle it and call this again.",
|
|
8188
|
+
fields: {
|
|
8189
|
+
sha: SHA,
|
|
8190
|
+
prNumber: PR_NUMBER,
|
|
8191
|
+
timeoutMinutes: TIMEOUT_MINUTES
|
|
8192
|
+
}
|
|
8193
|
+
},
|
|
8194
|
+
mcp: {
|
|
8195
|
+
description: "Park a task's agent session until GitHub reports the CI result for a commit. Pass projectId to target a specific project; otherwise the configured default project is used.",
|
|
8196
|
+
fields: {
|
|
8197
|
+
projectId: mcpProjectId,
|
|
8198
|
+
taskId: f.string({ desc: "The task whose agent session should wait" }),
|
|
8199
|
+
sha: SHA,
|
|
8200
|
+
prNumber: PR_NUMBER,
|
|
8201
|
+
timeoutMinutes: TIMEOUT_MINUTES
|
|
8202
|
+
}
|
|
8203
|
+
}
|
|
8204
|
+
});
|
|
8205
|
+
var ciWaitContracts = [waitForChecksContract];
|
|
10640
8206
|
var TOOL_CONTRACTS = Object.fromEntries(
|
|
10641
8207
|
[
|
|
10642
8208
|
...tasksContracts,
|
|
@@ -10651,14 +8217,15 @@ var TOOL_CONTRACTS = Object.fromEntries(
|
|
|
10651
8217
|
...integrationsContracts,
|
|
10652
8218
|
...driveContracts,
|
|
10653
8219
|
...meetingsContracts,
|
|
10654
|
-
...logsContracts
|
|
8220
|
+
...logsContracts,
|
|
8221
|
+
...ciWaitContracts
|
|
10655
8222
|
].map((contract) => [contract.name, contract])
|
|
10656
8223
|
);
|
|
10657
8224
|
|
|
10658
8225
|
// src/tools/contract-tool.ts
|
|
10659
|
-
import { z as
|
|
8226
|
+
import { z as z3 } from "zod";
|
|
10660
8227
|
function agentShape(surface) {
|
|
10661
|
-
return compileShape(
|
|
8228
|
+
return compileShape(z3, surface.fields);
|
|
10662
8229
|
}
|
|
10663
8230
|
function defineContractTool(contract, handler, options) {
|
|
10664
8231
|
return {
|
|
@@ -10815,11 +8382,11 @@ function buildGetExecutionLogsTool(connection) {
|
|
|
10815
8382
|
"get_execution_logs",
|
|
10816
8383
|
"Read CLI execution logs \u2014 agent reasoning, tool calls, and setup/dev-server output. Filter via source='agent' or 'application'. For human chat use read_task_chat.",
|
|
10817
8384
|
{
|
|
10818
|
-
task_id:
|
|
8385
|
+
task_id: z4.string().optional().describe(
|
|
10819
8386
|
"Task ID or slug. Omit to read logs from the current task. Only the current task or one of its child tasks can be read."
|
|
10820
8387
|
),
|
|
10821
|
-
source:
|
|
10822
|
-
limit:
|
|
8388
|
+
source: z4.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
|
|
8389
|
+
limit: z4.number().optional().describe("Max number of log entries to return (default 50, max 500).")
|
|
10823
8390
|
},
|
|
10824
8391
|
async ({ task_id, source, limit }) => {
|
|
10825
8392
|
try {
|
|
@@ -10914,7 +8481,7 @@ function buildTaskContextTools(connection) {
|
|
|
10914
8481
|
}
|
|
10915
8482
|
|
|
10916
8483
|
// src/tools/dependency-suggestion-tools.ts
|
|
10917
|
-
import { z as
|
|
8484
|
+
import { z as z5 } from "zod";
|
|
10918
8485
|
function buildGetDependenciesTool(connection) {
|
|
10919
8486
|
return defineContractTool(
|
|
10920
8487
|
getDependenciesContract,
|
|
@@ -10938,10 +8505,10 @@ function buildGetSuggestionsTool(connection) {
|
|
|
10938
8505
|
"get_suggestions",
|
|
10939
8506
|
"List project suggestions sorted by vote score. Filter by status or cap with limit (default 20). Suggestions are project-level ideas, not tasks \u2014 use get_task for tasks.",
|
|
10940
8507
|
{
|
|
10941
|
-
status:
|
|
8508
|
+
status: z5.string().optional().describe(
|
|
10942
8509
|
"Filter by status: Planning, Open, InProgress, ReviewPR, ReviewDev, ReviewLive, Complete, Cancelled"
|
|
10943
8510
|
),
|
|
10944
|
-
limit:
|
|
8511
|
+
limit: z5.number().int().min(1).max(100).optional().describe("Max results (default 20)")
|
|
10945
8512
|
},
|
|
10946
8513
|
async ({ status, limit }) => {
|
|
10947
8514
|
try {
|
|
@@ -10965,7 +8532,7 @@ function buildGetSuggestionsTool(connection) {
|
|
|
10965
8532
|
}
|
|
10966
8533
|
|
|
10967
8534
|
// src/tools/mutation-tools.ts
|
|
10968
|
-
import { z as
|
|
8535
|
+
import { z as z6 } from "zod";
|
|
10969
8536
|
|
|
10970
8537
|
// src/runner/refresh-verify-heal.ts
|
|
10971
8538
|
async function refreshAndVerifyGithubCredential(cwd, mint) {
|
|
@@ -11097,7 +8664,7 @@ function buildForceUpdateTaskStatusTool(connection) {
|
|
|
11097
8664
|
"force_update_task_status",
|
|
11098
8665
|
"EMERGENCY ONLY: force-override a task's Kanban status. Use when an automatic transition failed and the task is wedged. Normal flow transitions status automatically.",
|
|
11099
8666
|
{
|
|
11100
|
-
status:
|
|
8667
|
+
status: z6.enum([
|
|
11101
8668
|
"Planning",
|
|
11102
8669
|
"Open",
|
|
11103
8670
|
"InProgress",
|
|
@@ -11107,7 +8674,7 @@ function buildForceUpdateTaskStatusTool(connection) {
|
|
|
11107
8674
|
"Complete",
|
|
11108
8675
|
"Cancelled"
|
|
11109
8676
|
]).describe("The new status for the task"),
|
|
11110
|
-
task_id:
|
|
8677
|
+
task_id: z6.string().optional().describe("Child task ID to update. Omit to update the current task.")
|
|
11111
8678
|
},
|
|
11112
8679
|
async ({ status, task_id }) => {
|
|
11113
8680
|
try {
|
|
@@ -11260,10 +8827,10 @@ function buildCreateFollowUpTaskTool(connection) {
|
|
|
11260
8827
|
"create_follow_up_task",
|
|
11261
8828
|
"Create a follow-up task that depends on the current task. The new card is a SIBLING of this one (same parent) and is blocked until this task merges \u2014 it is NOT a child of this card. To break this card into child cards that build as a pack, use create_subtask. For blockers use add_dependency.",
|
|
11262
8829
|
{
|
|
11263
|
-
title:
|
|
11264
|
-
description:
|
|
11265
|
-
plan:
|
|
11266
|
-
story_point_value:
|
|
8830
|
+
title: z6.string().describe("Follow-up task title"),
|
|
8831
|
+
description: z6.string().optional().describe(cardDescriptionDesc("Brief description of the follow-up work")),
|
|
8832
|
+
plan: z6.string().optional().describe("Implementation plan if known"),
|
|
8833
|
+
story_point_value: z6.number().optional().describe("Story point estimate (1=Common, 2=Magic, 3=Rare, 5=Unique)")
|
|
11267
8834
|
},
|
|
11268
8835
|
async ({ title, description, plan, story_point_value }) => {
|
|
11269
8836
|
try {
|
|
@@ -11290,11 +8857,11 @@ function buildCreateSuggestionTool(connection) {
|
|
|
11290
8857
|
"create_suggestion",
|
|
11291
8858
|
"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded. For actionable work on this task open a follow-up task.",
|
|
11292
8859
|
{
|
|
11293
|
-
title:
|
|
11294
|
-
description:
|
|
8860
|
+
title: z6.string().describe("Short title for the suggestion"),
|
|
8861
|
+
description: z6.string().optional().describe(
|
|
11295
8862
|
"1-2 sentence description of what should change and why. Keep concise and project-focused."
|
|
11296
8863
|
),
|
|
11297
|
-
tag_names:
|
|
8864
|
+
tag_names: z6.array(z6.string()).optional().describe("Tag names to categorize the suggestion")
|
|
11298
8865
|
},
|
|
11299
8866
|
async ({ title, description, tag_names }) => {
|
|
11300
8867
|
try {
|
|
@@ -11323,8 +8890,8 @@ function buildVoteSuggestionTool(connection) {
|
|
|
11323
8890
|
"vote_suggestion",
|
|
11324
8891
|
"Vote +1 or -1 on a project suggestion. Use to express support or disagreement with a specific suggestion returned by get_suggestions.",
|
|
11325
8892
|
{
|
|
11326
|
-
suggestion_id:
|
|
11327
|
-
value:
|
|
8893
|
+
suggestion_id: z6.string().describe("The suggestion ID to vote on"),
|
|
8894
|
+
value: z6.number().refine((v) => v === 1 || v === -1, { message: "Value must be 1 or -1" }).describe("+1 to upvote, -1 to downvote")
|
|
11328
8895
|
},
|
|
11329
8896
|
async ({ suggestion_id, value }) => {
|
|
11330
8897
|
try {
|
|
@@ -11686,6 +9253,47 @@ function buildRejectManualTestTool(connection) {
|
|
|
11686
9253
|
});
|
|
11687
9254
|
}
|
|
11688
9255
|
|
|
9256
|
+
// src/tools/ci-wait-tools.ts
|
|
9257
|
+
function short(sha) {
|
|
9258
|
+
return sha.slice(0, 7);
|
|
9259
|
+
}
|
|
9260
|
+
function describeHead(result) {
|
|
9261
|
+
return `${short(result.sha)}${result.prNumber ? ` (PR #${result.prNumber})` : ""}`;
|
|
9262
|
+
}
|
|
9263
|
+
function formatParkOnCheckResult(result) {
|
|
9264
|
+
if (result.status === "parked") {
|
|
9265
|
+
const running = result.pendingChecks.length > 0 ? ` Still running: ${result.pendingChecks.join(", ")}.` : " No check has registered yet.";
|
|
9266
|
+
return `Parked on ${describeHead(result)} until ${result.deadline}.${running}
|
|
9267
|
+
|
|
9268
|
+
END YOUR TURN NOW: no further tool calls, no polling, no filler commands. Conveyor wakes this session with the result (SUCCESS or FAILURE with the failing jobs and run URL), with head_moved if the PR gets a new commit, or with timed_out at the deadline. Uncommitted work is covered by the per-turn WIP snapshot, but anything already committed and pushed needs no recovery at all. If something else wakes you first, handle it and call wait_for_checks again.`;
|
|
9269
|
+
}
|
|
9270
|
+
if (result.status === "completed") {
|
|
9271
|
+
if (result.conclusion === "success") {
|
|
9272
|
+
return `CI for ${describeHead(result)} already finished: SUCCESS. All ${result.checksTotal} checks passed. Continue with the next step.`;
|
|
9273
|
+
}
|
|
9274
|
+
const pending = result.pendingChecks.length > 0 ? ` Still running: ${result.pendingChecks.join(", ")}.` : "";
|
|
9275
|
+
return `CI for ${describeHead(result)} already has a result: FAILURE. Failing: ${result.failingChecks.join(", ")}.${result.runUrl ? ` Run: ${result.runUrl}.` : ""}${pending} Triage before treating it as your bug (stale head? runner preemption? file not in your diff? base branch red?), then fix, push, and call wait_for_checks again.`;
|
|
9276
|
+
}
|
|
9277
|
+
return `Cannot park this session: ${result.reason}. Read the checks ONCE with read-only \`gh pr checks\` and act on what you see; never loop on it.`;
|
|
9278
|
+
}
|
|
9279
|
+
function buildWaitForChecksTool(connection) {
|
|
9280
|
+
return defineContractTool(waitForChecksContract, async ({ sha, prNumber, timeoutMinutes }) => {
|
|
9281
|
+
try {
|
|
9282
|
+
const result = await connection.call("parkOnCheckResult", {
|
|
9283
|
+
sessionId: connection.sessionId,
|
|
9284
|
+
...sha === void 0 ? {} : { sha },
|
|
9285
|
+
...prNumber === void 0 ? {} : { prNumber },
|
|
9286
|
+
...timeoutMinutes === void 0 ? {} : { timeoutMinutes }
|
|
9287
|
+
});
|
|
9288
|
+
return textResult(formatParkOnCheckResult(result));
|
|
9289
|
+
} catch (error) {
|
|
9290
|
+
return textResult(
|
|
9291
|
+
`wait_for_checks failed: ${error instanceof Error ? error.message : String(error)}. Retry once if this was a transient socket reconnect; otherwise read the checks once with read-only \`gh pr checks\` and end your turn instead of polling.`
|
|
9292
|
+
);
|
|
9293
|
+
}
|
|
9294
|
+
});
|
|
9295
|
+
}
|
|
9296
|
+
|
|
11689
9297
|
// src/tools/common-tools.ts
|
|
11690
9298
|
function buildCommonTools(connection, config) {
|
|
11691
9299
|
return [
|
|
@@ -11705,7 +9313,7 @@ function buildCommonTools(connection, config) {
|
|
|
11705
9313
|
}
|
|
11706
9314
|
|
|
11707
9315
|
// src/tools/pm-tools.ts
|
|
11708
|
-
import { z as
|
|
9316
|
+
import { z as z7 } from "zod";
|
|
11709
9317
|
|
|
11710
9318
|
// src/tools/task-update-tools.ts
|
|
11711
9319
|
var CURRENT_TASK_ONLY = ["title", "description", "plan", "githubBranch"];
|
|
@@ -11778,8 +9386,8 @@ function buildUpdateTaskTool(connection) {
|
|
|
11778
9386
|
"update_task_plan",
|
|
11779
9387
|
"Save the plan and/or description to the current task. In auto/building mode, save the plan BEFORE writing code and keep it current as the approach evolves \u2014 post it, then build; never pause the build waiting for approval. For children use update_subtask; for title/tags/PR use update_task_properties.",
|
|
11780
9388
|
{
|
|
11781
|
-
plan:
|
|
11782
|
-
description:
|
|
9389
|
+
plan: z7.string().optional().describe("The task plan in markdown"),
|
|
9390
|
+
description: z7.string().optional().describe(cardDescriptionDesc("Updated task description"))
|
|
11783
9391
|
},
|
|
11784
9392
|
async ({ plan, description }) => {
|
|
11785
9393
|
try {
|
|
@@ -11802,10 +9410,10 @@ function buildHandoffTool(connection) {
|
|
|
11802
9410
|
"handoff_to_agent",
|
|
11803
9411
|
"Hand this task off to an implementer agent for the build phase \u2014 mid-conversation, same session, no restart. Call this once the plan is compiled and saved (update_task). The server swaps this task to the difficulty-sized implementer agent (which may run at a different model level), announces the handoff in the activity log + chat, and switches you into build mode to start implementing. Size the work with the storyPoints arg (or set it first via update_task_properties). Returns the implementer's name + model.",
|
|
11804
9412
|
{
|
|
11805
|
-
storyPoints:
|
|
9413
|
+
storyPoints: z7.number().int().positive().optional().describe(
|
|
11806
9414
|
"Difficulty sizing (1=Common, 2=Magic, 3=Rare, 5=Unique, 8=Pack) \u2014 picks which implementer agent takes over. Omit to use the task's current story points."
|
|
11807
9415
|
),
|
|
11808
|
-
message:
|
|
9416
|
+
message: z7.string().optional().describe("Optional kickoff note posted to the chat alongside the handoff notice.")
|
|
11809
9417
|
},
|
|
11810
9418
|
async ({ storyPoints, message }) => {
|
|
11811
9419
|
try {
|
|
@@ -11950,81 +9558,8 @@ function buildListSubtasksTool(connection) {
|
|
|
11950
9558
|
{ annotations: { readOnlyHint: true } }
|
|
11951
9559
|
);
|
|
11952
9560
|
}
|
|
11953
|
-
function
|
|
9561
|
+
function buildPmTools(connection) {
|
|
11954
9562
|
return [
|
|
11955
|
-
defineTool(
|
|
11956
|
-
"start_child_cloud_build",
|
|
11957
|
-
"Start a cloud build (codespace) for a child task. Preconditions: child status is `Open`, story points set, and an agent assigned \u2014 satisfy all three with update_subtask (status/agentIdOrName/storyPointValue) first; none happen automatically. A PACK_CHILD_LIMIT error is backpressure, not failure: check list_subtasks packSlots for which children hold the in-flight slots, merge/stop one, then retry. On a feature-branch pack, dev is merged into the pack branch first so the child branches from a fresh base; a conflict is reported in the result and never blocks the launch.",
|
|
11958
|
-
{
|
|
11959
|
-
childTaskId: z17.string().describe("The child task ID to start a cloud build for")
|
|
11960
|
-
},
|
|
11961
|
-
async ({ childTaskId }) => {
|
|
11962
|
-
try {
|
|
11963
|
-
const result = await connection.call("startChildCloudBuild", {
|
|
11964
|
-
sessionId: connection.sessionId,
|
|
11965
|
-
childTaskId
|
|
11966
|
-
});
|
|
11967
|
-
const started = `Cloud build started for child task: ${result.childTaskId}`;
|
|
11968
|
-
const sync = result.baseSync;
|
|
11969
|
-
if (sync?.error) {
|
|
11970
|
-
return textResult(
|
|
11971
|
-
`${started}
|
|
11972
|
-
|
|
11973
|
-
Base sync: dev \u2192 ${sync.branch} failed \u2014 ${sync.error}. The child was launched from the un-synced pack branch. Merge dev into ${sync.branch} in your local checkout, resolve the conflicts, and push before firing more children.`
|
|
11974
|
-
);
|
|
11975
|
-
}
|
|
11976
|
-
return textResult(started);
|
|
11977
|
-
} catch (error) {
|
|
11978
|
-
return textResult(
|
|
11979
|
-
`Failed to start child cloud build: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
11980
|
-
);
|
|
11981
|
-
}
|
|
11982
|
-
}
|
|
11983
|
-
),
|
|
11984
|
-
defineTool(
|
|
11985
|
-
"stop_child_build",
|
|
11986
|
-
"Send a graceful stop signal to a running child build's agent. Not a force-kill \u2014 the agent may take a moment to wind down. Stopping a child eventually frees its PACK_CHILD_LIMIT build slot (see list_subtasks packSlots).",
|
|
11987
|
-
{
|
|
11988
|
-
childTaskId: z17.string().describe("The child task ID whose build should be stopped")
|
|
11989
|
-
},
|
|
11990
|
-
async ({ childTaskId }) => {
|
|
11991
|
-
try {
|
|
11992
|
-
await connection.call("stopChildBuild", {
|
|
11993
|
-
sessionId: connection.sessionId,
|
|
11994
|
-
childTaskId
|
|
11995
|
-
});
|
|
11996
|
-
return textResult(`Stop signal sent to child task: ${childTaskId}`);
|
|
11997
|
-
} catch (error) {
|
|
11998
|
-
return textResult(
|
|
11999
|
-
`Failed to stop child build: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
12000
|
-
);
|
|
12001
|
-
}
|
|
12002
|
-
}
|
|
12003
|
-
),
|
|
12004
|
-
defineContractTool(approveAndMergePrContract, async ({ childTaskId }) => {
|
|
12005
|
-
try {
|
|
12006
|
-
const result = await connection.call("approveAndMergePR", {
|
|
12007
|
-
sessionId: connection.sessionId,
|
|
12008
|
-
childTaskId
|
|
12009
|
-
});
|
|
12010
|
-
if (result.merged) {
|
|
12011
|
-
return textResult(
|
|
12012
|
-
`PR #${result.prNumber} approved and merged for task ${result.childTaskId}. Task status updated to ReviewDev.`
|
|
12013
|
-
);
|
|
12014
|
-
}
|
|
12015
|
-
return textResult(
|
|
12016
|
-
`PR #${result.prNumber} merge queued for task ${result.childTaskId} \u2014 CI checks still in progress. The PR will auto-merge when all checks pass. Do NOT proceed as if merged. Wait for the child task status to change to ReviewDev before continuing.`
|
|
12017
|
-
);
|
|
12018
|
-
} catch (error) {
|
|
12019
|
-
return textResult(
|
|
12020
|
-
`Failed to approve and merge PR: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
12021
|
-
);
|
|
12022
|
-
}
|
|
12023
|
-
})
|
|
12024
|
-
];
|
|
12025
|
-
}
|
|
12026
|
-
function buildPmTools(connection, options) {
|
|
12027
|
-
const tools = [
|
|
12028
9563
|
buildUpdateTaskTool(connection),
|
|
12029
9564
|
// The shared-skill vocabulary alongside the split legacy tools above.
|
|
12030
9565
|
// Both stay REGISTERED, but the migration this comment used to defer has
|
|
@@ -12039,12 +9574,10 @@ function buildPmTools(connection, options) {
|
|
|
12039
9574
|
buildDeleteSubtaskTool(connection),
|
|
12040
9575
|
buildListSubtasksTool(connection)
|
|
12041
9576
|
];
|
|
12042
|
-
if (!options?.includePackTools) return tools;
|
|
12043
|
-
return [...tools, ...buildPackTools(connection)];
|
|
12044
9577
|
}
|
|
12045
9578
|
|
|
12046
9579
|
// src/tools/discovery-tools.ts
|
|
12047
|
-
import { z as
|
|
9580
|
+
import { z as z8 } from "zod";
|
|
12048
9581
|
var SP_DESCRIPTION2 = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique). The key is 'storyPointValue' \u2014 not 'storyPoints'.";
|
|
12049
9582
|
var VALID_PROPERTY_KEYS = "title, storyPointValue, tagNames, githubPRUrl, githubBranch, risk";
|
|
12050
9583
|
function describeUpdatedFields(p) {
|
|
@@ -12063,12 +9596,12 @@ function buildDiscoveryTools(connection) {
|
|
|
12063
9596
|
"update_task_properties",
|
|
12064
9597
|
"Set one or more task properties in a single call. Valid keys: title, storyPointValue, tagNames, githubPRUrl, githubBranch, risk. All are optional \u2014 include only the ones you want to update (at least one). Unknown keys are rejected.",
|
|
12065
9598
|
{
|
|
12066
|
-
title:
|
|
12067
|
-
storyPointValue:
|
|
12068
|
-
tagNames:
|
|
12069
|
-
githubPRUrl:
|
|
12070
|
-
githubBranch:
|
|
12071
|
-
risk:
|
|
9599
|
+
title: z8.string().optional().describe("The new task title"),
|
|
9600
|
+
storyPointValue: z8.number().optional().describe(SP_DESCRIPTION2),
|
|
9601
|
+
tagNames: z8.array(z8.string()).optional().describe("Array of tag names to assign"),
|
|
9602
|
+
githubPRUrl: z8.string().url().optional().describe("GitHub pull request URL to link to this task"),
|
|
9603
|
+
githubBranch: z8.string().optional().describe("Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')"),
|
|
9604
|
+
risk: z8.enum(["critical", "high", "medium", "low"]).nullable().optional().describe(
|
|
12072
9605
|
"Risk level \u2014 how much important surface the task touches (critical/high/medium/low). Pass null to clear."
|
|
12073
9606
|
)
|
|
12074
9607
|
},
|
|
@@ -12108,7 +9641,7 @@ function buildDiscoveryTools(connection) {
|
|
|
12108
9641
|
}
|
|
12109
9642
|
|
|
12110
9643
|
// src/tools/project-tools.ts
|
|
12111
|
-
import { z as
|
|
9644
|
+
import { z as z9 } from "zod";
|
|
12112
9645
|
|
|
12113
9646
|
// src/execution/context-path-verifier.ts
|
|
12114
9647
|
import { readFile as readFile3 } from "fs/promises";
|
|
@@ -12186,16 +9719,16 @@ function formatContextPathProblems(problems) {
|
|
|
12186
9719
|
}
|
|
12187
9720
|
|
|
12188
9721
|
// src/tools/project-tools.ts
|
|
12189
|
-
var CONTEXT_PATH_SHAPE =
|
|
12190
|
-
type:
|
|
9722
|
+
var CONTEXT_PATH_SHAPE = z9.object({
|
|
9723
|
+
type: z9.enum(["rule", "doc", "file", "folder"]).describe(
|
|
12191
9724
|
"Link kind \u2014 all paths are repo-relative; doc marks a synced project doc, which resolves from the workspace like rule/file"
|
|
12192
9725
|
),
|
|
12193
|
-
path:
|
|
12194
|
-
label:
|
|
12195
|
-
locator:
|
|
9726
|
+
path: z9.string().min(1).max(500).describe("Repo-relative path"),
|
|
9727
|
+
label: z9.string().max(100).optional(),
|
|
9728
|
+
locator: z9.string().min(1).max(CONTEXT_LINK_LOCATOR_MAX).regex(/^[^\r\n]*$/, "Locator cannot contain line breaks").optional().describe(
|
|
12196
9729
|
'Verified-link tether: text that must keep existing in the file. With locatorType "test" it must appear inside a real it/test/describe TITLE; with "code" anywhere in the file. Validated at write time against the checkout and re-checked by the periodic sweep \u2014 a rename/delete flags the link stale. Locators containing <> are placeholders and never checked.'
|
|
12197
9730
|
),
|
|
12198
|
-
locatorType:
|
|
9731
|
+
locatorType: z9.enum(["test", "code"]).optional().describe(
|
|
12199
9732
|
"How the locator must match \u2014 required iff locator is set; not valid on folder links"
|
|
12200
9733
|
)
|
|
12201
9734
|
}).refine((link) => link.locator === void 0 === (link.locatorType === void 0), {
|
|
@@ -12244,15 +9777,15 @@ function buildCreateTagTool(connection, projectId, workspaceDir) {
|
|
|
12244
9777
|
"create_tag",
|
|
12245
9778
|
"Create a project tag. Include a crisp description (\u2264255 chars \u2014 the summary) and contextPaths (rule/doc/file/folder links agents auto-load when working on matching tasks); put the full spec in overview. Set parentTagIds to place the tag in the hierarchy right away. Every contextPath is checked against the repo checkout \u2014 a path that does not exist, or whose type does not match what is on disk, rejects the whole call. Fails if the name already exists.",
|
|
12246
9779
|
{
|
|
12247
|
-
name:
|
|
12248
|
-
color:
|
|
12249
|
-
description:
|
|
12250
|
-
overview:
|
|
12251
|
-
overviewPath:
|
|
9780
|
+
name: z9.string().min(1).max(50),
|
|
9781
|
+
color: z9.string().regex(/^#[0-9a-fA-F]{6}$/).optional().describe("#RRGGBB (default gray)"),
|
|
9782
|
+
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
9783
|
+
overview: z9.string().max(TAG_OVERVIEW_MAX).optional().describe("Full markdown glossary body \u2014 the term's spec"),
|
|
9784
|
+
overviewPath: z9.string().min(1).max(500).optional().describe(
|
|
12252
9785
|
"Repo file to source the overview from (base-branch content is served everywhere). A not-yet-merged path is fine \u2014 the tag serves the stored overview as fallback until the file lands."
|
|
12253
9786
|
),
|
|
12254
|
-
parentTagIds:
|
|
12255
|
-
contextPaths:
|
|
9787
|
+
parentTagIds: z9.array(z9.string()).max(25).optional().describe("Parent tag ids from list_tags (multi-parent DAG) to link at create time"),
|
|
9788
|
+
contextPaths: z9.array(CONTEXT_PATH_SHAPE).max(20).optional()
|
|
12256
9789
|
},
|
|
12257
9790
|
async ({ name, color, description, overview, overviewPath, parentTagIds, contextPaths }) => {
|
|
12258
9791
|
const rejection = await rejectBadContextPaths(contextPaths, workspaceDir);
|
|
@@ -12280,19 +9813,19 @@ function buildUpdateTagTool(connection, projectId, taskId, workspaceDir) {
|
|
|
12280
9813
|
"update_tag",
|
|
12281
9814
|
"Update a tag's name, color, description (\u2264255), markdown overview, parent tags, or contextPaths. contextPaths and parentTagIds are FULL replacements \u2014 include what you want to keep. ALWAYS pass a short reason; it lands in the tag's revision history (with your current card auto-stamped) so the team sees why the glossary changed. Every contextPath is checked against the repo checkout \u2014 a path that does not exist, or whose type does not match what is on disk, rejects the whole call and nothing is written.",
|
|
12282
9815
|
{
|
|
12283
|
-
tagId:
|
|
12284
|
-
name:
|
|
12285
|
-
color:
|
|
12286
|
-
description:
|
|
12287
|
-
overview:
|
|
9816
|
+
tagId: z9.string().describe("Tag id from list_tags"),
|
|
9817
|
+
name: z9.string().min(1).max(50).optional(),
|
|
9818
|
+
color: z9.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
|
|
9819
|
+
description: z9.string().max(TAG_DESCRIPTION_MAX).optional(),
|
|
9820
|
+
overview: z9.string().max(TAG_OVERVIEW_MAX).nullable().optional().describe(
|
|
12288
9821
|
"Full markdown glossary body; null clears it. REJECTED while overviewPath is set \u2014 edit the sourced file in the repo instead"
|
|
12289
9822
|
),
|
|
12290
|
-
overviewPath:
|
|
9823
|
+
overviewPath: z9.string().min(1).max(500).nullable().optional().describe(
|
|
12291
9824
|
"Repo file to source the overview from (null clears back to the stored overview). A not-yet-merged path is fine \u2014 the stored overview serves as fallback until the file lands on the base branch."
|
|
12292
9825
|
),
|
|
12293
|
-
parentTagIds:
|
|
12294
|
-
reason:
|
|
12295
|
-
contextPaths:
|
|
9826
|
+
parentTagIds: z9.array(z9.string()).max(25).optional().describe("Full-set replacement of the tag's parent tags (multi-parent DAG)"),
|
|
9827
|
+
reason: z9.string().max(TAG_REASON_MAX).optional().describe("One line on why \u2014 shown in the tag's revision history"),
|
|
9828
|
+
contextPaths: z9.array(CONTEXT_PATH_SHAPE).max(20).optional()
|
|
12296
9829
|
},
|
|
12297
9830
|
async ({
|
|
12298
9831
|
tagId,
|
|
@@ -12350,8 +9883,8 @@ function buildPostToProjectChatTool(connection, projectId) {
|
|
|
12350
9883
|
"post_to_project_chat",
|
|
12351
9884
|
"Post a markdown message to the PROJECT chat \u2014 use once at the end of an audit for the summary the team reads.",
|
|
12352
9885
|
{
|
|
12353
|
-
message:
|
|
12354
|
-
kind:
|
|
9886
|
+
message: z9.string().min(1).max(2e4),
|
|
9887
|
+
kind: z9.enum(["tag_audit_summary"]).optional().describe(
|
|
12355
9888
|
"Set to 'tag_audit_summary' when posting a tag-audit summary so it is also saved to the persistent tag history"
|
|
12356
9889
|
)
|
|
12357
9890
|
},
|
|
@@ -12370,7 +9903,7 @@ function buildGetProjectTaskTool(connection, projectId) {
|
|
|
12370
9903
|
"get_project_task",
|
|
12371
9904
|
"Fetch any task in the project by id or slug: title, description, plan, status, and metadata. The audit evidence trail starts here.",
|
|
12372
9905
|
{
|
|
12373
|
-
taskId:
|
|
9906
|
+
taskId: z9.string().describe("Task id or slug")
|
|
12374
9907
|
},
|
|
12375
9908
|
async ({ taskId }) => {
|
|
12376
9909
|
try {
|
|
@@ -12388,8 +9921,8 @@ function buildReadProjectTaskChatTool(connection, projectId) {
|
|
|
12388
9921
|
"read_project_task_chat",
|
|
12389
9922
|
"Read any project task's chat messages (newest last). role 'user' rows are HUMAN turns; 'assistant'/'system' rows are agent posts and activity-log entries.",
|
|
12390
9923
|
{
|
|
12391
|
-
taskId:
|
|
12392
|
-
limit:
|
|
9924
|
+
taskId: z9.string().describe("Task id or slug"),
|
|
9925
|
+
limit: z9.number().int().min(1).max(200).optional().describe("Messages to fetch (default 50)")
|
|
12393
9926
|
},
|
|
12394
9927
|
async ({ taskId, limit }) => {
|
|
12395
9928
|
try {
|
|
@@ -12411,9 +9944,9 @@ function buildGetProjectTaskLogsTool(connection, projectId) {
|
|
|
12411
9944
|
"get_project_task_logs",
|
|
12412
9945
|
"Read any project task's persisted agent event stream (message / tool_use / turn_end / error / completed). Turn boundaries are turn_end events. Entries are truncated to ~2KB each; max 500 per call.",
|
|
12413
9946
|
{
|
|
12414
|
-
taskId:
|
|
12415
|
-
limit:
|
|
12416
|
-
source:
|
|
9947
|
+
taskId: z9.string().describe("Task id or slug"),
|
|
9948
|
+
limit: z9.number().int().min(1).max(500).optional().describe("Entries to fetch (default 50)"),
|
|
9949
|
+
source: z9.enum(["agent", "application"]).optional().describe("Filter: 'agent' = model events (default useful for grading)")
|
|
12417
9950
|
},
|
|
12418
9951
|
async ({ taskId, limit, source }) => {
|
|
12419
9952
|
try {
|
|
@@ -12431,44 +9964,44 @@ function buildGetProjectTaskLogsTool(connection, projectId) {
|
|
|
12431
9964
|
{ annotations: { readOnlyHint: true } }
|
|
12432
9965
|
);
|
|
12433
9966
|
}
|
|
12434
|
-
var TURN_GRADE_SHAPE =
|
|
12435
|
-
turnIndex:
|
|
12436
|
-
phase:
|
|
12437
|
-
grade:
|
|
12438
|
-
reasoning:
|
|
12439
|
-
eventType:
|
|
12440
|
-
eventSummary:
|
|
9967
|
+
var TURN_GRADE_SHAPE = z9.object({
|
|
9968
|
+
turnIndex: z9.number().int().min(0),
|
|
9969
|
+
phase: z9.enum(["planning", "building", "human"]),
|
|
9970
|
+
grade: z9.enum(["correct", "neutral", "blunder"]),
|
|
9971
|
+
reasoning: z9.string(),
|
|
9972
|
+
eventType: z9.string().describe('e.g. "message", "tool_use", "human_message"'),
|
|
9973
|
+
eventSummary: z9.string().max(200).describe("\u2264120 chars of what happened this turn")
|
|
12441
9974
|
});
|
|
12442
|
-
var HUMAN_EVAL_SHAPE =
|
|
12443
|
-
messageIndex:
|
|
12444
|
-
rating:
|
|
12445
|
-
reasoning:
|
|
9975
|
+
var HUMAN_EVAL_SHAPE = z9.object({
|
|
9976
|
+
messageIndex: z9.number().int().min(0).describe("Index into the task's human messages, oldest first"),
|
|
9977
|
+
rating: z9.number().int().min(-1).max(1),
|
|
9978
|
+
reasoning: z9.string()
|
|
12446
9979
|
});
|
|
12447
9980
|
function buildReportTaskAuditResultTool(connection, projectId) {
|
|
12448
9981
|
return defineTool(
|
|
12449
9982
|
"report_task_audit_result",
|
|
12450
9983
|
"Persist one audited task's grades (call once per task after grading it). Pass error instead to mark the audit failed when the evidence is unusable.",
|
|
12451
9984
|
{
|
|
12452
|
-
taskId:
|
|
12453
|
-
summary:
|
|
12454
|
-
turnGrades:
|
|
12455
|
-
planningAccuracy:
|
|
12456
|
-
buildingAccuracy:
|
|
12457
|
-
humanAccuracy:
|
|
12458
|
-
planningCorrect:
|
|
12459
|
-
planningNeutral:
|
|
12460
|
-
planningBlunder:
|
|
12461
|
-
buildingCorrect:
|
|
12462
|
-
buildingNeutral:
|
|
12463
|
-
buildingBlunder:
|
|
12464
|
-
humanCorrect:
|
|
12465
|
-
humanNeutral:
|
|
12466
|
-
humanBlunder:
|
|
12467
|
-
humanEvaluations:
|
|
12468
|
-
suggestionIds:
|
|
12469
|
-
auditCostUsd:
|
|
12470
|
-
model:
|
|
12471
|
-
error:
|
|
9985
|
+
taskId: z9.string().describe("The audited task's id (NOT slug)"),
|
|
9986
|
+
summary: z9.string().describe("3-6 sentences: what went well, what was wasted"),
|
|
9987
|
+
turnGrades: z9.array(TURN_GRADE_SHAPE),
|
|
9988
|
+
planningAccuracy: z9.number().min(0).max(1).nullable(),
|
|
9989
|
+
buildingAccuracy: z9.number().min(0).max(1).nullable(),
|
|
9990
|
+
humanAccuracy: z9.number().min(0).max(1).nullable(),
|
|
9991
|
+
planningCorrect: z9.number().int().min(0),
|
|
9992
|
+
planningNeutral: z9.number().int().min(0),
|
|
9993
|
+
planningBlunder: z9.number().int().min(0),
|
|
9994
|
+
buildingCorrect: z9.number().int().min(0),
|
|
9995
|
+
buildingNeutral: z9.number().int().min(0),
|
|
9996
|
+
buildingBlunder: z9.number().int().min(0),
|
|
9997
|
+
humanCorrect: z9.number().int().min(0),
|
|
9998
|
+
humanNeutral: z9.number().int().min(0),
|
|
9999
|
+
humanBlunder: z9.number().int().min(0),
|
|
10000
|
+
humanEvaluations: z9.array(HUMAN_EVAL_SHAPE).optional(),
|
|
10001
|
+
suggestionIds: z9.array(z9.string()).describe("Suggestion ids filed for this task, or []"),
|
|
10002
|
+
auditCostUsd: z9.number().nullable(),
|
|
10003
|
+
model: z9.string().nullable().describe("The model you are running as"),
|
|
10004
|
+
error: z9.string().optional().describe("Set ONLY to mark this task's audit failed")
|
|
12472
10005
|
},
|
|
12473
10006
|
async (input) => {
|
|
12474
10007
|
try {
|
|
@@ -12950,34 +10483,34 @@ function connectedToolsFor(connection, context) {
|
|
|
12950
10483
|
// src/tools/code-review-tools.ts
|
|
12951
10484
|
import { execFile } from "child_process";
|
|
12952
10485
|
import { promisify } from "util";
|
|
12953
|
-
import { z as
|
|
10486
|
+
import { z as z10 } from "zod";
|
|
12954
10487
|
async function endReviewSession(connection, reason) {
|
|
12955
10488
|
await connection.call("endReviewSession", {
|
|
12956
10489
|
sessionId: connection.sessionId,
|
|
12957
10490
|
reason
|
|
12958
10491
|
});
|
|
12959
10492
|
}
|
|
12960
|
-
var
|
|
12961
|
-
var reviewedShaSchema =
|
|
10493
|
+
var RISK_LEVELS = ["critical", "high", "medium", "low"];
|
|
10494
|
+
var reviewedShaSchema = z10.string().regex(/^[0-9a-f]{40}$/i).describe("REQUIRED. The full 40-character commit SHA this verdict reviews.");
|
|
12962
10495
|
var riskDescription = "REQUIRED. The risk level this change carries, judged by the surface area it touches: critical = touches critical/foundational surface, high = important surface, medium = moderate, low = small/isolated. Set this on every verdict. You have authority to override a risk level already set on the task if you disagree with it.";
|
|
12963
|
-
var ReviewGuideToolSchema =
|
|
12964
|
-
reviewedSha:
|
|
10496
|
+
var ReviewGuideToolSchema = z10.strictObject({
|
|
10497
|
+
reviewedSha: z10.string().regex(/^[0-9a-f]{40}$/i).describe(
|
|
12965
10498
|
"REQUIRED. The PR's current head as a full 40-char SHA. Run `git rev-parse HEAD` immediately before this call \u2014 never extend an abbreviated hash into 40 characters."
|
|
12966
10499
|
),
|
|
12967
|
-
overview:
|
|
12968
|
-
sections:
|
|
12969
|
-
|
|
12970
|
-
title:
|
|
12971
|
-
explanation:
|
|
12972
|
-
classification:
|
|
12973
|
-
files:
|
|
12974
|
-
|
|
12975
|
-
path:
|
|
10500
|
+
overview: z10.string().min(1).max(6e4).describe("REQUIRED. Plain-text walkthrough intro, max 3000 characters. Keep it short."),
|
|
10501
|
+
sections: z10.array(
|
|
10502
|
+
z10.strictObject({
|
|
10503
|
+
title: z10.string().min(1).max(160),
|
|
10504
|
+
explanation: z10.string().min(1).max(2e3),
|
|
10505
|
+
classification: z10.enum(["core", "supporting"]).optional(),
|
|
10506
|
+
files: z10.array(
|
|
10507
|
+
z10.strictObject({
|
|
10508
|
+
path: z10.string().min(1).max(500).describe(
|
|
12976
10509
|
"A file the PR's diff actually changed. Context files you merely read are rejected."
|
|
12977
10510
|
),
|
|
12978
|
-
startLine:
|
|
12979
|
-
endLine:
|
|
12980
|
-
hunkHeader:
|
|
10511
|
+
startLine: z10.number().int().positive().max(1e6).optional(),
|
|
10512
|
+
endLine: z10.number().int().positive().max(1e6).optional(),
|
|
10513
|
+
hunkHeader: z10.string().min(1).max(300).optional().describe(
|
|
12981
10514
|
"Optional anchor, matched byte-exactly against the full hunk header line from `git diff` INCLUDING the context text after the second @@. Copy it verbatim from `git diff <base>..HEAD -- <file> | grep '^@@'`, or omit anchors entirely (path-only entries always validate)."
|
|
12982
10515
|
)
|
|
12983
10516
|
})
|
|
@@ -13061,8 +10594,8 @@ function buildApproveCodeReviewTool(connection) {
|
|
|
13061
10594
|
"Approve the code review and exit. Use when the diff passes all review criteria. Requires a summary and a risk level \u2014 for changes, use request_code_changes with a structured issues[] list.",
|
|
13062
10595
|
{
|
|
13063
10596
|
reviewedSha: reviewedShaSchema,
|
|
13064
|
-
summary:
|
|
13065
|
-
risk:
|
|
10597
|
+
summary: z10.string().describe("Brief summary of what was reviewed and why it looks good"),
|
|
10598
|
+
risk: z10.enum(RISK_LEVELS).describe(riskDescription)
|
|
13066
10599
|
},
|
|
13067
10600
|
async ({ reviewedSha, summary, risk }) => {
|
|
13068
10601
|
const content = `**Code Review: Approved** :white_check_mark:
|
|
@@ -13093,16 +10626,16 @@ function buildRequestCodeChangesTool(connection) {
|
|
|
13093
10626
|
"Request changes during code review and exit. Use when substantive issues must be fixed before merge. Each issue: { file, line?, severity: critical|major|minor, description }.",
|
|
13094
10627
|
{
|
|
13095
10628
|
reviewedSha: reviewedShaSchema,
|
|
13096
|
-
issues:
|
|
13097
|
-
|
|
13098
|
-
file:
|
|
13099
|
-
line:
|
|
13100
|
-
severity:
|
|
13101
|
-
description:
|
|
10629
|
+
issues: z10.array(
|
|
10630
|
+
z10.object({
|
|
10631
|
+
file: z10.string().describe("File path where the issue was found"),
|
|
10632
|
+
line: z10.number().optional().describe("Line number (if applicable)"),
|
|
10633
|
+
severity: z10.enum(["critical", "major", "minor"]).describe("Issue severity"),
|
|
10634
|
+
description: z10.string().describe("What is wrong and how to fix it")
|
|
13102
10635
|
})
|
|
13103
10636
|
).describe("List of issues found during review"),
|
|
13104
|
-
summary:
|
|
13105
|
-
risk:
|
|
10637
|
+
summary: z10.string().describe("Brief overall summary of the review findings"),
|
|
10638
|
+
risk: z10.enum(RISK_LEVELS).describe(riskDescription)
|
|
13106
10639
|
},
|
|
13107
10640
|
async ({ reviewedSha, issues, summary, risk }) => {
|
|
13108
10641
|
const issueLines = issues.map((issue) => {
|
|
@@ -13145,41 +10678,38 @@ function buildCodeReviewTools(connection) {
|
|
|
13145
10678
|
// src/tools/index.ts
|
|
13146
10679
|
function getTaskModeTools(agentMode, connection) {
|
|
13147
10680
|
if (agentMode === "discovery" || agentMode === "auto" || agentMode === "building" || agentMode === "chat") {
|
|
13148
|
-
return buildPmTools(connection
|
|
10681
|
+
return buildPmTools(connection);
|
|
13149
10682
|
}
|
|
13150
10683
|
return [];
|
|
13151
10684
|
}
|
|
13152
10685
|
function getModeTools(agentMode, connection, config, context) {
|
|
13153
|
-
if (config.mode === "pack")
|
|
13154
|
-
return buildPmTools(connection, {
|
|
13155
|
-
includePackTools: config.packExecution === "fan-out"
|
|
13156
|
-
});
|
|
13157
|
-
}
|
|
10686
|
+
if (config.mode === "pack") return buildPmTools(connection);
|
|
13158
10687
|
if (config.mode === "task") return getTaskModeTools(agentMode, connection);
|
|
13159
|
-
const packToolsFor = (isParent) => ({
|
|
13160
|
-
includePackTools: !!isParent && config.packExecution === "fan-out"
|
|
13161
|
-
});
|
|
13162
10688
|
switch (agentMode) {
|
|
13163
10689
|
case "building":
|
|
13164
|
-
return context?.isParentTask ? buildPmTools(connection
|
|
10690
|
+
return context?.isParentTask ? buildPmTools(connection) : [];
|
|
13165
10691
|
case "review":
|
|
13166
10692
|
case "auto":
|
|
13167
10693
|
case "discovery":
|
|
13168
10694
|
case "help":
|
|
13169
|
-
return buildPmTools(connection
|
|
10695
|
+
return buildPmTools(connection);
|
|
13170
10696
|
default:
|
|
13171
|
-
return config.mode === "pm" ? buildPmTools(connection
|
|
10697
|
+
return config.mode === "pm" ? buildPmTools(connection) : [];
|
|
13172
10698
|
}
|
|
13173
10699
|
}
|
|
13174
10700
|
function buildPrGuideToolsFor(effectiveMode, connection, config, context) {
|
|
13175
10701
|
const isLeafBuild = effectiveMode === "building" || effectiveMode === "auto" || effectiveMode === "chat";
|
|
13176
|
-
const
|
|
13177
|
-
return (isLeafBuild ||
|
|
10702
|
+
const isPackRunner = config.mode === "pack";
|
|
10703
|
+
return (isLeafBuild || isPackRunner) && (isPackRunner || !context?.isParentTask) ? [
|
|
13178
10704
|
buildPublishReviewGuideTool(connection, {
|
|
13179
10705
|
resolveHeadSha: () => resolveGitHeadSha(config.workspaceDir)
|
|
13180
10706
|
})
|
|
13181
10707
|
] : [];
|
|
13182
10708
|
}
|
|
10709
|
+
function ciWaitToolsFor(effectiveMode, connection, config) {
|
|
10710
|
+
const isPackRunner = config.mode === "pack";
|
|
10711
|
+
return effectiveMode === "review" && !isPackRunner ? [] : [buildWaitForChecksTool(connection)];
|
|
10712
|
+
}
|
|
13183
10713
|
var ALWAYS_LOADED_TOOLS = /* @__PURE__ */ new Set([
|
|
13184
10714
|
// Every mode/session
|
|
13185
10715
|
"post_to_chat",
|
|
@@ -13218,26 +10748,29 @@ var ALWAYS_LOADED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
13218
10748
|
]);
|
|
13219
10749
|
var ORCHESTRATION_PROMOTED_TOOLS = /* @__PURE__ */ new Set([
|
|
13220
10750
|
"list_subtasks",
|
|
13221
|
-
"update_subtask"
|
|
13222
|
-
"start_child_cloud_build",
|
|
13223
|
-
"stop_child_build",
|
|
13224
|
-
"approve_and_merge_pr"
|
|
10751
|
+
"update_subtask"
|
|
13225
10752
|
]);
|
|
13226
10753
|
var BUILDING_PROMOTED_TOOLS = /* @__PURE__ */ new Set([
|
|
13227
10754
|
"upload_attachment",
|
|
13228
10755
|
"get_attachment",
|
|
13229
10756
|
"create_suggestion",
|
|
13230
10757
|
"create_follow_up_task",
|
|
13231
|
-
"list_manual_tests"
|
|
10758
|
+
"list_manual_tests",
|
|
10759
|
+
// Every PR-opening session waits on CI at least once; deferring the wait
|
|
10760
|
+
// tool behind ToolSearch is one more reason to fall back to a poll loop.
|
|
10761
|
+
"wait_for_checks"
|
|
13232
10762
|
]);
|
|
13233
10763
|
var REVIEW_PROMOTED_TOOLS = /* @__PURE__ */ new Set(["create_suggestion"]);
|
|
13234
|
-
var PACK_PROMOTED_TOOLS = /* @__PURE__ */ new Set([
|
|
10764
|
+
var PACK_PROMOTED_TOOLS = /* @__PURE__ */ new Set([
|
|
10765
|
+
"get_execution_logs",
|
|
10766
|
+
"wait_for_checks"
|
|
10767
|
+
]);
|
|
13235
10768
|
function glossaryToolsFor(connection, config, context) {
|
|
13236
10769
|
return context?.projectId ? buildGlossaryTools(connection, context.projectId, config.taskId, config.workspaceDir) : [];
|
|
13237
10770
|
}
|
|
13238
|
-
function promotedToolsFor(effectiveMode, isPack, isProjectAgent,
|
|
10771
|
+
function promotedToolsFor(effectiveMode, isPack, isProjectAgent, isPackRunner = false) {
|
|
13239
10772
|
const names = /* @__PURE__ */ new Set();
|
|
13240
|
-
if (effectiveMode === "building" || effectiveMode === "auto" ||
|
|
10773
|
+
if (effectiveMode === "building" || effectiveMode === "auto" || isPackRunner) {
|
|
13241
10774
|
for (const name of BUILDING_PROMOTED_TOOLS) names.add(name);
|
|
13242
10775
|
}
|
|
13243
10776
|
if (effectiveMode === "review") {
|
|
@@ -13263,6 +10796,7 @@ function buildConveyorTools(connection, config, context, agentMode) {
|
|
|
13263
10796
|
const discoveryTools = effectiveMode === "discovery" || effectiveMode === "auto" || effectiveMode === "building" || effectiveMode === "chat" ? buildDiscoveryTools(connection) : [];
|
|
13264
10797
|
const codeReviewTools = effectiveMode === "review" ? buildCodeReviewTools(connection) : [];
|
|
13265
10798
|
const prGuideTools = buildPrGuideToolsFor(effectiveMode, connection, config, context);
|
|
10799
|
+
const ciWaitTools = ciWaitToolsFor(effectiveMode, connection, config);
|
|
13266
10800
|
const handoffTools = config.mode === "pm" && (effectiveMode === "discovery" || effectiveMode === "auto") ? [buildHandoffTool(connection)] : [];
|
|
13267
10801
|
const emergencyTools = [buildForceUpdateTaskStatusTool(connection)];
|
|
13268
10802
|
const glossaryTools = glossaryToolsFor(connection, config, context);
|
|
@@ -13275,17 +10809,13 @@ function buildConveyorTools(connection, config, context, agentMode) {
|
|
|
13275
10809
|
...discoveryTools,
|
|
13276
10810
|
...codeReviewTools,
|
|
13277
10811
|
...prGuideTools,
|
|
10812
|
+
...ciWaitTools,
|
|
13278
10813
|
...handoffTools,
|
|
13279
10814
|
...glossaryTools,
|
|
13280
10815
|
...connectedTools,
|
|
13281
10816
|
...emergencyTools
|
|
13282
10817
|
],
|
|
13283
|
-
promotedToolsFor(
|
|
13284
|
-
effectiveMode,
|
|
13285
|
-
isPack,
|
|
13286
|
-
config.mode === "pm",
|
|
13287
|
-
config.mode === "pack" && config.packExecution !== "fan-out"
|
|
13288
|
-
)
|
|
10818
|
+
promotedToolsFor(effectiveMode, isPack, config.mode === "pm", config.mode === "pack")
|
|
13289
10819
|
);
|
|
13290
10820
|
}
|
|
13291
10821
|
function createConveyorMcpServer(harness, connection, config, context, agentMode) {
|
|
@@ -13895,7 +11425,7 @@ function buildNoOpKeepAliveMessage(noOpCount) {
|
|
|
13895
11425
|
if (process.env.CONVEYOR_TUI === "codex") {
|
|
13896
11426
|
return `Conveyor blocked this call: it is a no-op keep-alive (${noOpCount} this session). If a required command is running, resume its session for the exit result. Otherwise do real work or end the turn.`;
|
|
13897
11427
|
}
|
|
13898
|
-
return `Conveyor blocked this call: it is a no-op keep-alive (${noOpCount} this session). You do not need to emit tool calls to stay alive. Ending your turn with NO tool call is safe and expected while waiting: the pod stays up and the completion notification re-invokes you. If nothing is running, do real work or end the turn. For
|
|
11428
|
+
return `Conveyor blocked this call: it is a no-op keep-alive (${noOpCount} this session). You do not need to emit tool calls to stay alive. Ending your turn with NO tool call is safe and expected while waiting: the pod stays up and the completion notification re-invokes you. If nothing is running, do real work or end the turn. Waiting on CI is wait_for_checks, then end the turn. For any other long wait with no notification source, use Monitor or ScheduleWakeup instead of filler commands.`;
|
|
13899
11429
|
}
|
|
13900
11430
|
function buildRepeatLoopChatMessage(repeatCount, forceStopped) {
|
|
13901
11431
|
if (forceStopped) {
|
|
@@ -14347,6 +11877,11 @@ function buildQueryOptions(host, context) {
|
|
|
14347
11877
|
context,
|
|
14348
11878
|
{
|
|
14349
11879
|
...host.config,
|
|
11880
|
+
// ModeController's live value, NOT the boot-frozen `config.isAuto` the
|
|
11881
|
+
// spread carries: the pack gate reads this, and the turn prompt below
|
|
11882
|
+
// gates on `host.isAuto`. Letting the two read different sources is how
|
|
11883
|
+
// a codespace parent card got "you cannot write or edit files" beside
|
|
11884
|
+
// "run /conveyor-build".
|
|
14350
11885
|
isAuto: host.isAuto,
|
|
14351
11886
|
runtimeTui: process.env.CONVEYOR_TUI
|
|
14352
11887
|
},
|
|
@@ -14456,7 +11991,7 @@ async function buildFollowUpPrompt(host, context, followUpContent) {
|
|
|
14456
11991
|
const followUpImages = typeof followUpContent === "string" ? [] : followUpContent.filter(
|
|
14457
11992
|
(b) => b.type === "image"
|
|
14458
11993
|
);
|
|
14459
|
-
const textPrompt = isPmMode ? `${await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode
|
|
11994
|
+
const textPrompt = isPmMode ? `${await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode)}
|
|
14460
11995
|
|
|
14461
11996
|
---
|
|
14462
11997
|
|
|
@@ -14666,8 +12201,7 @@ async function prewarmInitialTuiQuery(host, context) {
|
|
|
14666
12201
|
host.config.mode,
|
|
14667
12202
|
context,
|
|
14668
12203
|
host.isAuto,
|
|
14669
|
-
host.agentMode
|
|
14670
|
-
host.config.packExecution
|
|
12204
|
+
host.agentMode
|
|
14671
12205
|
);
|
|
14672
12206
|
const { appendSystemPrompt } = selectInitialPromptInput(
|
|
14673
12207
|
promptDelivery,
|
|
@@ -14699,8 +12233,7 @@ async function runPrefilledFollowUp(host, context, options, resume, followUpCont
|
|
|
14699
12233
|
host.config.mode,
|
|
14700
12234
|
context,
|
|
14701
12235
|
host.isAuto,
|
|
14702
|
-
host.agentMode
|
|
14703
|
-
host.config.packExecution
|
|
12236
|
+
host.agentMode
|
|
14704
12237
|
);
|
|
14705
12238
|
queryOptions.appendSystemPrompt = [queryOptions.appendSystemPrompt, initialPrompt].filter(Boolean).join("\n\n").slice(0, APPEND_SYSTEM_PROMPT_MAX_CHARS);
|
|
14706
12239
|
}
|
|
@@ -14771,8 +12304,7 @@ async function runInitialQuery(host, context, options, resume, promptDelivery) {
|
|
|
14771
12304
|
host.config.mode,
|
|
14772
12305
|
context,
|
|
14773
12306
|
host.isAuto,
|
|
14774
|
-
host.agentMode
|
|
14775
|
-
host.config.packExecution
|
|
12307
|
+
host.agentMode
|
|
14776
12308
|
);
|
|
14777
12309
|
const { prompt, appendSystemPrompt } = selectInitialPromptInput(
|
|
14778
12310
|
promptDelivery,
|
|
@@ -14825,13 +12357,7 @@ async function buildRetryQuery(host, context, options, lastErrorWasImage) {
|
|
|
14825
12357
|
);
|
|
14826
12358
|
}
|
|
14827
12359
|
const retryPrompt = buildMultimodalPrompt(
|
|
14828
|
-
await buildInitialPrompt(
|
|
14829
|
-
host.config.mode,
|
|
14830
|
-
context,
|
|
14831
|
-
host.isAuto,
|
|
14832
|
-
host.agentMode,
|
|
14833
|
-
host.config.packExecution
|
|
14834
|
-
),
|
|
12360
|
+
await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),
|
|
14835
12361
|
context,
|
|
14836
12362
|
lastErrorWasImage || !supportsImageBlocks(host.harnessKind)
|
|
14837
12363
|
);
|
|
@@ -14857,13 +12383,7 @@ async function handleAuthError(context, host, options) {
|
|
|
14857
12383
|
context.claudeSessionId = null;
|
|
14858
12384
|
host.connection.storeSessionId("");
|
|
14859
12385
|
const freshPrompt = buildMultimodalPrompt(
|
|
14860
|
-
await buildInitialPrompt(
|
|
14861
|
-
host.config.mode,
|
|
14862
|
-
context,
|
|
14863
|
-
host.isAuto,
|
|
14864
|
-
host.agentMode,
|
|
14865
|
-
host.config.packExecution
|
|
14866
|
-
),
|
|
12386
|
+
await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),
|
|
14867
12387
|
context,
|
|
14868
12388
|
!supportsImageBlocks(host.harnessKind)
|
|
14869
12389
|
);
|
|
@@ -14878,13 +12398,7 @@ async function handleStaleSession(context, host, options) {
|
|
|
14878
12398
|
context.claudeSessionId = null;
|
|
14879
12399
|
host.connection.storeSessionId("");
|
|
14880
12400
|
const freshPrompt = buildMultimodalPrompt(
|
|
14881
|
-
await buildInitialPrompt(
|
|
14882
|
-
host.config.mode,
|
|
14883
|
-
context,
|
|
14884
|
-
host.isAuto,
|
|
14885
|
-
host.agentMode,
|
|
14886
|
-
host.config.packExecution
|
|
14887
|
-
),
|
|
12401
|
+
await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),
|
|
14888
12402
|
context,
|
|
14889
12403
|
!supportsImageBlocks(host.harnessKind)
|
|
14890
12404
|
);
|
|
@@ -14978,13 +12492,7 @@ async function handleUsageCapRejection(context, host, options, rateLimitType, re
|
|
|
14978
12492
|
context.claudeSessionId = null;
|
|
14979
12493
|
host.connection.storeSessionId("");
|
|
14980
12494
|
const freshPrompt = buildMultimodalPrompt(
|
|
14981
|
-
await buildInitialPrompt(
|
|
14982
|
-
host.config.mode,
|
|
14983
|
-
context,
|
|
14984
|
-
host.isAuto,
|
|
14985
|
-
host.agentMode,
|
|
14986
|
-
host.config.packExecution
|
|
14987
|
-
),
|
|
12495
|
+
await buildInitialPrompt(host.config.mode, context, host.isAuto, host.agentMode),
|
|
14988
12496
|
context,
|
|
14989
12497
|
!supportsImageBlocks(host.harnessKind)
|
|
14990
12498
|
);
|
|
@@ -16568,8 +14076,8 @@ var SessionRunner = class _SessionRunner {
|
|
|
16568
14076
|
"[conveyor-agent] Completed \u2014 entering dormant idle (staying connected)\n"
|
|
16569
14077
|
);
|
|
16570
14078
|
}
|
|
14079
|
+
this.pendingMessages = this.pendingMessages.filter((msg) => msg.source === "pty_passive");
|
|
16571
14080
|
await this.flushWipNow("WIP: turn complete");
|
|
16572
|
-
this.pendingMessages.length = 0;
|
|
16573
14081
|
if (this._state !== "idle") await this.setState("idle");
|
|
16574
14082
|
const remainingMs = Math.max(0, this.dormantDeadline - Date.now());
|
|
16575
14083
|
this.lifecycle.startDormantTimer(remainingMs);
|
|
@@ -17075,10 +14583,8 @@ var SessionRunner = class _SessionRunner {
|
|
|
17075
14583
|
taskToken: this.config.connection.taskToken,
|
|
17076
14584
|
taskId: this.fullContext?.taskId ?? "",
|
|
17077
14585
|
model: this.fullContext?.model ?? DEFAULT_SONNET_MODEL,
|
|
17078
|
-
instructions: this.fullContext?.agentInstructions ?? "",
|
|
17079
14586
|
workspaceDir: this.config.workspaceDir,
|
|
17080
14587
|
mode: this.config.runnerMode,
|
|
17081
|
-
packExecution: this.config.packExecution,
|
|
17082
14588
|
isAuto: this.config.isAuto
|
|
17083
14589
|
};
|
|
17084
14590
|
const bridge = new QueryBridge(this.connection, this.mode, runnerConfig, {
|
|
@@ -17457,9 +14963,6 @@ function unshallowRepo(workspaceDir) {
|
|
|
17457
14963
|
}
|
|
17458
14964
|
|
|
17459
14965
|
export {
|
|
17460
|
-
DEFAULT_SONNET_MODEL,
|
|
17461
|
-
RUNNER_MODES,
|
|
17462
|
-
parsePackExecution,
|
|
17463
14966
|
isPermissionDeniedError,
|
|
17464
14967
|
buildSynthesizedCredentials,
|
|
17465
14968
|
claudeJsonPath,
|