@rallycry/conveyor-agent 7.0.7 → 7.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7RSDCWEI.js → chunk-LKO3CBJU.js} +677 -251
- package/dist/chunk-LKO3CBJU.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7RSDCWEI.js.map +0 -1
|
@@ -15,6 +15,8 @@ var AgentConnection = class _AgentConnection {
|
|
|
15
15
|
eventBuffer = [];
|
|
16
16
|
flushTimer = null;
|
|
17
17
|
lastEmittedStatus = null;
|
|
18
|
+
// Pending answer resolvers for askUserQuestion room-event fallback
|
|
19
|
+
pendingAnswerResolvers = /* @__PURE__ */ new Map();
|
|
18
20
|
// Dedup: suppress near-identical messages within a short window
|
|
19
21
|
recentMessages = [];
|
|
20
22
|
static DEDUP_WINDOW_MS = 3e4;
|
|
@@ -90,8 +92,14 @@ var AgentConnection = class _AgentConnection {
|
|
|
90
92
|
extraHeaders: { "ngrok-skip-browser-warning": "true" }
|
|
91
93
|
});
|
|
92
94
|
this.socket.on("session:message", (msg) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
const incoming = {
|
|
96
|
+
content: msg.content,
|
|
97
|
+
userId: msg.userId,
|
|
98
|
+
...msg.source && { source: msg.source },
|
|
99
|
+
...msg.files && { files: msg.files }
|
|
100
|
+
};
|
|
101
|
+
if (this.messageCallback) this.messageCallback(incoming);
|
|
102
|
+
else this.earlyMessages.push(incoming);
|
|
95
103
|
});
|
|
96
104
|
this.socket.on("session:stop", () => {
|
|
97
105
|
if (this.stopCallback) this.stopCallback();
|
|
@@ -114,6 +122,13 @@ var AgentConnection = class _AgentConnection {
|
|
|
114
122
|
this.earlyMessages.push({ content: "", userId: "system" });
|
|
115
123
|
}
|
|
116
124
|
});
|
|
125
|
+
this.socket.on(
|
|
126
|
+
"session:answerQuestion",
|
|
127
|
+
(data) => {
|
|
128
|
+
const resolver = this.pendingAnswerResolvers.get(data.requestId);
|
|
129
|
+
if (resolver) resolver(data.answers);
|
|
130
|
+
}
|
|
131
|
+
);
|
|
117
132
|
this.socket.on("agentRunner:updateApiKey", (data) => {
|
|
118
133
|
if (this.apiKeyUpdateCallback) this.apiKeyUpdateCallback(data);
|
|
119
134
|
});
|
|
@@ -152,7 +167,7 @@ var AgentConnection = class _AgentConnection {
|
|
|
152
167
|
});
|
|
153
168
|
}
|
|
154
169
|
disconnect() {
|
|
155
|
-
this.flushEvents();
|
|
170
|
+
void this.flushEvents();
|
|
156
171
|
if (this.socket) {
|
|
157
172
|
this.socket.io.reconnection(false);
|
|
158
173
|
this.socket.removeAllListeners();
|
|
@@ -239,9 +254,9 @@ var AgentConnection = class _AgentConnection {
|
|
|
239
254
|
this.apiKeyUpdateCallback = callback;
|
|
240
255
|
}
|
|
241
256
|
// ── Convenience methods (thin wrappers around call / emit) ─────────
|
|
242
|
-
emitStatus(status) {
|
|
257
|
+
async emitStatus(status) {
|
|
243
258
|
this.lastEmittedStatus = status;
|
|
244
|
-
this.flushEvents();
|
|
259
|
+
await this.flushEvents();
|
|
245
260
|
void this.call("reportAgentStatus", {
|
|
246
261
|
sessionId: this.config.sessionId,
|
|
247
262
|
status
|
|
@@ -364,13 +379,20 @@ var AgentConnection = class _AgentConnection {
|
|
|
364
379
|
${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o.description}`).join("\n") : ""}`
|
|
365
380
|
).join("\n\n");
|
|
366
381
|
const requestId = crypto.randomUUID();
|
|
367
|
-
const
|
|
382
|
+
const roomEventPromise = new Promise((resolve2) => {
|
|
383
|
+
this.pendingAnswerResolvers.set(requestId, resolve2);
|
|
384
|
+
});
|
|
385
|
+
const rpcPromise = this.call("askUserQuestion", {
|
|
368
386
|
sessionId: this.config.sessionId,
|
|
369
387
|
question: questionText,
|
|
370
388
|
requestId,
|
|
371
389
|
questions
|
|
372
|
-
});
|
|
373
|
-
|
|
390
|
+
}).then((res) => res.answers);
|
|
391
|
+
try {
|
|
392
|
+
return await Promise.race([rpcPromise, roomEventPromise]);
|
|
393
|
+
} finally {
|
|
394
|
+
this.pendingAnswerResolvers.delete(requestId);
|
|
395
|
+
}
|
|
374
396
|
}
|
|
375
397
|
// ── Typed service method wrappers ───────────────────────────────────
|
|
376
398
|
getTaskProperties() {
|
|
@@ -408,10 +430,10 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
|
|
|
408
430
|
if (!this.socket) return;
|
|
409
431
|
this.eventBuffer.push({ event });
|
|
410
432
|
if (!this.flushTimer) {
|
|
411
|
-
this.flushTimer = setTimeout(() => this.flushEvents(), EVENT_BATCH_MS);
|
|
433
|
+
this.flushTimer = setTimeout(() => void this.flushEvents(), EVENT_BATCH_MS);
|
|
412
434
|
}
|
|
413
435
|
}
|
|
414
|
-
flushEvents() {
|
|
436
|
+
async flushEvents() {
|
|
415
437
|
if (this.flushTimer) {
|
|
416
438
|
clearTimeout(this.flushTimer);
|
|
417
439
|
this.flushTimer = null;
|
|
@@ -419,7 +441,7 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
|
|
|
419
441
|
if (!this.socket || this.eventBuffer.length === 0) return;
|
|
420
442
|
const events = this.eventBuffer.map((entry) => entry.event);
|
|
421
443
|
this.eventBuffer = [];
|
|
422
|
-
this.call("emitAgentEvent", { sessionId: this.config.sessionId, events }).catch(() => {
|
|
444
|
+
await this.call("emitAgentEvent", { sessionId: this.config.sessionId, events }).catch(() => {
|
|
423
445
|
});
|
|
424
446
|
}
|
|
425
447
|
};
|
|
@@ -863,6 +885,472 @@ var PlanSync = class {
|
|
|
863
885
|
}
|
|
864
886
|
};
|
|
865
887
|
|
|
888
|
+
// ../shared/dist/index.js
|
|
889
|
+
import { z } from "zod";
|
|
890
|
+
var MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024;
|
|
891
|
+
var EMBED_THRESHOLD_IMAGES = 5 * 1024 * 1024;
|
|
892
|
+
var EMBED_THRESHOLD_TEXT = 2 * 1024 * 1024;
|
|
893
|
+
var AgentHeartbeatSchema = z.object({
|
|
894
|
+
sessionId: z.string().optional(),
|
|
895
|
+
timestamp: z.string(),
|
|
896
|
+
status: z.enum(["active", "idle", "building"]),
|
|
897
|
+
currentAction: z.string().optional()
|
|
898
|
+
});
|
|
899
|
+
var CreatePRInputSchema = z.object({
|
|
900
|
+
title: z.string().min(1),
|
|
901
|
+
body: z.string(),
|
|
902
|
+
head: z.string().optional(),
|
|
903
|
+
base: z.string().optional()
|
|
904
|
+
});
|
|
905
|
+
var PostToChatInputSchema = z.object({
|
|
906
|
+
message: z.string().min(1),
|
|
907
|
+
type: z.enum(["message", "question", "update"]).optional().default("message")
|
|
908
|
+
});
|
|
909
|
+
var GetTaskContextRequestSchema = z.object({
|
|
910
|
+
sessionId: z.string(),
|
|
911
|
+
includeHistory: z.boolean().optional().default(false)
|
|
912
|
+
});
|
|
913
|
+
var GetChatMessagesRequestSchema = z.object({
|
|
914
|
+
sessionId: z.string(),
|
|
915
|
+
limit: z.number().int().positive().optional().default(50),
|
|
916
|
+
offset: z.number().int().nonnegative().optional().default(0)
|
|
917
|
+
});
|
|
918
|
+
var GetTaskFilesRequestSchema = z.object({
|
|
919
|
+
sessionId: z.string()
|
|
920
|
+
});
|
|
921
|
+
var GetTaskFileRequestSchema = z.object({
|
|
922
|
+
sessionId: z.string(),
|
|
923
|
+
fileId: z.string()
|
|
924
|
+
});
|
|
925
|
+
var GetTaskRequestSchema = z.object({
|
|
926
|
+
sessionId: z.string(),
|
|
927
|
+
taskSlugOrId: z.string()
|
|
928
|
+
});
|
|
929
|
+
var GetCliHistoryRequestSchema = z.object({
|
|
930
|
+
sessionId: z.string(),
|
|
931
|
+
limit: z.number().int().positive().optional().default(100),
|
|
932
|
+
source: z.enum(["agent", "application"]).optional()
|
|
933
|
+
});
|
|
934
|
+
var ListSubtasksRequestSchema = z.object({
|
|
935
|
+
sessionId: z.string()
|
|
936
|
+
});
|
|
937
|
+
var GetDependenciesRequestSchema = z.object({
|
|
938
|
+
sessionId: z.string()
|
|
939
|
+
});
|
|
940
|
+
var GetSuggestionsRequestSchema = z.object({
|
|
941
|
+
sessionId: z.string()
|
|
942
|
+
});
|
|
943
|
+
var GetTaskIncidentsRequestSchema = z.object({
|
|
944
|
+
sessionId: z.string()
|
|
945
|
+
});
|
|
946
|
+
var CreatePullRequestRequestSchema = CreatePRInputSchema.extend({ sessionId: z.string() });
|
|
947
|
+
var UpdateTaskStatusRequestSchema = z.object({
|
|
948
|
+
sessionId: z.string(),
|
|
949
|
+
status: z.string(),
|
|
950
|
+
force: z.boolean().optional().default(false)
|
|
951
|
+
});
|
|
952
|
+
var StoreSessionIdRequestSchema = z.object({
|
|
953
|
+
sessionId: z.string(),
|
|
954
|
+
sdkSessionId: z.string()
|
|
955
|
+
});
|
|
956
|
+
var TrackSpendingRequestSchema = z.object({
|
|
957
|
+
sessionId: z.string(),
|
|
958
|
+
inputTokens: z.number().int().nonnegative(),
|
|
959
|
+
outputTokens: z.number().int().nonnegative(),
|
|
960
|
+
costUsd: z.number().nonnegative(),
|
|
961
|
+
model: z.string()
|
|
962
|
+
});
|
|
963
|
+
var SessionStartRequestSchema = z.object({
|
|
964
|
+
sessionId: z.string(),
|
|
965
|
+
agentVersion: z.string(),
|
|
966
|
+
capabilities: z.array(z.string())
|
|
967
|
+
});
|
|
968
|
+
var SessionStopRequestSchema = z.object({
|
|
969
|
+
sessionId: z.string(),
|
|
970
|
+
reason: z.string().optional()
|
|
971
|
+
});
|
|
972
|
+
var ConnectAgentRequestSchema = z.object({
|
|
973
|
+
sessionId: z.string()
|
|
974
|
+
});
|
|
975
|
+
var ReportAgentStatusRequestSchema = z.object({
|
|
976
|
+
sessionId: z.string(),
|
|
977
|
+
status: z.string()
|
|
978
|
+
});
|
|
979
|
+
var CreateSubtaskRequestSchema = z.object({
|
|
980
|
+
sessionId: z.string(),
|
|
981
|
+
title: z.string().min(1),
|
|
982
|
+
description: z.string().optional(),
|
|
983
|
+
plan: z.string().optional(),
|
|
984
|
+
storyPointValue: z.number().int().positive().optional(),
|
|
985
|
+
ordinal: z.number().int().nonnegative().optional()
|
|
986
|
+
});
|
|
987
|
+
var UpdateSubtaskRequestSchema = z.object({
|
|
988
|
+
sessionId: z.string(),
|
|
989
|
+
subtaskId: z.string(),
|
|
990
|
+
title: z.string().min(1).optional(),
|
|
991
|
+
description: z.string().optional(),
|
|
992
|
+
plan: z.string().optional(),
|
|
993
|
+
status: z.string().optional(),
|
|
994
|
+
storyPointValue: z.number().int().positive().optional()
|
|
995
|
+
});
|
|
996
|
+
var DeleteSubtaskRequestSchema = z.object({
|
|
997
|
+
sessionId: z.string(),
|
|
998
|
+
subtaskId: z.string()
|
|
999
|
+
});
|
|
1000
|
+
var SearchIncidentsRequestSchema = z.object({
|
|
1001
|
+
sessionId: z.string(),
|
|
1002
|
+
status: z.string().optional(),
|
|
1003
|
+
source: z.string().optional()
|
|
1004
|
+
});
|
|
1005
|
+
var QueryGcpLogsRequestSchema = z.object({
|
|
1006
|
+
sessionId: z.string(),
|
|
1007
|
+
filter: z.string().optional(),
|
|
1008
|
+
startTime: z.string().optional(),
|
|
1009
|
+
endTime: z.string().optional(),
|
|
1010
|
+
severity: z.string().optional(),
|
|
1011
|
+
pageSize: z.number().int().positive().optional().default(100)
|
|
1012
|
+
});
|
|
1013
|
+
var GetTaskPropertiesRequestSchema = z.object({
|
|
1014
|
+
sessionId: z.string()
|
|
1015
|
+
});
|
|
1016
|
+
var UpdateTaskFieldsRequestSchema = z.object({
|
|
1017
|
+
sessionId: z.string(),
|
|
1018
|
+
plan: z.string().optional(),
|
|
1019
|
+
description: z.string().optional()
|
|
1020
|
+
});
|
|
1021
|
+
var UpdateTaskPropertiesRequestSchema = z.object({
|
|
1022
|
+
sessionId: z.string(),
|
|
1023
|
+
title: z.string().optional(),
|
|
1024
|
+
storyPointValue: z.number().int().positive().optional(),
|
|
1025
|
+
tagIds: z.array(z.string()).optional()
|
|
1026
|
+
});
|
|
1027
|
+
var ListIconsRequestSchema = z.object({
|
|
1028
|
+
sessionId: z.string()
|
|
1029
|
+
});
|
|
1030
|
+
var GenerateTaskIconRequestSchema = z.object({
|
|
1031
|
+
sessionId: z.string(),
|
|
1032
|
+
prompt: z.string().min(1),
|
|
1033
|
+
aspectRatio: z.string().optional()
|
|
1034
|
+
});
|
|
1035
|
+
var SearchFaIconsRequestSchema = z.object({
|
|
1036
|
+
sessionId: z.string(),
|
|
1037
|
+
query: z.string().min(1),
|
|
1038
|
+
first: z.number().int().positive().optional()
|
|
1039
|
+
});
|
|
1040
|
+
var PickFaIconRequestSchema = z.object({
|
|
1041
|
+
sessionId: z.string(),
|
|
1042
|
+
fontAwesomeId: z.string().min(1),
|
|
1043
|
+
fontAwesomeStyle: z.string().optional()
|
|
1044
|
+
});
|
|
1045
|
+
var CreateFollowUpTaskRequestSchema = z.object({
|
|
1046
|
+
sessionId: z.string(),
|
|
1047
|
+
title: z.string().min(1),
|
|
1048
|
+
description: z.string().optional(),
|
|
1049
|
+
plan: z.string().optional(),
|
|
1050
|
+
storyPointValue: z.number().int().positive().optional()
|
|
1051
|
+
});
|
|
1052
|
+
var AddDependencyRequestSchema = z.object({
|
|
1053
|
+
sessionId: z.string(),
|
|
1054
|
+
dependsOnSlugOrId: z.string()
|
|
1055
|
+
});
|
|
1056
|
+
var RemoveDependencyRequestSchema = z.object({
|
|
1057
|
+
sessionId: z.string(),
|
|
1058
|
+
dependsOnSlugOrId: z.string()
|
|
1059
|
+
});
|
|
1060
|
+
var CreateSuggestionRequestSchema = z.object({
|
|
1061
|
+
sessionId: z.string(),
|
|
1062
|
+
title: z.string().min(1),
|
|
1063
|
+
description: z.string().optional(),
|
|
1064
|
+
tagNames: z.array(z.string()).optional()
|
|
1065
|
+
});
|
|
1066
|
+
var VoteSuggestionRequestSchema = z.object({
|
|
1067
|
+
sessionId: z.string(),
|
|
1068
|
+
suggestionId: z.string(),
|
|
1069
|
+
value: z.union([z.literal(1), z.literal(-1)])
|
|
1070
|
+
});
|
|
1071
|
+
var ScaleUpResourcesRequestSchema = z.object({
|
|
1072
|
+
sessionId: z.string(),
|
|
1073
|
+
tier: z.string(),
|
|
1074
|
+
reason: z.string().optional()
|
|
1075
|
+
});
|
|
1076
|
+
var TriggerIdentificationRequestSchema = z.object({
|
|
1077
|
+
sessionId: z.string()
|
|
1078
|
+
});
|
|
1079
|
+
var SubmitCodeReviewResultRequestSchema = z.object({
|
|
1080
|
+
sessionId: z.string(),
|
|
1081
|
+
approved: z.boolean(),
|
|
1082
|
+
content: z.string()
|
|
1083
|
+
});
|
|
1084
|
+
var StartChildCloudBuildRequestSchema = z.object({
|
|
1085
|
+
sessionId: z.string(),
|
|
1086
|
+
childTaskId: z.string()
|
|
1087
|
+
});
|
|
1088
|
+
var StopChildBuildRequestSchema = z.object({
|
|
1089
|
+
sessionId: z.string(),
|
|
1090
|
+
childTaskId: z.string()
|
|
1091
|
+
});
|
|
1092
|
+
var ApproveAndMergePRRequestSchema = z.object({
|
|
1093
|
+
sessionId: z.string(),
|
|
1094
|
+
childTaskId: z.string()
|
|
1095
|
+
});
|
|
1096
|
+
var PostChildChatMessageRequestSchema = z.object({
|
|
1097
|
+
sessionId: z.string(),
|
|
1098
|
+
childTaskId: z.string(),
|
|
1099
|
+
message: z.string().min(1)
|
|
1100
|
+
});
|
|
1101
|
+
var UpdateChildStatusRequestSchema = z.object({
|
|
1102
|
+
sessionId: z.string(),
|
|
1103
|
+
childTaskId: z.string(),
|
|
1104
|
+
status: z.string()
|
|
1105
|
+
});
|
|
1106
|
+
var RegisterProjectAgentRequestSchema = z.object({
|
|
1107
|
+
projectId: z.string(),
|
|
1108
|
+
capabilities: z.array(z.string())
|
|
1109
|
+
});
|
|
1110
|
+
var ProjectRunnerHeartbeatRequestSchema = z.object({
|
|
1111
|
+
projectId: z.string()
|
|
1112
|
+
});
|
|
1113
|
+
var ReportProjectAgentStatusRequestSchema = z.object({
|
|
1114
|
+
projectId: z.string(),
|
|
1115
|
+
status: z.enum(["busy", "idle"]),
|
|
1116
|
+
activeChatId: z.string().nullish(),
|
|
1117
|
+
activeTaskId: z.string().nullish(),
|
|
1118
|
+
activeBranch: z.string().nullish()
|
|
1119
|
+
});
|
|
1120
|
+
var DisconnectProjectRunnerRequestSchema = z.object({
|
|
1121
|
+
projectId: z.string()
|
|
1122
|
+
});
|
|
1123
|
+
var GetProjectAgentContextRequestSchema = z.object({
|
|
1124
|
+
projectId: z.string()
|
|
1125
|
+
});
|
|
1126
|
+
var GetProjectChatHistoryRequestSchema = z.object({
|
|
1127
|
+
projectId: z.string(),
|
|
1128
|
+
limit: z.number().int().positive().optional().default(50),
|
|
1129
|
+
chatId: z.string().optional()
|
|
1130
|
+
});
|
|
1131
|
+
var PostProjectAgentMessageRequestSchema = z.object({
|
|
1132
|
+
projectId: z.string(),
|
|
1133
|
+
content: z.string().min(1),
|
|
1134
|
+
chatId: z.string().optional()
|
|
1135
|
+
});
|
|
1136
|
+
var ListProjectTasksRequestSchema = z.object({
|
|
1137
|
+
projectId: z.string(),
|
|
1138
|
+
status: z.string().optional(),
|
|
1139
|
+
assigneeId: z.string().optional(),
|
|
1140
|
+
limit: z.number().int().positive().optional().default(50)
|
|
1141
|
+
});
|
|
1142
|
+
var GetProjectTaskRequestSchema = z.object({
|
|
1143
|
+
projectId: z.string(),
|
|
1144
|
+
taskId: z.string()
|
|
1145
|
+
});
|
|
1146
|
+
var SearchProjectTasksRequestSchema = z.object({
|
|
1147
|
+
projectId: z.string(),
|
|
1148
|
+
tagNames: z.array(z.string()).optional(),
|
|
1149
|
+
searchQuery: z.string().optional(),
|
|
1150
|
+
statusFilters: z.array(z.string()).optional(),
|
|
1151
|
+
limit: z.number().int().positive().optional().default(20)
|
|
1152
|
+
});
|
|
1153
|
+
var ListProjectTagsRequestSchema = z.object({
|
|
1154
|
+
projectId: z.string()
|
|
1155
|
+
});
|
|
1156
|
+
var GetProjectSummaryRequestSchema = z.object({
|
|
1157
|
+
projectId: z.string()
|
|
1158
|
+
});
|
|
1159
|
+
var CreateProjectTaskRequestSchema = z.object({
|
|
1160
|
+
projectId: z.string(),
|
|
1161
|
+
title: z.string().min(1),
|
|
1162
|
+
description: z.string().optional(),
|
|
1163
|
+
plan: z.string().optional(),
|
|
1164
|
+
status: z.string().optional(),
|
|
1165
|
+
isBug: z.boolean().optional()
|
|
1166
|
+
});
|
|
1167
|
+
var UpdateProjectTaskRequestSchema = z.object({
|
|
1168
|
+
projectId: z.string(),
|
|
1169
|
+
taskId: z.string(),
|
|
1170
|
+
title: z.string().optional(),
|
|
1171
|
+
description: z.string().optional(),
|
|
1172
|
+
plan: z.string().optional(),
|
|
1173
|
+
status: z.string().optional(),
|
|
1174
|
+
assignedUserId: z.string().nullish()
|
|
1175
|
+
});
|
|
1176
|
+
var ReportProjectAgentEventRequestSchema = z.object({
|
|
1177
|
+
projectId: z.string(),
|
|
1178
|
+
event: z.record(z.string(), z.unknown())
|
|
1179
|
+
});
|
|
1180
|
+
var ReportTagAuditProgressRequestSchema = z.object({
|
|
1181
|
+
projectId: z.string(),
|
|
1182
|
+
requestId: z.string(),
|
|
1183
|
+
activity: z.object({
|
|
1184
|
+
tool: z.string(),
|
|
1185
|
+
input: z.string().optional(),
|
|
1186
|
+
timestamp: z.string()
|
|
1187
|
+
})
|
|
1188
|
+
});
|
|
1189
|
+
var ReportTagAuditResultRequestSchema = z.object({
|
|
1190
|
+
projectId: z.string(),
|
|
1191
|
+
requestId: z.string(),
|
|
1192
|
+
recommendations: z.array(z.record(z.string(), z.unknown())),
|
|
1193
|
+
summary: z.string(),
|
|
1194
|
+
complete: z.boolean()
|
|
1195
|
+
});
|
|
1196
|
+
var ReportNewCommitsDetectedRequestSchema = z.object({
|
|
1197
|
+
projectId: z.string(),
|
|
1198
|
+
commits: z.array(
|
|
1199
|
+
z.object({
|
|
1200
|
+
sha: z.string(),
|
|
1201
|
+
message: z.string(),
|
|
1202
|
+
author: z.string()
|
|
1203
|
+
})
|
|
1204
|
+
),
|
|
1205
|
+
branch: z.string()
|
|
1206
|
+
});
|
|
1207
|
+
var ReportEnvironmentReadyRequestSchema = z.object({
|
|
1208
|
+
projectId: z.string(),
|
|
1209
|
+
branch: z.string(),
|
|
1210
|
+
setupComplete: z.boolean(),
|
|
1211
|
+
startCommandRunning: z.boolean()
|
|
1212
|
+
});
|
|
1213
|
+
var ReportEnvSwitchProgressRequestSchema = z.object({
|
|
1214
|
+
projectId: z.string(),
|
|
1215
|
+
step: z.string(),
|
|
1216
|
+
progress: z.number(),
|
|
1217
|
+
message: z.string().optional()
|
|
1218
|
+
});
|
|
1219
|
+
var ForwardProjectChatMessageRequestSchema = z.object({
|
|
1220
|
+
projectId: z.string(),
|
|
1221
|
+
chatId: z.string(),
|
|
1222
|
+
content: z.string().min(1),
|
|
1223
|
+
targetUserId: z.string().optional()
|
|
1224
|
+
});
|
|
1225
|
+
var CancelQueuedProjectMessageRequestSchema = z.object({
|
|
1226
|
+
projectId: z.string(),
|
|
1227
|
+
index: z.number().int().nonnegative()
|
|
1228
|
+
});
|
|
1229
|
+
var GetProjectCliHistoryRequestSchema = z.object({
|
|
1230
|
+
projectId: z.string(),
|
|
1231
|
+
limit: z.number().int().positive().optional().default(50),
|
|
1232
|
+
source: z.string().optional()
|
|
1233
|
+
});
|
|
1234
|
+
var PostToProjectTaskChatRequestSchema = z.object({
|
|
1235
|
+
projectId: z.string(),
|
|
1236
|
+
taskId: z.string(),
|
|
1237
|
+
content: z.string()
|
|
1238
|
+
});
|
|
1239
|
+
var GetProjectTaskCliRequestSchema = z.object({
|
|
1240
|
+
projectId: z.string(),
|
|
1241
|
+
taskId: z.string(),
|
|
1242
|
+
limit: z.number().int().positive().optional().default(50),
|
|
1243
|
+
source: z.string().optional()
|
|
1244
|
+
});
|
|
1245
|
+
var StartProjectBuildRequestSchema = z.object({
|
|
1246
|
+
projectId: z.string(),
|
|
1247
|
+
taskId: z.string()
|
|
1248
|
+
});
|
|
1249
|
+
var StopProjectBuildRequestSchema = z.object({
|
|
1250
|
+
projectId: z.string(),
|
|
1251
|
+
taskId: z.string()
|
|
1252
|
+
});
|
|
1253
|
+
var ApproveProjectMergePRRequestSchema = z.object({
|
|
1254
|
+
projectId: z.string(),
|
|
1255
|
+
childTaskId: z.string()
|
|
1256
|
+
});
|
|
1257
|
+
var GetAgentStatusRequestSchema = z.object({
|
|
1258
|
+
taskId: z.string()
|
|
1259
|
+
});
|
|
1260
|
+
var GetUiCliHistoryRequestSchema = z.object({
|
|
1261
|
+
taskId: z.string()
|
|
1262
|
+
});
|
|
1263
|
+
var SendSoftStopRequestSchema = z.object({
|
|
1264
|
+
taskId: z.string().optional(),
|
|
1265
|
+
projectId: z.string().optional()
|
|
1266
|
+
});
|
|
1267
|
+
var FlushTaskQueueRequestSchema = z.object({
|
|
1268
|
+
taskId: z.string()
|
|
1269
|
+
});
|
|
1270
|
+
var FlushProjectQueueRequestSchema = z.object({
|
|
1271
|
+
projectId: z.string()
|
|
1272
|
+
});
|
|
1273
|
+
var CancelTaskQueuedMessageRequestSchema = z.object({
|
|
1274
|
+
taskId: z.string(),
|
|
1275
|
+
messageId: z.string()
|
|
1276
|
+
});
|
|
1277
|
+
var FlushSingleQueuedMessageRequestSchema = z.object({
|
|
1278
|
+
taskId: z.string(),
|
|
1279
|
+
messageId: z.string()
|
|
1280
|
+
});
|
|
1281
|
+
var FlushSingleProjectQueuedMessageRequestSchema = z.object({
|
|
1282
|
+
projectId: z.string(),
|
|
1283
|
+
index: z.number().int().nonnegative()
|
|
1284
|
+
});
|
|
1285
|
+
var AnswerAgentQuestionRequestSchema = z.object({
|
|
1286
|
+
taskId: z.string(),
|
|
1287
|
+
requestId: z.string(),
|
|
1288
|
+
answers: z.record(z.string(), z.string())
|
|
1289
|
+
});
|
|
1290
|
+
var ClearAgentTodosRequestSchema = z.object({
|
|
1291
|
+
taskId: z.string()
|
|
1292
|
+
});
|
|
1293
|
+
var AgentQuestionOptionSchema = z.object({
|
|
1294
|
+
label: z.string(),
|
|
1295
|
+
description: z.string(),
|
|
1296
|
+
preview: z.string().optional()
|
|
1297
|
+
});
|
|
1298
|
+
var AgentQuestionSchema = z.object({
|
|
1299
|
+
question: z.string(),
|
|
1300
|
+
header: z.string(),
|
|
1301
|
+
options: z.array(AgentQuestionOptionSchema),
|
|
1302
|
+
multiSelect: z.boolean().optional()
|
|
1303
|
+
});
|
|
1304
|
+
var AskUserQuestionRequestSchema = z.object({
|
|
1305
|
+
sessionId: z.string(),
|
|
1306
|
+
question: z.string().min(1),
|
|
1307
|
+
requestId: z.string().min(1),
|
|
1308
|
+
questions: z.array(AgentQuestionSchema).min(1)
|
|
1309
|
+
});
|
|
1310
|
+
var RefreshGithubTokenRequestSchema = z.object({
|
|
1311
|
+
sessionId: z.string()
|
|
1312
|
+
});
|
|
1313
|
+
var RefreshGithubTokenResponseSchema = z.object({
|
|
1314
|
+
token: z.string()
|
|
1315
|
+
});
|
|
1316
|
+
var CreatePRResponseSchema = z.object({
|
|
1317
|
+
prNumber: z.number().int().positive(),
|
|
1318
|
+
prUrl: z.string().url()
|
|
1319
|
+
});
|
|
1320
|
+
var PostToChatResponseSchema = z.object({
|
|
1321
|
+
messageId: z.string()
|
|
1322
|
+
});
|
|
1323
|
+
var UpdateTaskStatusResponseSchema = z.object({
|
|
1324
|
+
taskId: z.string(),
|
|
1325
|
+
status: z.string()
|
|
1326
|
+
});
|
|
1327
|
+
var StoreSessionIdResponseSchema = z.object({
|
|
1328
|
+
success: z.boolean()
|
|
1329
|
+
});
|
|
1330
|
+
var HeartbeatResponseSchema = z.object({
|
|
1331
|
+
acknowledged: z.boolean()
|
|
1332
|
+
});
|
|
1333
|
+
var SessionStartResponseSchema = z.object({
|
|
1334
|
+
sessionId: z.string(),
|
|
1335
|
+
startedAt: z.string()
|
|
1336
|
+
});
|
|
1337
|
+
var SessionStopResponseSchema = z.object({
|
|
1338
|
+
sessionId: z.string(),
|
|
1339
|
+
stoppedAt: z.string()
|
|
1340
|
+
});
|
|
1341
|
+
var DeleteSubtaskResponseSchema = z.object({
|
|
1342
|
+
deleted: z.boolean()
|
|
1343
|
+
});
|
|
1344
|
+
var RegisterProjectAgentResponseSchema = z.object({
|
|
1345
|
+
registered: z.boolean(),
|
|
1346
|
+
agentName: z.string(),
|
|
1347
|
+
agentInstructions: z.string(),
|
|
1348
|
+
model: z.string(),
|
|
1349
|
+
agentSettings: z.record(z.string(), z.unknown()).nullable(),
|
|
1350
|
+
branchSwitchCommand: z.string().nullable()
|
|
1351
|
+
});
|
|
1352
|
+
var CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set(["ci_failure"]);
|
|
1353
|
+
|
|
866
1354
|
// src/execution/pack-runner-prompt.ts
|
|
867
1355
|
function findLastAgentMessageIndex(history) {
|
|
868
1356
|
for (let i = history.length - 1; i >= 0; i--) {
|
|
@@ -1178,10 +1666,9 @@ function buildPropertyInstructions(context) {
|
|
|
1178
1666
|
``,
|
|
1179
1667
|
`### Proactive Property Management`,
|
|
1180
1668
|
`As you plan this task, proactively fill in task properties when you have enough context:`,
|
|
1181
|
-
`- Use update_task_properties to set any combination of: title, story points,
|
|
1669
|
+
`- Use update_task_properties to set any combination of: title, story points, and tags`,
|
|
1182
1670
|
`- You can update all properties at once or just one at a time as needed`,
|
|
1183
|
-
`-
|
|
1184
|
-
` Only call generate_task_icon if no existing icon is a good fit.`,
|
|
1671
|
+
`- Icons are assigned automatically during identification \u2014 do not set icons manually`,
|
|
1185
1672
|
``,
|
|
1186
1673
|
`Don't wait for the user to ask \u2014 fill these in naturally as the plan takes shape.`,
|
|
1187
1674
|
`If the user adjusts the plan significantly, update the properties to match.`
|
|
@@ -1219,22 +1706,22 @@ function buildDiscoveryPrompt(context) {
|
|
|
1219
1706
|
`- If you identify code changes needed, describe them in the plan instead of implementing them`,
|
|
1220
1707
|
`- You can create and manage subtasks`,
|
|
1221
1708
|
`- Goal: collaborate with the user to create a clear plan`,
|
|
1222
|
-
`- Proactively fill task properties (SP, tags
|
|
1709
|
+
`- Proactively fill task properties (SP, tags) as the plan takes shape`,
|
|
1223
1710
|
``,
|
|
1224
1711
|
`### Planning Checklist (complete ALL before calling ExitPlanMode)`,
|
|
1225
1712
|
`Your PRIMARY goal is to create a thorough plan. Complete these steps in order:`,
|
|
1226
1713
|
`1. Read the task description and chat history \u2014 respond to what's been discussed`,
|
|
1227
1714
|
`2. Explore the codebase to understand relevant files and patterns`,
|
|
1228
1715
|
`3. Save a detailed plan via \`update_task\``,
|
|
1229
|
-
`4. Set story points, tags, and title via \`update_task_properties
|
|
1716
|
+
`4. Set story points, tags, and title via \`update_task_properties\` (icon is set automatically)`,
|
|
1230
1717
|
`5. Discuss the plan with the team if they're engaged, incorporate feedback`,
|
|
1231
1718
|
`6. THEN call ExitPlanMode \u2014 it is the LAST step, not the first`,
|
|
1232
1719
|
``,
|
|
1233
1720
|
`### Self-Identification Tools`,
|
|
1234
1721
|
`Use these MCP tools to set your own task properties:`,
|
|
1235
1722
|
`- \`update_task\` \u2014 save your plan and description`,
|
|
1236
|
-
`- \`update_task_properties\` \u2014 set title, story points,
|
|
1237
|
-
|
|
1723
|
+
`- \`update_task_properties\` \u2014 set title, story points, and tags (any combination)`,
|
|
1724
|
+
`Note: Icons are assigned automatically during identification after planning is complete.`,
|
|
1238
1725
|
``,
|
|
1239
1726
|
`### Tags & Context`,
|
|
1240
1727
|
`- Early in discovery, identify relevant project tags that match this task's domain`,
|
|
@@ -1451,6 +1938,9 @@ function buildCodeReviewPrompt() {
|
|
|
1451
1938
|
`- Explain what's wrong and suggest fixes`,
|
|
1452
1939
|
`- Focus on substantive issues, not style nitpicks (linting handles that)`,
|
|
1453
1940
|
``,
|
|
1941
|
+
`## Previous Review Feedback`,
|
|
1942
|
+
`If previous review feedback is present in the chat history, verify those specific issues were addressed before raising new concerns. Focus on whether the requested changes were implemented correctly.`,
|
|
1943
|
+
``,
|
|
1454
1944
|
`## Rules`,
|
|
1455
1945
|
`- You are READ-ONLY. Do NOT modify any files.`,
|
|
1456
1946
|
`- Do NOT re-review things CI already validates (formatting, lint rules).`,
|
|
@@ -2054,7 +2544,7 @@ async function buildInitialPrompt(mode, context, isAuto, agentMode) {
|
|
|
2054
2544
|
}
|
|
2055
2545
|
|
|
2056
2546
|
// src/tools/common-tools.ts
|
|
2057
|
-
import { z } from "zod";
|
|
2547
|
+
import { z as z2 } from "zod";
|
|
2058
2548
|
|
|
2059
2549
|
// src/tools/helpers.ts
|
|
2060
2550
|
function textResult(text) {
|
|
@@ -2088,8 +2578,8 @@ function buildReadTaskChatTool(connection) {
|
|
|
2088
2578
|
"read_task_chat",
|
|
2089
2579
|
"Read recent messages from a task chat. Omit task_id to read the current task's chat, or provide a child task ID to read a child's chat.",
|
|
2090
2580
|
{
|
|
2091
|
-
limit:
|
|
2092
|
-
task_id:
|
|
2581
|
+
limit: z2.number().optional().describe("Number of recent messages to fetch (default 20)"),
|
|
2582
|
+
task_id: z2.string().optional().describe("Child task ID to read chat from. Omit to read the current task's chat.")
|
|
2093
2583
|
},
|
|
2094
2584
|
async ({ limit, task_id }) => {
|
|
2095
2585
|
try {
|
|
@@ -2133,7 +2623,7 @@ function buildGetTaskTool(connection) {
|
|
|
2133
2623
|
"get_task",
|
|
2134
2624
|
"Look up a task by slug or ID to get its title, description, plan, and status",
|
|
2135
2625
|
{
|
|
2136
|
-
slug_or_id:
|
|
2626
|
+
slug_or_id: z2.string().describe("The task slug (e.g. 'my-task') or CUID")
|
|
2137
2627
|
},
|
|
2138
2628
|
async ({ slug_or_id }) => {
|
|
2139
2629
|
try {
|
|
@@ -2156,9 +2646,9 @@ function buildGetTaskCliTool(connection) {
|
|
|
2156
2646
|
"get_task_cli",
|
|
2157
2647
|
"Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events. Use 'source' to filter: 'agent' for agent reasoning/tool calls only, 'application' for setup/dev-server output only.",
|
|
2158
2648
|
{
|
|
2159
|
-
task_id:
|
|
2160
|
-
source:
|
|
2161
|
-
limit:
|
|
2649
|
+
task_id: z2.string().optional().describe("Task ID or slug. Omit to read logs from the current task."),
|
|
2650
|
+
source: z2.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
|
|
2651
|
+
limit: z2.number().optional().describe("Max number of log entries to return (default 50, max 500).")
|
|
2162
2652
|
},
|
|
2163
2653
|
async ({ task_id, source, limit }) => {
|
|
2164
2654
|
try {
|
|
@@ -2218,7 +2708,7 @@ function buildGetTaskFileTool(connection) {
|
|
|
2218
2708
|
return defineTool(
|
|
2219
2709
|
"get_task_file",
|
|
2220
2710
|
"Get a specific task file's content and download URL by file ID",
|
|
2221
|
-
{ fileId:
|
|
2711
|
+
{ fileId: z2.string().describe("The file ID to retrieve") },
|
|
2222
2712
|
async ({ fileId }) => {
|
|
2223
2713
|
try {
|
|
2224
2714
|
const file = await connection.call("getTaskFile", {
|
|
@@ -2249,8 +2739,8 @@ function buildSearchIncidentsTool(connection) {
|
|
|
2249
2739
|
"search_incidents",
|
|
2250
2740
|
"Search incidents in the current project. Optionally filter by status (Open, Acknowledged, Investigating, Resolved, Closed) or source.",
|
|
2251
2741
|
{
|
|
2252
|
-
status:
|
|
2253
|
-
source:
|
|
2742
|
+
status: z2.string().optional().describe("Filter by incident status"),
|
|
2743
|
+
source: z2.string().optional().describe("Filter by source (e.g., 'conveyor', 'agent', 'build')")
|
|
2254
2744
|
},
|
|
2255
2745
|
async ({ status, source }) => {
|
|
2256
2746
|
try {
|
|
@@ -2274,7 +2764,7 @@ function buildGetTaskIncidentsTool(connection) {
|
|
|
2274
2764
|
"get_task_incidents",
|
|
2275
2765
|
"Get all incidents linked to the current task (or a specified task). Returns full incident details including title, description, severity, status, and source.",
|
|
2276
2766
|
{
|
|
2277
|
-
task_id:
|
|
2767
|
+
task_id: z2.string().optional().describe("Task ID (defaults to current task)")
|
|
2278
2768
|
},
|
|
2279
2769
|
async ({ task_id }) => {
|
|
2280
2770
|
try {
|
|
@@ -2297,12 +2787,12 @@ function buildQueryGcpLogsTool(connection) {
|
|
|
2297
2787
|
"query_gcp_logs",
|
|
2298
2788
|
"Query GCP Cloud Logging for the current project. Returns log entries matching the given filters. Use severity to filter by minimum log level. The project's GCP credentials are used automatically.",
|
|
2299
2789
|
{
|
|
2300
|
-
filter:
|
|
2790
|
+
filter: z2.string().optional().describe(
|
|
2301
2791
|
`Cloud Logging filter expression (e.g., 'resource.type="gce_instance"'). Max 1000 chars.`
|
|
2302
2792
|
),
|
|
2303
|
-
start_time:
|
|
2304
|
-
end_time:
|
|
2305
|
-
severity:
|
|
2793
|
+
start_time: z2.string().optional().describe("Start time in ISO 8601 format (e.g., '2024-01-01T00:00:00Z')"),
|
|
2794
|
+
end_time: z2.string().optional().describe("End time in ISO 8601 format (e.g., '2024-01-02T00:00:00Z')"),
|
|
2795
|
+
severity: z2.enum([
|
|
2306
2796
|
"DEFAULT",
|
|
2307
2797
|
"DEBUG",
|
|
2308
2798
|
"INFO",
|
|
@@ -2313,7 +2803,7 @@ function buildQueryGcpLogsTool(connection) {
|
|
|
2313
2803
|
"ALERT",
|
|
2314
2804
|
"EMERGENCY"
|
|
2315
2805
|
]).optional().describe("Minimum severity level to filter by (default: all levels)"),
|
|
2316
|
-
page_size:
|
|
2806
|
+
page_size: z2.number().optional().describe("Number of log entries to return (default 100, max 500)")
|
|
2317
2807
|
},
|
|
2318
2808
|
async ({ filter, start_time, end_time, severity, page_size }) => {
|
|
2319
2809
|
try {
|
|
@@ -2367,8 +2857,8 @@ function buildGetSuggestionsTool(connection) {
|
|
|
2367
2857
|
"get_suggestions",
|
|
2368
2858
|
"List project suggestions sorted by vote score. Use this to see what the team thinks is important.",
|
|
2369
2859
|
{
|
|
2370
|
-
status:
|
|
2371
|
-
limit:
|
|
2860
|
+
status: z2.string().optional().describe("Filter by status: Open, Accepted, Rejected, Implemented"),
|
|
2861
|
+
limit: z2.number().optional().describe("Max results (default 20)")
|
|
2372
2862
|
},
|
|
2373
2863
|
async ({ status: _status, limit: _limit }) => {
|
|
2374
2864
|
try {
|
|
@@ -2393,8 +2883,8 @@ function buildPostToChatTool(connection) {
|
|
|
2393
2883
|
"post_to_chat",
|
|
2394
2884
|
"Post a message to a task chat. Your normal replies already appear in chat \u2014 only use this for explicit out-of-band updates or posting to a child task's chat.",
|
|
2395
2885
|
{
|
|
2396
|
-
message:
|
|
2397
|
-
task_id:
|
|
2886
|
+
message: z2.string().describe("The message to post to the team"),
|
|
2887
|
+
task_id: z2.string().optional().describe("Child task ID to post to. Omit to post to the current task's chat.")
|
|
2398
2888
|
},
|
|
2399
2889
|
async ({ message, task_id }) => {
|
|
2400
2890
|
try {
|
|
@@ -2421,8 +2911,8 @@ function buildForceUpdateTaskStatusTool(connection) {
|
|
|
2421
2911
|
"force_update_task_status",
|
|
2422
2912
|
"EMERGENCY ONLY: Force-override a task's Kanban status. Status transitions happen automatically (building sets InProgress, PR creation sets ReviewPR, merge sets ReviewDev). Only use this if an automatic transition failed or a task is stuck in the wrong status. Omit task_id to update the current task, or provide a child task ID.",
|
|
2423
2913
|
{
|
|
2424
|
-
status:
|
|
2425
|
-
task_id:
|
|
2914
|
+
status: z2.enum(["InProgress", "ReviewPR", "ReviewDev", "Complete"]).describe("The new status for the task"),
|
|
2915
|
+
task_id: z2.string().optional().describe("Child task ID to update. Omit to update the current task.")
|
|
2426
2916
|
},
|
|
2427
2917
|
async ({ status, task_id }) => {
|
|
2428
2918
|
try {
|
|
@@ -2453,15 +2943,15 @@ function buildCreatePullRequestTool(connection, config) {
|
|
|
2453
2943
|
"create_pull_request",
|
|
2454
2944
|
"Create a GitHub pull request for this task. Automatically stages uncommitted changes, commits them, and pushes before creating the PR. Use this instead of gh CLI or git commands to create PRs.",
|
|
2455
2945
|
{
|
|
2456
|
-
title:
|
|
2457
|
-
body:
|
|
2458
|
-
branch:
|
|
2946
|
+
title: z2.string().describe("The PR title"),
|
|
2947
|
+
body: z2.string().describe("The PR description/body in markdown"),
|
|
2948
|
+
branch: z2.string().optional().describe(
|
|
2459
2949
|
"The head branch name for the PR. If the task doesn't have a branch set, this will be used. Defaults to the task's existing branch."
|
|
2460
2950
|
),
|
|
2461
|
-
baseBranch:
|
|
2951
|
+
baseBranch: z2.string().optional().describe(
|
|
2462
2952
|
"The base branch to target for the PR (e.g. 'main', 'develop'). Defaults to the project's configured dev branch."
|
|
2463
2953
|
),
|
|
2464
|
-
commitMessage:
|
|
2954
|
+
commitMessage: z2.string().optional().describe(
|
|
2465
2955
|
"Commit message for staging uncommitted changes. If not provided, a default message based on the PR title will be used."
|
|
2466
2956
|
)
|
|
2467
2957
|
},
|
|
@@ -2539,7 +3029,7 @@ function buildAddDependencyTool(connection) {
|
|
|
2539
3029
|
"add_dependency",
|
|
2540
3030
|
"Add a dependency \u2014 this task cannot start until the specified task is merged to dev",
|
|
2541
3031
|
{
|
|
2542
|
-
depends_on_slug_or_id:
|
|
3032
|
+
depends_on_slug_or_id: z2.string().describe("Slug or ID of the task this task depends on")
|
|
2543
3033
|
},
|
|
2544
3034
|
async ({ depends_on_slug_or_id }) => {
|
|
2545
3035
|
try {
|
|
@@ -2561,7 +3051,7 @@ function buildRemoveDependencyTool(connection) {
|
|
|
2561
3051
|
"remove_dependency",
|
|
2562
3052
|
"Remove a dependency from this task",
|
|
2563
3053
|
{
|
|
2564
|
-
depends_on_slug_or_id:
|
|
3054
|
+
depends_on_slug_or_id: z2.string().describe("Slug or ID of the task to remove as dependency")
|
|
2565
3055
|
},
|
|
2566
3056
|
async ({ depends_on_slug_or_id }) => {
|
|
2567
3057
|
try {
|
|
@@ -2583,10 +3073,10 @@ function buildCreateFollowUpTaskTool(connection) {
|
|
|
2583
3073
|
"create_follow_up_task",
|
|
2584
3074
|
"Create a follow-up task in this project that depends on the current task. Use for out-of-scope work, v1.1 features, or cleanup that should happen after this task merges.",
|
|
2585
3075
|
{
|
|
2586
|
-
title:
|
|
2587
|
-
description:
|
|
2588
|
-
plan:
|
|
2589
|
-
story_point_value:
|
|
3076
|
+
title: z2.string().describe("Follow-up task title"),
|
|
3077
|
+
description: z2.string().optional().describe("Brief description of the follow-up work"),
|
|
3078
|
+
plan: z2.string().optional().describe("Implementation plan if known"),
|
|
3079
|
+
story_point_value: z2.number().optional().describe("Story point estimate (1=Common, 2=Magic, 3=Rare, 5=Unique)")
|
|
2590
3080
|
},
|
|
2591
3081
|
async ({ title, description, plan, story_point_value }) => {
|
|
2592
3082
|
try {
|
|
@@ -2613,9 +3103,9 @@ function buildCreateSuggestionTool(connection) {
|
|
|
2613
3103
|
"create_suggestion",
|
|
2614
3104
|
"Suggest a feature, improvement, or idea for the project. If you want to recommend something \u2014 a document, a rule, a feature, a task, an optimization \u2014 use this tool. If a similar suggestion already exists, your vote will be added to it instead of creating a duplicate.",
|
|
2615
3105
|
{
|
|
2616
|
-
title:
|
|
2617
|
-
description:
|
|
2618
|
-
tag_names:
|
|
3106
|
+
title: z2.string().describe("Short title for the suggestion"),
|
|
3107
|
+
description: z2.string().optional().describe("Details about the suggestion"),
|
|
3108
|
+
tag_names: z2.array(z2.string()).optional().describe("Tag names to categorize the suggestion")
|
|
2619
3109
|
},
|
|
2620
3110
|
async ({ title, description, tag_names }) => {
|
|
2621
3111
|
try {
|
|
@@ -2644,8 +3134,8 @@ function buildVoteSuggestionTool(connection) {
|
|
|
2644
3134
|
"vote_suggestion",
|
|
2645
3135
|
"Vote on a project suggestion. Use +1 to upvote or -1 to downvote.",
|
|
2646
3136
|
{
|
|
2647
|
-
suggestion_id:
|
|
2648
|
-
value:
|
|
3137
|
+
suggestion_id: z2.string().describe("The suggestion ID to vote on"),
|
|
3138
|
+
value: z2.number().refine((v) => v === 1 || v === -1, { message: "Value must be 1 or -1" }).describe("+1 to upvote, -1 to downvote")
|
|
2649
3139
|
},
|
|
2650
3140
|
async ({ suggestion_id, value }) => {
|
|
2651
3141
|
try {
|
|
@@ -2668,8 +3158,8 @@ function buildScaleUpResourcesTool(connection) {
|
|
|
2668
3158
|
"scale_up_resources",
|
|
2669
3159
|
"Scale up the pod's CPU and memory resources. Use before running dev servers, tests, builds, or other resource-intensive operations. Phases: 'setup' (installs, basic dev servers), 'build' (full dev servers, test suites, typecheck, builds). Actual CPU/memory values are configured per-project. Scaling is one-way (up only).",
|
|
2670
3160
|
{
|
|
2671
|
-
tier:
|
|
2672
|
-
reason:
|
|
3161
|
+
tier: z2.enum(["initial", "setup", "build"]).describe("The resource phase to scale up to"),
|
|
3162
|
+
reason: z2.string().optional().describe("Brief reason for scaling (e.g., 'running test suite')")
|
|
2673
3163
|
},
|
|
2674
3164
|
async ({ tier, reason }) => {
|
|
2675
3165
|
try {
|
|
@@ -2722,15 +3212,15 @@ function buildCommonTools(connection, config) {
|
|
|
2722
3212
|
}
|
|
2723
3213
|
|
|
2724
3214
|
// src/tools/pm-tools.ts
|
|
2725
|
-
import { z as
|
|
3215
|
+
import { z as z3 } from "zod";
|
|
2726
3216
|
var SP_DESCRIPTION = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
|
|
2727
3217
|
function buildUpdateTaskTool(connection) {
|
|
2728
3218
|
return defineTool(
|
|
2729
3219
|
"update_task",
|
|
2730
3220
|
"Save the finalized task plan and/or description",
|
|
2731
3221
|
{
|
|
2732
|
-
plan:
|
|
2733
|
-
description:
|
|
3222
|
+
plan: z3.string().optional().describe("The task plan in markdown"),
|
|
3223
|
+
description: z3.string().optional().describe("Updated task description")
|
|
2734
3224
|
},
|
|
2735
3225
|
async ({ plan, description }) => {
|
|
2736
3226
|
try {
|
|
@@ -2751,11 +3241,11 @@ function buildCreateSubtaskTool(connection) {
|
|
|
2751
3241
|
"create_subtask",
|
|
2752
3242
|
"Create a subtask under the current parent task. Use for breaking complex tasks into smaller pieces.",
|
|
2753
3243
|
{
|
|
2754
|
-
title:
|
|
2755
|
-
description:
|
|
2756
|
-
plan:
|
|
2757
|
-
ordinal:
|
|
2758
|
-
storyPointValue:
|
|
3244
|
+
title: z3.string().describe("Subtask title"),
|
|
3245
|
+
description: z3.string().optional().describe("Brief description"),
|
|
3246
|
+
plan: z3.string().optional().describe("Implementation plan in markdown"),
|
|
3247
|
+
ordinal: z3.number().optional().describe("Step/order number (0-based)"),
|
|
3248
|
+
storyPointValue: z3.number().optional().describe(SP_DESCRIPTION)
|
|
2759
3249
|
},
|
|
2760
3250
|
async ({ title, description, plan, ordinal, storyPointValue }) => {
|
|
2761
3251
|
try {
|
|
@@ -2781,12 +3271,12 @@ function buildUpdateSubtaskTool(connection) {
|
|
|
2781
3271
|
"update_subtask",
|
|
2782
3272
|
"Update an existing subtask's fields",
|
|
2783
3273
|
{
|
|
2784
|
-
subtaskId:
|
|
2785
|
-
title:
|
|
2786
|
-
description:
|
|
2787
|
-
plan:
|
|
2788
|
-
ordinal:
|
|
2789
|
-
storyPointValue:
|
|
3274
|
+
subtaskId: z3.string().describe("The subtask ID to update"),
|
|
3275
|
+
title: z3.string().optional(),
|
|
3276
|
+
description: z3.string().optional(),
|
|
3277
|
+
plan: z3.string().optional(),
|
|
3278
|
+
ordinal: z3.number().optional(),
|
|
3279
|
+
storyPointValue: z3.number().optional().describe(SP_DESCRIPTION)
|
|
2790
3280
|
},
|
|
2791
3281
|
async ({ subtaskId, title, description, plan, storyPointValue }) => {
|
|
2792
3282
|
try {
|
|
@@ -2809,7 +3299,7 @@ function buildDeleteSubtaskTool(connection) {
|
|
|
2809
3299
|
return defineTool(
|
|
2810
3300
|
"delete_subtask",
|
|
2811
3301
|
"Delete a subtask",
|
|
2812
|
-
{ subtaskId:
|
|
3302
|
+
{ subtaskId: z3.string().describe("The subtask ID to delete") },
|
|
2813
3303
|
async ({ subtaskId }) => {
|
|
2814
3304
|
try {
|
|
2815
3305
|
await connection.call("deleteSubtask", {
|
|
@@ -2847,7 +3337,7 @@ function buildPackTools(connection) {
|
|
|
2847
3337
|
"start_child_cloud_build",
|
|
2848
3338
|
"Start a cloud build for a child task. The child must be in Open status with story points and an agent assigned.",
|
|
2849
3339
|
{
|
|
2850
|
-
childTaskId:
|
|
3340
|
+
childTaskId: z3.string().describe("The child task ID to start a cloud build for")
|
|
2851
3341
|
},
|
|
2852
3342
|
async ({ childTaskId }) => {
|
|
2853
3343
|
try {
|
|
@@ -2867,7 +3357,7 @@ function buildPackTools(connection) {
|
|
|
2867
3357
|
"stop_child_build",
|
|
2868
3358
|
"Stop a running cloud build for a child task. Sends a stop signal to the child agent.",
|
|
2869
3359
|
{
|
|
2870
|
-
childTaskId:
|
|
3360
|
+
childTaskId: z3.string().describe("The child task ID whose build should be stopped")
|
|
2871
3361
|
},
|
|
2872
3362
|
async ({ childTaskId }) => {
|
|
2873
3363
|
try {
|
|
@@ -2887,7 +3377,7 @@ function buildPackTools(connection) {
|
|
|
2887
3377
|
"approve_and_merge_pr",
|
|
2888
3378
|
"Approve and merge a child task's pull request. Only succeeds if all CI/CD checks are passing. Returns an error if checks are pending (retry after waiting) or failed (investigate). The child task must be in ReviewPR status.",
|
|
2889
3379
|
{
|
|
2890
|
-
childTaskId:
|
|
3380
|
+
childTaskId: z3.string().describe("The child task ID whose PR should be approved and merged")
|
|
2891
3381
|
},
|
|
2892
3382
|
async ({ childTaskId }) => {
|
|
2893
3383
|
try {
|
|
@@ -2925,119 +3415,31 @@ function buildPmTools(connection, options) {
|
|
|
2925
3415
|
}
|
|
2926
3416
|
|
|
2927
3417
|
// src/tools/discovery-tools.ts
|
|
2928
|
-
import { z as
|
|
3418
|
+
import { z as z4 } from "zod";
|
|
2929
3419
|
var SP_DESCRIPTION2 = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
|
|
2930
|
-
function buildSearchIconsTool(connection) {
|
|
2931
|
-
return defineTool(
|
|
2932
|
-
"search_icons",
|
|
2933
|
-
"Search for icons by keyword. Searches both the Conveyor database (existing icons) and FontAwesome library (~2200 icons). Returns matching icons with IDs and preview info. Use this to find an icon before generating one.",
|
|
2934
|
-
{
|
|
2935
|
-
query: z3.string().describe("Search query for icon name or keyword (e.g. 'bug', 'gear', 'star')")
|
|
2936
|
-
},
|
|
2937
|
-
async ({ query }) => {
|
|
2938
|
-
try {
|
|
2939
|
-
const [dbIcons, faIcons] = await Promise.all([
|
|
2940
|
-
connection.call("listIcons", { sessionId: connection.sessionId }),
|
|
2941
|
-
connection.call("searchFaIcons", { sessionId: connection.sessionId, query })
|
|
2942
|
-
]);
|
|
2943
|
-
const q = query.toLowerCase();
|
|
2944
|
-
const matchingDbIcons = dbIcons.filter((icon) => icon.name.toLowerCase().includes(q));
|
|
2945
|
-
const dbFaIds = new Set(matchingDbIcons.map((i) => i.name));
|
|
2946
|
-
const uniqueFaIcons = faIcons.filter((fa) => !dbFaIds.has(fa.fontAwesomeId));
|
|
2947
|
-
const results = {
|
|
2948
|
-
existingIcons: matchingDbIcons.map((i) => ({
|
|
2949
|
-
id: i.id,
|
|
2950
|
-
name: i.name,
|
|
2951
|
-
source: "database"
|
|
2952
|
-
})),
|
|
2953
|
-
fontAwesomeIcons: uniqueFaIcons.map((fa) => ({
|
|
2954
|
-
fontAwesomeId: fa.fontAwesomeId,
|
|
2955
|
-
label: fa.label,
|
|
2956
|
-
styles: fa.styles,
|
|
2957
|
-
source: "fontawesome"
|
|
2958
|
-
}))
|
|
2959
|
-
};
|
|
2960
|
-
return textResult(JSON.stringify(results, null, 2));
|
|
2961
|
-
} catch (error) {
|
|
2962
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2963
|
-
return textResult(`Failed to search icons: ${message}`);
|
|
2964
|
-
}
|
|
2965
|
-
},
|
|
2966
|
-
{ annotations: { readOnlyHint: true } }
|
|
2967
|
-
);
|
|
2968
|
-
}
|
|
2969
|
-
function buildIconTools(connection) {
|
|
2970
|
-
return [
|
|
2971
|
-
defineTool(
|
|
2972
|
-
"list_icons",
|
|
2973
|
-
"List available icons (default library + user-created). Returns icon IDs, names, and whether they're defaults. Call this FIRST before update_task_properties to check for existing matches.",
|
|
2974
|
-
{},
|
|
2975
|
-
async () => {
|
|
2976
|
-
try {
|
|
2977
|
-
const icons = await connection.call("listIcons", {
|
|
2978
|
-
sessionId: connection.sessionId
|
|
2979
|
-
});
|
|
2980
|
-
return textResult(JSON.stringify(icons, null, 2));
|
|
2981
|
-
} catch (error) {
|
|
2982
|
-
return textResult(
|
|
2983
|
-
`Failed to list icons: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2984
|
-
);
|
|
2985
|
-
}
|
|
2986
|
-
},
|
|
2987
|
-
{ annotations: { readOnlyHint: true } }
|
|
2988
|
-
),
|
|
2989
|
-
defineTool(
|
|
2990
|
-
"generate_task_icon",
|
|
2991
|
-
"Find a FontAwesome icon matching the description and assign it to this task. Falls back to a placeholder if no match is found. Provide a concise keyword or description.",
|
|
2992
|
-
{
|
|
2993
|
-
prompt: z3.string().describe(
|
|
2994
|
-
"Keyword or description to search FontAwesome icons (e.g. 'bug', 'gear', 'rocket')"
|
|
2995
|
-
),
|
|
2996
|
-
aspectRatio: z3.enum(["auto", "portrait", "landscape", "square"]).optional().describe("Icon aspect ratio, defaults to square")
|
|
2997
|
-
},
|
|
2998
|
-
async ({ prompt, aspectRatio }) => {
|
|
2999
|
-
try {
|
|
3000
|
-
const result = await connection.call("generateTaskIcon", {
|
|
3001
|
-
sessionId: connection.sessionId,
|
|
3002
|
-
prompt,
|
|
3003
|
-
aspectRatio: aspectRatio ?? "square"
|
|
3004
|
-
});
|
|
3005
|
-
return textResult(`Icon generated and assigned: ${result.iconId}`);
|
|
3006
|
-
} catch (error) {
|
|
3007
|
-
return textResult(
|
|
3008
|
-
`Failed to generate icon: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3009
|
-
);
|
|
3010
|
-
}
|
|
3011
|
-
}
|
|
3012
|
-
)
|
|
3013
|
-
];
|
|
3014
|
-
}
|
|
3015
3420
|
function buildDiscoveryTools(connection) {
|
|
3016
3421
|
return [
|
|
3017
3422
|
defineTool(
|
|
3018
3423
|
"update_task_properties",
|
|
3019
3424
|
"Set one or more task properties in a single call. All fields are optional \u2014 only include the fields you want to update.",
|
|
3020
3425
|
{
|
|
3021
|
-
title:
|
|
3022
|
-
storyPointValue:
|
|
3023
|
-
tagIds:
|
|
3024
|
-
iconId: z3.string().optional().describe("Icon ID to assign (use list_icons first)")
|
|
3426
|
+
title: z4.string().optional().describe("The new task title"),
|
|
3427
|
+
storyPointValue: z4.number().optional().describe(SP_DESCRIPTION2),
|
|
3428
|
+
tagIds: z4.array(z4.string()).optional().describe("Array of tag IDs to assign")
|
|
3025
3429
|
},
|
|
3026
|
-
async ({ title, storyPointValue, tagIds
|
|
3430
|
+
async ({ title, storyPointValue, tagIds }) => {
|
|
3027
3431
|
try {
|
|
3028
3432
|
await connection.call("updateTaskProperties", {
|
|
3029
3433
|
sessionId: connection.sessionId,
|
|
3030
3434
|
title,
|
|
3031
3435
|
storyPointValue,
|
|
3032
|
-
tagIds
|
|
3033
|
-
iconId
|
|
3436
|
+
tagIds
|
|
3034
3437
|
});
|
|
3035
3438
|
const updatedFields = [];
|
|
3036
3439
|
if (title !== void 0) updatedFields.push(`title to "${title}"`);
|
|
3037
3440
|
if (storyPointValue !== void 0)
|
|
3038
3441
|
updatedFields.push(`story points to ${storyPointValue}`);
|
|
3039
3442
|
if (tagIds !== void 0) updatedFields.push(`tags (${tagIds.length} tag(s))`);
|
|
3040
|
-
if (iconId !== void 0) updatedFields.push(`icon`);
|
|
3041
3443
|
return textResult(`Task properties updated: ${updatedFields.join(", ")}`);
|
|
3042
3444
|
} catch (error) {
|
|
3043
3445
|
return textResult(
|
|
@@ -3045,21 +3447,19 @@ function buildDiscoveryTools(connection) {
|
|
|
3045
3447
|
);
|
|
3046
3448
|
}
|
|
3047
3449
|
}
|
|
3048
|
-
)
|
|
3049
|
-
buildSearchIconsTool(connection),
|
|
3050
|
-
...buildIconTools(connection)
|
|
3450
|
+
)
|
|
3051
3451
|
];
|
|
3052
3452
|
}
|
|
3053
3453
|
|
|
3054
3454
|
// src/tools/code-review-tools.ts
|
|
3055
|
-
import { z as
|
|
3455
|
+
import { z as z5 } from "zod";
|
|
3056
3456
|
function buildCodeReviewTools(connection) {
|
|
3057
3457
|
return [
|
|
3058
3458
|
defineTool(
|
|
3059
3459
|
"approve_code_review",
|
|
3060
3460
|
"Approve the code review. Use this when the code passes all review criteria and is ready to merge.",
|
|
3061
3461
|
{
|
|
3062
|
-
summary:
|
|
3462
|
+
summary: z5.string().describe("Brief summary of what was reviewed and why it looks good")
|
|
3063
3463
|
},
|
|
3064
3464
|
async ({ summary }) => {
|
|
3065
3465
|
const content = `**Code Review: Approved** :white_check_mark:
|
|
@@ -3082,15 +3482,15 @@ ${summary}`;
|
|
|
3082
3482
|
"request_code_changes",
|
|
3083
3483
|
"Request changes during code review. Use this when substantive issues are found that need to be fixed before merge.",
|
|
3084
3484
|
{
|
|
3085
|
-
issues:
|
|
3086
|
-
|
|
3087
|
-
file:
|
|
3088
|
-
line:
|
|
3089
|
-
severity:
|
|
3090
|
-
description:
|
|
3485
|
+
issues: z5.array(
|
|
3486
|
+
z5.object({
|
|
3487
|
+
file: z5.string().describe("File path where the issue was found"),
|
|
3488
|
+
line: z5.number().optional().describe("Line number (if applicable)"),
|
|
3489
|
+
severity: z5.enum(["critical", "major", "minor"]).describe("Issue severity"),
|
|
3490
|
+
description: z5.string().describe("What is wrong and how to fix it")
|
|
3091
3491
|
})
|
|
3092
3492
|
).describe("List of issues found during review"),
|
|
3093
|
-
summary:
|
|
3493
|
+
summary: z5.string().describe("Brief overall summary of the review findings")
|
|
3094
3494
|
},
|
|
3095
3495
|
async ({ issues, summary }) => {
|
|
3096
3496
|
const issueLines = issues.map((issue) => {
|
|
@@ -3120,10 +3520,10 @@ ${issueLines}`;
|
|
|
3120
3520
|
}
|
|
3121
3521
|
|
|
3122
3522
|
// src/tools/debug-tools.ts
|
|
3123
|
-
import { z as
|
|
3523
|
+
import { z as z8 } from "zod";
|
|
3124
3524
|
|
|
3125
3525
|
// src/tools/telemetry-tools.ts
|
|
3126
|
-
import { z as
|
|
3526
|
+
import { z as z6 } from "zod";
|
|
3127
3527
|
|
|
3128
3528
|
// src/debug/telemetry-injector.ts
|
|
3129
3529
|
var BUFFER_SIZE = 200;
|
|
@@ -3518,12 +3918,12 @@ function buildGetTelemetryTool(manager) {
|
|
|
3518
3918
|
"debug_get_telemetry",
|
|
3519
3919
|
"Query structured telemetry events (HTTP requests, database queries, Socket.IO events, errors) captured from the running dev server. Returns filtered, structured data instead of raw logs.",
|
|
3520
3920
|
{
|
|
3521
|
-
type:
|
|
3522
|
-
urlPattern:
|
|
3523
|
-
minDuration:
|
|
3524
|
-
errorOnly:
|
|
3525
|
-
since:
|
|
3526
|
-
limit:
|
|
3921
|
+
type: z6.enum(["http", "db", "socket", "error"]).optional().describe("Filter by event type"),
|
|
3922
|
+
urlPattern: z6.string().optional().describe("Regex pattern to filter HTTP events by URL"),
|
|
3923
|
+
minDuration: z6.number().optional().describe("Minimum duration in ms \u2014 only return events slower than this"),
|
|
3924
|
+
errorOnly: z6.boolean().optional().describe("Only return error events and HTTP 4xx/5xx responses"),
|
|
3925
|
+
since: z6.number().optional().describe("Only return events after this timestamp (ms since epoch)"),
|
|
3926
|
+
limit: z6.number().optional().describe("Max events to return (default: 20, from most recent)")
|
|
3527
3927
|
},
|
|
3528
3928
|
async ({ type, urlPattern, minDuration, errorOnly, since, limit }) => {
|
|
3529
3929
|
const clientOrErr = requireDebugClient(manager);
|
|
@@ -3593,7 +3993,7 @@ function buildTelemetryTools(manager) {
|
|
|
3593
3993
|
}
|
|
3594
3994
|
|
|
3595
3995
|
// src/tools/client-debug-tools.ts
|
|
3596
|
-
import { z as
|
|
3996
|
+
import { z as z7 } from "zod";
|
|
3597
3997
|
function requirePlaywrightClient(manager) {
|
|
3598
3998
|
if (!manager.isClientDebugMode()) {
|
|
3599
3999
|
return "Client debug mode is not active. Use debug_enter_mode with clientSide: true first.";
|
|
@@ -3613,11 +4013,11 @@ function buildClientBreakpointTools(manager) {
|
|
|
3613
4013
|
"debug_set_client_breakpoint",
|
|
3614
4014
|
"Set a breakpoint in client-side code running in the headless Chromium browser. V8 resolves source maps automatically, so original .tsx/.ts file paths work. Use this for React components, client utilities, and browser-side code.",
|
|
3615
4015
|
{
|
|
3616
|
-
file:
|
|
4016
|
+
file: z7.string().describe(
|
|
3617
4017
|
"Original source file path (e.g., src/components/App.tsx) \u2014 source maps resolve automatically"
|
|
3618
4018
|
),
|
|
3619
|
-
line:
|
|
3620
|
-
condition:
|
|
4019
|
+
line: z7.number().describe("Line number (1-based) in the original source file"),
|
|
4020
|
+
condition: z7.string().optional().describe("JavaScript condition expression \u2014 breakpoint only triggers when truthy")
|
|
3621
4021
|
},
|
|
3622
4022
|
async ({ file, line, condition }) => {
|
|
3623
4023
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -3639,7 +4039,7 @@ Breakpoint ID: ${breakpointId}${sourceMapNote}`
|
|
|
3639
4039
|
"debug_remove_client_breakpoint",
|
|
3640
4040
|
"Remove a previously set client-side breakpoint by its ID.",
|
|
3641
4041
|
{
|
|
3642
|
-
breakpointId:
|
|
4042
|
+
breakpointId: z7.string().describe("The breakpoint ID returned by debug_set_client_breakpoint")
|
|
3643
4043
|
},
|
|
3644
4044
|
async ({ breakpointId }) => {
|
|
3645
4045
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -3719,8 +4119,8 @@ ${JSON.stringify(queuedHits, null, 2)}`
|
|
|
3719
4119
|
"debug_evaluate_client",
|
|
3720
4120
|
"Evaluate a JavaScript expression in the client-side browser context. When paused at a client breakpoint, evaluates in the paused scope. Can access DOM, window, React internals, etc.",
|
|
3721
4121
|
{
|
|
3722
|
-
expression:
|
|
3723
|
-
frameIndex:
|
|
4122
|
+
expression: z7.string().describe("JavaScript expression to evaluate in the browser context"),
|
|
4123
|
+
frameIndex: z7.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
|
|
3724
4124
|
},
|
|
3725
4125
|
async ({ expression, frameIndex }) => {
|
|
3726
4126
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -3793,7 +4193,7 @@ function buildClientInteractionTools(manager) {
|
|
|
3793
4193
|
"debug_navigate_client",
|
|
3794
4194
|
"Navigate the headless browser to a specific URL. Use this to reproduce specific flows or visit different pages.",
|
|
3795
4195
|
{
|
|
3796
|
-
url:
|
|
4196
|
+
url: z7.string().describe("URL to navigate to (e.g., http://localhost:3000/dashboard)")
|
|
3797
4197
|
},
|
|
3798
4198
|
async ({ url }) => {
|
|
3799
4199
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -3810,7 +4210,7 @@ function buildClientInteractionTools(manager) {
|
|
|
3810
4210
|
"debug_click_client",
|
|
3811
4211
|
"Click an element on the page in the headless browser. Use CSS selectors to target elements. Useful for reproducing bugs by interacting with the UI programmatically.",
|
|
3812
4212
|
{
|
|
3813
|
-
selector:
|
|
4213
|
+
selector: z7.string().describe(
|
|
3814
4214
|
"CSS selector of the element to click (e.g., 'button.submit', '#login-form input[type=submit]')"
|
|
3815
4215
|
)
|
|
3816
4216
|
},
|
|
@@ -3832,8 +4232,8 @@ function buildClientConsoleTool(manager) {
|
|
|
3832
4232
|
"debug_get_client_console",
|
|
3833
4233
|
"Get console messages captured from the headless browser. Includes console.log, warn, error, etc.",
|
|
3834
4234
|
{
|
|
3835
|
-
level:
|
|
3836
|
-
limit:
|
|
4235
|
+
level: z7.string().optional().describe("Filter by console level: log, warn, error, info, debug"),
|
|
4236
|
+
limit: z7.number().optional().describe("Maximum number of recent messages to return (default: all)")
|
|
3837
4237
|
},
|
|
3838
4238
|
// oxlint-disable-next-line require-await
|
|
3839
4239
|
async ({ level, limit }) => {
|
|
@@ -3860,8 +4260,8 @@ function buildClientNetworkTool(manager) {
|
|
|
3860
4260
|
"debug_get_client_network",
|
|
3861
4261
|
"Get network requests captured from the headless browser. Shows URLs, methods, status codes, and timing.",
|
|
3862
4262
|
{
|
|
3863
|
-
filter:
|
|
3864
|
-
limit:
|
|
4263
|
+
filter: z7.string().optional().describe("Regex pattern to filter requests by URL"),
|
|
4264
|
+
limit: z7.number().optional().describe("Maximum number of recent requests to return (default: all)")
|
|
3865
4265
|
},
|
|
3866
4266
|
// oxlint-disable-next-line require-await
|
|
3867
4267
|
async ({ filter, limit }) => {
|
|
@@ -3889,7 +4289,7 @@ function buildClientErrorsTool(manager) {
|
|
|
3889
4289
|
"debug_get_client_errors",
|
|
3890
4290
|
"Get uncaught errors captured from the headless browser. Includes error messages and source-mapped stack traces.",
|
|
3891
4291
|
{
|
|
3892
|
-
limit:
|
|
4292
|
+
limit: z7.number().optional().describe("Maximum number of recent errors to return (default: all)")
|
|
3893
4293
|
},
|
|
3894
4294
|
// oxlint-disable-next-line require-await
|
|
3895
4295
|
async ({ limit }) => {
|
|
@@ -3983,12 +4383,12 @@ function buildDebugLifecycleTools(manager) {
|
|
|
3983
4383
|
"debug_enter_mode",
|
|
3984
4384
|
"Activate debug mode: restarts the dev server with Node.js --inspect flag and connects the CDP debugger. Optionally launch a headless Chromium browser for client-side debugging. Use serverSide for backend breakpoints, clientSide for frontend breakpoints, or both for full-stack.",
|
|
3985
4385
|
{
|
|
3986
|
-
hypothesis:
|
|
3987
|
-
serverSide:
|
|
4386
|
+
hypothesis: z8.string().optional().describe("Your hypothesis about the bug \u2014 helps track debugging intent"),
|
|
4387
|
+
serverSide: z8.boolean().optional().describe(
|
|
3988
4388
|
"Enable server-side Node.js debugging (default: true if clientSide is not set)"
|
|
3989
4389
|
),
|
|
3990
|
-
clientSide:
|
|
3991
|
-
previewUrl:
|
|
4390
|
+
clientSide: z8.boolean().optional().describe("Enable client-side browser debugging via headless Chromium + Playwright"),
|
|
4391
|
+
previewUrl: z8.string().optional().describe(
|
|
3992
4392
|
"Preview URL for client-side debugging (e.g., http://localhost:3000). Required when clientSide is true."
|
|
3993
4393
|
)
|
|
3994
4394
|
},
|
|
@@ -4024,9 +4424,9 @@ function buildBreakpointTools(manager) {
|
|
|
4024
4424
|
"debug_set_breakpoint",
|
|
4025
4425
|
"Set a breakpoint at the specified file and line number. Optionally provide a condition expression that must evaluate to true for the breakpoint to pause execution.",
|
|
4026
4426
|
{
|
|
4027
|
-
file:
|
|
4028
|
-
line:
|
|
4029
|
-
condition:
|
|
4427
|
+
file: z8.string().describe("Absolute or relative file path to set the breakpoint in"),
|
|
4428
|
+
line: z8.number().describe("Line number (1-based) to set the breakpoint on"),
|
|
4429
|
+
condition: z8.string().optional().describe("JavaScript condition expression \u2014 breakpoint only triggers when truthy")
|
|
4030
4430
|
},
|
|
4031
4431
|
async ({ file, line, condition }) => {
|
|
4032
4432
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4048,7 +4448,7 @@ Breakpoint ID: ${breakpointId}`
|
|
|
4048
4448
|
"debug_remove_breakpoint",
|
|
4049
4449
|
"Remove a previously set breakpoint by its ID.",
|
|
4050
4450
|
{
|
|
4051
|
-
breakpointId:
|
|
4451
|
+
breakpointId: z8.string().describe("The breakpoint ID returned by debug_set_breakpoint")
|
|
4052
4452
|
},
|
|
4053
4453
|
async ({ breakpointId }) => {
|
|
4054
4454
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4129,8 +4529,8 @@ ${JSON.stringify(queuedHits, null, 2)}`
|
|
|
4129
4529
|
"debug_evaluate",
|
|
4130
4530
|
"Evaluate a JavaScript expression in the current paused scope (or globally if not paused). When paused, use frameIndex to evaluate in a specific call frame.",
|
|
4131
4531
|
{
|
|
4132
|
-
expression:
|
|
4133
|
-
frameIndex:
|
|
4532
|
+
expression: z8.string().describe("The JavaScript expression to evaluate"),
|
|
4533
|
+
frameIndex: z8.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
|
|
4134
4534
|
},
|
|
4135
4535
|
async ({ expression, frameIndex }) => {
|
|
4136
4536
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4158,12 +4558,12 @@ function buildProbeManagementTools(manager) {
|
|
|
4158
4558
|
"debug_add_probe",
|
|
4159
4559
|
"Add a debug probe at a specific code location. Captures expression values each time the line executes \u2014 without pausing or modifying source files. Like console.log but better: structured, no diff pollution, auto-cleaned on debug exit.",
|
|
4160
4560
|
{
|
|
4161
|
-
file:
|
|
4162
|
-
line:
|
|
4163
|
-
expressions:
|
|
4561
|
+
file: z8.string().describe("File path to probe"),
|
|
4562
|
+
line: z8.number().describe("Line number (1-based) to probe"),
|
|
4563
|
+
expressions: z8.array(z8.string()).describe(
|
|
4164
4564
|
'JavaScript expressions to capture when the line executes (e.g., ["req.params.id", "user.role"])'
|
|
4165
4565
|
),
|
|
4166
|
-
label:
|
|
4566
|
+
label: z8.string().optional().describe("Optional label for this probe (defaults to file:line)")
|
|
4167
4567
|
},
|
|
4168
4568
|
async ({ file, line, expressions, label }) => {
|
|
4169
4569
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4188,7 +4588,7 @@ Trigger the code path, then use debug_get_probe_results to see captured values.`
|
|
|
4188
4588
|
"debug_remove_probe",
|
|
4189
4589
|
"Remove a previously set debug probe by its ID.",
|
|
4190
4590
|
{
|
|
4191
|
-
probeId:
|
|
4591
|
+
probeId: z8.string().describe("The probe ID returned by debug_add_probe")
|
|
4192
4592
|
},
|
|
4193
4593
|
async ({ probeId }) => {
|
|
4194
4594
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4228,9 +4628,9 @@ function buildProbeResultTools(manager) {
|
|
|
4228
4628
|
"debug_get_probe_results",
|
|
4229
4629
|
"Fetch captured probe hit data. Returns expression values from each time a probed line executed.",
|
|
4230
4630
|
{
|
|
4231
|
-
probeId:
|
|
4232
|
-
label:
|
|
4233
|
-
limit:
|
|
4631
|
+
probeId: z8.string().optional().describe("Filter results by probe ID (resolves to its label)"),
|
|
4632
|
+
label: z8.string().optional().describe("Filter results by probe label"),
|
|
4633
|
+
limit: z8.number().optional().describe("Maximum number of recent hits to return (default: all)")
|
|
4234
4634
|
},
|
|
4235
4635
|
async ({ probeId, label, limit }) => {
|
|
4236
4636
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -4954,14 +5354,14 @@ async function handleExitPlanMode(host, input) {
|
|
|
4954
5354
|
}
|
|
4955
5355
|
if (host.agentMode === "discovery") {
|
|
4956
5356
|
host.hasExitedPlanMode = true;
|
|
5357
|
+
void host.connection.triggerIdentification();
|
|
4957
5358
|
host.connection.postChatMessage(
|
|
4958
|
-
"Plan complete.
|
|
5359
|
+
"Plan complete. Running identification \u2014 icon and agent assignment will be set automatically."
|
|
4959
5360
|
);
|
|
4960
|
-
host.
|
|
5361
|
+
host.requestSoftStop();
|
|
4961
5362
|
return { behavior: "allow", updatedInput: input };
|
|
4962
5363
|
}
|
|
4963
5364
|
await host.connection.triggerIdentification();
|
|
4964
|
-
host.connection.updateStatus("InProgress");
|
|
4965
5365
|
host.hasExitedPlanMode = true;
|
|
4966
5366
|
const newMode = host.isParentTask ? "review" : "building";
|
|
4967
5367
|
host.pendingModeRestart = true;
|
|
@@ -5000,6 +5400,7 @@ async function handleAskUserQuestion(host, input) {
|
|
|
5000
5400
|
return { behavior: "allow", updatedInput: { questions: input.questions, answers } };
|
|
5001
5401
|
}
|
|
5002
5402
|
var DENIAL_WARNING_THRESHOLD = 3;
|
|
5403
|
+
var DENIAL_FORCE_STOP_THRESHOLD = 8;
|
|
5003
5404
|
function isResourceHeavyCommand(command) {
|
|
5004
5405
|
return RESOURCE_HEAVY_PATTERNS.some((p) => p.test(command));
|
|
5005
5406
|
}
|
|
@@ -5048,6 +5449,12 @@ function buildCanUseTool(host) {
|
|
|
5048
5449
|
`\u26A0\uFE0F Multiple tool denials detected. You are in ${host.agentMode} mode \u2014 file writes outside .claude/plans/ are not permitted. Focus on creating a plan instead of implementing code changes.`
|
|
5049
5450
|
);
|
|
5050
5451
|
}
|
|
5452
|
+
if (consecutiveDenials >= DENIAL_FORCE_STOP_THRESHOLD) {
|
|
5453
|
+
host.connection.postChatMessage(
|
|
5454
|
+
`Agent force-stopped after ${DENIAL_FORCE_STOP_THRESHOLD} consecutive tool denials. The agent appears stuck \u2014 send a message to resume.`
|
|
5455
|
+
);
|
|
5456
|
+
host.requestStop();
|
|
5457
|
+
}
|
|
5051
5458
|
} else {
|
|
5052
5459
|
consecutiveDenials = 0;
|
|
5053
5460
|
}
|
|
@@ -5485,6 +5892,8 @@ var QueryBridge = class {
|
|
|
5485
5892
|
_abortController = null;
|
|
5486
5893
|
/** Called by SessionRunner when ExitPlanMode triggers a mode transition. */
|
|
5487
5894
|
onModeTransition;
|
|
5895
|
+
/** Called by tool handlers to soft-stop (abort query, keep session alive). */
|
|
5896
|
+
onSoftStop;
|
|
5488
5897
|
get isStopped() {
|
|
5489
5898
|
return this._stopped;
|
|
5490
5899
|
}
|
|
@@ -5568,6 +5977,9 @@ var QueryBridge = class {
|
|
|
5568
5977
|
},
|
|
5569
5978
|
isStopped: () => bridge._stopped,
|
|
5570
5979
|
requestStop: () => bridge.stop(),
|
|
5980
|
+
requestSoftStop: () => {
|
|
5981
|
+
if (bridge.onSoftStop) bridge.onSoftStop();
|
|
5982
|
+
},
|
|
5571
5983
|
createInputStream: (prompt) => bridge.createInputStream(prompt),
|
|
5572
5984
|
snapshotPlanFiles: () => bridge.planSync.snapshotPlanFiles(),
|
|
5573
5985
|
syncPlanFile: () => bridge.planSync.syncPlanFile(),
|
|
@@ -5722,6 +6134,17 @@ var SessionRunner = class _SessionRunner {
|
|
|
5722
6134
|
await this.connect();
|
|
5723
6135
|
await this.run();
|
|
5724
6136
|
}
|
|
6137
|
+
// ── Message filtering ──────────────────────────────────────────────
|
|
6138
|
+
/** Returns true if the message should be skipped (not processed). */
|
|
6139
|
+
shouldSkipMessage(msg) {
|
|
6140
|
+
if (!this.hasCompleted || msg.userId !== "system") return false;
|
|
6141
|
+
const isCritical = !!msg.source && CRITICAL_AUTOMATED_SOURCES.has(msg.source);
|
|
6142
|
+
if (isCritical) {
|
|
6143
|
+
this.hasCompleted = false;
|
|
6144
|
+
return false;
|
|
6145
|
+
}
|
|
6146
|
+
return true;
|
|
6147
|
+
}
|
|
5725
6148
|
// ── Core loop ──────────────────────────────────────────────────────
|
|
5726
6149
|
async coreLoop() {
|
|
5727
6150
|
while (!this.stopped) {
|
|
@@ -5736,9 +6159,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
5736
6159
|
}
|
|
5737
6160
|
break;
|
|
5738
6161
|
}
|
|
5739
|
-
if (this.
|
|
5740
|
-
continue;
|
|
5741
|
-
}
|
|
6162
|
+
if (this.shouldSkipMessage(msg)) continue;
|
|
5742
6163
|
if (msg.userId !== "system") {
|
|
5743
6164
|
this.hasCompleted = false;
|
|
5744
6165
|
}
|
|
@@ -5879,7 +6300,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
5879
6300
|
async maybeSendPRNudge() {
|
|
5880
6301
|
await this.refreshTaskContext();
|
|
5881
6302
|
if (!this.needsPRNudge()) return;
|
|
5882
|
-
while (!this.stopped && this.needsPRNudge()) {
|
|
6303
|
+
while (!this.stopped && !this.interrupted && this.needsPRNudge()) {
|
|
5883
6304
|
this.prNudgeCount++;
|
|
5884
6305
|
if (this.prNudgeCount > _SessionRunner.MAX_PR_NUDGES) {
|
|
5885
6306
|
this.connection.postChatMessage(
|
|
@@ -5894,6 +6315,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
5894
6315
|
this.connection.postChatMessage(chatMsg);
|
|
5895
6316
|
await this.setState("running");
|
|
5896
6317
|
await this.callbacks.onEvent({ type: "pr_nudge", prompt });
|
|
6318
|
+
if (this.interrupted || this.stopped) return;
|
|
5897
6319
|
await this.executeQuery(prompt);
|
|
5898
6320
|
if (this.interrupted || this.stopped) return;
|
|
5899
6321
|
await this.refreshTaskContext();
|
|
@@ -5966,6 +6388,10 @@ var SessionRunner = class _SessionRunner {
|
|
|
5966
6388
|
this.config.workspaceDir
|
|
5967
6389
|
);
|
|
5968
6390
|
bridge.isParentTask = this.fullContext?.isParentTask ?? false;
|
|
6391
|
+
bridge.onSoftStop = () => {
|
|
6392
|
+
process.stderr.write("[conveyor-agent] Soft stop requested (discovery ExitPlanMode)\n");
|
|
6393
|
+
this.softStop();
|
|
6394
|
+
};
|
|
5969
6395
|
bridge.onModeTransition = (newMode) => {
|
|
5970
6396
|
const oldMode = this.mode.effectiveMode;
|
|
5971
6397
|
process.stderr.write(`[conveyor-agent] Mode transition: ${oldMode} \u2192 ${newMode}
|
|
@@ -6002,7 +6428,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
6002
6428
|
}
|
|
6003
6429
|
async setState(status) {
|
|
6004
6430
|
this._state = status;
|
|
6005
|
-
this.connection.emitStatus(status);
|
|
6431
|
+
await this.connection.emitStatus(status);
|
|
6006
6432
|
await this.callbacks.onStatusChange(status);
|
|
6007
6433
|
}
|
|
6008
6434
|
async shutdown(finalState) {
|
|
@@ -6442,7 +6868,7 @@ import * as path from "path";
|
|
|
6442
6868
|
import { fileURLToPath } from "url";
|
|
6443
6869
|
|
|
6444
6870
|
// src/tools/project-tools.ts
|
|
6445
|
-
import { z as
|
|
6871
|
+
import { z as z9 } from "zod";
|
|
6446
6872
|
function buildTaskListTools(connection) {
|
|
6447
6873
|
const projectId = connection.projectId;
|
|
6448
6874
|
return [
|
|
@@ -6450,9 +6876,9 @@ function buildTaskListTools(connection) {
|
|
|
6450
6876
|
"list_tasks",
|
|
6451
6877
|
"List tasks in the project. Optionally filter by status or assignee.",
|
|
6452
6878
|
{
|
|
6453
|
-
status:
|
|
6454
|
-
assigneeId:
|
|
6455
|
-
limit:
|
|
6879
|
+
status: z9.string().optional().describe("Filter by task status"),
|
|
6880
|
+
assigneeId: z9.string().optional().describe("Filter by assigned user ID"),
|
|
6881
|
+
limit: z9.number().optional().describe("Max number of tasks to return (default 50)")
|
|
6456
6882
|
},
|
|
6457
6883
|
async (params) => {
|
|
6458
6884
|
try {
|
|
@@ -6469,7 +6895,7 @@ function buildTaskListTools(connection) {
|
|
|
6469
6895
|
defineTool(
|
|
6470
6896
|
"get_task",
|
|
6471
6897
|
"Get detailed information about a task including chat messages, child tasks, and session.",
|
|
6472
|
-
{ task_id:
|
|
6898
|
+
{ task_id: z9.string().describe("The task ID to look up") },
|
|
6473
6899
|
async ({ task_id }) => {
|
|
6474
6900
|
try {
|
|
6475
6901
|
const task = await connection.call("getProjectTask", { projectId, taskId: task_id });
|
|
@@ -6486,10 +6912,10 @@ function buildTaskListTools(connection) {
|
|
|
6486
6912
|
"search_tasks",
|
|
6487
6913
|
"Search tasks by tags, text query, or status filters.",
|
|
6488
6914
|
{
|
|
6489
|
-
tagNames:
|
|
6490
|
-
searchQuery:
|
|
6491
|
-
statusFilters:
|
|
6492
|
-
limit:
|
|
6915
|
+
tagNames: z9.array(z9.string()).optional().describe("Filter by tag names"),
|
|
6916
|
+
searchQuery: z9.string().optional().describe("Text search in title/description"),
|
|
6917
|
+
statusFilters: z9.array(z9.string()).optional().describe("Filter by statuses"),
|
|
6918
|
+
limit: z9.number().optional().describe("Max results (default 20)")
|
|
6493
6919
|
},
|
|
6494
6920
|
async (params) => {
|
|
6495
6921
|
try {
|
|
@@ -6549,11 +6975,11 @@ function buildMutationTools(connection) {
|
|
|
6549
6975
|
"create_task",
|
|
6550
6976
|
"Create a new task in the project.",
|
|
6551
6977
|
{
|
|
6552
|
-
title:
|
|
6553
|
-
description:
|
|
6554
|
-
plan:
|
|
6555
|
-
status:
|
|
6556
|
-
isBug:
|
|
6978
|
+
title: z9.string().describe("Task title"),
|
|
6979
|
+
description: z9.string().optional().describe("Task description"),
|
|
6980
|
+
plan: z9.string().optional().describe("Implementation plan in markdown"),
|
|
6981
|
+
status: z9.string().optional().describe("Initial status (default: Planning)"),
|
|
6982
|
+
isBug: z9.boolean().optional().describe("Whether this is a bug report")
|
|
6557
6983
|
},
|
|
6558
6984
|
async (params) => {
|
|
6559
6985
|
try {
|
|
@@ -6570,12 +6996,12 @@ function buildMutationTools(connection) {
|
|
|
6570
6996
|
"update_task",
|
|
6571
6997
|
"Update an existing task's title, description, plan, status, or assignee.",
|
|
6572
6998
|
{
|
|
6573
|
-
task_id:
|
|
6574
|
-
title:
|
|
6575
|
-
description:
|
|
6576
|
-
plan:
|
|
6577
|
-
status:
|
|
6578
|
-
assignedUserId:
|
|
6999
|
+
task_id: z9.string().describe("The task ID to update"),
|
|
7000
|
+
title: z9.string().optional().describe("New title"),
|
|
7001
|
+
description: z9.string().optional().describe("New description"),
|
|
7002
|
+
plan: z9.string().optional().describe("New plan in markdown"),
|
|
7003
|
+
status: z9.string().optional().describe("New status"),
|
|
7004
|
+
assignedUserId: z9.string().nullable().optional().describe("Assign to user ID, or null to unassign")
|
|
6579
7005
|
},
|
|
6580
7006
|
async ({ task_id, ...fields }) => {
|
|
6581
7007
|
try {
|
|
@@ -7445,4 +7871,4 @@ export {
|
|
|
7445
7871
|
loadForwardPorts,
|
|
7446
7872
|
loadConveyorConfig
|
|
7447
7873
|
};
|
|
7448
|
-
//# sourceMappingURL=chunk-
|
|
7874
|
+
//# sourceMappingURL=chunk-LKO3CBJU.js.map
|