@rallycry/conveyor-agent 6.2.0 → 6.4.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-RMNWEID4.js → chunk-WBBX5AIX.js} +423 -74
- package/dist/chunk-WBBX5AIX.js.map +1 -0
- package/dist/cli.js +12 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-RMNWEID4.js.map +0 -1
|
@@ -161,6 +161,21 @@ function getTaskIncidents(socket, taskId) {
|
|
|
161
161
|
function requestScaleUp(socket, tier, reason) {
|
|
162
162
|
return emitRpc(requireSocket(socket), "agentRunner:scaleUp", { tier, reason });
|
|
163
163
|
}
|
|
164
|
+
function addDependency(socket, dependsOnSlugOrId) {
|
|
165
|
+
return emitRpcVoid(requireSocket(socket), "agentRunner:addDependency", { dependsOnSlugOrId });
|
|
166
|
+
}
|
|
167
|
+
function removeDependency(socket, dependsOnSlugOrId) {
|
|
168
|
+
return emitRpcVoid(requireSocket(socket), "agentRunner:removeDependency", { dependsOnSlugOrId });
|
|
169
|
+
}
|
|
170
|
+
function getDependencies(socket) {
|
|
171
|
+
return emitRpc(requireSocket(socket), "agentRunner:getDependencies", {});
|
|
172
|
+
}
|
|
173
|
+
function createFollowUpTask(socket, data) {
|
|
174
|
+
return emitRpc(requireSocket(socket), "agentRunner:createFollowUpTask", data);
|
|
175
|
+
}
|
|
176
|
+
function queryGcpLogs(socket, params) {
|
|
177
|
+
return emitRpc(requireSocket(socket), "agentRunner:queryGcpLogs", params);
|
|
178
|
+
}
|
|
164
179
|
|
|
165
180
|
// src/connection/task-connection.ts
|
|
166
181
|
var ConveyorConnection = class _ConveyorConnection {
|
|
@@ -464,7 +479,7 @@ var ConveyorConnection = class _ConveyorConnection {
|
|
|
464
479
|
return triggerIdentification(this.socket);
|
|
465
480
|
}
|
|
466
481
|
async refreshAuthToken() {
|
|
467
|
-
const codespaceName = process.env.CODESPACE_NAME;
|
|
482
|
+
const codespaceName = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;
|
|
468
483
|
const apiUrl = process.env.CONVEYOR_API_URL ?? this.config.conveyorApiUrl;
|
|
469
484
|
if (!codespaceName || !apiUrl) return false;
|
|
470
485
|
try {
|
|
@@ -509,10 +524,29 @@ var ConveyorConnection = class _ConveyorConnection {
|
|
|
509
524
|
requestScaleUp(tier, reason) {
|
|
510
525
|
return requestScaleUp(this.socket, tier, reason);
|
|
511
526
|
}
|
|
527
|
+
addDependency(dependsOnSlugOrId) {
|
|
528
|
+
return addDependency(this.socket, dependsOnSlugOrId);
|
|
529
|
+
}
|
|
530
|
+
removeDependency(dependsOnSlugOrId) {
|
|
531
|
+
return removeDependency(this.socket, dependsOnSlugOrId);
|
|
532
|
+
}
|
|
533
|
+
getDependencies() {
|
|
534
|
+
return getDependencies(this.socket);
|
|
535
|
+
}
|
|
536
|
+
createFollowUpTask(data) {
|
|
537
|
+
return createFollowUpTask(this.socket, data);
|
|
538
|
+
}
|
|
539
|
+
queryGcpLogs(params) {
|
|
540
|
+
return queryGcpLogs(this.socket, params);
|
|
541
|
+
}
|
|
512
542
|
disconnect() {
|
|
513
543
|
this.flushEvents();
|
|
514
|
-
this.socket
|
|
515
|
-
|
|
544
|
+
if (this.socket) {
|
|
545
|
+
this.socket.io.reconnection(false);
|
|
546
|
+
this.socket.removeAllListeners();
|
|
547
|
+
this.socket.disconnect();
|
|
548
|
+
this.socket = null;
|
|
549
|
+
}
|
|
516
550
|
}
|
|
517
551
|
};
|
|
518
552
|
|
|
@@ -805,8 +839,12 @@ var ProjectConnection = class {
|
|
|
805
839
|
}
|
|
806
840
|
}
|
|
807
841
|
disconnect() {
|
|
808
|
-
this.socket
|
|
809
|
-
|
|
842
|
+
if (this.socket) {
|
|
843
|
+
this.socket.io.reconnection(false);
|
|
844
|
+
this.socket.removeAllListeners();
|
|
845
|
+
this.socket.disconnect();
|
|
846
|
+
this.socket = null;
|
|
847
|
+
}
|
|
810
848
|
}
|
|
811
849
|
};
|
|
812
850
|
|
|
@@ -862,6 +900,82 @@ function getCurrentBranch(cwd) {
|
|
|
862
900
|
return null;
|
|
863
901
|
}
|
|
864
902
|
}
|
|
903
|
+
function hasUnpushedCommits(cwd) {
|
|
904
|
+
try {
|
|
905
|
+
const currentBranch = getCurrentBranch(cwd);
|
|
906
|
+
if (!currentBranch) return false;
|
|
907
|
+
try {
|
|
908
|
+
execSync2(`git rev-parse origin/${currentBranch}`, {
|
|
909
|
+
cwd,
|
|
910
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
911
|
+
});
|
|
912
|
+
} catch {
|
|
913
|
+
try {
|
|
914
|
+
execSync2("git rev-parse HEAD", {
|
|
915
|
+
cwd,
|
|
916
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
917
|
+
});
|
|
918
|
+
return true;
|
|
919
|
+
} catch {
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
const ahead = execSync2(`git rev-list --count HEAD --not origin/${currentBranch}`, {
|
|
924
|
+
cwd,
|
|
925
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
926
|
+
}).toString().trim();
|
|
927
|
+
return parseInt(ahead, 10) > 0;
|
|
928
|
+
} catch {
|
|
929
|
+
return false;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
function stageAndCommit(cwd, message) {
|
|
933
|
+
try {
|
|
934
|
+
execSync2("git add -A", {
|
|
935
|
+
cwd,
|
|
936
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
937
|
+
});
|
|
938
|
+
if (!hasUncommittedChanges(cwd)) {
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
execSync2(`git commit -m "${message}"`, {
|
|
942
|
+
cwd,
|
|
943
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
944
|
+
});
|
|
945
|
+
const hash = execSync2("git rev-parse HEAD", {
|
|
946
|
+
cwd,
|
|
947
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
948
|
+
}).toString().trim();
|
|
949
|
+
return hash;
|
|
950
|
+
} catch {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
function pushToOrigin(cwd) {
|
|
955
|
+
try {
|
|
956
|
+
const currentBranch = getCurrentBranch(cwd);
|
|
957
|
+
if (!currentBranch) return false;
|
|
958
|
+
try {
|
|
959
|
+
execSync2(`git push origin ${currentBranch}`, {
|
|
960
|
+
cwd,
|
|
961
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
962
|
+
});
|
|
963
|
+
return true;
|
|
964
|
+
} catch {
|
|
965
|
+
try {
|
|
966
|
+
execSync2(`git push --force-with-lease origin ${currentBranch}`, {
|
|
967
|
+
cwd,
|
|
968
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
969
|
+
});
|
|
970
|
+
return true;
|
|
971
|
+
} catch {
|
|
972
|
+
return false;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
} catch {
|
|
976
|
+
return false;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
865
979
|
|
|
866
980
|
// src/runner/worktree.ts
|
|
867
981
|
var WORKTREE_DIR = ".worktrees";
|
|
@@ -1691,11 +1805,11 @@ function buildPackRunnerSystemPrompt(context, config, setupLog) {
|
|
|
1691
1805
|
const parts = [
|
|
1692
1806
|
`You are an autonomous Pack Runner managing child tasks for the "${context.title}" project.`,
|
|
1693
1807
|
`You are running locally with full access to the repository and task management tools.`,
|
|
1694
|
-
`Your job is to
|
|
1808
|
+
`Your job is to execute child tasks by firing cloud builds, reviewing their PRs, and merging them \u2014 respecting dependency chains for parallel execution.`,
|
|
1695
1809
|
``,
|
|
1696
1810
|
`## Child Task Status Lifecycle`,
|
|
1697
1811
|
`- "Planning" \u2014 Not ready for execution. Skip it (or escalate if blocking).`,
|
|
1698
|
-
`- "Open" \u2014 Ready to execute. Use start_child_cloud_build to fire it.`,
|
|
1812
|
+
`- "Open" \u2014 Ready to execute (if dependencies are met). Use start_child_cloud_build to fire it.`,
|
|
1699
1813
|
`- "InProgress" \u2014 Currently being worked on by a Task Runner. Wait \u2014 it will move to ReviewPR when done.`,
|
|
1700
1814
|
`- "ReviewPR" \u2014 Task Runner finished and opened a PR. Review and merge it.`,
|
|
1701
1815
|
`- "Hold" \u2014 PR exists but is on hold for team review. Do not merge \u2014 skip and move on.`,
|
|
@@ -1706,32 +1820,35 @@ function buildPackRunnerSystemPrompt(context, config, setupLog) {
|
|
|
1706
1820
|
`Follow this loop each time you are launched or relaunched:`,
|
|
1707
1821
|
``,
|
|
1708
1822
|
`1. Call list_subtasks to see the current state of all child tasks.`,
|
|
1709
|
-
` The response includes PR info
|
|
1823
|
+
` The response includes PR info, agent assignment, and **dependency info** (dependencies array + allDependenciesMet flag).`,
|
|
1710
1824
|
``,
|
|
1711
|
-
`2. Evaluate
|
|
1712
|
-
` - "ReviewPR": Review and merge its PR with approve_and_merge_pr
|
|
1713
|
-
` - If merge fails due to pending CI: post a status update to chat, state you are going idle
|
|
1714
|
-
` - If merge fails due to failed CI: use get_task_cli(childTaskId) to check
|
|
1715
|
-
` - "InProgress": A Task Runner is actively working
|
|
1716
|
-
` - "Open"
|
|
1717
|
-
`
|
|
1825
|
+
`2. Evaluate children by status and dependency readiness:`,
|
|
1826
|
+
` - "ReviewPR": Review and merge its PR with approve_and_merge_pr. (Highest priority)`,
|
|
1827
|
+
` - If merge fails due to pending CI: post a status update to chat, state you are going idle.`,
|
|
1828
|
+
` - If merge fails due to failed CI: use get_task_cli(childTaskId) to check. Escalate to team.`,
|
|
1829
|
+
` - "InProgress": A Task Runner is actively working. Do nothing \u2014 wait.`,
|
|
1830
|
+
` - "Open" + allDependenciesMet=true: Ready to fire. Use start_child_cloud_build.`,
|
|
1831
|
+
` - "Open" + allDependenciesMet=false: Blocked \u2014 skip for now. Will be unblocked when deps complete.`,
|
|
1718
1832
|
` - "Hold": On hold \u2014 team must review before merge. Skip.`,
|
|
1719
1833
|
` - "ReviewDev" / "Complete": Already done. Skip.`,
|
|
1720
|
-
` - "Planning": Not ready. If
|
|
1834
|
+
` - "Planning": Not ready. If blocking progress, notify team.`,
|
|
1835
|
+
``,
|
|
1836
|
+
`3. Fire ALL ready "Open" tasks whose dependencies are met, not just one. Independent tasks can run in parallel.`,
|
|
1721
1837
|
``,
|
|
1722
|
-
`
|
|
1838
|
+
`4. After merging a PR: run \`git pull origin ${context.baseBranch}\` then re-check list_subtasks \u2014 previously blocked tasks may now be ready.`,
|
|
1723
1839
|
``,
|
|
1724
|
-
`
|
|
1840
|
+
`5. After firing all ready tasks: report which tasks you fired to chat, then state you are going idle.`,
|
|
1725
1841
|
``,
|
|
1726
|
-
`
|
|
1842
|
+
`6. When ALL children are in "ReviewDev", "Complete", or "Hold" (no "Open", "InProgress", or "ReviewPR" remaining): do a final review, summarize results in chat, and mark this parent task complete with force_update_task_status("Complete").`,
|
|
1727
1843
|
``,
|
|
1728
1844
|
`## Important Rules`,
|
|
1729
|
-
`-
|
|
1730
|
-
`-
|
|
1845
|
+
`- When dependencies are set on children, use them to determine execution order. Fire all ready tasks in parallel.`,
|
|
1846
|
+
`- When NO dependencies are set on any children, fall back to ordinal order (one at a time). This preserves backward compatibility.`,
|
|
1847
|
+
`- After firing builds OR when waiting on CI, explicitly state you are going idle. The system will disconnect you and relaunch when there's a status change.`,
|
|
1731
1848
|
`- Do NOT attempt to write code yourself. Your role is coordination only.`,
|
|
1732
1849
|
`- If a child is stuck in "InProgress" for an unusually long time, use get_task_cli(childTaskId) to check its logs and escalate to the team if it appears stuck.`,
|
|
1733
1850
|
`- You can use get_task(childTaskId) to get a child's full details including PR URL and branch.`,
|
|
1734
|
-
`- list_subtasks returns PR info (githubPRNumber, githubPRUrl)
|
|
1851
|
+
`- list_subtasks returns PR info (githubPRNumber, githubPRUrl), agent assignment (agentId), and dependency info for each child \u2014 use this to verify readiness before firing builds.`,
|
|
1735
1852
|
`- You can use read_task_chat to check for team messages.`
|
|
1736
1853
|
];
|
|
1737
1854
|
if (context.storyPoints && context.storyPoints.length > 0) {
|
|
@@ -1770,11 +1887,12 @@ function buildPackRunnerInstructions(context, scenario) {
|
|
|
1770
1887
|
);
|
|
1771
1888
|
} else if (scenario === "idle_relaunch") {
|
|
1772
1889
|
parts.push(
|
|
1773
|
-
`You have been relaunched \u2014 a child task likely changed status
|
|
1890
|
+
`You have been relaunched \u2014 a child task likely changed status.`,
|
|
1774
1891
|
`Call list_subtasks to check the current state of all children.`,
|
|
1775
1892
|
`Look for children in "ReviewPR" status first \u2014 review and merge their PRs.`,
|
|
1776
|
-
`
|
|
1777
|
-
`If
|
|
1893
|
+
`Check if any previously blocked tasks now have allDependenciesMet=true \u2014 fire them.`,
|
|
1894
|
+
`If a child you previously fired is now in "ReviewDev", pull latest with \`git pull origin ${context.baseBranch}\`.`,
|
|
1895
|
+
`If no children need action, state you are going idle.`
|
|
1778
1896
|
);
|
|
1779
1897
|
} else {
|
|
1780
1898
|
const lastAgentIdx = findLastAgentMessageIndex(context.chatHistory);
|
|
@@ -2032,7 +2150,7 @@ function buildDiscoveryPrompt(context) {
|
|
|
2032
2150
|
`### Finishing Planning`,
|
|
2033
2151
|
`Once your plan is complete and all required properties are set, call the **ExitPlanMode** tool.`,
|
|
2034
2152
|
`- Required before ExitPlanMode will succeed: **plan** (via update_task), **story points** (via update_task_properties), **title** (via update_task_properties)`,
|
|
2035
|
-
`- ExitPlanMode validates these properties and
|
|
2153
|
+
`- ExitPlanMode validates these properties and marks planning as complete`,
|
|
2036
2154
|
`- It does NOT start building \u2014 the team controls when to switch to Build mode`
|
|
2037
2155
|
];
|
|
2038
2156
|
if (context) parts.push(...buildPropertyInstructions(context));
|
|
@@ -2087,13 +2205,13 @@ function buildModePrompt(agentMode, context) {
|
|
|
2087
2205
|
parts.push(
|
|
2088
2206
|
``,
|
|
2089
2207
|
`### Resource Management`,
|
|
2090
|
-
`Your pod starts with minimal resources (0.25 CPU / 1 Gi).
|
|
2091
|
-
`operations
|
|
2092
|
-
`- **light** (1 CPU / 4 Gi) \u2014
|
|
2208
|
+
`Your pod starts with minimal resources (0.25 CPU / 1 Gi). You MUST call \`scale_up_resources\``,
|
|
2209
|
+
`BEFORE running any of these operations \u2014 they WILL fail or OOM at baseline resources:`,
|
|
2210
|
+
`- **light** (1 CPU / 4 Gi) \u2014 bun/npm/yarn install, pip install, basic dev servers, light builds`,
|
|
2093
2211
|
`- **standard** (2 CPU / 8 Gi) \u2014 full dev servers, test suites, typecheck, lint`,
|
|
2094
2212
|
`- **heavy** (4 CPU / 16 Gi) \u2014 E2E/browser automation, large parallel builds`,
|
|
2095
|
-
`Scaling is one-way (up only) and capped by project limits
|
|
2096
|
-
`
|
|
2213
|
+
`Scaling is one-way (up only) and capped by project limits.`,
|
|
2214
|
+
`CRITICAL: Always scale to at least "light" before running any package install command.`
|
|
2097
2215
|
);
|
|
2098
2216
|
}
|
|
2099
2217
|
return parts.join("\n");
|
|
@@ -2332,7 +2450,7 @@ Your responses are sent directly to the task chat \u2014 the team sees everythin
|
|
|
2332
2450
|
);
|
|
2333
2451
|
if (!isPm || isPmActive) {
|
|
2334
2452
|
parts.push(
|
|
2335
|
-
`Use the mcp__conveyor__create_pull_request tool to open PRs \u2014
|
|
2453
|
+
`Use the mcp__conveyor__create_pull_request tool to open PRs \u2014 it automatically stages, commits, and pushes changes before creating the PR. Do NOT use gh CLI or shell commands for PR creation.`
|
|
2336
2454
|
);
|
|
2337
2455
|
}
|
|
2338
2456
|
if (options?.hasDebugTools) {
|
|
@@ -2545,12 +2663,12 @@ function buildFreshInstructions(isPm, isAutoMode, context, agentMode) {
|
|
|
2545
2663
|
`Your plan has been approved. Begin implementing it now.`,
|
|
2546
2664
|
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
|
|
2547
2665
|
`Start by reading the relevant source files mentioned in the plan, then write code.`,
|
|
2548
|
-
`When finished,
|
|
2666
|
+
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,
|
|
2549
2667
|
`
|
|
2550
2668
|
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
2551
2669
|
`Your FIRST action must be reading source files from the plan, then immediately writing code.`,
|
|
2552
2670
|
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing.`,
|
|
2553
|
-
`When all changes are
|
|
2671
|
+
`When all changes are ready, use mcp__conveyor__create_pull_request to open a PR.`,
|
|
2554
2672
|
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
2555
2673
|
];
|
|
2556
2674
|
}
|
|
@@ -2584,14 +2702,14 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
|
|
|
2584
2702
|
`Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first \u2014 the environment is already set up.`,
|
|
2585
2703
|
`Work on the git branch "${context.githubBranch}". Stay on this branch for the entire task. Do not checkout or create other branches.`,
|
|
2586
2704
|
`Your replies are visible to the team in chat \u2014 briefly describe what you're doing when you begin meaningful implementation, and again when the PR is ready.`,
|
|
2587
|
-
`When finished,
|
|
2705
|
+
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`
|
|
2588
2706
|
];
|
|
2589
2707
|
if (isAutoMode) {
|
|
2590
2708
|
parts.push(
|
|
2591
2709
|
`
|
|
2592
2710
|
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
2593
2711
|
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing immediately.`,
|
|
2594
|
-
`When all changes are
|
|
2712
|
+
`When all changes are ready, you MUST use mcp__conveyor__create_pull_request to open a PR before finishing.`,
|
|
2595
2713
|
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
2596
2714
|
);
|
|
2597
2715
|
}
|
|
@@ -2620,7 +2738,7 @@ New messages since your last run:`,
|
|
|
2620
2738
|
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
|
|
2621
2739
|
`
|
|
2622
2740
|
Address the requested changes directly. Do NOT re-investigate the codebase from scratch or write a new plan \u2014 go straight to implementing the feedback.`,
|
|
2623
|
-
`
|
|
2741
|
+
`Implement your updates and open a PR when finished.`
|
|
2624
2742
|
];
|
|
2625
2743
|
if (context.githubPRUrl) {
|
|
2626
2744
|
parts.push(
|
|
@@ -2671,7 +2789,7 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
|
|
|
2671
2789
|
);
|
|
2672
2790
|
if (agentMode === "auto" || agentMode === "building" && isAuto) {
|
|
2673
2791
|
parts.push(
|
|
2674
|
-
`If work is incomplete, continue implementing the plan. When finished,
|
|
2792
|
+
`If work is incomplete, continue implementing the plan. When finished, use mcp__conveyor__create_pull_request to open a PR.`,
|
|
2675
2793
|
`Do NOT go idle or wait for instructions \u2014 you are in auto mode.`
|
|
2676
2794
|
);
|
|
2677
2795
|
} else {
|
|
@@ -2950,20 +3068,56 @@ function buildGetTaskIncidentsTool(connection) {
|
|
|
2950
3068
|
{ annotations: { readOnlyHint: true } }
|
|
2951
3069
|
);
|
|
2952
3070
|
}
|
|
2953
|
-
function buildCreatePullRequestTool(connection) {
|
|
3071
|
+
function buildCreatePullRequestTool(connection, config) {
|
|
2954
3072
|
return defineTool(
|
|
2955
3073
|
"create_pull_request",
|
|
2956
|
-
"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.",
|
|
3074
|
+
"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.",
|
|
2957
3075
|
{
|
|
2958
3076
|
title: z.string().describe("The PR title"),
|
|
2959
3077
|
body: z.string().describe("The PR description/body in markdown"),
|
|
2960
3078
|
branch: z.string().optional().describe(
|
|
2961
3079
|
"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."
|
|
3080
|
+
),
|
|
3081
|
+
baseBranch: z.string().optional().describe(
|
|
3082
|
+
"The base branch to target for the PR (e.g. 'main', 'develop'). Defaults to the project's configured dev branch."
|
|
3083
|
+
),
|
|
3084
|
+
commitMessage: z.string().optional().describe(
|
|
3085
|
+
"Commit message for staging uncommitted changes. If not provided, a default message based on the PR title will be used."
|
|
2962
3086
|
)
|
|
2963
3087
|
},
|
|
2964
|
-
async ({ title, body, branch }) => {
|
|
3088
|
+
async ({ title, body, branch, baseBranch, commitMessage }) => {
|
|
2965
3089
|
try {
|
|
2966
|
-
const
|
|
3090
|
+
const cwd = config.workspaceDir;
|
|
3091
|
+
if (hasUncommittedChanges(cwd)) {
|
|
3092
|
+
const message = commitMessage || `${title}
|
|
3093
|
+
|
|
3094
|
+
Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>`;
|
|
3095
|
+
const commitHash = stageAndCommit(cwd, message);
|
|
3096
|
+
if (commitHash) {
|
|
3097
|
+
connection.sendEvent({
|
|
3098
|
+
type: "message",
|
|
3099
|
+
content: `Auto-committed changes: ${commitHash.slice(0, 7)}`
|
|
3100
|
+
});
|
|
3101
|
+
} else {
|
|
3102
|
+
return textResult(
|
|
3103
|
+
"Failed to stage and commit changes. Please check git status and commit manually before creating PR."
|
|
3104
|
+
);
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
if (hasUnpushedCommits(cwd)) {
|
|
3108
|
+
const pushSuccess = pushToOrigin(cwd);
|
|
3109
|
+
if (pushSuccess) {
|
|
3110
|
+
connection.sendEvent({
|
|
3111
|
+
type: "message",
|
|
3112
|
+
content: "Auto-pushed committed changes to origin"
|
|
3113
|
+
});
|
|
3114
|
+
} else {
|
|
3115
|
+
return textResult(
|
|
3116
|
+
"Failed to push changes to origin. Please check git status and push manually before creating PR."
|
|
3117
|
+
);
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
const result = await connection.createPR({ title, body, branch, baseBranch });
|
|
2967
3121
|
connection.sendEvent({
|
|
2968
3122
|
type: "pr_created",
|
|
2969
3123
|
url: result.url,
|
|
@@ -2977,6 +3131,55 @@ function buildCreatePullRequestTool(connection) {
|
|
|
2977
3131
|
}
|
|
2978
3132
|
);
|
|
2979
3133
|
}
|
|
3134
|
+
function buildQueryGcpLogsTool(connection) {
|
|
3135
|
+
return defineTool(
|
|
3136
|
+
"query_gcp_logs",
|
|
3137
|
+
"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.",
|
|
3138
|
+
{
|
|
3139
|
+
filter: z.string().optional().describe(
|
|
3140
|
+
`Cloud Logging filter expression (e.g., 'resource.type="gce_instance"'). Max 1000 chars.`
|
|
3141
|
+
),
|
|
3142
|
+
start_time: z.string().optional().describe("Start time in ISO 8601 format (e.g., '2024-01-01T00:00:00Z')"),
|
|
3143
|
+
end_time: z.string().optional().describe("End time in ISO 8601 format (e.g., '2024-01-02T00:00:00Z')"),
|
|
3144
|
+
severity: z.enum([
|
|
3145
|
+
"DEFAULT",
|
|
3146
|
+
"DEBUG",
|
|
3147
|
+
"INFO",
|
|
3148
|
+
"NOTICE",
|
|
3149
|
+
"WARNING",
|
|
3150
|
+
"ERROR",
|
|
3151
|
+
"CRITICAL",
|
|
3152
|
+
"ALERT",
|
|
3153
|
+
"EMERGENCY"
|
|
3154
|
+
]).optional().describe("Minimum severity level to filter by (default: all levels)"),
|
|
3155
|
+
page_size: z.number().optional().describe("Number of log entries to return (default 100, max 500)")
|
|
3156
|
+
},
|
|
3157
|
+
async ({ filter, start_time, end_time, severity, page_size }) => {
|
|
3158
|
+
try {
|
|
3159
|
+
const result = await connection.queryGcpLogs({
|
|
3160
|
+
filter,
|
|
3161
|
+
startTime: start_time,
|
|
3162
|
+
endTime: end_time,
|
|
3163
|
+
severity,
|
|
3164
|
+
pageSize: page_size
|
|
3165
|
+
});
|
|
3166
|
+
if (result.entries.length === 0) {
|
|
3167
|
+
return textResult("No log entries found matching the given filters.");
|
|
3168
|
+
}
|
|
3169
|
+
const summary = `Found ${result.entries.length} log entries${result.hasMore ? " (more available \u2014 refine filters or increase page_size)" : ""}.`;
|
|
3170
|
+
const formatted = result.entries.map((e) => `[${e.timestamp}] [${e.severity}] ${e.message}`).join("\n");
|
|
3171
|
+
return textResult(`${summary}
|
|
3172
|
+
|
|
3173
|
+
${formatted}`);
|
|
3174
|
+
} catch (error) {
|
|
3175
|
+
return textResult(
|
|
3176
|
+
`Failed to query GCP logs: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3177
|
+
);
|
|
3178
|
+
}
|
|
3179
|
+
},
|
|
3180
|
+
{ annotations: { readOnlyHint: true } }
|
|
3181
|
+
);
|
|
3182
|
+
}
|
|
2980
3183
|
function buildScaleUpResourcesTool(connection) {
|
|
2981
3184
|
return defineTool(
|
|
2982
3185
|
"scale_up_resources",
|
|
@@ -3009,6 +3212,91 @@ function buildScaleUpResourcesTool(connection) {
|
|
|
3009
3212
|
}
|
|
3010
3213
|
);
|
|
3011
3214
|
}
|
|
3215
|
+
function buildAddDependencyTool(connection) {
|
|
3216
|
+
return defineTool(
|
|
3217
|
+
"add_dependency",
|
|
3218
|
+
"Add a dependency \u2014 this task cannot start until the specified task is merged to dev",
|
|
3219
|
+
{
|
|
3220
|
+
depends_on_slug_or_id: z.string().describe("Slug or ID of the task this task depends on")
|
|
3221
|
+
},
|
|
3222
|
+
async ({ depends_on_slug_or_id }) => {
|
|
3223
|
+
try {
|
|
3224
|
+
await connection.addDependency(depends_on_slug_or_id);
|
|
3225
|
+
return textResult(`Dependency added: this task now depends on "${depends_on_slug_or_id}"`);
|
|
3226
|
+
} catch (error) {
|
|
3227
|
+
return textResult(
|
|
3228
|
+
`Failed to add dependency: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3229
|
+
);
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
);
|
|
3233
|
+
}
|
|
3234
|
+
function buildRemoveDependencyTool(connection) {
|
|
3235
|
+
return defineTool(
|
|
3236
|
+
"remove_dependency",
|
|
3237
|
+
"Remove a dependency from this task",
|
|
3238
|
+
{
|
|
3239
|
+
depends_on_slug_or_id: z.string().describe("Slug or ID of the task to remove as dependency")
|
|
3240
|
+
},
|
|
3241
|
+
async ({ depends_on_slug_or_id }) => {
|
|
3242
|
+
try {
|
|
3243
|
+
await connection.removeDependency(depends_on_slug_or_id);
|
|
3244
|
+
return textResult("Dependency removed");
|
|
3245
|
+
} catch (error) {
|
|
3246
|
+
return textResult(
|
|
3247
|
+
`Failed to remove dependency: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3248
|
+
);
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
function buildGetDependenciesTool(connection) {
|
|
3254
|
+
return defineTool(
|
|
3255
|
+
"get_dependencies",
|
|
3256
|
+
"Get this task's dependencies and their current status (met = merged to dev)",
|
|
3257
|
+
{},
|
|
3258
|
+
async () => {
|
|
3259
|
+
try {
|
|
3260
|
+
const deps = await connection.getDependencies();
|
|
3261
|
+
return textResult(JSON.stringify(deps, null, 2));
|
|
3262
|
+
} catch (error) {
|
|
3263
|
+
return textResult(
|
|
3264
|
+
`Failed to get dependencies: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3265
|
+
);
|
|
3266
|
+
}
|
|
3267
|
+
},
|
|
3268
|
+
{ annotations: { readOnlyHint: true } }
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
3271
|
+
function buildCreateFollowUpTaskTool(connection) {
|
|
3272
|
+
return defineTool(
|
|
3273
|
+
"create_follow_up_task",
|
|
3274
|
+
"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.",
|
|
3275
|
+
{
|
|
3276
|
+
title: z.string().describe("Follow-up task title"),
|
|
3277
|
+
description: z.string().optional().describe("Brief description of the follow-up work"),
|
|
3278
|
+
plan: z.string().optional().describe("Implementation plan if known"),
|
|
3279
|
+
story_point_value: z.number().optional().describe("Story point estimate (1=Common, 2=Magic, 3=Rare, 5=Unique)")
|
|
3280
|
+
},
|
|
3281
|
+
async ({ title, description, plan, story_point_value }) => {
|
|
3282
|
+
try {
|
|
3283
|
+
const result = await connection.createFollowUpTask({
|
|
3284
|
+
title,
|
|
3285
|
+
description,
|
|
3286
|
+
plan,
|
|
3287
|
+
storyPointValue: story_point_value
|
|
3288
|
+
});
|
|
3289
|
+
return textResult(
|
|
3290
|
+
`Follow-up task created: "${title}" (slug: ${result.slug}). It depends on the current task and will be unblocked when this task is merged.`
|
|
3291
|
+
);
|
|
3292
|
+
} catch (error) {
|
|
3293
|
+
return textResult(
|
|
3294
|
+
`Failed to create follow-up task: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3295
|
+
);
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
);
|
|
3299
|
+
}
|
|
3012
3300
|
function buildCommonTools(connection, config) {
|
|
3013
3301
|
const tools = [
|
|
3014
3302
|
buildReadTaskChatTool(connection),
|
|
@@ -3020,7 +3308,12 @@ function buildCommonTools(connection, config) {
|
|
|
3020
3308
|
buildGetTaskFileTool(connection),
|
|
3021
3309
|
buildSearchIncidentsTool(connection),
|
|
3022
3310
|
buildGetTaskIncidentsTool(connection),
|
|
3023
|
-
|
|
3311
|
+
buildQueryGcpLogsTool(connection),
|
|
3312
|
+
buildCreatePullRequestTool(connection, config),
|
|
3313
|
+
buildAddDependencyTool(connection),
|
|
3314
|
+
buildRemoveDependencyTool(connection),
|
|
3315
|
+
buildGetDependenciesTool(connection),
|
|
3316
|
+
buildCreateFollowUpTaskTool(connection)
|
|
3024
3317
|
];
|
|
3025
3318
|
if (process.env.CLAUDESPACE_NAME) {
|
|
3026
3319
|
tools.push(buildScaleUpResourcesTool(connection));
|
|
@@ -4652,6 +4945,14 @@ import { randomUUID } from "crypto";
|
|
|
4652
4945
|
var PM_PLAN_FILE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit"]);
|
|
4653
4946
|
var DESTRUCTIVE_CMD_PATTERN = /git\s+push\s+--force(?!\s*-with-lease)|git\s+reset\s+--hard|rm\s+-rf\s+\//;
|
|
4654
4947
|
var CODE_REVIEW_WRITE_CMD_PATTERN = /git\s+push|git\s+commit|git\s+add|rm\s+|mv\s+|cp\s+|mkdir\s+|touch\s+|chmod\s+|chown\s+/;
|
|
4948
|
+
var RESOURCE_HEAVY_PATTERNS = [
|
|
4949
|
+
/\bbun\s+(install|i|add)\b/,
|
|
4950
|
+
/\bnpm\s+(install|ci|i)\b/,
|
|
4951
|
+
/\byarn(\s+install)?\s/,
|
|
4952
|
+
/\bpnpm\s+(install|i|add)\b/,
|
|
4953
|
+
/\bpip\s+install\b/,
|
|
4954
|
+
/\bcargo\s+build\b/
|
|
4955
|
+
];
|
|
4655
4956
|
function isPlanFile(input) {
|
|
4656
4957
|
const filePath = String(input.file_path ?? input.path ?? "");
|
|
4657
4958
|
return filePath.includes(".claude/plans/");
|
|
@@ -4754,14 +5055,15 @@ async function handleExitPlanMode(host, input) {
|
|
|
4754
5055
|
].join("\n")
|
|
4755
5056
|
};
|
|
4756
5057
|
}
|
|
4757
|
-
await host.connection.triggerIdentification();
|
|
4758
|
-
host.hasExitedPlanMode = true;
|
|
4759
5058
|
if (host.agentMode === "discovery") {
|
|
5059
|
+
host.hasExitedPlanMode = true;
|
|
4760
5060
|
host.connection.postChatMessage(
|
|
4761
|
-
"
|
|
5061
|
+
"Plan complete. The task stays in Planning \u2014 identify it or switch to Build mode when ready."
|
|
4762
5062
|
);
|
|
4763
5063
|
return { behavior: "allow", updatedInput: input };
|
|
4764
5064
|
}
|
|
5065
|
+
await host.connection.triggerIdentification();
|
|
5066
|
+
host.hasExitedPlanMode = true;
|
|
4765
5067
|
const newMode = host.isParentTask ? "review" : "building";
|
|
4766
5068
|
host.pendingModeRestart = true;
|
|
4767
5069
|
if (host.onModeTransition) {
|
|
@@ -4800,35 +5102,47 @@ async function handleAskUserQuestion(host, input) {
|
|
|
4800
5102
|
return { behavior: "allow", updatedInput: { questions: input.questions, answers } };
|
|
4801
5103
|
}
|
|
4802
5104
|
var DENIAL_WARNING_THRESHOLD = 3;
|
|
5105
|
+
function isResourceHeavyCommand(command) {
|
|
5106
|
+
return RESOURCE_HEAVY_PATTERNS.some((p) => p.test(command));
|
|
5107
|
+
}
|
|
5108
|
+
var autoScaled = false;
|
|
5109
|
+
async function maybeAutoScale(host, toolName, input) {
|
|
5110
|
+
if (autoScaled || !process.env.CLAUDESPACE_NAME || toolName !== "Bash" || typeof input.command !== "string" || !isResourceHeavyCommand(input.command)) {
|
|
5111
|
+
return;
|
|
5112
|
+
}
|
|
5113
|
+
autoScaled = true;
|
|
5114
|
+
try {
|
|
5115
|
+
await host.connection.requestScaleUp("light", `auto-scale: ${input.command.slice(0, 60)}`);
|
|
5116
|
+
} catch {
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5119
|
+
function resolveToolAccess(host, toolName, input) {
|
|
5120
|
+
switch (host.agentMode) {
|
|
5121
|
+
case "discovery":
|
|
5122
|
+
return handleDiscoveryToolAccess(toolName, input);
|
|
5123
|
+
case "building":
|
|
5124
|
+
return handleBuildingToolAccess(toolName, input);
|
|
5125
|
+
case "review":
|
|
5126
|
+
return handleReviewToolAccess(toolName, input, host.isParentTask);
|
|
5127
|
+
case "auto":
|
|
5128
|
+
return handleAutoToolAccess(toolName, input, host.hasExitedPlanMode, host.isParentTask);
|
|
5129
|
+
case "code-review":
|
|
5130
|
+
return handleCodeReviewToolAccess(toolName, input);
|
|
5131
|
+
default:
|
|
5132
|
+
return { behavior: "allow", updatedInput: input };
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
4803
5135
|
function buildCanUseTool(host) {
|
|
4804
5136
|
let consecutiveDenials = 0;
|
|
4805
5137
|
return async (toolName, input) => {
|
|
5138
|
+
await maybeAutoScale(host, toolName, input);
|
|
4806
5139
|
if (toolName === "ExitPlanMode" && (host.agentMode === "auto" || host.agentMode === "discovery") && !host.hasExitedPlanMode) {
|
|
4807
5140
|
return await handleExitPlanMode(host, input);
|
|
4808
5141
|
}
|
|
4809
5142
|
if (toolName === "AskUserQuestion") {
|
|
4810
5143
|
return await handleAskUserQuestion(host, input);
|
|
4811
5144
|
}
|
|
4812
|
-
|
|
4813
|
-
switch (host.agentMode) {
|
|
4814
|
-
case "discovery":
|
|
4815
|
-
result = handleDiscoveryToolAccess(toolName, input);
|
|
4816
|
-
break;
|
|
4817
|
-
case "building":
|
|
4818
|
-
result = handleBuildingToolAccess(toolName, input);
|
|
4819
|
-
break;
|
|
4820
|
-
case "review":
|
|
4821
|
-
result = handleReviewToolAccess(toolName, input, host.isParentTask);
|
|
4822
|
-
break;
|
|
4823
|
-
case "auto":
|
|
4824
|
-
result = handleAutoToolAccess(toolName, input, host.hasExitedPlanMode, host.isParentTask);
|
|
4825
|
-
break;
|
|
4826
|
-
case "code-review":
|
|
4827
|
-
result = handleCodeReviewToolAccess(toolName, input);
|
|
4828
|
-
break;
|
|
4829
|
-
default:
|
|
4830
|
-
result = { behavior: "allow", updatedInput: input };
|
|
4831
|
-
}
|
|
5145
|
+
const result = resolveToolAccess(host, toolName, input);
|
|
4832
5146
|
if (result.behavior === "deny") {
|
|
4833
5147
|
consecutiveDenials++;
|
|
4834
5148
|
if (consecutiveDenials === DENIAL_WARNING_THRESHOLD) {
|
|
@@ -4854,6 +5168,7 @@ function buildHooks(host) {
|
|
|
4854
5168
|
{
|
|
4855
5169
|
hooks: [
|
|
4856
5170
|
async (input) => {
|
|
5171
|
+
if (host.isStopped()) return await Promise.resolve({ continue: false });
|
|
4857
5172
|
if (input.hook_event_name === "PostToolUse") {
|
|
4858
5173
|
const output = typeof input.tool_response === "string" ? input.tool_response.slice(0, 500) : JSON.stringify(input.tool_response).slice(0, 500);
|
|
4859
5174
|
host.connection.sendEvent({
|
|
@@ -5773,6 +6088,9 @@ var AgentRunner = class {
|
|
|
5773
6088
|
const pastPlanning = this.taskContext.status !== "Planning" && this.taskContext.status !== "Unidentified";
|
|
5774
6089
|
if (this.agentMode === "auto" && pastPlanning) {
|
|
5775
6090
|
this.hasExitedPlanMode = true;
|
|
6091
|
+
this.agentMode = "building";
|
|
6092
|
+
const builderModel = this.taskContext.builderModel ?? this.taskContext.model;
|
|
6093
|
+
if (builderModel) this.taskContext.model = builderModel;
|
|
5776
6094
|
}
|
|
5777
6095
|
this.logEffectiveSettings();
|
|
5778
6096
|
if (process.env.CODESPACES === "true") unshallowRepo(this.config.workspaceDir);
|
|
@@ -6077,16 +6395,21 @@ var AgentRunner = class {
|
|
|
6077
6395
|
this._queryHost = host;
|
|
6078
6396
|
return host;
|
|
6079
6397
|
}
|
|
6398
|
+
lastAnnouncedMode = null;
|
|
6080
6399
|
handleModeChange(newAgentMode) {
|
|
6081
6400
|
if (this.config.mode !== "pm") return;
|
|
6082
|
-
if (newAgentMode
|
|
6401
|
+
if (!newAgentMode || newAgentMode === this.agentMode) return;
|
|
6402
|
+
this.agentMode = newAgentMode;
|
|
6083
6403
|
this.updateExitedPlanModeFlag(newAgentMode);
|
|
6084
6404
|
const effectiveMode = this.effectiveAgentMode;
|
|
6085
6405
|
const isBuildCapable = effectiveMode === "building" || effectiveMode === "auto" && this.hasExitedPlanMode;
|
|
6086
6406
|
this.connection.emitModeChanged(effectiveMode);
|
|
6087
|
-
this.
|
|
6088
|
-
|
|
6089
|
-
|
|
6407
|
+
if (effectiveMode !== this.lastAnnouncedMode) {
|
|
6408
|
+
this.lastAnnouncedMode = effectiveMode;
|
|
6409
|
+
this.connection.postChatMessage(
|
|
6410
|
+
`Mode switched to **${effectiveMode}**${effectiveMode === "building" ? " \u2014 I now have direct coding access." : ""}`
|
|
6411
|
+
);
|
|
6412
|
+
}
|
|
6090
6413
|
if (isBuildCapable && this.taskContext?.status === "Open") {
|
|
6091
6414
|
this.connection.updateStatus("InProgress");
|
|
6092
6415
|
this.taskContext.status = "InProgress";
|
|
@@ -6124,8 +6447,19 @@ var AgentRunner = class {
|
|
|
6124
6447
|
}
|
|
6125
6448
|
stop() {
|
|
6126
6449
|
this.stopped = true;
|
|
6450
|
+
this.stopHeartbeat();
|
|
6127
6451
|
this.clearIdleTimers();
|
|
6452
|
+
const host = this._queryHost;
|
|
6453
|
+
if (host?.activeQuery) {
|
|
6454
|
+
const q = host.activeQuery;
|
|
6455
|
+
if (typeof q.abort === "function") {
|
|
6456
|
+
q.abort();
|
|
6457
|
+
}
|
|
6458
|
+
void host.activeQuery.return(void 0);
|
|
6459
|
+
host.activeQuery = null;
|
|
6460
|
+
}
|
|
6128
6461
|
this.tunnelClient?.disconnect();
|
|
6462
|
+
this.connection.disconnect();
|
|
6129
6463
|
if (this.inputResolver) {
|
|
6130
6464
|
this.inputResolver(null);
|
|
6131
6465
|
this.inputResolver = null;
|
|
@@ -7468,8 +7802,23 @@ var ProjectRunner = class {
|
|
|
7468
7802
|
logger8.info("Connected, waiting for task assignments");
|
|
7469
7803
|
await new Promise((resolve2) => {
|
|
7470
7804
|
this.resolveLifecycle = resolve2;
|
|
7471
|
-
|
|
7472
|
-
|
|
7805
|
+
this.setupSignalHandlers();
|
|
7806
|
+
});
|
|
7807
|
+
}
|
|
7808
|
+
setupSignalHandlers() {
|
|
7809
|
+
process.on("SIGTERM", () => {
|
|
7810
|
+
setTimeout(() => {
|
|
7811
|
+
logger8.warn("Forcing exit after SIGTERM timeout");
|
|
7812
|
+
process.exit(1);
|
|
7813
|
+
}, STOP_TIMEOUT_MS + 1e4).unref();
|
|
7814
|
+
void this.stop();
|
|
7815
|
+
});
|
|
7816
|
+
process.on("SIGINT", () => {
|
|
7817
|
+
setTimeout(() => {
|
|
7818
|
+
logger8.warn("Forcing exit after SIGINT timeout");
|
|
7819
|
+
process.exit(1);
|
|
7820
|
+
}, STOP_TIMEOUT_MS + 1e4).unref();
|
|
7821
|
+
void this.stop();
|
|
7473
7822
|
});
|
|
7474
7823
|
}
|
|
7475
7824
|
handleAssignment(assignment) {
|
|
@@ -7577,7 +7926,7 @@ var ProjectRunner = class {
|
|
|
7577
7926
|
await Promise.race([
|
|
7578
7927
|
Promise.all(stopPromises),
|
|
7579
7928
|
new Promise((resolve2) => {
|
|
7580
|
-
setTimeout(resolve2,
|
|
7929
|
+
setTimeout(resolve2, STOP_TIMEOUT_MS + 5e3);
|
|
7581
7930
|
})
|
|
7582
7931
|
]);
|
|
7583
7932
|
this.connection.disconnect();
|
|
@@ -7668,4 +8017,4 @@ export {
|
|
|
7668
8017
|
ProjectRunner,
|
|
7669
8018
|
FileCache
|
|
7670
8019
|
};
|
|
7671
|
-
//# sourceMappingURL=chunk-
|
|
8020
|
+
//# sourceMappingURL=chunk-WBBX5AIX.js.map
|