@rallycry/conveyor-agent 8.0.1 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-2L7ROQE6.js → chunk-W4NCD23G.js} +413 -169
- package/dist/chunk-W4NCD23G.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2L7ROQE6.js.map +0 -1
|
@@ -1233,8 +1233,8 @@ var PlanSync = class {
|
|
|
1233
1233
|
for (const file of readdirSync(plansDir).filter((f) => f.endsWith(".md"))) {
|
|
1234
1234
|
try {
|
|
1235
1235
|
const fullPath = join(plansDir, file);
|
|
1236
|
-
const
|
|
1237
|
-
this.planFileSnapshot.set(fullPath,
|
|
1236
|
+
const stat3 = statSync(fullPath);
|
|
1237
|
+
this.planFileSnapshot.set(fullPath, stat3.mtimeMs);
|
|
1238
1238
|
} catch {
|
|
1239
1239
|
continue;
|
|
1240
1240
|
}
|
|
@@ -1255,11 +1255,11 @@ var PlanSync = class {
|
|
|
1255
1255
|
for (const file of files) {
|
|
1256
1256
|
const fullPath = join(plansDir, file);
|
|
1257
1257
|
try {
|
|
1258
|
-
const
|
|
1258
|
+
const stat3 = statSync(fullPath);
|
|
1259
1259
|
const prevMtime = this.planFileSnapshot.get(fullPath);
|
|
1260
|
-
const isNew = prevMtime === void 0 ||
|
|
1261
|
-
if (isNew && (!newest ||
|
|
1262
|
-
newest = { path: fullPath, mtime:
|
|
1260
|
+
const isNew = prevMtime === void 0 || stat3.mtimeMs > prevMtime;
|
|
1261
|
+
if (isNew && (!newest || stat3.mtimeMs > newest.mtime)) {
|
|
1262
|
+
newest = { path: fullPath, mtime: stat3.mtimeMs };
|
|
1263
1263
|
}
|
|
1264
1264
|
} catch {
|
|
1265
1265
|
continue;
|
|
@@ -1304,7 +1304,7 @@ var PlanSync = class {
|
|
|
1304
1304
|
import { createHash } from "crypto";
|
|
1305
1305
|
import { existsSync } from "fs";
|
|
1306
1306
|
import { homedir } from "os";
|
|
1307
|
-
import { join as
|
|
1307
|
+
import { join as join3 } from "path";
|
|
1308
1308
|
|
|
1309
1309
|
// ../shared/dist/index.js
|
|
1310
1310
|
import { z } from "zod";
|
|
@@ -1365,7 +1365,21 @@ var GetSuggestionsRequestSchema = z.object({
|
|
|
1365
1365
|
status: z.string().optional(),
|
|
1366
1366
|
limit: z.number().int().min(1).max(100).optional()
|
|
1367
1367
|
});
|
|
1368
|
+
var ListManualTestsRequestSchema = z.object({
|
|
1369
|
+
sessionId: z.string()
|
|
1370
|
+
});
|
|
1368
1371
|
var CreatePullRequestRequestSchema = CreatePRInputSchema.extend({ sessionId: z.string() });
|
|
1372
|
+
var RequestFileUploadRequestSchema = z.object({
|
|
1373
|
+
sessionId: z.string(),
|
|
1374
|
+
fileName: z.string().min(1).max(255),
|
|
1375
|
+
mimeType: z.string().min(1).max(128),
|
|
1376
|
+
fileSize: z.number().int().positive().max(MAX_FILE_SIZE_BYTES)
|
|
1377
|
+
});
|
|
1378
|
+
var ConfirmFileUploadRequestSchema = z.object({
|
|
1379
|
+
sessionId: z.string(),
|
|
1380
|
+
fileId: z.string(),
|
|
1381
|
+
title: z.string().max(500).optional()
|
|
1382
|
+
});
|
|
1369
1383
|
var UpdateTaskStatusRequestSchema = z.object({
|
|
1370
1384
|
sessionId: z.string(),
|
|
1371
1385
|
status: z.string(),
|
|
@@ -1375,6 +1389,10 @@ var StoreSessionIdRequestSchema = z.object({
|
|
|
1375
1389
|
sessionId: z.string(),
|
|
1376
1390
|
sdkSessionId: z.string()
|
|
1377
1391
|
});
|
|
1392
|
+
var SetManualTestsRequestSchema = z.object({
|
|
1393
|
+
sessionId: z.string(),
|
|
1394
|
+
items: z.array(z.object({ title: z.string().min(1) })).min(1)
|
|
1395
|
+
});
|
|
1378
1396
|
var TrackSpendingRequestSchema = z.object({
|
|
1379
1397
|
sessionId: z.string(),
|
|
1380
1398
|
inputTokens: z.number().int().nonnegative(),
|
|
@@ -1700,7 +1718,10 @@ var ListProjectTasksRequestSchema = z2.object({
|
|
|
1700
1718
|
projectId: z2.string(),
|
|
1701
1719
|
status: z2.string().optional(),
|
|
1702
1720
|
assigneeId: z2.string().optional(),
|
|
1721
|
+
unassigned: z2.boolean().optional(),
|
|
1703
1722
|
limit: z2.number().int().positive().optional().default(50)
|
|
1723
|
+
}).refine((p) => !(p.unassigned && p.assigneeId), {
|
|
1724
|
+
message: "Pass either assigneeId or unassigned, not both"
|
|
1704
1725
|
});
|
|
1705
1726
|
var GetProjectTaskRequestSchema = z2.object({
|
|
1706
1727
|
projectId: z2.string(),
|
|
@@ -1711,7 +1732,11 @@ var SearchProjectTasksRequestSchema = z2.object({
|
|
|
1711
1732
|
tagNames: z2.array(z2.string()).optional(),
|
|
1712
1733
|
searchQuery: z2.string().optional(),
|
|
1713
1734
|
statusFilters: z2.array(z2.string()).optional(),
|
|
1735
|
+
assigneeId: z2.string().optional(),
|
|
1736
|
+
unassigned: z2.boolean().optional(),
|
|
1714
1737
|
limit: z2.number().int().positive().optional().default(20)
|
|
1738
|
+
}).refine((p) => !(p.unassigned && p.assigneeId), {
|
|
1739
|
+
message: "Pass either assigneeId or unassigned, not both"
|
|
1715
1740
|
});
|
|
1716
1741
|
var ListProjectTagsRequestSchema = z2.object({
|
|
1717
1742
|
projectId: z2.string()
|
|
@@ -1901,6 +1926,21 @@ var CreateProjectPullRequestRequestSchema = z2.object({
|
|
|
1901
1926
|
base: z2.string().optional(),
|
|
1902
1927
|
requestingUserId: z2.string().optional()
|
|
1903
1928
|
});
|
|
1929
|
+
var ListProjectMembersRequestSchema = z2.object({
|
|
1930
|
+
projectId: z2.string()
|
|
1931
|
+
});
|
|
1932
|
+
var AddProjectTaskReviewerRequestSchema = z2.object({
|
|
1933
|
+
projectId: z2.string(),
|
|
1934
|
+
taskId: z2.string(),
|
|
1935
|
+
userId: z2.string(),
|
|
1936
|
+
requestingUserId: z2.string().optional()
|
|
1937
|
+
});
|
|
1938
|
+
var RemoveProjectTaskReviewerRequestSchema = z2.object({
|
|
1939
|
+
projectId: z2.string(),
|
|
1940
|
+
taskId: z2.string(),
|
|
1941
|
+
userId: z2.string(),
|
|
1942
|
+
requestingUserId: z2.string().optional()
|
|
1943
|
+
});
|
|
1904
1944
|
var StartTaskAuditRequestSchema = z3.object({
|
|
1905
1945
|
projectId: z3.string(),
|
|
1906
1946
|
taskIds: z3.array(z3.string()).min(1)
|
|
@@ -3845,26 +3885,150 @@ function buildMutationTools(connection, config) {
|
|
|
3845
3885
|
];
|
|
3846
3886
|
}
|
|
3847
3887
|
|
|
3888
|
+
// src/tools/attachment-tools.ts
|
|
3889
|
+
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
3890
|
+
import { basename, extname, isAbsolute, join as join2 } from "path";
|
|
3891
|
+
import { z as z7 } from "zod";
|
|
3892
|
+
var IMAGE_MIME_BY_EXT = {
|
|
3893
|
+
".png": "image/png",
|
|
3894
|
+
".jpg": "image/jpeg",
|
|
3895
|
+
".jpeg": "image/jpeg",
|
|
3896
|
+
".gif": "image/gif",
|
|
3897
|
+
".webp": "image/webp"
|
|
3898
|
+
};
|
|
3899
|
+
function buildUploadAttachmentTool(connection, config) {
|
|
3900
|
+
return defineTool(
|
|
3901
|
+
"upload_attachment",
|
|
3902
|
+
"Upload an image file (e.g. a Playwright screenshot) as a task attachment AND post it to the task chat in one step \u2014 no follow-up post_to_chat call needed. Supports png/jpg/gif/webp.",
|
|
3903
|
+
{
|
|
3904
|
+
path: z7.string().describe("Path to the image file \u2014 absolute, or relative to the workspace root"),
|
|
3905
|
+
title: z7.string().optional().describe("Short caption posted with the image (defaults to the file name)")
|
|
3906
|
+
},
|
|
3907
|
+
async ({ path: path2, title }) => {
|
|
3908
|
+
try {
|
|
3909
|
+
const filePath = isAbsolute(path2) ? path2 : join2(config.workspaceDir, path2);
|
|
3910
|
+
const mimeType = IMAGE_MIME_BY_EXT[extname(filePath).toLowerCase()];
|
|
3911
|
+
if (!mimeType) {
|
|
3912
|
+
return textResult(
|
|
3913
|
+
`Unsupported file type "${extname(filePath) || "(none)"}". Supported: ${Object.keys(IMAGE_MIME_BY_EXT).join(", ")}`
|
|
3914
|
+
);
|
|
3915
|
+
}
|
|
3916
|
+
const info = await stat2(filePath).catch(() => null);
|
|
3917
|
+
if (!info?.isFile()) {
|
|
3918
|
+
return textResult(`File not found: ${filePath}`);
|
|
3919
|
+
}
|
|
3920
|
+
if (info.size > MAX_FILE_SIZE_BYTES) {
|
|
3921
|
+
return textResult(
|
|
3922
|
+
`File is ${info.size} bytes \u2014 exceeds the ${MAX_FILE_SIZE_BYTES} byte upload limit. Resize or crop the image first.`
|
|
3923
|
+
);
|
|
3924
|
+
}
|
|
3925
|
+
const fileName = basename(filePath);
|
|
3926
|
+
const { fileId, uploadUrl } = await connection.call("requestFileUpload", {
|
|
3927
|
+
sessionId: connection.sessionId,
|
|
3928
|
+
fileName,
|
|
3929
|
+
mimeType,
|
|
3930
|
+
fileSize: info.size
|
|
3931
|
+
});
|
|
3932
|
+
const body = await readFile2(filePath);
|
|
3933
|
+
const res = await fetch(uploadUrl, {
|
|
3934
|
+
method: "PUT",
|
|
3935
|
+
headers: { "Content-Type": mimeType },
|
|
3936
|
+
body
|
|
3937
|
+
});
|
|
3938
|
+
if (!res.ok) {
|
|
3939
|
+
return textResult(
|
|
3940
|
+
`Upload to storage failed: HTTP ${res.status} ${await res.text().catch(() => "")}`
|
|
3941
|
+
);
|
|
3942
|
+
}
|
|
3943
|
+
const result = await connection.call("confirmFileUpload", {
|
|
3944
|
+
sessionId: connection.sessionId,
|
|
3945
|
+
fileId,
|
|
3946
|
+
title
|
|
3947
|
+
});
|
|
3948
|
+
return textResult(
|
|
3949
|
+
`Uploaded ${fileName} (${info.size} bytes) and posted it to the task chat${title ? ` with caption "${title}"` : ""}. File ID: ${result.fileId}`
|
|
3950
|
+
);
|
|
3951
|
+
} catch (error) {
|
|
3952
|
+
return textResult(
|
|
3953
|
+
`Failed to upload attachment: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3954
|
+
);
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
);
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
// src/tools/checklist-tools.ts
|
|
3961
|
+
import { z as z8 } from "zod";
|
|
3962
|
+
function buildListManualTestsTool(connection) {
|
|
3963
|
+
return defineTool(
|
|
3964
|
+
"list_manual_tests",
|
|
3965
|
+
"List the manual test checklist items for the current task. Use to see what manual verification steps have already been recorded.",
|
|
3966
|
+
{},
|
|
3967
|
+
async () => {
|
|
3968
|
+
try {
|
|
3969
|
+
const items = await connection.call("listManualTests", {
|
|
3970
|
+
sessionId: connection.sessionId
|
|
3971
|
+
});
|
|
3972
|
+
if (items.length === 0) return textResult("No manual tests recorded for this task.");
|
|
3973
|
+
const lines = items.map((item, i) => {
|
|
3974
|
+
const checked = item.checked ? "[x]" : "[ ]";
|
|
3975
|
+
return `${i + 1}. ${checked} ${item.title}`;
|
|
3976
|
+
});
|
|
3977
|
+
return textResult(lines.join("\n"));
|
|
3978
|
+
} catch {
|
|
3979
|
+
return textResult("Failed to list manual tests.");
|
|
3980
|
+
}
|
|
3981
|
+
},
|
|
3982
|
+
{ annotations: { readOnlyHint: true } }
|
|
3983
|
+
);
|
|
3984
|
+
}
|
|
3985
|
+
function buildSetManualTestsTool(connection) {
|
|
3986
|
+
return defineTool(
|
|
3987
|
+
"set_manual_tests",
|
|
3988
|
+
"Add manual test steps to the task checklist. Existing items with the same title are automatically skipped (deduplication). Use to record specific manual verification steps that reviewers should follow when testing this PR.",
|
|
3989
|
+
{
|
|
3990
|
+
items: z8.array(z8.object({ title: z8.string().min(1).describe("A concise, actionable test step") })).min(1).describe("List of manual test steps to add")
|
|
3991
|
+
},
|
|
3992
|
+
async ({ items }) => {
|
|
3993
|
+
try {
|
|
3994
|
+
const result = await connection.call("setManualTests", {
|
|
3995
|
+
sessionId: connection.sessionId,
|
|
3996
|
+
items
|
|
3997
|
+
});
|
|
3998
|
+
const parts = [`Created ${result.created} manual test item(s).`];
|
|
3999
|
+
if (result.skipped > 0) parts.push(`Skipped ${result.skipped} duplicate(s).`);
|
|
4000
|
+
return textResult(parts.join(" "));
|
|
4001
|
+
} catch (error) {
|
|
4002
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
4003
|
+
return textResult(`Failed to set manual tests: ${msg}`);
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
);
|
|
4007
|
+
}
|
|
4008
|
+
|
|
3848
4009
|
// src/tools/common-tools.ts
|
|
3849
4010
|
function buildCommonTools(connection, config) {
|
|
3850
4011
|
return [
|
|
3851
4012
|
...buildTaskContextTools(connection),
|
|
3852
4013
|
buildGetDependenciesTool(connection),
|
|
3853
4014
|
buildGetSuggestionsTool(connection),
|
|
3854
|
-
|
|
4015
|
+
buildListManualTestsTool(connection),
|
|
4016
|
+
buildSetManualTestsTool(connection),
|
|
4017
|
+
...buildMutationTools(connection, config),
|
|
4018
|
+
buildUploadAttachmentTool(connection, config)
|
|
3855
4019
|
];
|
|
3856
4020
|
}
|
|
3857
4021
|
|
|
3858
4022
|
// src/tools/pm-tools.ts
|
|
3859
|
-
import { z as
|
|
4023
|
+
import { z as z9 } from "zod";
|
|
3860
4024
|
var SP_DESCRIPTION = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
|
|
3861
4025
|
function buildUpdateTaskTool(connection) {
|
|
3862
4026
|
return defineTool(
|
|
3863
4027
|
"update_task_plan",
|
|
3864
4028
|
"Save the finalized plan and/or description to the current task. Use in Plan mode after alignment. For children use update_subtask; for title/tags/PR use update_task_properties.",
|
|
3865
4029
|
{
|
|
3866
|
-
plan:
|
|
3867
|
-
description:
|
|
4030
|
+
plan: z9.string().optional().describe("The task plan in markdown"),
|
|
4031
|
+
description: z9.string().optional().describe("Updated task description")
|
|
3868
4032
|
},
|
|
3869
4033
|
async ({ plan, description }) => {
|
|
3870
4034
|
try {
|
|
@@ -3885,11 +4049,11 @@ function buildCreateSubtaskTool(connection) {
|
|
|
3885
4049
|
"create_subtask",
|
|
3886
4050
|
"Create a subtask under the current parent task. Use when breaking a complex parent into smaller pieces during planning. For post-task follow-ups use create_follow_up_task.",
|
|
3887
4051
|
{
|
|
3888
|
-
title:
|
|
3889
|
-
description:
|
|
3890
|
-
plan:
|
|
3891
|
-
ordinal:
|
|
3892
|
-
storyPointValue:
|
|
4052
|
+
title: z9.string().describe("Subtask title"),
|
|
4053
|
+
description: z9.string().optional().describe("Brief description"),
|
|
4054
|
+
plan: z9.string().optional().describe("Implementation plan in markdown"),
|
|
4055
|
+
ordinal: z9.number().optional().describe("Step/order number (0-based)"),
|
|
4056
|
+
storyPointValue: z9.number().optional().describe(SP_DESCRIPTION)
|
|
3893
4057
|
},
|
|
3894
4058
|
async ({ title, description, plan, ordinal, storyPointValue }) => {
|
|
3895
4059
|
try {
|
|
@@ -3915,12 +4079,12 @@ function buildUpdateSubtaskTool(connection) {
|
|
|
3915
4079
|
"update_subtask",
|
|
3916
4080
|
"Update an existing subtask's fields (title, description, plan, ordinal, storyPointValue). Use when refining a child's plan or reordering. For the current task use update_task_plan.",
|
|
3917
4081
|
{
|
|
3918
|
-
subtaskId:
|
|
3919
|
-
title:
|
|
3920
|
-
description:
|
|
3921
|
-
plan:
|
|
3922
|
-
ordinal:
|
|
3923
|
-
storyPointValue:
|
|
4082
|
+
subtaskId: z9.string().describe("The subtask ID to update"),
|
|
4083
|
+
title: z9.string().optional(),
|
|
4084
|
+
description: z9.string().optional(),
|
|
4085
|
+
plan: z9.string().optional(),
|
|
4086
|
+
ordinal: z9.number().optional(),
|
|
4087
|
+
storyPointValue: z9.number().optional().describe(SP_DESCRIPTION)
|
|
3924
4088
|
},
|
|
3925
4089
|
async ({ subtaskId, title, description, plan, storyPointValue }) => {
|
|
3926
4090
|
try {
|
|
@@ -3943,7 +4107,7 @@ function buildDeleteSubtaskTool(connection) {
|
|
|
3943
4107
|
return defineTool(
|
|
3944
4108
|
"delete_subtask",
|
|
3945
4109
|
"Delete a subtask by id. When to use: a subtask was created in error or is no longer needed. Returns: confirmation string.",
|
|
3946
|
-
{ subtaskId:
|
|
4110
|
+
{ subtaskId: z9.string().describe("The subtask ID to delete") },
|
|
3947
4111
|
async ({ subtaskId }) => {
|
|
3948
4112
|
try {
|
|
3949
4113
|
await connection.call("deleteSubtask", {
|
|
@@ -3981,7 +4145,7 @@ function buildPackTools(connection) {
|
|
|
3981
4145
|
"start_child_cloud_build",
|
|
3982
4146
|
"Start a cloud build (codespace) for a child task. Preconditions: child is in Open status, has a story point value, and has an agent assigned.",
|
|
3983
4147
|
{
|
|
3984
|
-
childTaskId:
|
|
4148
|
+
childTaskId: z9.string().describe("The child task ID to start a cloud build for")
|
|
3985
4149
|
},
|
|
3986
4150
|
async ({ childTaskId }) => {
|
|
3987
4151
|
try {
|
|
@@ -4001,7 +4165,7 @@ function buildPackTools(connection) {
|
|
|
4001
4165
|
"stop_child_build",
|
|
4002
4166
|
"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.",
|
|
4003
4167
|
{
|
|
4004
|
-
childTaskId:
|
|
4168
|
+
childTaskId: z9.string().describe("The child task ID whose build should be stopped")
|
|
4005
4169
|
},
|
|
4006
4170
|
async ({ childTaskId }) => {
|
|
4007
4171
|
try {
|
|
@@ -4021,7 +4185,7 @@ function buildPackTools(connection) {
|
|
|
4021
4185
|
"approve_and_merge_pr",
|
|
4022
4186
|
"Approve and merge a child task's PR. Preconditions: child in ReviewPR. Returns { merged }: true = merged (status\u2192ReviewDev); false = automerge queued, wait for ReviewDev.",
|
|
4023
4187
|
{
|
|
4024
|
-
childTaskId:
|
|
4188
|
+
childTaskId: z9.string().describe("The child task ID whose PR should be approved and merged")
|
|
4025
4189
|
},
|
|
4026
4190
|
async ({ childTaskId }) => {
|
|
4027
4191
|
try {
|
|
@@ -4059,7 +4223,7 @@ function buildPmTools(connection, options) {
|
|
|
4059
4223
|
}
|
|
4060
4224
|
|
|
4061
4225
|
// src/tools/discovery-tools.ts
|
|
4062
|
-
import { z as
|
|
4226
|
+
import { z as z10 } from "zod";
|
|
4063
4227
|
var SP_DESCRIPTION2 = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
|
|
4064
4228
|
function buildDiscoveryTools(connection) {
|
|
4065
4229
|
return [
|
|
@@ -4067,11 +4231,11 @@ function buildDiscoveryTools(connection) {
|
|
|
4067
4231
|
"update_task_properties",
|
|
4068
4232
|
"Set one or more task properties in a single call. All fields are optional \u2014 only include the fields you want to update.",
|
|
4069
4233
|
{
|
|
4070
|
-
title:
|
|
4071
|
-
storyPointValue:
|
|
4072
|
-
tagNames:
|
|
4073
|
-
githubPRUrl:
|
|
4074
|
-
githubBranch:
|
|
4234
|
+
title: z10.string().optional().describe("The new task title"),
|
|
4235
|
+
storyPointValue: z10.number().optional().describe(SP_DESCRIPTION2),
|
|
4236
|
+
tagNames: z10.array(z10.string()).optional().describe("Array of tag names to assign"),
|
|
4237
|
+
githubPRUrl: z10.string().url().optional().describe("GitHub pull request URL to link to this task"),
|
|
4238
|
+
githubBranch: z10.string().optional().describe("Set the GitHub branch name for this task (e.g. 'conveyor/my-feature-abc123')")
|
|
4075
4239
|
},
|
|
4076
4240
|
async ({ title, storyPointValue, tagNames, githubPRUrl, githubBranch }) => {
|
|
4077
4241
|
try {
|
|
@@ -4102,14 +4266,14 @@ function buildDiscoveryTools(connection) {
|
|
|
4102
4266
|
}
|
|
4103
4267
|
|
|
4104
4268
|
// src/tools/code-review-tools.ts
|
|
4105
|
-
import { z as
|
|
4269
|
+
import { z as z11 } from "zod";
|
|
4106
4270
|
function buildCodeReviewTools(connection) {
|
|
4107
4271
|
return [
|
|
4108
4272
|
defineTool(
|
|
4109
4273
|
"approve_code_review",
|
|
4110
4274
|
"Approve the code review and exit. Use when the diff passes all review criteria. Takes only a summary \u2014 for changes, use request_code_changes with a structured issues[] list.",
|
|
4111
4275
|
{
|
|
4112
|
-
summary:
|
|
4276
|
+
summary: z11.string().describe("Brief summary of what was reviewed and why it looks good")
|
|
4113
4277
|
},
|
|
4114
4278
|
async ({ summary }) => {
|
|
4115
4279
|
const content = `**Code Review: Approved** :white_check_mark:
|
|
@@ -4132,15 +4296,15 @@ ${summary}`;
|
|
|
4132
4296
|
"request_code_changes",
|
|
4133
4297
|
"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 }.",
|
|
4134
4298
|
{
|
|
4135
|
-
issues:
|
|
4136
|
-
|
|
4137
|
-
file:
|
|
4138
|
-
line:
|
|
4139
|
-
severity:
|
|
4140
|
-
description:
|
|
4299
|
+
issues: z11.array(
|
|
4300
|
+
z11.object({
|
|
4301
|
+
file: z11.string().describe("File path where the issue was found"),
|
|
4302
|
+
line: z11.number().optional().describe("Line number (if applicable)"),
|
|
4303
|
+
severity: z11.enum(["critical", "major", "minor"]).describe("Issue severity"),
|
|
4304
|
+
description: z11.string().describe("What is wrong and how to fix it")
|
|
4141
4305
|
})
|
|
4142
4306
|
).describe("List of issues found during review"),
|
|
4143
|
-
summary:
|
|
4307
|
+
summary: z11.string().describe("Brief overall summary of the review findings")
|
|
4144
4308
|
},
|
|
4145
4309
|
async ({ issues, summary }) => {
|
|
4146
4310
|
const issueLines = issues.map((issue) => {
|
|
@@ -4170,10 +4334,10 @@ ${issueLines}`;
|
|
|
4170
4334
|
}
|
|
4171
4335
|
|
|
4172
4336
|
// src/tools/debug-tools.ts
|
|
4173
|
-
import { z as
|
|
4337
|
+
import { z as z14 } from "zod";
|
|
4174
4338
|
|
|
4175
4339
|
// src/tools/telemetry-tools.ts
|
|
4176
|
-
import { z as
|
|
4340
|
+
import { z as z12 } from "zod";
|
|
4177
4341
|
|
|
4178
4342
|
// src/debug/telemetry-injector.ts
|
|
4179
4343
|
var BUFFER_SIZE = 200;
|
|
@@ -4568,12 +4732,12 @@ function buildGetTelemetryTool(manager) {
|
|
|
4568
4732
|
"debug_get_telemetry",
|
|
4569
4733
|
"Query structured telemetry events (HTTP, DB, Socket.IO, errors) captured from the dev server. Returns filtered structured data instead of raw logs.",
|
|
4570
4734
|
{
|
|
4571
|
-
type:
|
|
4572
|
-
urlPattern:
|
|
4573
|
-
minDuration:
|
|
4574
|
-
errorOnly:
|
|
4575
|
-
since:
|
|
4576
|
-
limit:
|
|
4735
|
+
type: z12.enum(["http", "db", "socket", "error"]).optional().describe("Filter by event type"),
|
|
4736
|
+
urlPattern: z12.string().optional().describe("Regex pattern to filter HTTP events by URL"),
|
|
4737
|
+
minDuration: z12.number().optional().describe("Minimum duration in ms \u2014 only return events slower than this"),
|
|
4738
|
+
errorOnly: z12.boolean().optional().describe("Only return error events and HTTP 4xx/5xx responses"),
|
|
4739
|
+
since: z12.number().optional().describe("Only return events after this timestamp (ms since epoch)"),
|
|
4740
|
+
limit: z12.number().optional().describe("Max events to return (default: 20, from most recent)")
|
|
4577
4741
|
},
|
|
4578
4742
|
async ({ type, urlPattern, minDuration, errorOnly, since, limit }) => {
|
|
4579
4743
|
const clientOrErr = requireDebugClient(manager);
|
|
@@ -4643,7 +4807,7 @@ function buildTelemetryTools(manager) {
|
|
|
4643
4807
|
}
|
|
4644
4808
|
|
|
4645
4809
|
// src/tools/client-debug-tools.ts
|
|
4646
|
-
import { z as
|
|
4810
|
+
import { z as z13 } from "zod";
|
|
4647
4811
|
function requirePlaywrightClient(manager) {
|
|
4648
4812
|
if (!manager.isClientDebugMode()) {
|
|
4649
4813
|
return "Client debug mode is not active. Use debug_enter_mode with clientSide: true first.";
|
|
@@ -4663,11 +4827,11 @@ function buildClientBreakpointTools(manager) {
|
|
|
4663
4827
|
"debug_set_client_breakpoint",
|
|
4664
4828
|
"Set a breakpoint in client-side code running in headless Chromium. V8 resolves source maps automatically \u2014 use original .tsx/.ts file paths.",
|
|
4665
4829
|
{
|
|
4666
|
-
file:
|
|
4830
|
+
file: z13.string().describe(
|
|
4667
4831
|
"Original source file path (e.g., src/components/App.tsx) \u2014 source maps resolve automatically"
|
|
4668
4832
|
),
|
|
4669
|
-
line:
|
|
4670
|
-
condition:
|
|
4833
|
+
line: z13.number().describe("Line number (1-based) in the original source file"),
|
|
4834
|
+
condition: z13.string().optional().describe("JavaScript condition expression \u2014 breakpoint only triggers when truthy")
|
|
4671
4835
|
},
|
|
4672
4836
|
async ({ file, line, condition }) => {
|
|
4673
4837
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -4689,7 +4853,7 @@ Breakpoint ID: ${breakpointId}${sourceMapNote}`
|
|
|
4689
4853
|
"debug_remove_client_breakpoint",
|
|
4690
4854
|
"Remove a previously set client-side breakpoint by its ID.",
|
|
4691
4855
|
{
|
|
4692
|
-
breakpointId:
|
|
4856
|
+
breakpointId: z13.string().describe("The breakpoint ID returned by debug_set_client_breakpoint")
|
|
4693
4857
|
},
|
|
4694
4858
|
async ({ breakpointId }) => {
|
|
4695
4859
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -4769,8 +4933,8 @@ ${JSON.stringify(queuedHits, null, 2)}`
|
|
|
4769
4933
|
"debug_evaluate_client",
|
|
4770
4934
|
"Evaluate a JavaScript expression in the browser context. When paused, runs in the paused frame's scope; otherwise the page's global scope. Side effects execute \u2014 prefer read-only.",
|
|
4771
4935
|
{
|
|
4772
|
-
expression:
|
|
4773
|
-
frameIndex:
|
|
4936
|
+
expression: z13.string().describe("JavaScript expression to evaluate in the browser context"),
|
|
4937
|
+
frameIndex: z13.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
|
|
4774
4938
|
},
|
|
4775
4939
|
async ({ expression, frameIndex }) => {
|
|
4776
4940
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -4843,7 +5007,7 @@ function buildClientInteractionTools(manager) {
|
|
|
4843
5007
|
"debug_navigate_client",
|
|
4844
5008
|
"Navigate the headless browser to a URL. Waits for domcontentloaded (Playwright's default ~30s timeout applies).",
|
|
4845
5009
|
{
|
|
4846
|
-
url:
|
|
5010
|
+
url: z13.string().describe("URL to navigate to (e.g., http://localhost:3000/dashboard)")
|
|
4847
5011
|
},
|
|
4848
5012
|
async ({ url }) => {
|
|
4849
5013
|
const clientOrErr = requirePlaywrightClient(manager);
|
|
@@ -4860,7 +5024,7 @@ function buildClientInteractionTools(manager) {
|
|
|
4860
5024
|
"debug_click_client",
|
|
4861
5025
|
"Click an element in the headless browser by CSS selector. Playwright auto-waits for visibility/stability/enabled up to 10s \u2014 a miss throws with a failure message.",
|
|
4862
5026
|
{
|
|
4863
|
-
selector:
|
|
5027
|
+
selector: z13.string().describe(
|
|
4864
5028
|
"CSS selector of the element to click (e.g., 'button.submit', '#login-form input[type=submit]')"
|
|
4865
5029
|
)
|
|
4866
5030
|
},
|
|
@@ -4882,8 +5046,8 @@ function buildClientConsoleTool(manager) {
|
|
|
4882
5046
|
"debug_get_client_console",
|
|
4883
5047
|
"Get console messages captured from the headless browser. Includes console.log, warn, error, etc.",
|
|
4884
5048
|
{
|
|
4885
|
-
level:
|
|
4886
|
-
limit:
|
|
5049
|
+
level: z13.string().optional().describe("Filter by console level: log, warn, error, info, debug"),
|
|
5050
|
+
limit: z13.number().optional().describe("Maximum number of recent messages to return (default: all)")
|
|
4887
5051
|
},
|
|
4888
5052
|
// oxlint-disable-next-line require-await
|
|
4889
5053
|
async ({ level, limit }) => {
|
|
@@ -4910,8 +5074,8 @@ function buildClientNetworkTool(manager) {
|
|
|
4910
5074
|
"debug_get_client_network",
|
|
4911
5075
|
"Get network requests captured from the headless browser. Shows URLs, methods, status codes, and timing.",
|
|
4912
5076
|
{
|
|
4913
|
-
filter:
|
|
4914
|
-
limit:
|
|
5077
|
+
filter: z13.string().optional().describe("Regex pattern to filter requests by URL"),
|
|
5078
|
+
limit: z13.number().optional().describe("Maximum number of recent requests to return (default: all)")
|
|
4915
5079
|
},
|
|
4916
5080
|
// oxlint-disable-next-line require-await
|
|
4917
5081
|
async ({ filter, limit }) => {
|
|
@@ -4939,7 +5103,7 @@ function buildClientErrorsTool(manager) {
|
|
|
4939
5103
|
"debug_get_client_errors",
|
|
4940
5104
|
"Get uncaught errors captured from the headless browser. Includes error messages and source-mapped stack traces.",
|
|
4941
5105
|
{
|
|
4942
|
-
limit:
|
|
5106
|
+
limit: z13.number().optional().describe("Maximum number of recent errors to return (default: all)")
|
|
4943
5107
|
},
|
|
4944
5108
|
// oxlint-disable-next-line require-await
|
|
4945
5109
|
async ({ limit }) => {
|
|
@@ -5033,12 +5197,12 @@ function buildDebugLifecycleTools(manager) {
|
|
|
5033
5197
|
"debug_enter_mode",
|
|
5034
5198
|
"Activate debug mode. Default: server-only (Node --inspect via CDP). Set clientSide=true (previewUrl required) or both flags for full-stack (adds headless Chromium via Playwright).",
|
|
5035
5199
|
{
|
|
5036
|
-
hypothesis:
|
|
5037
|
-
serverSide:
|
|
5200
|
+
hypothesis: z14.string().optional().describe("Your hypothesis about the bug \u2014 helps track debugging intent"),
|
|
5201
|
+
serverSide: z14.boolean().optional().describe(
|
|
5038
5202
|
"Enable server-side Node.js debugging (default: true if clientSide is not set)"
|
|
5039
5203
|
),
|
|
5040
|
-
clientSide:
|
|
5041
|
-
previewUrl:
|
|
5204
|
+
clientSide: z14.boolean().optional().describe("Enable client-side browser debugging via headless Chromium + Playwright"),
|
|
5205
|
+
previewUrl: z14.string().optional().describe(
|
|
5042
5206
|
"Preview URL for client-side debugging (e.g., http://localhost:3000). Required when clientSide is true."
|
|
5043
5207
|
)
|
|
5044
5208
|
},
|
|
@@ -5074,9 +5238,9 @@ function buildBreakpointTools(manager) {
|
|
|
5074
5238
|
"debug_set_breakpoint",
|
|
5075
5239
|
"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.",
|
|
5076
5240
|
{
|
|
5077
|
-
file:
|
|
5078
|
-
line:
|
|
5079
|
-
condition:
|
|
5241
|
+
file: z14.string().describe("Absolute or relative file path to set the breakpoint in"),
|
|
5242
|
+
line: z14.number().describe("Line number (1-based) to set the breakpoint on"),
|
|
5243
|
+
condition: z14.string().optional().describe("JavaScript condition expression \u2014 breakpoint only triggers when truthy")
|
|
5080
5244
|
},
|
|
5081
5245
|
async ({ file, line, condition }) => {
|
|
5082
5246
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5098,7 +5262,7 @@ Breakpoint ID: ${breakpointId}`
|
|
|
5098
5262
|
"debug_remove_breakpoint",
|
|
5099
5263
|
"Remove a previously set breakpoint by its ID.",
|
|
5100
5264
|
{
|
|
5101
|
-
breakpointId:
|
|
5265
|
+
breakpointId: z14.string().describe("The breakpoint ID returned by debug_set_breakpoint")
|
|
5102
5266
|
},
|
|
5103
5267
|
async ({ breakpointId }) => {
|
|
5104
5268
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5179,8 +5343,8 @@ ${JSON.stringify(queuedHits, null, 2)}`
|
|
|
5179
5343
|
"debug_evaluate",
|
|
5180
5344
|
"Evaluate a JavaScript expression server-side in the Node process. When paused, runs in the frame's scope (frameIndex selects frame). Side effects execute \u2014 prefer read-only.",
|
|
5181
5345
|
{
|
|
5182
|
-
expression:
|
|
5183
|
-
frameIndex:
|
|
5346
|
+
expression: z14.string().describe("The JavaScript expression to evaluate"),
|
|
5347
|
+
frameIndex: z14.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
|
|
5184
5348
|
},
|
|
5185
5349
|
async ({ expression, frameIndex }) => {
|
|
5186
5350
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5208,12 +5372,12 @@ function buildProbeManagementTools(manager) {
|
|
|
5208
5372
|
"debug_add_probe",
|
|
5209
5373
|
"Add a debug probe at a code location. Captures expression values each time the line executes, without pausing or modifying source. Auto-cleaned on debug exit.",
|
|
5210
5374
|
{
|
|
5211
|
-
file:
|
|
5212
|
-
line:
|
|
5213
|
-
expressions:
|
|
5375
|
+
file: z14.string().describe("File path to probe"),
|
|
5376
|
+
line: z14.number().describe("Line number (1-based) to probe"),
|
|
5377
|
+
expressions: z14.array(z14.string()).describe(
|
|
5214
5378
|
'JavaScript expressions to capture when the line executes (e.g., ["req.params.id", "user.role"])'
|
|
5215
5379
|
),
|
|
5216
|
-
label:
|
|
5380
|
+
label: z14.string().optional().describe("Optional label for this probe (defaults to file:line)")
|
|
5217
5381
|
},
|
|
5218
5382
|
async ({ file, line, expressions, label }) => {
|
|
5219
5383
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5238,7 +5402,7 @@ Trigger the code path, then use debug_get_probe_results to see captured values.`
|
|
|
5238
5402
|
"debug_remove_probe",
|
|
5239
5403
|
"Remove a previously set debug probe by its ID.",
|
|
5240
5404
|
{
|
|
5241
|
-
probeId:
|
|
5405
|
+
probeId: z14.string().describe("The probe ID returned by debug_add_probe")
|
|
5242
5406
|
},
|
|
5243
5407
|
async ({ probeId }) => {
|
|
5244
5408
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5278,9 +5442,9 @@ function buildProbeResultTools(manager) {
|
|
|
5278
5442
|
"debug_get_probe_results",
|
|
5279
5443
|
"Fetch captured probe hit data. Filter by label (wins) or probeId. Returns grouped text with per-probe hit count, timestamps, and captured expression values.",
|
|
5280
5444
|
{
|
|
5281
|
-
probeId:
|
|
5282
|
-
label:
|
|
5283
|
-
limit:
|
|
5445
|
+
probeId: z14.string().optional().describe("Filter results by probe ID (resolves to its label)"),
|
|
5446
|
+
label: z14.string().optional().describe("Filter results by probe label"),
|
|
5447
|
+
limit: z14.number().optional().describe("Maximum number of recent hits to return (default: all)")
|
|
5284
5448
|
},
|
|
5285
5449
|
async ({ probeId, label, limit }) => {
|
|
5286
5450
|
const clientOrErr = requireDebugClient2(manager);
|
|
@@ -5503,9 +5667,6 @@ async function processAssistantEvent(event, host, turnToolCalls) {
|
|
|
5503
5667
|
await host.callbacks.onEvent({ type: "tool_use", tool: block.name, input: inputStr });
|
|
5504
5668
|
}
|
|
5505
5669
|
}
|
|
5506
|
-
if (turnTextParts.length > 0) {
|
|
5507
|
-
host.connection.postChatMessage(turnTextParts.join("\n\n"));
|
|
5508
|
-
}
|
|
5509
5670
|
}
|
|
5510
5671
|
var API_ERROR_PATTERN = /API Error: (?:[45]\d\d|terminated)/;
|
|
5511
5672
|
var IMAGE_ERROR_PATTERN = /Could not process image/i;
|
|
@@ -6235,7 +6396,7 @@ function taskIdToSessionUuid(taskId) {
|
|
|
6235
6396
|
function sessionFileExists(sessionUuid, cwd) {
|
|
6236
6397
|
try {
|
|
6237
6398
|
const cwdSlug = cwd.replace(/\//g, "-");
|
|
6238
|
-
const sessionFile =
|
|
6399
|
+
const sessionFile = join3(homedir(), ".claude", "projects", cwdSlug, `${sessionUuid}.jsonl`);
|
|
6239
6400
|
return existsSync(sessionFile);
|
|
6240
6401
|
} catch {
|
|
6241
6402
|
return false;
|
|
@@ -6901,7 +7062,7 @@ var QueryBridge = class {
|
|
|
6901
7062
|
|
|
6902
7063
|
// src/runner/session-runner-helpers.ts
|
|
6903
7064
|
import { readFileSync as readFileSync2 } from "fs";
|
|
6904
|
-
import { dirname, join as
|
|
7065
|
+
import { dirname, join as join4 } from "path";
|
|
6905
7066
|
import { fileURLToPath } from "url";
|
|
6906
7067
|
function mapChatHistory(messages) {
|
|
6907
7068
|
if (!messages) return [];
|
|
@@ -6930,7 +7091,7 @@ function readAgentVersion() {
|
|
|
6930
7091
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
6931
7092
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
6932
7093
|
try {
|
|
6933
|
-
const pkg = JSON.parse(readFileSync2(
|
|
7094
|
+
const pkg = JSON.parse(readFileSync2(join4(here, rel), "utf-8"));
|
|
6934
7095
|
if (pkg.version) return pkg.version;
|
|
6935
7096
|
} catch {
|
|
6936
7097
|
}
|
|
@@ -7943,13 +8104,13 @@ var CommitWatcher = class {
|
|
|
7943
8104
|
// src/runner/worktree.ts
|
|
7944
8105
|
import { execSync as execSync4 } from "child_process";
|
|
7945
8106
|
import { existsSync as existsSync2 } from "fs";
|
|
7946
|
-
import { join as
|
|
8107
|
+
import { join as join5 } from "path";
|
|
7947
8108
|
var WORKTREE_DIR = ".worktrees";
|
|
7948
8109
|
function ensureWorktree(projectDir, taskId, branch) {
|
|
7949
8110
|
if (projectDir.includes(`/${WORKTREE_DIR}/`)) {
|
|
7950
8111
|
return projectDir;
|
|
7951
8112
|
}
|
|
7952
|
-
const worktreePath =
|
|
8113
|
+
const worktreePath = join5(projectDir, WORKTREE_DIR, taskId);
|
|
7953
8114
|
if (existsSync2(worktreePath)) {
|
|
7954
8115
|
if (branch) {
|
|
7955
8116
|
if (hasUncommittedChanges(worktreePath)) {
|
|
@@ -7995,7 +8156,7 @@ function detachWorktreeBranch(projectDir, branch) {
|
|
|
7995
8156
|
}
|
|
7996
8157
|
}
|
|
7997
8158
|
function removeWorktree(projectDir, taskId) {
|
|
7998
|
-
const worktreePath =
|
|
8159
|
+
const worktreePath = join5(projectDir, WORKTREE_DIR, taskId);
|
|
7999
8160
|
if (!existsSync2(worktreePath)) return;
|
|
8000
8161
|
try {
|
|
8001
8162
|
execSync4(`git worktree remove "${worktreePath}" --force`, {
|
|
@@ -8066,10 +8227,10 @@ function runStartCommand(cmd, cwd, onOutput) {
|
|
|
8066
8227
|
}
|
|
8067
8228
|
|
|
8068
8229
|
// src/tools/project-tools.ts
|
|
8069
|
-
import { z as
|
|
8230
|
+
import { z as z17 } from "zod";
|
|
8070
8231
|
|
|
8071
8232
|
// src/tools/project-action-tools.ts
|
|
8072
|
-
import { z as
|
|
8233
|
+
import { z as z15 } from "zod";
|
|
8073
8234
|
var SP_DESCRIPTION3 = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
|
|
8074
8235
|
function withRequestingUser(payload, getRequestingUserId) {
|
|
8075
8236
|
const requestingUserId = getRequestingUserId();
|
|
@@ -8081,10 +8242,10 @@ function buildCreateTaskTool(connection, getRequestingUserId) {
|
|
|
8081
8242
|
"create_task",
|
|
8082
8243
|
"Create a new task in the project.",
|
|
8083
8244
|
{
|
|
8084
|
-
title:
|
|
8085
|
-
description:
|
|
8086
|
-
plan:
|
|
8087
|
-
status:
|
|
8245
|
+
title: z15.string().describe("Task title"),
|
|
8246
|
+
description: z15.string().optional().describe("Task description"),
|
|
8247
|
+
plan: z15.string().optional().describe("Implementation plan in markdown"),
|
|
8248
|
+
status: z15.string().optional().describe("Initial status (default: Planning)")
|
|
8088
8249
|
},
|
|
8089
8250
|
async (params) => {
|
|
8090
8251
|
try {
|
|
@@ -8105,12 +8266,12 @@ function buildUpdateProjectTaskTool(connection, getRequestingUserId) {
|
|
|
8105
8266
|
"update_project_task",
|
|
8106
8267
|
"Update an existing task's title, description, plan, status, or assignee. Project-runner scope.",
|
|
8107
8268
|
{
|
|
8108
|
-
task_id:
|
|
8109
|
-
title:
|
|
8110
|
-
description:
|
|
8111
|
-
plan:
|
|
8112
|
-
status:
|
|
8113
|
-
assignedUserId:
|
|
8269
|
+
task_id: z15.string().describe("The task ID to update"),
|
|
8270
|
+
title: z15.string().optional().describe("New title"),
|
|
8271
|
+
description: z15.string().optional().describe("New description"),
|
|
8272
|
+
plan: z15.string().optional().describe("New plan in markdown"),
|
|
8273
|
+
status: z15.string().optional().describe("New status"),
|
|
8274
|
+
assignedUserId: z15.string().nullable().optional().describe("Assign to user ID, or null to unassign")
|
|
8114
8275
|
},
|
|
8115
8276
|
async ({ task_id, ...fields }) => {
|
|
8116
8277
|
try {
|
|
@@ -8131,9 +8292,9 @@ function buildUpdateTaskPlanTool(connection, getRequestingUserId) {
|
|
|
8131
8292
|
"update_task_plan",
|
|
8132
8293
|
"Save a plan or description to a task. Convenience wrapper around update_project_task for the common Plan-mode case.",
|
|
8133
8294
|
{
|
|
8134
|
-
task_id:
|
|
8135
|
-
plan:
|
|
8136
|
-
description:
|
|
8295
|
+
task_id: z15.string().describe("The task ID to update"),
|
|
8296
|
+
plan: z15.string().optional().describe("The task plan in markdown"),
|
|
8297
|
+
description: z15.string().optional().describe("Updated task description")
|
|
8137
8298
|
},
|
|
8138
8299
|
async ({ task_id, plan, description }) => {
|
|
8139
8300
|
try {
|
|
@@ -8162,8 +8323,8 @@ function buildForceUpdateStatusTool(connection, getRequestingUserId) {
|
|
|
8162
8323
|
"force_update_task_status",
|
|
8163
8324
|
"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.",
|
|
8164
8325
|
{
|
|
8165
|
-
task_id:
|
|
8166
|
-
status:
|
|
8326
|
+
task_id: z15.string().describe("The task ID to update"),
|
|
8327
|
+
status: z15.enum(["Planning", "Open", "InProgress", "ReviewPR", "ReviewDev", "ReviewLive", "Complete"]).describe("The new status for the task")
|
|
8167
8328
|
},
|
|
8168
8329
|
async ({ task_id, status }) => {
|
|
8169
8330
|
try {
|
|
@@ -8178,18 +8339,70 @@ function buildForceUpdateStatusTool(connection, getRequestingUserId) {
|
|
|
8178
8339
|
}
|
|
8179
8340
|
);
|
|
8180
8341
|
}
|
|
8342
|
+
function formatReviewerList(reviewers) {
|
|
8343
|
+
if (reviewers.length === 0) return "none";
|
|
8344
|
+
return reviewers.map((r) => `${r.name ?? "unknown"} (${r.userId})`).join(", ");
|
|
8345
|
+
}
|
|
8346
|
+
function buildAddReviewerTool(connection, getRequestingUserId) {
|
|
8347
|
+
const projectId = connection.projectId;
|
|
8348
|
+
return defineTool(
|
|
8349
|
+
"add_reviewer",
|
|
8350
|
+
"Add a project member as a reviewer on a task. Idempotent \u2014 adding an existing reviewer is a no-op.",
|
|
8351
|
+
{
|
|
8352
|
+
task_id: z15.string().describe("The task ID or slug"),
|
|
8353
|
+
user_id: z15.string().describe("User ID of the reviewer (use list_project_members to resolve a name or email)")
|
|
8354
|
+
},
|
|
8355
|
+
async ({ task_id, user_id }) => {
|
|
8356
|
+
try {
|
|
8357
|
+
const result = await connection.call(
|
|
8358
|
+
"addProjectTaskReviewer",
|
|
8359
|
+
withRequestingUser({ projectId, taskId: task_id, userId: user_id }, getRequestingUserId)
|
|
8360
|
+
);
|
|
8361
|
+
return textResult(
|
|
8362
|
+
`Reviewer added to task ${result.taskId}. Reviewers: ${formatReviewerList(result.reviewers)}`
|
|
8363
|
+
);
|
|
8364
|
+
} catch (error) {
|
|
8365
|
+
return textResult(`Failed to add reviewer: ${errorMessage(error)}`);
|
|
8366
|
+
}
|
|
8367
|
+
}
|
|
8368
|
+
);
|
|
8369
|
+
}
|
|
8370
|
+
function buildRemoveReviewerTool(connection, getRequestingUserId) {
|
|
8371
|
+
const projectId = connection.projectId;
|
|
8372
|
+
return defineTool(
|
|
8373
|
+
"remove_reviewer",
|
|
8374
|
+
"Remove a reviewer from a task. Idempotent \u2014 removing a non-reviewer is a no-op.",
|
|
8375
|
+
{
|
|
8376
|
+
task_id: z15.string().describe("The task ID or slug"),
|
|
8377
|
+
user_id: z15.string().describe("User ID of the reviewer to remove")
|
|
8378
|
+
},
|
|
8379
|
+
async ({ task_id, user_id }) => {
|
|
8380
|
+
try {
|
|
8381
|
+
const result = await connection.call(
|
|
8382
|
+
"removeProjectTaskReviewer",
|
|
8383
|
+
withRequestingUser({ projectId, taskId: task_id, userId: user_id }, getRequestingUserId)
|
|
8384
|
+
);
|
|
8385
|
+
return textResult(
|
|
8386
|
+
`Reviewer removed from task ${result.taskId}. Reviewers: ${formatReviewerList(result.reviewers)}`
|
|
8387
|
+
);
|
|
8388
|
+
} catch (error) {
|
|
8389
|
+
return textResult(`Failed to remove reviewer: ${errorMessage(error)}`);
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
);
|
|
8393
|
+
}
|
|
8181
8394
|
function buildCreateSubtaskTool2(connection, getRequestingUserId) {
|
|
8182
8395
|
const projectId = connection.projectId;
|
|
8183
8396
|
return defineTool(
|
|
8184
8397
|
"create_subtask",
|
|
8185
8398
|
"Create a subtask under a parent task in this project. Use for breaking parent tasks into smaller pieces during planning.",
|
|
8186
8399
|
{
|
|
8187
|
-
parent_task_id:
|
|
8188
|
-
title:
|
|
8189
|
-
description:
|
|
8190
|
-
plan:
|
|
8191
|
-
ordinal:
|
|
8192
|
-
storyPointValue:
|
|
8400
|
+
parent_task_id: z15.string().describe("The parent task ID"),
|
|
8401
|
+
title: z15.string().describe("Subtask title"),
|
|
8402
|
+
description: z15.string().optional().describe("Brief description"),
|
|
8403
|
+
plan: z15.string().optional().describe("Implementation plan in markdown"),
|
|
8404
|
+
ordinal: z15.number().optional().describe("Step/order number (0-based)"),
|
|
8405
|
+
storyPointValue: z15.number().optional().describe(SP_DESCRIPTION3)
|
|
8193
8406
|
},
|
|
8194
8407
|
async ({ parent_task_id, title, description, plan, ordinal, storyPointValue }) => {
|
|
8195
8408
|
try {
|
|
@@ -8221,13 +8434,13 @@ function buildUpdateSubtaskTool2(connection, getRequestingUserId) {
|
|
|
8221
8434
|
"update_subtask",
|
|
8222
8435
|
"Update an existing subtask's fields (title, description, plan, status, ordinal, storyPointValue).",
|
|
8223
8436
|
{
|
|
8224
|
-
subtask_id:
|
|
8225
|
-
title:
|
|
8226
|
-
description:
|
|
8227
|
-
plan:
|
|
8228
|
-
status:
|
|
8229
|
-
ordinal:
|
|
8230
|
-
storyPointValue:
|
|
8437
|
+
subtask_id: z15.string().describe("The subtask ID to update"),
|
|
8438
|
+
title: z15.string().optional(),
|
|
8439
|
+
description: z15.string().optional(),
|
|
8440
|
+
plan: z15.string().optional(),
|
|
8441
|
+
status: z15.string().optional(),
|
|
8442
|
+
ordinal: z15.number().optional(),
|
|
8443
|
+
storyPointValue: z15.number().optional().describe(SP_DESCRIPTION3)
|
|
8231
8444
|
},
|
|
8232
8445
|
async ({ subtask_id, ...fields }) => {
|
|
8233
8446
|
try {
|
|
@@ -8247,7 +8460,7 @@ function buildDeleteSubtaskTool2(connection, getRequestingUserId) {
|
|
|
8247
8460
|
return defineTool(
|
|
8248
8461
|
"delete_subtask",
|
|
8249
8462
|
"Delete a subtask by id. Use when a subtask was created in error or is no longer needed.",
|
|
8250
|
-
{ subtask_id:
|
|
8463
|
+
{ subtask_id: z15.string().describe("The subtask ID to delete") },
|
|
8251
8464
|
async ({ subtask_id }) => {
|
|
8252
8465
|
try {
|
|
8253
8466
|
await connection.call(
|
|
@@ -8266,7 +8479,7 @@ function buildStartTaskTool(connection, getRequestingUserId) {
|
|
|
8266
8479
|
return defineTool(
|
|
8267
8480
|
"start_task",
|
|
8268
8481
|
"Start a cloud build (codespace) for a task. Preconditions: task has a story point value and an agent assigned.",
|
|
8269
|
-
{ task_id:
|
|
8482
|
+
{ task_id: z15.string().describe("The task ID to start a build for") },
|
|
8270
8483
|
async ({ task_id }) => {
|
|
8271
8484
|
try {
|
|
8272
8485
|
const result = await connection.call(
|
|
@@ -8287,7 +8500,7 @@ function buildStopTaskTool(connection, getRequestingUserId) {
|
|
|
8287
8500
|
return defineTool(
|
|
8288
8501
|
"stop_task",
|
|
8289
8502
|
"Send a stop signal to a running task's cloud build. Not a force-kill \u2014 the agent may take a moment to wind down.",
|
|
8290
|
-
{ task_id:
|
|
8503
|
+
{ task_id: z15.string().describe("The task ID whose build should be stopped") },
|
|
8291
8504
|
async ({ task_id }) => {
|
|
8292
8505
|
try {
|
|
8293
8506
|
await connection.call(
|
|
@@ -8306,7 +8519,7 @@ function buildMergePRTool(connection, getRequestingUserId) {
|
|
|
8306
8519
|
return defineTool(
|
|
8307
8520
|
"merge_pr",
|
|
8308
8521
|
"Approve and merge a task's PR. Preconditions: task in ReviewPR with an open PR. Returns { merged }: false means automerge queued \u2014 wait for status to flip to ReviewDev.",
|
|
8309
|
-
{ task_id:
|
|
8522
|
+
{ task_id: z15.string().describe("The task ID whose PR should be approved and merged") },
|
|
8310
8523
|
async ({ task_id }) => {
|
|
8311
8524
|
try {
|
|
8312
8525
|
const result = await connection.call(
|
|
@@ -8327,15 +8540,34 @@ function buildMergePRTool(connection, getRequestingUserId) {
|
|
|
8327
8540
|
}
|
|
8328
8541
|
);
|
|
8329
8542
|
}
|
|
8543
|
+
function buildProjectActionTools(connection, getRequestingUserId = () => void 0) {
|
|
8544
|
+
return [
|
|
8545
|
+
buildCreateTaskTool(connection, getRequestingUserId),
|
|
8546
|
+
buildUpdateProjectTaskTool(connection, getRequestingUserId),
|
|
8547
|
+
buildUpdateTaskPlanTool(connection, getRequestingUserId),
|
|
8548
|
+
buildForceUpdateStatusTool(connection, getRequestingUserId),
|
|
8549
|
+
buildAddReviewerTool(connection, getRequestingUserId),
|
|
8550
|
+
buildRemoveReviewerTool(connection, getRequestingUserId),
|
|
8551
|
+
buildCreateSubtaskTool2(connection, getRequestingUserId),
|
|
8552
|
+
buildUpdateSubtaskTool2(connection, getRequestingUserId),
|
|
8553
|
+
buildDeleteSubtaskTool2(connection, getRequestingUserId),
|
|
8554
|
+
buildStartTaskTool(connection, getRequestingUserId),
|
|
8555
|
+
buildStopTaskTool(connection, getRequestingUserId),
|
|
8556
|
+
buildMergePRTool(connection, getRequestingUserId)
|
|
8557
|
+
];
|
|
8558
|
+
}
|
|
8559
|
+
|
|
8560
|
+
// src/tools/project-suggestion-dependency-tools.ts
|
|
8561
|
+
import { z as z16 } from "zod";
|
|
8330
8562
|
function buildCreateSuggestionTool2(connection, getRequestingUserId) {
|
|
8331
8563
|
const projectId = connection.projectId;
|
|
8332
8564
|
return defineTool(
|
|
8333
8565
|
"create_suggestion",
|
|
8334
8566
|
"Suggest a feature, improvement, rule, or idea for the project. Duplicates are deduped and your upvote is recorded.",
|
|
8335
8567
|
{
|
|
8336
|
-
title:
|
|
8337
|
-
description:
|
|
8338
|
-
tag_names:
|
|
8568
|
+
title: z16.string().describe("Short title for the suggestion"),
|
|
8569
|
+
description: z16.string().optional().describe("1-2 sentence description of what should change and why."),
|
|
8570
|
+
tag_names: z16.array(z16.string()).optional().describe("Tag names to categorize the suggestion")
|
|
8339
8571
|
},
|
|
8340
8572
|
async ({ title, description, tag_names }) => {
|
|
8341
8573
|
try {
|
|
@@ -8369,8 +8601,8 @@ function buildVoteSuggestionTool2(connection, getRequestingUserId) {
|
|
|
8369
8601
|
"vote_suggestion",
|
|
8370
8602
|
"Vote +1 or -1 on a project suggestion.",
|
|
8371
8603
|
{
|
|
8372
|
-
suggestion_id:
|
|
8373
|
-
value:
|
|
8604
|
+
suggestion_id: z16.string().describe("The suggestion ID to vote on"),
|
|
8605
|
+
value: z16.number().refine((v) => v === 1 || v === -1, { message: "Value must be 1 or -1" }).describe("+1 to upvote, -1 to downvote")
|
|
8374
8606
|
},
|
|
8375
8607
|
async ({ suggestion_id, value }) => {
|
|
8376
8608
|
try {
|
|
@@ -8398,8 +8630,8 @@ function buildAddDependencyTool2(connection, getRequestingUserId) {
|
|
|
8398
8630
|
"add_dependency",
|
|
8399
8631
|
"Add a blocking dependency \u2014 a task cannot start until the named task is merged to dev.",
|
|
8400
8632
|
{
|
|
8401
|
-
task_id:
|
|
8402
|
-
depends_on_slug_or_id:
|
|
8633
|
+
task_id: z16.string().describe("The task that should be blocked"),
|
|
8634
|
+
depends_on_slug_or_id: z16.string().describe("Slug or ID of the task this task depends on")
|
|
8403
8635
|
},
|
|
8404
8636
|
async ({ task_id, depends_on_slug_or_id }) => {
|
|
8405
8637
|
try {
|
|
@@ -8429,8 +8661,8 @@ function buildRemoveDependencyTool2(connection, getRequestingUserId) {
|
|
|
8429
8661
|
"remove_dependency",
|
|
8430
8662
|
"Remove a previously added dependency from a task.",
|
|
8431
8663
|
{
|
|
8432
|
-
task_id:
|
|
8433
|
-
depends_on_slug_or_id:
|
|
8664
|
+
task_id: z16.string().describe("The task to update"),
|
|
8665
|
+
depends_on_slug_or_id: z16.string().describe("Slug or ID of the task to remove as dependency")
|
|
8434
8666
|
},
|
|
8435
8667
|
async ({ task_id, depends_on_slug_or_id }) => {
|
|
8436
8668
|
try {
|
|
@@ -8452,18 +8684,8 @@ function buildRemoveDependencyTool2(connection, getRequestingUserId) {
|
|
|
8452
8684
|
}
|
|
8453
8685
|
);
|
|
8454
8686
|
}
|
|
8455
|
-
function
|
|
8687
|
+
function buildProjectSuggestionDependencyTools(connection, getRequestingUserId = () => void 0) {
|
|
8456
8688
|
return [
|
|
8457
|
-
buildCreateTaskTool(connection, getRequestingUserId),
|
|
8458
|
-
buildUpdateProjectTaskTool(connection, getRequestingUserId),
|
|
8459
|
-
buildUpdateTaskPlanTool(connection, getRequestingUserId),
|
|
8460
|
-
buildForceUpdateStatusTool(connection, getRequestingUserId),
|
|
8461
|
-
buildCreateSubtaskTool2(connection, getRequestingUserId),
|
|
8462
|
-
buildUpdateSubtaskTool2(connection, getRequestingUserId),
|
|
8463
|
-
buildDeleteSubtaskTool2(connection, getRequestingUserId),
|
|
8464
|
-
buildStartTaskTool(connection, getRequestingUserId),
|
|
8465
|
-
buildStopTaskTool(connection, getRequestingUserId),
|
|
8466
|
-
buildMergePRTool(connection, getRequestingUserId),
|
|
8467
8689
|
buildCreateSuggestionTool2(connection, getRequestingUserId),
|
|
8468
8690
|
buildVoteSuggestionTool2(connection, getRequestingUserId),
|
|
8469
8691
|
buildAddDependencyTool2(connection, getRequestingUserId),
|
|
@@ -8479,11 +8701,12 @@ function buildListTasksTool(connection) {
|
|
|
8479
8701
|
const projectId = connection.projectId;
|
|
8480
8702
|
return defineTool(
|
|
8481
8703
|
"list_tasks",
|
|
8482
|
-
"List tasks in the project. Optionally filter by status or assignee.",
|
|
8704
|
+
"List tasks in the project. Optionally filter by status or assignment (a specific assignee, or unassigned tasks).",
|
|
8483
8705
|
{
|
|
8484
|
-
status:
|
|
8485
|
-
assigneeId:
|
|
8486
|
-
|
|
8706
|
+
status: z17.string().optional().describe("Filter by task status"),
|
|
8707
|
+
assigneeId: z17.string().optional().describe("Filter by assigned user ID"),
|
|
8708
|
+
unassigned: z17.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
8709
|
+
limit: z17.number().optional().describe("Max number of tasks to return (default 50)")
|
|
8487
8710
|
},
|
|
8488
8711
|
async (params) => {
|
|
8489
8712
|
try {
|
|
@@ -8501,7 +8724,7 @@ function buildGetProjectTaskTool(connection) {
|
|
|
8501
8724
|
return defineTool(
|
|
8502
8725
|
"get_project_task",
|
|
8503
8726
|
"Get detailed information about a task in this project (chat messages, child tasks, session). Project-runner scope.",
|
|
8504
|
-
{ task_id:
|
|
8727
|
+
{ task_id: z17.string().describe("The task ID to look up") },
|
|
8505
8728
|
async ({ task_id }) => {
|
|
8506
8729
|
try {
|
|
8507
8730
|
const task = await connection.call("getProjectTask", { projectId, taskId: task_id });
|
|
@@ -8517,12 +8740,14 @@ function buildSearchTasksTool(connection) {
|
|
|
8517
8740
|
const projectId = connection.projectId;
|
|
8518
8741
|
return defineTool(
|
|
8519
8742
|
"search_tasks",
|
|
8520
|
-
"Search tasks by tags, text query,
|
|
8743
|
+
"Search tasks by tags, text query, status filters, or assignment.",
|
|
8521
8744
|
{
|
|
8522
|
-
tagNames:
|
|
8523
|
-
searchQuery:
|
|
8524
|
-
statusFilters:
|
|
8525
|
-
|
|
8745
|
+
tagNames: z17.array(z17.string()).optional().describe("Filter by tag names"),
|
|
8746
|
+
searchQuery: z17.string().optional().describe("Text search in title/description"),
|
|
8747
|
+
statusFilters: z17.array(z17.string()).optional().describe("Filter by statuses"),
|
|
8748
|
+
assigneeId: z17.string().optional().describe("Filter by assigned user ID"),
|
|
8749
|
+
unassigned: z17.boolean().optional().describe("Only return tasks with no assignee (mutually exclusive with assigneeId)"),
|
|
8750
|
+
limit: z17.number().optional().describe("Max results (default 20)")
|
|
8526
8751
|
},
|
|
8527
8752
|
async (params) => {
|
|
8528
8753
|
try {
|
|
@@ -8540,7 +8765,7 @@ function buildListSubtasksTool2(connection) {
|
|
|
8540
8765
|
return defineTool(
|
|
8541
8766
|
"list_subtasks",
|
|
8542
8767
|
"List the immediate child tasks under a parent task. Use to coordinate subtask work \u2014 see status, ordering, and PR state.",
|
|
8543
|
-
{ task_id:
|
|
8768
|
+
{ task_id: z17.string().describe("Parent task ID") },
|
|
8544
8769
|
async ({ task_id }) => {
|
|
8545
8770
|
try {
|
|
8546
8771
|
const subtasks = await connection.call("listProjectSubtasks", {
|
|
@@ -8572,6 +8797,23 @@ function buildListTagsTool(connection) {
|
|
|
8572
8797
|
{ annotations: { readOnlyHint: true } }
|
|
8573
8798
|
);
|
|
8574
8799
|
}
|
|
8800
|
+
function buildListProjectMembersTool(connection) {
|
|
8801
|
+
const projectId = connection.projectId;
|
|
8802
|
+
return defineTool(
|
|
8803
|
+
"list_project_members",
|
|
8804
|
+
"List project members with user ID, name, email, and access level. Use to resolve a person's name or email to a user ID for task assignment or review.",
|
|
8805
|
+
{},
|
|
8806
|
+
async () => {
|
|
8807
|
+
try {
|
|
8808
|
+
const members = await connection.call("listProjectMembers", { projectId });
|
|
8809
|
+
return textResult(JSON.stringify(members, null, 2));
|
|
8810
|
+
} catch (error) {
|
|
8811
|
+
return textResult(`Failed to list project members: ${errorMessage(error)}`);
|
|
8812
|
+
}
|
|
8813
|
+
},
|
|
8814
|
+
{ annotations: { readOnlyHint: true } }
|
|
8815
|
+
);
|
|
8816
|
+
}
|
|
8575
8817
|
function buildGetProjectSummaryTool(connection) {
|
|
8576
8818
|
const projectId = connection.projectId;
|
|
8577
8819
|
return defineTool(
|
|
@@ -8595,8 +8837,8 @@ function buildPostToChatTool2(connection, getRequestingUserId) {
|
|
|
8595
8837
|
"post_to_chat",
|
|
8596
8838
|
"Post an out-of-band message into a chat. Omit task_id to post into the project chat; pass task_id to post into a specific task's chat. Normal replies already appear in chat automatically.",
|
|
8597
8839
|
{
|
|
8598
|
-
message:
|
|
8599
|
-
task_id:
|
|
8840
|
+
message: z17.string().describe("The message content to post"),
|
|
8841
|
+
task_id: z17.string().optional().describe("Task ID to post into a specific task's chat. Omit for the project chat.")
|
|
8600
8842
|
},
|
|
8601
8843
|
async ({ message, task_id }) => {
|
|
8602
8844
|
try {
|
|
@@ -8624,8 +8866,8 @@ function buildReadChatHistoryTool(connection) {
|
|
|
8624
8866
|
"read_chat_history",
|
|
8625
8867
|
"Read recent messages from a chat. Omit chat_id to read the project chat; pass a chat_id to read a specific chat.",
|
|
8626
8868
|
{
|
|
8627
|
-
chat_id:
|
|
8628
|
-
limit:
|
|
8869
|
+
chat_id: z17.string().optional().describe("Chat ID to read. Omit for the project chat."),
|
|
8870
|
+
limit: z17.number().optional().describe("Number of recent messages to fetch (default 50)")
|
|
8629
8871
|
},
|
|
8630
8872
|
async ({ chat_id, limit }) => {
|
|
8631
8873
|
try {
|
|
@@ -8648,8 +8890,8 @@ function buildReadTaskChatTool2(connection) {
|
|
|
8648
8890
|
"read_task_chat",
|
|
8649
8891
|
"Read recent human/user chat messages for a specific task in this project. For agent execution logs use get_task_logs.",
|
|
8650
8892
|
{
|
|
8651
|
-
task_id:
|
|
8652
|
-
limit:
|
|
8893
|
+
task_id: z17.string().describe("The task ID whose chat to read"),
|
|
8894
|
+
limit: z17.number().optional().describe("Number of recent messages to fetch (default 20)")
|
|
8653
8895
|
},
|
|
8654
8896
|
async ({ task_id, limit }) => {
|
|
8655
8897
|
try {
|
|
@@ -8672,9 +8914,9 @@ function buildGetTaskLogsTool(connection) {
|
|
|
8672
8914
|
"get_task_logs",
|
|
8673
8915
|
"Read CLI execution logs for a task \u2014 agent reasoning, tool calls, and setup/dev-server output. For human chat use read_task_chat.",
|
|
8674
8916
|
{
|
|
8675
|
-
task_id:
|
|
8676
|
-
source:
|
|
8677
|
-
limit:
|
|
8917
|
+
task_id: z17.string().describe("Task ID to read logs from"),
|
|
8918
|
+
source: z17.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
|
|
8919
|
+
limit: z17.number().optional().describe("Max number of log entries to return (default 50, max 500).")
|
|
8678
8920
|
},
|
|
8679
8921
|
async ({ task_id, source, limit }) => {
|
|
8680
8922
|
try {
|
|
@@ -8699,12 +8941,14 @@ function buildProjectTools(connection, getRequestingUserId = () => void 0) {
|
|
|
8699
8941
|
buildSearchTasksTool(connection),
|
|
8700
8942
|
buildListSubtasksTool2(connection),
|
|
8701
8943
|
buildListTagsTool(connection),
|
|
8944
|
+
buildListProjectMembersTool(connection),
|
|
8702
8945
|
buildGetProjectSummaryTool(connection),
|
|
8703
8946
|
buildPostToChatTool2(connection, getRequestingUserId),
|
|
8704
8947
|
buildReadChatHistoryTool(connection),
|
|
8705
8948
|
buildReadTaskChatTool2(connection),
|
|
8706
8949
|
buildGetTaskLogsTool(connection),
|
|
8707
|
-
...buildProjectActionTools(connection, getRequestingUserId)
|
|
8950
|
+
...buildProjectActionTools(connection, getRequestingUserId),
|
|
8951
|
+
...buildProjectSuggestionDependencyTools(connection, getRequestingUserId)
|
|
8708
8952
|
];
|
|
8709
8953
|
}
|
|
8710
8954
|
|
|
@@ -9665,13 +9909,13 @@ var ProjectRunner = class {
|
|
|
9665
9909
|
};
|
|
9666
9910
|
|
|
9667
9911
|
// src/setup/config.ts
|
|
9668
|
-
import { readFile as
|
|
9669
|
-
import { join as
|
|
9912
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
9913
|
+
import { join as join6 } from "path";
|
|
9670
9914
|
var DEVCONTAINER_PATH = ".devcontainer/conveyor/devcontainer.json";
|
|
9671
9915
|
var DEVCONTAINER_PORT_DENY_LIST = /* @__PURE__ */ new Set([5432, 6379, 9200]);
|
|
9672
9916
|
async function loadForwardPorts(workspaceDir) {
|
|
9673
9917
|
try {
|
|
9674
|
-
const raw = await
|
|
9918
|
+
const raw = await readFile3(join6(workspaceDir, DEVCONTAINER_PATH), "utf-8");
|
|
9675
9919
|
const parsed = JSON.parse(raw);
|
|
9676
9920
|
const ports = (parsed.forwardPorts ?? []).filter(
|
|
9677
9921
|
(p) => typeof p === "number" && !DEVCONTAINER_PORT_DENY_LIST.has(p)
|
|
@@ -9758,4 +10002,4 @@ export {
|
|
|
9758
10002
|
loadConveyorConfig,
|
|
9759
10003
|
unshallowRepo
|
|
9760
10004
|
};
|
|
9761
|
-
//# sourceMappingURL=chunk-
|
|
10005
|
+
//# sourceMappingURL=chunk-W4NCD23G.js.map
|