@rallycry/conveyor-agent 10.0.3 → 10.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-QKRPJ7DB.js → chunk-S72TAMGA.js} +130 -76
- package/dist/chunk-S72TAMGA.js.map +1 -0
- package/dist/cli.js +20 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/runtime/entrypoint.sh +7 -10
- package/dist/chunk-QKRPJ7DB.js.map +0 -1
|
@@ -944,8 +944,10 @@ function createServiceLogger(service) {
|
|
|
944
944
|
}
|
|
945
945
|
|
|
946
946
|
// src/runner/git-utils.ts
|
|
947
|
-
import { execSync } from "child_process";
|
|
947
|
+
import { execSync, exec } from "child_process";
|
|
948
948
|
import { realpathSync } from "fs";
|
|
949
|
+
import { promisify } from "util";
|
|
950
|
+
var execAsync = promisify(exec);
|
|
949
951
|
function syncWithBaseBranch(cwd, baseBranch) {
|
|
950
952
|
if (!baseBranch) return true;
|
|
951
953
|
try {
|
|
@@ -1057,20 +1059,15 @@ function stageAndCommit(cwd, message) {
|
|
|
1057
1059
|
return null;
|
|
1058
1060
|
}
|
|
1059
1061
|
}
|
|
1060
|
-
function tryPush(cwd, branch, skipVerify = false) {
|
|
1062
|
+
async function tryPush(cwd, branch, skipVerify = false) {
|
|
1061
1063
|
const noVerify = skipVerify ? "--no-verify " : "";
|
|
1062
1064
|
try {
|
|
1063
|
-
|
|
1064
|
-
cwd,
|
|
1065
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1066
|
-
timeout: 3e4
|
|
1067
|
-
});
|
|
1065
|
+
await execAsync(`git push ${noVerify}origin ${branch}`, { cwd, timeout: 3e4 });
|
|
1068
1066
|
return true;
|
|
1069
1067
|
} catch {
|
|
1070
1068
|
try {
|
|
1071
|
-
|
|
1069
|
+
await execAsync(`git push ${noVerify}--force-with-lease origin ${branch}`, {
|
|
1072
1070
|
cwd,
|
|
1073
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
1074
1071
|
timeout: 3e4
|
|
1075
1072
|
});
|
|
1076
1073
|
return true;
|
|
@@ -1079,9 +1076,9 @@ function tryPush(cwd, branch, skipVerify = false) {
|
|
|
1079
1076
|
}
|
|
1080
1077
|
}
|
|
1081
1078
|
}
|
|
1082
|
-
function isAuthError(cwd) {
|
|
1079
|
+
async function isAuthError(cwd) {
|
|
1083
1080
|
try {
|
|
1084
|
-
|
|
1081
|
+
await execAsync("git push --dry-run", { cwd, timeout: 3e4 });
|
|
1085
1082
|
return false;
|
|
1086
1083
|
} catch (err) {
|
|
1087
1084
|
if (err.killed) return true;
|
|
@@ -1243,14 +1240,14 @@ async function pushToOrigin(cwd, refreshToken, skipVerify = false) {
|
|
|
1243
1240
|
} catch {
|
|
1244
1241
|
}
|
|
1245
1242
|
}
|
|
1246
|
-
if (tryPush(cwd, currentBranch, skipVerify)) return true;
|
|
1247
|
-
if (refreshToken && isAuthError(cwd)) {
|
|
1243
|
+
if (await tryPush(cwd, currentBranch, skipVerify)) return true;
|
|
1244
|
+
if (refreshToken && await isAuthError(cwd)) {
|
|
1248
1245
|
const token = await refreshToken();
|
|
1249
1246
|
if (token) {
|
|
1250
1247
|
updateRemoteToken(cwd, token);
|
|
1251
1248
|
process.env.GITHUB_TOKEN = token;
|
|
1252
1249
|
process.env.GH_TOKEN = token;
|
|
1253
|
-
return tryPush(cwd, currentBranch, skipVerify);
|
|
1250
|
+
return await tryPush(cwd, currentBranch, skipVerify);
|
|
1254
1251
|
}
|
|
1255
1252
|
}
|
|
1256
1253
|
return false;
|
|
@@ -1779,11 +1776,11 @@ function execErrorDetail(err) {
|
|
|
1779
1776
|
const message = withStreams.message ?? String(err);
|
|
1780
1777
|
return stderr ? `${message} \u2014 stderr: ${stderr}` : message;
|
|
1781
1778
|
}
|
|
1782
|
-
function dumpPostgresIfPresent(
|
|
1779
|
+
function dumpPostgresIfPresent(exec2 = execSync2) {
|
|
1783
1780
|
if (!hasPostgresDep()) return Promise.resolve({ dumped: false });
|
|
1784
1781
|
const outputPath = path.join(tmpdir(), `conveyor-pgdump-${randomUUID()}.sql`);
|
|
1785
1782
|
try {
|
|
1786
|
-
|
|
1783
|
+
exec2(buildPgDumpCommand({ outputPath }), {
|
|
1787
1784
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1788
1785
|
timeout: 6e4
|
|
1789
1786
|
});
|
|
@@ -1794,10 +1791,10 @@ function dumpPostgresIfPresent(exec = execSync2) {
|
|
|
1794
1791
|
return Promise.resolve({ dumped: false });
|
|
1795
1792
|
}
|
|
1796
1793
|
}
|
|
1797
|
-
function applyPgDumpIfConfigured(dumpPath,
|
|
1794
|
+
function applyPgDumpIfConfigured(dumpPath, exec2 = execSync2) {
|
|
1798
1795
|
if (!hasPostgresDep()) return false;
|
|
1799
1796
|
try {
|
|
1800
|
-
|
|
1797
|
+
exec2(buildPsqlRestoreCommand({ dumpPath }), {
|
|
1801
1798
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1802
1799
|
timeout: 12e4
|
|
1803
1800
|
});
|
|
@@ -4890,6 +4887,95 @@ function truncatePlanForPrompt(plan) {
|
|
|
4890
4887
|
return `${head}${PLAN_TRUNCATION_MARKER}${tail}`;
|
|
4891
4888
|
}
|
|
4892
4889
|
|
|
4890
|
+
// src/execution/pm-relaunch-instructions.ts
|
|
4891
|
+
function resolvePmRelaunchIntent(context, isAuto, agentMode) {
|
|
4892
|
+
switch (agentMode) {
|
|
4893
|
+
case "building":
|
|
4894
|
+
return "build" /* Build */;
|
|
4895
|
+
case "review":
|
|
4896
|
+
return "review" /* Review */;
|
|
4897
|
+
default:
|
|
4898
|
+
break;
|
|
4899
|
+
}
|
|
4900
|
+
if (!isAuto) return "wait_for_team" /* WaitForTeam */;
|
|
4901
|
+
return context.plan?.trim() ? "auto_with_plan" /* AutoWithPlan */ : "auto_planning" /* AutoPlanning */;
|
|
4902
|
+
}
|
|
4903
|
+
function buildRelaunchMessageSummary(context, lastAgentIdx) {
|
|
4904
|
+
const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
|
|
4905
|
+
if (newMessages.length === 0) {
|
|
4906
|
+
return [`You have been relaunched. No new messages since your last session.`];
|
|
4907
|
+
}
|
|
4908
|
+
return [
|
|
4909
|
+
`You have been relaunched. Here are new messages since your last session:`,
|
|
4910
|
+
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`)
|
|
4911
|
+
];
|
|
4912
|
+
}
|
|
4913
|
+
function buildPmBuildRelaunchParts(context, isAuto) {
|
|
4914
|
+
const parts = [
|
|
4915
|
+
`
|
|
4916
|
+
Your plan has been approved. Begin implementing it now.`,
|
|
4917
|
+
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
|
|
4918
|
+
`Start by reading the relevant source files mentioned in the plan, then write code.`,
|
|
4919
|
+
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`
|
|
4920
|
+
];
|
|
4921
|
+
if (isAuto) {
|
|
4922
|
+
parts.push(
|
|
4923
|
+
`
|
|
4924
|
+
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
4925
|
+
`Your FIRST action must be reading source files from the plan, then immediately writing code.`,
|
|
4926
|
+
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing.`,
|
|
4927
|
+
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
4928
|
+
);
|
|
4929
|
+
}
|
|
4930
|
+
return parts;
|
|
4931
|
+
}
|
|
4932
|
+
function buildPmReviewRelaunchParts() {
|
|
4933
|
+
return [
|
|
4934
|
+
`
|
|
4935
|
+
Resume reviewing and coordinating this task.`,
|
|
4936
|
+
`Call list_subtasks to check current child-task state and progress.`,
|
|
4937
|
+
`Review children in ReviewPR status first, then approve and merge passing PRs.`,
|
|
4938
|
+
`Fire next child builds with start_child_cloud_build when ready.`,
|
|
4939
|
+
`Do not implement code directly or create a new PR from the PM review session.`
|
|
4940
|
+
];
|
|
4941
|
+
}
|
|
4942
|
+
function buildPmAutoWithPlanRelaunchParts() {
|
|
4943
|
+
return [
|
|
4944
|
+
`
|
|
4945
|
+
You are in auto mode. A plan already exists for this task.`,
|
|
4946
|
+
`Verify that story points, title, and tags are set via get_current_plan, then call ExitPlanMode immediately to transition to building.`,
|
|
4947
|
+
`Do NOT wait for team input \u2014 proceed autonomously.`
|
|
4948
|
+
];
|
|
4949
|
+
}
|
|
4950
|
+
function buildPmAutoPlanningRelaunchParts() {
|
|
4951
|
+
return [
|
|
4952
|
+
`
|
|
4953
|
+
You are in auto mode. Continue planning autonomously.`,
|
|
4954
|
+
`When the plan and all required properties are set, call ExitPlanMode to transition to building.`,
|
|
4955
|
+
`Do NOT wait for team input \u2014 proceed autonomously.`
|
|
4956
|
+
];
|
|
4957
|
+
}
|
|
4958
|
+
function buildPmWaitForTeamRelaunchParts() {
|
|
4959
|
+
return [
|
|
4960
|
+
`
|
|
4961
|
+
You are the project manager for this task.`,
|
|
4962
|
+
`Review the context above and wait for the team to provide instructions before taking action.`
|
|
4963
|
+
];
|
|
4964
|
+
}
|
|
4965
|
+
function buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode) {
|
|
4966
|
+
const parts = buildRelaunchMessageSummary(context, lastAgentIdx);
|
|
4967
|
+
const intent = resolvePmRelaunchIntent(context, isAuto, agentMode);
|
|
4968
|
+
const intentPartsByIntent = {
|
|
4969
|
+
["build" /* Build */]: () => buildPmBuildRelaunchParts(context, isAuto),
|
|
4970
|
+
["review" /* Review */]: buildPmReviewRelaunchParts,
|
|
4971
|
+
["auto_with_plan" /* AutoWithPlan */]: buildPmAutoWithPlanRelaunchParts,
|
|
4972
|
+
["auto_planning" /* AutoPlanning */]: buildPmAutoPlanningRelaunchParts,
|
|
4973
|
+
["wait_for_team" /* WaitForTeam */]: buildPmWaitForTeamRelaunchParts
|
|
4974
|
+
};
|
|
4975
|
+
parts.push(...intentPartsByIntent[intent]());
|
|
4976
|
+
return parts;
|
|
4977
|
+
}
|
|
4978
|
+
|
|
4893
4979
|
// src/execution/mode-prompt.ts
|
|
4894
4980
|
var SP_DESC_MAX_CHARS = 80;
|
|
4895
4981
|
function truncateDescription(desc, maxChars) {
|
|
@@ -5360,59 +5446,6 @@ function detectRelaunchScenario(context, trustChatHistory = false) {
|
|
|
5360
5446
|
const hasNewUserMessages = messagesAfterAgent.some((m) => m.role === "user");
|
|
5361
5447
|
return hasNewUserMessages ? "feedback_relaunch" : "idle_relaunch";
|
|
5362
5448
|
}
|
|
5363
|
-
function buildPmRelaunchParts(context, lastAgentIdx, isAuto, agentMode) {
|
|
5364
|
-
const parts = [];
|
|
5365
|
-
const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
|
|
5366
|
-
if (newMessages.length > 0) {
|
|
5367
|
-
parts.push(
|
|
5368
|
-
`You have been relaunched. Here are new messages since your last session:`,
|
|
5369
|
-
...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`)
|
|
5370
|
-
);
|
|
5371
|
-
} else {
|
|
5372
|
-
parts.push(`You have been relaunched. No new messages since your last session.`);
|
|
5373
|
-
}
|
|
5374
|
-
if (agentMode === "building" || agentMode === "review") {
|
|
5375
|
-
parts.push(
|
|
5376
|
-
`
|
|
5377
|
-
Your plan has been approved. Begin implementing it now.`,
|
|
5378
|
-
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
|
|
5379
|
-
`Start by reading the relevant source files mentioned in the plan, then write code.`,
|
|
5380
|
-
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`
|
|
5381
|
-
);
|
|
5382
|
-
if (isAuto) {
|
|
5383
|
-
parts.push(
|
|
5384
|
-
`
|
|
5385
|
-
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
5386
|
-
`Your FIRST action must be reading source files from the plan, then immediately writing code.`,
|
|
5387
|
-
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing.`,
|
|
5388
|
-
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
5389
|
-
);
|
|
5390
|
-
}
|
|
5391
|
-
} else if (isAuto) {
|
|
5392
|
-
if (context.plan?.trim()) {
|
|
5393
|
-
parts.push(
|
|
5394
|
-
`
|
|
5395
|
-
You are in auto mode. A plan already exists for this task.`,
|
|
5396
|
-
`Verify that story points, title, and tags are set via get_current_plan, then call ExitPlanMode immediately to transition to building.`,
|
|
5397
|
-
`Do NOT wait for team input \u2014 proceed autonomously.`
|
|
5398
|
-
);
|
|
5399
|
-
} else {
|
|
5400
|
-
parts.push(
|
|
5401
|
-
`
|
|
5402
|
-
You are in auto mode. Continue planning autonomously.`,
|
|
5403
|
-
`When the plan and all required properties are set, call ExitPlanMode to transition to building.`,
|
|
5404
|
-
`Do NOT wait for team input \u2014 proceed autonomously.`
|
|
5405
|
-
);
|
|
5406
|
-
}
|
|
5407
|
-
} else {
|
|
5408
|
-
parts.push(
|
|
5409
|
-
`
|
|
5410
|
-
You are the project manager for this task.`,
|
|
5411
|
-
`Review the context above and wait for the team to provide instructions before taking action.`
|
|
5412
|
-
);
|
|
5413
|
-
}
|
|
5414
|
-
return parts;
|
|
5415
|
-
}
|
|
5416
5449
|
function buildRelaunchWithSession(mode, context, agentMode, isAuto) {
|
|
5417
5450
|
const scenario = detectRelaunchScenario(context);
|
|
5418
5451
|
const hasPriorTurn = !!context.lastSeenMessageId || !!context.claudeSessionId;
|
|
@@ -5527,7 +5560,10 @@ ${truncatePlanForPrompt(context.plan)}`);
|
|
|
5527
5560
|
}
|
|
5528
5561
|
return parts;
|
|
5529
5562
|
}
|
|
5530
|
-
function buildFreshInstructions(isPm, isAutoMode, context, agentMode) {
|
|
5563
|
+
function buildFreshInstructions(isPm, isCodeReview, isAutoMode, context, agentMode) {
|
|
5564
|
+
if (isCodeReview) {
|
|
5565
|
+
return buildFreshCodeReviewInstructions(context);
|
|
5566
|
+
}
|
|
5531
5567
|
if (isPm && agentMode === "building") {
|
|
5532
5568
|
return [
|
|
5533
5569
|
`Your plan has been approved. Begin implementing it now.`,
|
|
@@ -5595,6 +5631,21 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
|
|
|
5595
5631
|
}
|
|
5596
5632
|
return parts;
|
|
5597
5633
|
}
|
|
5634
|
+
function buildFreshCodeReviewInstructions(context) {
|
|
5635
|
+
const parts = [
|
|
5636
|
+
`Perform the automated code review for this PR.`,
|
|
5637
|
+
`Work on the git branch "${context.githubBranch}". Stay on this branch for the entire review. Do not checkout or create other branches.`,
|
|
5638
|
+
`Start by running \`git diff ${context.baseBranch ?? "dev"}..HEAD\` to inspect the submitted changes, then read the task plan and surrounding code as needed.`,
|
|
5639
|
+
`Review for correctness, security, performance, error handling, test coverage, and consistency with existing patterns.`,
|
|
5640
|
+
`If small fixes are needed, make them directly, commit, push, and re-review the result.`,
|
|
5641
|
+
`Use approve_code_review when the PR passes review.`,
|
|
5642
|
+
`Use request_code_changes when substantive issues remain that you cannot fix directly.`
|
|
5643
|
+
];
|
|
5644
|
+
if (context.githubPRUrl) {
|
|
5645
|
+
parts.push(`The PR under review is ${context.githubPRUrl}. Do not create a new PR.`);
|
|
5646
|
+
}
|
|
5647
|
+
return parts;
|
|
5648
|
+
}
|
|
5598
5649
|
function buildFeedbackInstructions(context, isPm, agentMode, isAuto) {
|
|
5599
5650
|
const lastAgentIdx = findLastAgentMessageIndex2(context.chatHistory);
|
|
5600
5651
|
const newMessages = context.chatHistory.slice(lastAgentIdx + 1).filter((m) => m.role === "user");
|
|
@@ -5700,8 +5751,11 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
|
|
|
5700
5751
|
const parts = [`
|
|
5701
5752
|
## Instructions`];
|
|
5702
5753
|
const isPm = mode === "pm";
|
|
5754
|
+
const isCodeReview = mode === "code-review" || !isPm && agentMode === "review";
|
|
5703
5755
|
if (scenario === "fresh") {
|
|
5704
|
-
parts.push(
|
|
5756
|
+
parts.push(
|
|
5757
|
+
...buildFreshInstructions(isPm, isCodeReview, agentMode === "auto", context, agentMode)
|
|
5758
|
+
);
|
|
5705
5759
|
return parts;
|
|
5706
5760
|
}
|
|
5707
5761
|
if (scenario === "idle_relaunch") {
|
|
@@ -6072,7 +6126,7 @@ function buildCreatePullRequestTool(connection, config) {
|
|
|
6072
6126
|
"Commit message for staging uncommitted changes. If not provided, a default message based on the PR title will be used."
|
|
6073
6127
|
),
|
|
6074
6128
|
skipVerify: z5.boolean().optional().describe(
|
|
6075
|
-
"
|
|
6129
|
+
"Controls the local pre-push quality gate (lint/typecheck/test). Defaults to true (--no-verify): the push skips the local gate because you should run gates yourself before opening the PR and CI re-runs them on the resulting PR. Running the full gate synchronously during the push would block the agent's event loop long enough to drop the Conveyor socket connection. Pass false to force the local pre-push hook to run."
|
|
6076
6130
|
)
|
|
6077
6131
|
},
|
|
6078
6132
|
async ({ title, body, branch, baseBranch, commitMessage, skipVerify }) => {
|
|
@@ -6107,7 +6161,7 @@ Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>`;
|
|
|
6107
6161
|
return void 0;
|
|
6108
6162
|
}
|
|
6109
6163
|
},
|
|
6110
|
-
skipVerify ??
|
|
6164
|
+
skipVerify ?? true
|
|
6111
6165
|
);
|
|
6112
6166
|
if (pushSuccess) {
|
|
6113
6167
|
connection.sendEvent({
|
|
@@ -9859,4 +9913,4 @@ export {
|
|
|
9859
9913
|
runStartCommand,
|
|
9860
9914
|
unshallowRepo
|
|
9861
9915
|
};
|
|
9862
|
-
//# sourceMappingURL=chunk-
|
|
9916
|
+
//# sourceMappingURL=chunk-S72TAMGA.js.map
|