@rallycry/conveyor-agent 10.3.1 → 10.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-HAH2S5AD.js → chunk-TZYEU4QE.js} +109 -89
- package/dist/chunk-TZYEU4QE.js.map +1 -0
- package/dist/cli.js +146 -54
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/runtime/entrypoint.sh +68 -0
- package/dist/chunk-HAH2S5AD.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
runSetupCommand,
|
|
26
26
|
runStartCommand,
|
|
27
27
|
sampleKeyUsage
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-TZYEU4QE.js";
|
|
29
29
|
import "./chunk-7TQO4ZF4.js";
|
|
30
30
|
|
|
31
31
|
// src/cli.ts
|
|
32
32
|
import { readFileSync } from "fs";
|
|
33
|
-
import { join, dirname as
|
|
33
|
+
import { join as join2, dirname as dirname3 } from "path";
|
|
34
34
|
import { fileURLToPath } from "url";
|
|
35
35
|
|
|
36
36
|
// src/setup/sidecars.ts
|
|
@@ -154,14 +154,14 @@ async function waitForSidecars(opts = {}) {
|
|
|
154
154
|
|
|
155
155
|
// src/utils/session-identity.ts
|
|
156
156
|
async function checkSessionTaskIdentity(params) {
|
|
157
|
-
const { sessionId, taskId, fetchSessionTaskId, logger:
|
|
157
|
+
const { sessionId, taskId, fetchSessionTaskId, logger: logger4 } = params;
|
|
158
158
|
if (!sessionId || sessionId === taskId) return "skipped";
|
|
159
159
|
let sessionTaskId;
|
|
160
160
|
try {
|
|
161
161
|
sessionTaskId = await fetchSessionTaskId(sessionId);
|
|
162
162
|
} catch (err) {
|
|
163
163
|
const message = err instanceof Error ? err.message : String(err);
|
|
164
|
-
|
|
164
|
+
logger4.warn("Could not verify session/task identity \u2014 continuing (defense-in-depth only)", {
|
|
165
165
|
sessionId,
|
|
166
166
|
taskId,
|
|
167
167
|
error: message
|
|
@@ -169,7 +169,7 @@ async function checkSessionTaskIdentity(params) {
|
|
|
169
169
|
return "error";
|
|
170
170
|
}
|
|
171
171
|
if (sessionTaskId !== taskId) {
|
|
172
|
-
|
|
172
|
+
logger4.warn(
|
|
173
173
|
"!!! CONVEYOR_SESSION_ID is bound to a different task than CONVEYOR_TASK_ID \u2014 server-side guards should still block mutations, but this indicates a misconfiguration or replayed token.",
|
|
174
174
|
{ sessionId, envTaskId: taskId, sessionTaskId }
|
|
175
175
|
);
|
|
@@ -349,6 +349,95 @@ var ProjectSessionRunner = class {
|
|
|
349
349
|
}
|
|
350
350
|
};
|
|
351
351
|
|
|
352
|
+
// src/harness/pty/adapters/opencode-auth.ts
|
|
353
|
+
import { promises as fs } from "fs";
|
|
354
|
+
import { dirname as dirname2, join } from "path";
|
|
355
|
+
import { homedir } from "os";
|
|
356
|
+
var logger = createServiceLogger("opencode-auth");
|
|
357
|
+
var OPENCODE_CODEX_PLUGIN = "opencode-openai-codex-auth@4.4.0";
|
|
358
|
+
var PLUGIN_PACKAGE = "opencode-openai-codex-auth";
|
|
359
|
+
function opencodeAuthPath(env) {
|
|
360
|
+
const dataHome = env.XDG_DATA_HOME ?? join(env.HOME ?? homedir(), ".local", "share");
|
|
361
|
+
return join(dataHome, "opencode", "auth.json");
|
|
362
|
+
}
|
|
363
|
+
function opencodeConfigPath(env) {
|
|
364
|
+
const configHome = env.XDG_CONFIG_HOME ?? join(env.HOME ?? homedir(), ".config");
|
|
365
|
+
return join(configHome, "opencode", "opencode.json");
|
|
366
|
+
}
|
|
367
|
+
function parseOauthSeed(b64) {
|
|
368
|
+
if (!b64) return null;
|
|
369
|
+
try {
|
|
370
|
+
const parsed = JSON.parse(Buffer.from(b64, "base64").toString("utf8"));
|
|
371
|
+
if (typeof parsed.access === "string" && typeof parsed.refresh === "string" && typeof parsed.expires === "number") {
|
|
372
|
+
return { access: parsed.access, refresh: parsed.refresh, expires: parsed.expires };
|
|
373
|
+
}
|
|
374
|
+
return null;
|
|
375
|
+
} catch {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function shouldSeed(existingEntry, seed) {
|
|
380
|
+
if (!existingEntry || typeof existingEntry !== "object") return true;
|
|
381
|
+
const entry = existingEntry;
|
|
382
|
+
if (entry.type !== "oauth") return true;
|
|
383
|
+
if (typeof entry.access !== "string" || typeof entry.refresh !== "string") return true;
|
|
384
|
+
if (typeof entry.expires !== "number") return true;
|
|
385
|
+
return entry.expires < seed.expires;
|
|
386
|
+
}
|
|
387
|
+
async function readJsonFile(path) {
|
|
388
|
+
try {
|
|
389
|
+
return JSON.parse(await fs.readFile(path, "utf8"));
|
|
390
|
+
} catch {
|
|
391
|
+
return {};
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
async function writeJsonFile(path, value) {
|
|
395
|
+
await fs.mkdir(dirname2(path), { recursive: true });
|
|
396
|
+
await fs.writeFile(path, `${JSON.stringify(value, null, 2)}
|
|
397
|
+
`, { mode: 384 });
|
|
398
|
+
}
|
|
399
|
+
async function ensureAuthEntry(env, seed) {
|
|
400
|
+
const path = opencodeAuthPath(env);
|
|
401
|
+
const store = await readJsonFile(path);
|
|
402
|
+
if (!shouldSeed(store.openai, seed)) {
|
|
403
|
+
logger.info("opencode oauth store is fresher than the seed; leaving it alone");
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
store.openai = {
|
|
407
|
+
type: "oauth",
|
|
408
|
+
access: seed.access,
|
|
409
|
+
refresh: seed.refresh,
|
|
410
|
+
expires: seed.expires
|
|
411
|
+
};
|
|
412
|
+
await writeJsonFile(path, store);
|
|
413
|
+
logger.info("seeded opencode oauth store entry");
|
|
414
|
+
}
|
|
415
|
+
async function ensurePluginConfig(env) {
|
|
416
|
+
const path = opencodeConfigPath(env);
|
|
417
|
+
const config = await readJsonFile(path);
|
|
418
|
+
const plugins = Array.isArray(config.plugin) ? config.plugin : [];
|
|
419
|
+
const isOurs = (p) => typeof p === "string" && (p === PLUGIN_PACKAGE || p.startsWith(`${PLUGIN_PACKAGE}@`));
|
|
420
|
+
const hasExactPin = plugins.includes(OPENCODE_CODEX_PLUGIN);
|
|
421
|
+
const hasStalePin = plugins.some((p) => isOurs(p) && p !== OPENCODE_CODEX_PLUGIN);
|
|
422
|
+
if (hasExactPin && !hasStalePin) return;
|
|
423
|
+
const kept = plugins.filter((p) => !isOurs(p));
|
|
424
|
+
config.plugin = [...kept, OPENCODE_CODEX_PLUGIN];
|
|
425
|
+
await writeJsonFile(path, config);
|
|
426
|
+
logger.info("ensured opencode codex-auth plugin in config");
|
|
427
|
+
}
|
|
428
|
+
async function seedOpenCodeOauth(env) {
|
|
429
|
+
const seed = parseOauthSeed(env.CONVEYOR_OPENCODE_OAUTH);
|
|
430
|
+
if (!seed) return;
|
|
431
|
+
try {
|
|
432
|
+
await ensureAuthEntry(env, seed);
|
|
433
|
+
await ensurePluginConfig(env);
|
|
434
|
+
} catch (err) {
|
|
435
|
+
logger.warn(
|
|
436
|
+
`failed to seed opencode oauth store: ${err instanceof Error ? err.message : String(err)}`
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
352
441
|
// src/harness/pty/adapters/opencode.ts
|
|
353
442
|
var PROVIDER_KEY_ENV = {
|
|
354
443
|
openai: "OPENAI_API_KEY",
|
|
@@ -380,16 +469,19 @@ var OpenCodeTuiAdapter = class {
|
|
|
380
469
|
buildSpawn(input) {
|
|
381
470
|
const env = { ...inheritedEnv() };
|
|
382
471
|
delete env.CONVEYOR_AGENT_KEY;
|
|
472
|
+
delete env.CONVEYOR_OPENCODE_OAUTH;
|
|
473
|
+
const oauthActive = Boolean(this.env.CONVEYOR_OPENCODE_OAUTH);
|
|
383
474
|
const key = this.env.CONVEYOR_AGENT_KEY;
|
|
384
475
|
const provider = this.env.CONVEYOR_AGENT_PROVIDER ?? "openai";
|
|
385
476
|
const keyEnvVar = PROVIDER_KEY_ENV[provider];
|
|
386
|
-
if (key && keyEnvVar) env[keyEnvVar] = key;
|
|
477
|
+
if (key && keyEnvVar && !oauthActive) env[keyEnvVar] = key;
|
|
387
478
|
const model = this.env.CONVEYOR_AGENT_MODEL ?? input.options.model;
|
|
388
479
|
const args = [];
|
|
389
480
|
if (model) args.push("--model", model.includes("/") ? model : `${provider}/${model}`);
|
|
390
481
|
return { file: this.resolveBinary(), args, env };
|
|
391
482
|
}
|
|
392
483
|
async prepareEnvironment() {
|
|
484
|
+
await seedOpenCodeOauth(this.env);
|
|
393
485
|
}
|
|
394
486
|
spawnFingerprint(input) {
|
|
395
487
|
return JSON.stringify(["opencode", input.model, input.cwd]);
|
|
@@ -589,7 +681,7 @@ var AdhocSessionRunner = class {
|
|
|
589
681
|
import { spawn as nodeSpawn, execFile } from "child_process";
|
|
590
682
|
import { promisify } from "util";
|
|
591
683
|
var execFileAsync = promisify(execFile);
|
|
592
|
-
var
|
|
684
|
+
var logger2 = createServiceLogger("ReviewChild");
|
|
593
685
|
var SPAWN_FAILURE_GRACE_MS = 15e3;
|
|
594
686
|
var KILL_WAIT_MS = 5e3;
|
|
595
687
|
function buildReviewChildEnv(baseEnv, data) {
|
|
@@ -618,7 +710,7 @@ var ReviewChildSupervisor = class {
|
|
|
618
710
|
childSessionId = null;
|
|
619
711
|
/** Spawn (or replace) the review child for a `session:spawnReview` push. */
|
|
620
712
|
async spawn(data) {
|
|
621
|
-
|
|
713
|
+
logger2.info("Spawning same-pod review child", {
|
|
622
714
|
reviewSessionId: data.sessionId,
|
|
623
715
|
branch: data.branch ?? void 0,
|
|
624
716
|
prNumber: data.prNumber ?? void 0
|
|
@@ -661,7 +753,7 @@ var ReviewChildSupervisor = class {
|
|
|
661
753
|
process.stderr.write(`[review-child] ${chunk.toString()}`);
|
|
662
754
|
});
|
|
663
755
|
child.on("error", (err) => {
|
|
664
|
-
|
|
756
|
+
logger2.error("Review child spawn error", { error: err.message });
|
|
665
757
|
if (this.child === child) {
|
|
666
758
|
this.child = null;
|
|
667
759
|
this.childSessionId = null;
|
|
@@ -674,7 +766,7 @@ var ReviewChildSupervisor = class {
|
|
|
674
766
|
this.child = null;
|
|
675
767
|
this.childSessionId = null;
|
|
676
768
|
}
|
|
677
|
-
|
|
769
|
+
logger2.info("Review child exited", { code, signal, reviewSessionId: data.sessionId });
|
|
678
770
|
const withinGrace = Date.now() - spawnedAt < SPAWN_FAILURE_GRACE_MS;
|
|
679
771
|
if (wasCurrent && withinGrace && code !== null && code !== 0) {
|
|
680
772
|
reportOnce(`review child exited with code ${code} within startup grace`);
|
|
@@ -692,7 +784,7 @@ var ReviewChildSupervisor = class {
|
|
|
692
784
|
this.childSessionId = null;
|
|
693
785
|
return;
|
|
694
786
|
}
|
|
695
|
-
|
|
787
|
+
logger2.info("Stopping review child", { reason, reviewSessionId: this.childSessionId });
|
|
696
788
|
this.child = null;
|
|
697
789
|
this.childSessionId = null;
|
|
698
790
|
await new Promise((resolve) => {
|
|
@@ -734,7 +826,7 @@ var ReviewChildSupervisor = class {
|
|
|
734
826
|
timeout: 3e4
|
|
735
827
|
});
|
|
736
828
|
} catch (err) {
|
|
737
|
-
|
|
829
|
+
logger2.warn("Review checkout freshen skipped", {
|
|
738
830
|
branch,
|
|
739
831
|
error: err instanceof Error ? err.message : String(err)
|
|
740
832
|
});
|
|
@@ -744,13 +836,13 @@ var ReviewChildSupervisor = class {
|
|
|
744
836
|
|
|
745
837
|
// src/cli.ts
|
|
746
838
|
if (process.argv.includes("--version")) {
|
|
747
|
-
const __dirname =
|
|
748
|
-
const pkgPath =
|
|
839
|
+
const __dirname = dirname3(fileURLToPath(import.meta.url));
|
|
840
|
+
const pkgPath = join2(__dirname, "..", "package.json");
|
|
749
841
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
750
842
|
process.stdout.write(pkg.version + "\n");
|
|
751
843
|
process.exit(0);
|
|
752
844
|
}
|
|
753
|
-
var
|
|
845
|
+
var logger3 = createServiceLogger("CLI");
|
|
754
846
|
var exitContext = {};
|
|
755
847
|
var exitLogged = false;
|
|
756
848
|
function logAgentExit(reason, opts) {
|
|
@@ -764,12 +856,12 @@ function logAgentExit(reason, opts) {
|
|
|
764
856
|
uptimeSec: process.uptime(),
|
|
765
857
|
identity: exitContext
|
|
766
858
|
});
|
|
767
|
-
|
|
859
|
+
logger3[exitLogLevel(reason)]("agent_exit", payload);
|
|
768
860
|
}
|
|
769
861
|
async function bootstrapFromCodespace(apiUrl, instanceName) {
|
|
770
862
|
const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;
|
|
771
863
|
const apiUrlFromEnv = Boolean(process.env.CONVEYOR_API_URL);
|
|
772
|
-
|
|
864
|
+
logger3.info("Bootstrapping from codespace", {
|
|
773
865
|
codespace: instanceName,
|
|
774
866
|
apiUrl,
|
|
775
867
|
apiUrlFromEnv,
|
|
@@ -781,7 +873,7 @@ async function bootstrapFromCodespace(apiUrl, instanceName) {
|
|
|
781
873
|
bootstrapToken
|
|
782
874
|
});
|
|
783
875
|
if (!result.ok) {
|
|
784
|
-
|
|
876
|
+
logger3.error("Bootstrap failed after retries", {
|
|
785
877
|
reason: result.reason,
|
|
786
878
|
attempts: result.attempts,
|
|
787
879
|
status: result.status,
|
|
@@ -794,7 +886,7 @@ async function bootstrapFromCodespace(apiUrl, instanceName) {
|
|
|
794
886
|
process.exit(1);
|
|
795
887
|
}
|
|
796
888
|
applyBootstrapToEnv(result.config);
|
|
797
|
-
|
|
889
|
+
logger3.info("Bootstrap complete", {
|
|
798
890
|
taskId: result.config.taskId,
|
|
799
891
|
attempts: result.attempts
|
|
800
892
|
});
|
|
@@ -808,20 +900,20 @@ function isExpectedAbortError(error) {
|
|
|
808
900
|
process.on("uncaughtException", (err) => {
|
|
809
901
|
if (err.code === "EPIPE") return;
|
|
810
902
|
if (isExpectedAbortError(err)) {
|
|
811
|
-
|
|
903
|
+
logger3.info("Ignored expected abort after shutdown", { error: err.message, code: err.code });
|
|
812
904
|
return;
|
|
813
905
|
}
|
|
814
|
-
|
|
906
|
+
logger3.error("Uncaught exception", { error: err.message, code: err.code });
|
|
815
907
|
logAgentExit("uncaught_exception", { exitCode: 1 });
|
|
816
908
|
process.exit(1);
|
|
817
909
|
});
|
|
818
910
|
process.on("unhandledRejection", (reason) => {
|
|
819
911
|
const err = reason instanceof Error ? reason : new Error(String(reason));
|
|
820
912
|
if (isExpectedAbortError(err)) {
|
|
821
|
-
|
|
913
|
+
logger3.info("Ignored expected abort rejection after shutdown", { error: err.message });
|
|
822
914
|
return;
|
|
823
915
|
}
|
|
824
|
-
|
|
916
|
+
logger3.error("Unhandled rejection", { error: err.message });
|
|
825
917
|
logAgentExit("unhandled_rejection", { exitCode: 1 });
|
|
826
918
|
process.exit(1);
|
|
827
919
|
});
|
|
@@ -830,7 +922,7 @@ var conveyorApiUrl = process.env.CONVEYOR_API_URL || DEFAULT_CONVEYOR_API_URL;
|
|
|
830
922
|
var INSTANCE_NAME = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;
|
|
831
923
|
if (INSTANCE_NAME && !process.env.CONVEYOR_TASK_TOKEN) {
|
|
832
924
|
if (!conveyorApiUrl) {
|
|
833
|
-
|
|
925
|
+
logger3.error("Could not resolve CONVEYOR_API_URL for codespace bootstrap");
|
|
834
926
|
process.exit(1);
|
|
835
927
|
}
|
|
836
928
|
await bootstrapFromCodespace(conveyorApiUrl, INSTANCE_NAME);
|
|
@@ -848,7 +940,7 @@ exitContext.runnerMode = CONVEYOR_MODE;
|
|
|
848
940
|
exitContext.sessionId = process.env.CONVEYOR_SESSION_ID ?? CONVEYOR_TASK_ID;
|
|
849
941
|
var projectIdentity = resolveProjectRunnerIdentity(process.env);
|
|
850
942
|
if (!CONVEYOR_TASK_ID && projectIdentity && CONVEYOR_MODE === "adhoc") {
|
|
851
|
-
|
|
943
|
+
logger3.info("Starting ad-hoc agent", { projectId: projectIdentity.projectId });
|
|
852
944
|
const adhocRunner = new AdhocSessionRunner(
|
|
853
945
|
{
|
|
854
946
|
connection: {
|
|
@@ -864,7 +956,7 @@ if (!CONVEYOR_TASK_ID && projectIdentity && CONVEYOR_MODE === "adhoc") {
|
|
|
864
956
|
},
|
|
865
957
|
{
|
|
866
958
|
onEvent: (event) => {
|
|
867
|
-
|
|
959
|
+
logger3.info("Ad-hoc runner event", { eventType: event.type });
|
|
868
960
|
}
|
|
869
961
|
}
|
|
870
962
|
);
|
|
@@ -882,7 +974,7 @@ if (!CONVEYOR_TASK_ID && projectIdentity && CONVEYOR_MODE === "adhoc") {
|
|
|
882
974
|
process.exit(adhocError ? 1 : 0);
|
|
883
975
|
}
|
|
884
976
|
if (!CONVEYOR_TASK_ID && projectIdentity) {
|
|
885
|
-
|
|
977
|
+
logger3.info("Starting project agent", { projectId: projectIdentity.projectId });
|
|
886
978
|
const projectRunner = new ProjectSessionRunner(
|
|
887
979
|
{
|
|
888
980
|
connection: {
|
|
@@ -897,7 +989,7 @@ if (!CONVEYOR_TASK_ID && projectIdentity) {
|
|
|
897
989
|
},
|
|
898
990
|
{
|
|
899
991
|
onEvent: (event) => {
|
|
900
|
-
|
|
992
|
+
logger3.info("Project runner event", { eventType: event.type });
|
|
901
993
|
}
|
|
902
994
|
}
|
|
903
995
|
);
|
|
@@ -915,28 +1007,28 @@ if (!CONVEYOR_TASK_ID && projectIdentity) {
|
|
|
915
1007
|
process.exit(projectError ? 1 : 0);
|
|
916
1008
|
}
|
|
917
1009
|
if (!CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1010
|
+
logger3.error("Missing required environment variables");
|
|
1011
|
+
logger3.error(" CONVEYOR_TASK_TOKEN - JWT token for task authentication");
|
|
1012
|
+
logger3.error(" CONVEYOR_TASK_ID - ID of the task to execute");
|
|
1013
|
+
logger3.error("");
|
|
1014
|
+
logger3.error("CONVEYOR_API_URL is provided via codespace secret or bootstrap.");
|
|
1015
|
+
logger3.error("");
|
|
1016
|
+
logger3.error("Optional:");
|
|
1017
|
+
logger3.error(" CONVEYOR_MODE - Runner mode: 'task' (default), 'pack', or 'pm'");
|
|
1018
|
+
logger3.error(" CONVEYOR_WORKSPACE - Working directory (defaults to cwd)");
|
|
1019
|
+
logger3.error(
|
|
928
1020
|
" Project pods instead require CONVEYOR_PROJECT_ID + CONVEYOR_SESSION_ID + CONVEYOR_MODE=pm"
|
|
929
1021
|
);
|
|
930
1022
|
process.exit(1);
|
|
931
1023
|
}
|
|
932
1024
|
if (CONVEYOR_MODE !== "task" && CONVEYOR_MODE !== "pm" && CONVEYOR_MODE !== "code-review" && CONVEYOR_MODE !== "adhoc" && CONVEYOR_MODE !== "pack") {
|
|
933
|
-
|
|
1025
|
+
logger3.error("Invalid CONVEYOR_MODE", {
|
|
934
1026
|
mode: CONVEYOR_MODE,
|
|
935
1027
|
expected: ["task", "pm", "code-review", "adhoc", "pack"]
|
|
936
1028
|
});
|
|
937
1029
|
process.exit(1);
|
|
938
1030
|
}
|
|
939
|
-
|
|
1031
|
+
logger3.info("Starting agent", { mode: CONVEYOR_MODE });
|
|
940
1032
|
var lifecycleOverrides = process.env.CLAUDESPACE_NAME ? { idleTimeoutMs: 60 * 60 * 1e3 } : { gitFlushIntervalMs: 0 };
|
|
941
1033
|
var runner = new SessionRunner(
|
|
942
1034
|
{
|
|
@@ -956,12 +1048,12 @@ var runner = new SessionRunner(
|
|
|
956
1048
|
},
|
|
957
1049
|
{
|
|
958
1050
|
onStatusChange: (status) => {
|
|
959
|
-
|
|
1051
|
+
logger3.info("Status changed", { status });
|
|
960
1052
|
},
|
|
961
1053
|
onEvent: (event) => {
|
|
962
1054
|
const detail = event.message ?? event.content ?? event.summary ?? "";
|
|
963
1055
|
if (detail) {
|
|
964
|
-
|
|
1056
|
+
logger3.info(detail, { eventType: event.type });
|
|
965
1057
|
}
|
|
966
1058
|
}
|
|
967
1059
|
}
|
|
@@ -969,7 +1061,7 @@ var runner = new SessionRunner(
|
|
|
969
1061
|
var reviewChildren = new ReviewChildSupervisor(runner.connection, CONVEYOR_WORKSPACE);
|
|
970
1062
|
var shutdownSignal;
|
|
971
1063
|
var shutdownAgent = (signal) => {
|
|
972
|
-
|
|
1064
|
+
logger3.info(`Received ${signal}, flushing git and stopping agent`);
|
|
973
1065
|
shutdownSignal = signal;
|
|
974
1066
|
void (async () => {
|
|
975
1067
|
try {
|
|
@@ -983,8 +1075,8 @@ var shutdownAgent = (signal) => {
|
|
|
983
1075
|
}
|
|
984
1076
|
})();
|
|
985
1077
|
setTimeout(() => {
|
|
986
|
-
|
|
987
|
-
|
|
1078
|
+
logger3.warn(`Forcing exit after ${signal} timeout`);
|
|
1079
|
+
logger3.warn(
|
|
988
1080
|
"agent_exit",
|
|
989
1081
|
buildAgentExitLog({
|
|
990
1082
|
reason: "force_timeout",
|
|
@@ -1022,7 +1114,7 @@ var stopStartCommandChild = () => {
|
|
|
1022
1114
|
}
|
|
1023
1115
|
};
|
|
1024
1116
|
var launchStartCommand = (command) => {
|
|
1025
|
-
|
|
1117
|
+
logger3.info("Running start command", { command });
|
|
1026
1118
|
runner.connection.sendEvent({ type: "start_command_started" });
|
|
1027
1119
|
const child = runStartCommand(command, CONVEYOR_WORKSPACE, (stream, data) => {
|
|
1028
1120
|
runner.connection.sendEvent({ type: "start_command_output", stream, data });
|
|
@@ -1032,7 +1124,7 @@ var launchStartCommand = (command) => {
|
|
|
1032
1124
|
child.on("exit", (code, signal) => {
|
|
1033
1125
|
if (startCommandChild === child) startCommandChild = null;
|
|
1034
1126
|
if (expectedStartCommandStops.has(child)) return;
|
|
1035
|
-
|
|
1127
|
+
logger3.info("Start command exited", { code, signal });
|
|
1036
1128
|
runner.connection.sendEvent({
|
|
1037
1129
|
type: "start_command_exited",
|
|
1038
1130
|
code,
|
|
@@ -1048,7 +1140,7 @@ var launchStartCommand = (command) => {
|
|
|
1048
1140
|
});
|
|
1049
1141
|
child.on("error", (err) => {
|
|
1050
1142
|
if (startCommandChild === child) startCommandChild = null;
|
|
1051
|
-
|
|
1143
|
+
logger3.error("Start command error", { error: err.message });
|
|
1052
1144
|
runner.connection.sendEvent({ type: "start_command_error", message: err.message });
|
|
1053
1145
|
});
|
|
1054
1146
|
};
|
|
@@ -1064,12 +1156,12 @@ void checkSessionTaskIdentity({
|
|
|
1064
1156
|
const ctx = await runner.connection.call("getTaskContext", { sessionId });
|
|
1065
1157
|
return ctx.id;
|
|
1066
1158
|
},
|
|
1067
|
-
logger:
|
|
1159
|
+
logger: logger3
|
|
1068
1160
|
});
|
|
1069
1161
|
if (CONVEYOR_MODE === "task") {
|
|
1070
1162
|
runner.connection.onSpawnReview((data) => {
|
|
1071
1163
|
void reviewChildren.spawn(data).catch((err) => {
|
|
1072
|
-
|
|
1164
|
+
logger3.error("Review child spawn threw", {
|
|
1073
1165
|
error: err instanceof Error ? err.message : String(err)
|
|
1074
1166
|
});
|
|
1075
1167
|
runner.connection.reportReviewSpawnFailure(
|
|
@@ -1109,15 +1201,15 @@ if (conveyorConfig) {
|
|
|
1109
1201
|
startLazy: false
|
|
1110
1202
|
});
|
|
1111
1203
|
if (conveyorConfig.setupCommand) {
|
|
1112
|
-
|
|
1204
|
+
logger3.info("Running setup command (background)", {
|
|
1113
1205
|
command: conveyorConfig.setupCommand
|
|
1114
1206
|
});
|
|
1115
1207
|
try {
|
|
1116
1208
|
await runSetupCommand(conveyorConfig.setupCommand, CONVEYOR_WORKSPACE, logSetupOutput);
|
|
1117
|
-
|
|
1209
|
+
logger3.info("Setup command completed");
|
|
1118
1210
|
} catch (error) {
|
|
1119
1211
|
const msg = error instanceof Error ? error.message : "Setup command failed";
|
|
1120
|
-
|
|
1212
|
+
logger3.error("Setup command failed", { error: msg });
|
|
1121
1213
|
runner.connection.sendEvent({ type: "setup_error", message: msg });
|
|
1122
1214
|
}
|
|
1123
1215
|
}
|
|
@@ -1146,7 +1238,7 @@ runner.run().then(() => {
|
|
|
1146
1238
|
process.exit(errored ? 1 : 0);
|
|
1147
1239
|
}).catch((error) => {
|
|
1148
1240
|
const msg = error instanceof Error ? error.message : String(error);
|
|
1149
|
-
|
|
1241
|
+
logger3.error("Agent runner failed", { error: msg });
|
|
1150
1242
|
logAgentExit("error", { exitCode: 1, finalState: runner.finalState ?? void 0 });
|
|
1151
1243
|
process.exit(1);
|
|
1152
1244
|
});
|