@rallycry/conveyor-agent 10.2.4 → 10.2.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-DEMRCBJN.js → chunk-CFELRV35.js} +383 -292
- package/dist/chunk-CFELRV35.js.map +1 -0
- package/dist/cli.js +123 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/runtime/entrypoint.sh +93 -4
- package/dist/chunk-DEMRCBJN.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AgentConnection,
|
|
4
|
+
ClaudeTuiAdapter,
|
|
4
5
|
DEFAULT_LIFECYCLE_CONFIG,
|
|
5
6
|
DEFAULT_SONNET_MODEL,
|
|
6
7
|
Lifecycle,
|
|
7
8
|
PtyHarness,
|
|
8
9
|
SessionRunner,
|
|
10
|
+
TUI_KINDS,
|
|
9
11
|
applyBootstrapToEnv,
|
|
10
12
|
awaitGitReady,
|
|
13
|
+
buildPromptBytes,
|
|
11
14
|
buildSessionPreviewPorts,
|
|
15
|
+
cleanTerminalOutput,
|
|
12
16
|
createServiceLogger,
|
|
13
17
|
fetchBootstrap,
|
|
18
|
+
inheritedEnv,
|
|
14
19
|
loadConveyorConfig,
|
|
15
20
|
loadForwardPorts,
|
|
16
21
|
resolveSessionStart,
|
|
17
22
|
runSetupCommand,
|
|
18
23
|
runStartCommand,
|
|
19
24
|
sampleKeyUsage
|
|
20
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-CFELRV35.js";
|
|
21
26
|
import "./chunk-7TQO4ZF4.js";
|
|
22
27
|
|
|
23
28
|
// src/cli.ts
|
|
24
29
|
import { readFileSync } from "fs";
|
|
25
|
-
import { join, dirname as dirname2 } from "path";
|
|
30
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
26
31
|
import { fileURLToPath } from "url";
|
|
27
32
|
|
|
28
33
|
// src/setup/sidecars.ts
|
|
@@ -341,8 +346,114 @@ var ProjectSessionRunner = class {
|
|
|
341
346
|
}
|
|
342
347
|
};
|
|
343
348
|
|
|
349
|
+
// src/harness/pty/adapters/types.ts
|
|
350
|
+
import { accessSync, constants, statSync } from "fs";
|
|
351
|
+
import { join } from "path";
|
|
352
|
+
var TuiUnavailableError = class extends Error {
|
|
353
|
+
constructor(tui, message) {
|
|
354
|
+
super(message);
|
|
355
|
+
this.tui = tui;
|
|
356
|
+
this.name = "TuiUnavailableError";
|
|
357
|
+
}
|
|
358
|
+
tui;
|
|
359
|
+
};
|
|
360
|
+
function isExecutable(path) {
|
|
361
|
+
try {
|
|
362
|
+
if (!statSync(path).isFile()) return false;
|
|
363
|
+
accessSync(path, constants.X_OK);
|
|
364
|
+
return true;
|
|
365
|
+
} catch {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function findOnPath(binary, env = process.env) {
|
|
370
|
+
if (binary.includes("/")) {
|
|
371
|
+
return isExecutable(binary) ? binary : null;
|
|
372
|
+
}
|
|
373
|
+
for (const dir of (env.PATH ?? "").split(":")) {
|
|
374
|
+
if (!dir) continue;
|
|
375
|
+
const candidate = join(dir, binary);
|
|
376
|
+
if (isExecutable(candidate)) return candidate;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/harness/pty/adapters/opencode.ts
|
|
382
|
+
var PROVIDER_KEY_ENV = {
|
|
383
|
+
openai: "OPENAI_API_KEY",
|
|
384
|
+
anthropic: "ANTHROPIC_API_KEY"
|
|
385
|
+
};
|
|
386
|
+
var OpenCodeTuiAdapter = class {
|
|
387
|
+
constructor(env = process.env) {
|
|
388
|
+
this.env = env;
|
|
389
|
+
}
|
|
390
|
+
env;
|
|
391
|
+
id = "opencode";
|
|
392
|
+
capabilities = {
|
|
393
|
+
resume: false,
|
|
394
|
+
structuredEvents: false,
|
|
395
|
+
prefill: false,
|
|
396
|
+
passiveTurns: false
|
|
397
|
+
};
|
|
398
|
+
resolveBinary(env = this.env) {
|
|
399
|
+
const override = env.CONVEYOR_OPENCODE_BIN;
|
|
400
|
+
const found = override ? findOnPath(override, env) : findOnPath("opencode", env);
|
|
401
|
+
if (!found) {
|
|
402
|
+
throw new TuiUnavailableError(
|
|
403
|
+
"opencode",
|
|
404
|
+
"The opencode CLI is not available in this environment. It must be baked into the pod image (see Dockerfile.base) \u2014 re-run Build Image for this project, or set CONVEYOR_OPENCODE_BIN to its absolute path."
|
|
405
|
+
);
|
|
406
|
+
}
|
|
407
|
+
return found;
|
|
408
|
+
}
|
|
409
|
+
buildSpawn(input) {
|
|
410
|
+
const env = { ...inheritedEnv() };
|
|
411
|
+
delete env.CONVEYOR_AGENT_KEY;
|
|
412
|
+
const key = this.env.CONVEYOR_AGENT_KEY;
|
|
413
|
+
const provider = this.env.CONVEYOR_AGENT_PROVIDER ?? "openai";
|
|
414
|
+
const keyEnvVar = PROVIDER_KEY_ENV[provider];
|
|
415
|
+
if (key && keyEnvVar) env[keyEnvVar] = key;
|
|
416
|
+
const model = this.env.CONVEYOR_AGENT_MODEL ?? input.options.model;
|
|
417
|
+
const args = [];
|
|
418
|
+
if (model) args.push("--model", model.includes("/") ? model : `${provider}/${model}`);
|
|
419
|
+
return { file: this.resolveBinary(), args, env };
|
|
420
|
+
}
|
|
421
|
+
async prepareEnvironment() {
|
|
422
|
+
}
|
|
423
|
+
spawnFingerprint(input) {
|
|
424
|
+
return JSON.stringify(["opencode", input.model, input.cwd]);
|
|
425
|
+
}
|
|
426
|
+
encodePromptBytes(text) {
|
|
427
|
+
return buildPromptBytes(text);
|
|
428
|
+
}
|
|
429
|
+
buildExitErrors(exitCode, rawOutput) {
|
|
430
|
+
const errors = [`opencode exited (code ${exitCode}) without a result`];
|
|
431
|
+
const tail = cleanTerminalOutput(rawOutput);
|
|
432
|
+
if (tail) errors.push(`Last terminal output before exit:
|
|
433
|
+
${tail}`);
|
|
434
|
+
return errors;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
// src/harness/pty/adapters/index.ts
|
|
439
|
+
function resolveTuiAdapter(kind = "claude-code") {
|
|
440
|
+
switch (kind) {
|
|
441
|
+
case "claude-code":
|
|
442
|
+
return new ClaudeTuiAdapter();
|
|
443
|
+
case "opencode":
|
|
444
|
+
return new OpenCodeTuiAdapter();
|
|
445
|
+
default:
|
|
446
|
+
throw new Error(`Unknown TUI kind: ${kind}`);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
344
450
|
// src/runner/adhoc-session-runner.ts
|
|
345
451
|
var ADHOC_SYSTEM_NOTE = "You are running in an ad-hoc Conveyor scratch pod \u2014 an interactive terminal on the project's repository checked out at its default branch. There is no task or plan; help the human with whatever they ask directly.";
|
|
452
|
+
function resolveAdhocTui(env) {
|
|
453
|
+
const raw = env.CONVEYOR_TUI ?? "claude-code";
|
|
454
|
+
if (TUI_KINDS.includes(raw)) return raw;
|
|
455
|
+
throw new Error(`Unknown TUI "${raw}" in CONVEYOR_TUI (expected: ${TUI_KINDS.join(", ")})`);
|
|
456
|
+
}
|
|
346
457
|
function buildAdhocPtyBridge(connection) {
|
|
347
458
|
return {
|
|
348
459
|
sendOutput: (data, dims) => connection.sendPtyOutput(data, dims),
|
|
@@ -384,7 +495,10 @@ var AdhocSessionRunner = class {
|
|
|
384
495
|
this.config = config;
|
|
385
496
|
this.callbacks = callbacks;
|
|
386
497
|
this.connection = deps?.connection ?? new AgentConnection(config.connection);
|
|
387
|
-
this.harness = deps?.harness ?? new PtyHarness(
|
|
498
|
+
this.harness = deps?.harness ?? new PtyHarness(
|
|
499
|
+
buildAdhocPtyBridge(this.connection),
|
|
500
|
+
resolveTuiAdapter(resolveAdhocTui(process.env))
|
|
501
|
+
);
|
|
388
502
|
this.lifecycle = new Lifecycle(
|
|
389
503
|
// No git flush: the WIP snapshot machinery is branch/task-shaped; the human
|
|
390
504
|
// commits/pushes explicitly from the interactive shell.
|
|
@@ -444,7 +558,7 @@ var AdhocSessionRunner = class {
|
|
|
444
558
|
* loop blocks (keeping the pod alive) until the human exits or stop() aborts.
|
|
445
559
|
*/
|
|
446
560
|
async runInteractiveTui() {
|
|
447
|
-
const model = this.config.model ?? process.env.CONVEYOR_ADHOC_MODEL ?? DEFAULT_SONNET_MODEL;
|
|
561
|
+
const model = this.config.model ?? process.env.CONVEYOR_AGENT_MODEL ?? process.env.CONVEYOR_ADHOC_MODEL ?? DEFAULT_SONNET_MODEL;
|
|
448
562
|
const session = resolveSessionStart(this.config.workspaceId, this.config.workspaceDir);
|
|
449
563
|
const options = buildAdhocQueryOptions(
|
|
450
564
|
this.config.workspaceDir,
|
|
@@ -453,8 +567,11 @@ var AdhocSessionRunner = class {
|
|
|
453
567
|
session
|
|
454
568
|
);
|
|
455
569
|
try {
|
|
456
|
-
for await (const
|
|
570
|
+
for await (const event of this.harness.executeQuery({ prompt: "", options })) {
|
|
457
571
|
if (this.stopped) break;
|
|
572
|
+
if (event.type === "result" && event.subtype === "error") {
|
|
573
|
+
throw new Error(event.errors.join("\n"));
|
|
574
|
+
}
|
|
458
575
|
}
|
|
459
576
|
} catch (error) {
|
|
460
577
|
if (!this.stopped) throw error;
|
|
@@ -653,7 +770,7 @@ var ReviewChildSupervisor = class {
|
|
|
653
770
|
// src/cli.ts
|
|
654
771
|
if (process.argv.includes("--version")) {
|
|
655
772
|
const __dirname = dirname2(fileURLToPath(import.meta.url));
|
|
656
|
-
const pkgPath =
|
|
773
|
+
const pkgPath = join2(__dirname, "..", "package.json");
|
|
657
774
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
658
775
|
process.stdout.write(pkg.version + "\n");
|
|
659
776
|
process.exit(0);
|