@rallycry/conveyor-agent 9.0.0 → 9.0.2
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-JH7GUOGW.js → chunk-5W6MHROF.js} +130 -6
- package/dist/chunk-5W6MHROF.js.map +1 -0
- package/dist/cli.js +18 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-JH7GUOGW.js.map +0 -1
|
@@ -830,6 +830,7 @@ function createServiceLogger(service) {
|
|
|
830
830
|
|
|
831
831
|
// src/runner/git-utils.ts
|
|
832
832
|
import { execSync } from "child_process";
|
|
833
|
+
import { realpathSync } from "fs";
|
|
833
834
|
function syncWithBaseBranch(cwd, baseBranch) {
|
|
834
835
|
if (!baseBranch) return true;
|
|
835
836
|
try {
|
|
@@ -1131,6 +1132,105 @@ async function pushToOrigin(cwd, refreshToken, skipVerify = false) {
|
|
|
1131
1132
|
return false;
|
|
1132
1133
|
}
|
|
1133
1134
|
}
|
|
1135
|
+
function branchBackupRef(branch) {
|
|
1136
|
+
return `conveyor-wip/branches/${branch}`;
|
|
1137
|
+
}
|
|
1138
|
+
function listWorktrees(cwd) {
|
|
1139
|
+
try {
|
|
1140
|
+
const out = execSync("git worktree list --porcelain", {
|
|
1141
|
+
cwd,
|
|
1142
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1143
|
+
}).toString();
|
|
1144
|
+
const result = [];
|
|
1145
|
+
for (const entry of out.split("\n\n")) {
|
|
1146
|
+
const lines = entry.trim().split("\n");
|
|
1147
|
+
const wl = lines.find((l) => l.startsWith("worktree "));
|
|
1148
|
+
if (!wl) continue;
|
|
1149
|
+
const bl = lines.find((l) => l.startsWith("branch "));
|
|
1150
|
+
result.push({
|
|
1151
|
+
path: wl.slice("worktree ".length),
|
|
1152
|
+
branch: bl ? bl.slice("branch refs/heads/".length) : null
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
return result;
|
|
1156
|
+
} catch {
|
|
1157
|
+
return [];
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
function listLocalBranches(cwd) {
|
|
1161
|
+
try {
|
|
1162
|
+
return execSync("git for-each-ref --format='%(refname:short)' refs/heads/", {
|
|
1163
|
+
cwd,
|
|
1164
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1165
|
+
}).toString().split("\n").map((s) => s.trim()).filter(Boolean);
|
|
1166
|
+
} catch {
|
|
1167
|
+
return [];
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function branchUnpushedCount(cwd, branch) {
|
|
1171
|
+
try {
|
|
1172
|
+
const n = execSync(`git rev-list --count ${JSON.stringify(branch)} --not --remotes=origin`, {
|
|
1173
|
+
cwd,
|
|
1174
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1175
|
+
}).toString().trim();
|
|
1176
|
+
return Number.parseInt(n, 10) || 0;
|
|
1177
|
+
} catch {
|
|
1178
|
+
return 0;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
function samePath(a, b) {
|
|
1182
|
+
try {
|
|
1183
|
+
return realpathSync(a) === realpathSync(b);
|
|
1184
|
+
} catch {
|
|
1185
|
+
return a === b;
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
async function flushAllPendingWork(cwd, opts) {
|
|
1189
|
+
try {
|
|
1190
|
+
const primary = await flushPendingChanges(cwd, opts);
|
|
1191
|
+
await refreshRemoteToken(cwd, opts?.refreshToken);
|
|
1192
|
+
const currentBranch = getCurrentBranch(cwd);
|
|
1193
|
+
const worktreesSnapshotted = snapshotOtherWorktrees(cwd, opts?.wipMessage);
|
|
1194
|
+
const branchesBackedUp = backupOtherBranches(cwd, currentBranch);
|
|
1195
|
+
return {
|
|
1196
|
+
hadWork: primary.hadWork || worktreesSnapshotted > 0 || branchesBackedUp > 0,
|
|
1197
|
+
branchesBackedUp,
|
|
1198
|
+
worktreesSnapshotted
|
|
1199
|
+
};
|
|
1200
|
+
} catch {
|
|
1201
|
+
return { hadWork: false, branchesBackedUp: 0, worktreesSnapshotted: 0 };
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
function snapshotOtherWorktrees(cwd, wipMessage) {
|
|
1205
|
+
let count = 0;
|
|
1206
|
+
for (const wt of listWorktrees(cwd)) {
|
|
1207
|
+
if (samePath(wt.path, cwd) || !wt.branch) continue;
|
|
1208
|
+
try {
|
|
1209
|
+
if (!hasUncommittedChanges(wt.path)) continue;
|
|
1210
|
+
const sha = createWipSnapshot(wt.path, wipMessage ?? "WIP: conveyor-agent snapshot");
|
|
1211
|
+
if (sha && tryPushRefspec(wt.path, `${sha}:refs/heads/${wipRefForBranch(wt.branch)}`, true)) {
|
|
1212
|
+
wipRefPushed.add(wt.path);
|
|
1213
|
+
count++;
|
|
1214
|
+
}
|
|
1215
|
+
} catch {
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return count;
|
|
1219
|
+
}
|
|
1220
|
+
function backupOtherBranches(cwd, currentBranch) {
|
|
1221
|
+
let count = 0;
|
|
1222
|
+
for (const branch of listLocalBranches(cwd)) {
|
|
1223
|
+
if (branch === currentBranch || branch.startsWith("conveyor-wip/")) continue;
|
|
1224
|
+
try {
|
|
1225
|
+
if (branchUnpushedCount(cwd, branch) === 0) continue;
|
|
1226
|
+
if (tryPushRefspec(cwd, `refs/heads/${branch}:refs/heads/${branchBackupRef(branch)}`, true)) {
|
|
1227
|
+
count++;
|
|
1228
|
+
}
|
|
1229
|
+
} catch {
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return count;
|
|
1233
|
+
}
|
|
1134
1234
|
|
|
1135
1235
|
// src/runner/plan-sync.ts
|
|
1136
1236
|
import { readdirSync, statSync, readFileSync } from "fs";
|
|
@@ -2982,6 +3082,8 @@ function buildPromptBytes(text) {
|
|
|
2982
3082
|
var SUBMIT_SETTLE_MS = 300;
|
|
2983
3083
|
var SUBMIT_NUDGE_INTERVAL_MS = 2e3;
|
|
2984
3084
|
var SUBMIT_NUDGE_MAX_PRESSES = 5;
|
|
3085
|
+
var SUBMIT_NUDGE_SLOW_INTERVAL_MS = 5e3;
|
|
3086
|
+
var SUBMIT_NUDGE_WINDOW_MS = 9e4;
|
|
2985
3087
|
function sleep2(ms) {
|
|
2986
3088
|
return new Promise((resolve) => {
|
|
2987
3089
|
setTimeout(resolve, ms);
|
|
@@ -3230,18 +3332,28 @@ var PtySession = class {
|
|
|
3230
3332
|
* Deliberate trade-off (same as the plan-dialog auto-accept below): a press
|
|
3231
3333
|
* can accept the default of an unexpected startup dialog — in a headless
|
|
3232
3334
|
* pod that unblocks the run rather than parking it forever.
|
|
3335
|
+
*
|
|
3336
|
+
* Two phases: SUBMIT_NUDGE_MAX_PRESSES fast presses for the swallowed-Enter
|
|
3337
|
+
* race, then a slow cadence out to SUBMIT_NUDGE_WINDOW_MS for startup
|
|
3338
|
+
* dialogs that render late on cold pods (the folder-trust dialog's default
|
|
3339
|
+
* is the accept option, so one late Enter un-parks the run).
|
|
3233
3340
|
*/
|
|
3234
3341
|
armSubmitNudge() {
|
|
3235
3342
|
if (this.submitNudgeTimer) return;
|
|
3236
3343
|
this.pendingSubmitNudge = true;
|
|
3344
|
+
const startedAt = Date.now();
|
|
3237
3345
|
let presses = 0;
|
|
3238
3346
|
const press = () => {
|
|
3239
|
-
if (this._toreDown || !this.pendingSubmitNudge ||
|
|
3347
|
+
if (this._toreDown || !this.pendingSubmitNudge || Date.now() - startedAt >= SUBMIT_NUDGE_WINDOW_MS) {
|
|
3240
3348
|
this.disarmSubmitNudge();
|
|
3241
3349
|
return;
|
|
3242
3350
|
}
|
|
3243
3351
|
presses++;
|
|
3244
3352
|
this.writeStdin("\r");
|
|
3353
|
+
if (presses === SUBMIT_NUDGE_MAX_PRESSES && this.submitNudgeTimer) {
|
|
3354
|
+
clearInterval(this.submitNudgeTimer);
|
|
3355
|
+
this.submitNudgeTimer = setInterval(press, SUBMIT_NUDGE_SLOW_INTERVAL_MS);
|
|
3356
|
+
}
|
|
3245
3357
|
};
|
|
3246
3358
|
this.submitNudgeTimer = setInterval(press, SUBMIT_NUDGE_INTERVAL_MS);
|
|
3247
3359
|
}
|
|
@@ -3467,6 +3579,18 @@ async function ensureClaudeOnboarding(env = process.env, trustCwd) {
|
|
|
3467
3579
|
const contents = planClaudeJsonSeed(await readRaw(path), trustCwd);
|
|
3468
3580
|
if (contents === null) return;
|
|
3469
3581
|
await writeFile3(path, contents, "utf8");
|
|
3582
|
+
const verify = await readRaw(path);
|
|
3583
|
+
if (verify === contents) {
|
|
3584
|
+
process.stderr.write(
|
|
3585
|
+
`[conveyor-agent] claude onboarding seeded${trustCwd ? ` (trust: ${trustCwd})` : ""}
|
|
3586
|
+
`
|
|
3587
|
+
);
|
|
3588
|
+
} else {
|
|
3589
|
+
process.stderr.write(
|
|
3590
|
+
`[conveyor-agent] claude onboarding seed read-back MISMATCH at ${path}: wrote ${contents.length}B, read ${verify?.length ?? 0}B \u2014 CLI may see stale config and park at a startup dialog
|
|
3591
|
+
`
|
|
3592
|
+
);
|
|
3593
|
+
}
|
|
3470
3594
|
} catch (err) {
|
|
3471
3595
|
const message = err instanceof Error ? err.message : String(err);
|
|
3472
3596
|
process.stderr.write(`[conveyor-agent] claude onboarding seed failed: ${message}
|
|
@@ -8217,7 +8341,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
8217
8341
|
if (this.periodicFlushInFlight || this.stopped) return;
|
|
8218
8342
|
this.periodicFlushInFlight = true;
|
|
8219
8343
|
try {
|
|
8220
|
-
const result = await
|
|
8344
|
+
const result = await flushAllPendingWork(this.config.workspaceDir, {
|
|
8221
8345
|
wipMessage: "WIP: periodic auto-commit",
|
|
8222
8346
|
refreshToken: async () => {
|
|
8223
8347
|
try {
|
|
@@ -8232,7 +8356,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
8232
8356
|
});
|
|
8233
8357
|
if (result.hadWork) {
|
|
8234
8358
|
process.stderr.write(
|
|
8235
|
-
`[conveyor-agent] Periodic git flush:
|
|
8359
|
+
`[conveyor-agent] Periodic git flush: branchesBackedUp=${result.branchesBackedUp} worktreesSnapshotted=${result.worktreesSnapshotted}
|
|
8236
8360
|
`
|
|
8237
8361
|
);
|
|
8238
8362
|
}
|
|
@@ -8246,7 +8370,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
8246
8370
|
* connection is still alive for token refresh. Never throws. */
|
|
8247
8371
|
async flushGitOnShutdown() {
|
|
8248
8372
|
try {
|
|
8249
|
-
const result = await
|
|
8373
|
+
const result = await flushAllPendingWork(this.config.workspaceDir, {
|
|
8250
8374
|
wipMessage: "WIP: auto-commit on conveyor-agent shutdown",
|
|
8251
8375
|
refreshToken: async () => {
|
|
8252
8376
|
try {
|
|
@@ -8261,7 +8385,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
8261
8385
|
});
|
|
8262
8386
|
if (result.hadWork) {
|
|
8263
8387
|
process.stderr.write(
|
|
8264
|
-
`[conveyor-agent] Shutdown git flush:
|
|
8388
|
+
`[conveyor-agent] Shutdown git flush: branchesBackedUp=${result.branchesBackedUp} worktreesSnapshotted=${result.worktreesSnapshotted}
|
|
8265
8389
|
`
|
|
8266
8390
|
);
|
|
8267
8391
|
}
|
|
@@ -8758,4 +8882,4 @@ export {
|
|
|
8758
8882
|
runStartCommand,
|
|
8759
8883
|
unshallowRepo
|
|
8760
8884
|
};
|
|
8761
|
-
//# sourceMappingURL=chunk-
|
|
8885
|
+
//# sourceMappingURL=chunk-5W6MHROF.js.map
|