@rallycry/conveyor-agent 10.13.59 → 10.13.60
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.
|
@@ -3535,6 +3535,12 @@ var CATALOG = {
|
|
|
3535
3535
|
command: FIREBASE_EMULATOR_COMMAND,
|
|
3536
3536
|
environment: FIREBASE_EMULATOR_ENV,
|
|
3537
3537
|
healthcheck: {
|
|
3538
|
+
// Probe with node, the one runtime this image guarantees. The image
|
|
3539
|
+
// (`andreysenov/firebase-tools`) is a slim Node image that ships
|
|
3540
|
+
// NEITHER `wget` NOR `curl`, so the `wget -qO- …` probe this replaced
|
|
3541
|
+
// exited 127 on every attempt: a healthy emulator burned all 20 retries
|
|
3542
|
+
// and every bake reported it unhealthy. See the catalog invariant in
|
|
3543
|
+
// `service-definitions.test.ts`, which also executes this probe.
|
|
3538
3544
|
test: [
|
|
3539
3545
|
"CMD-SHELL",
|
|
3540
3546
|
`node -e "fetch('http://localhost:9099/').then((response) => process.exit(response.ok ? 0 : 1)).catch(() => process.exit(1))"`
|
|
@@ -3910,7 +3916,7 @@ var ClaudeCodeHarness = class {
|
|
|
3910
3916
|
// src/harness/pty/session.ts
|
|
3911
3917
|
import { randomUUID } from "crypto";
|
|
3912
3918
|
import { mkdtemp, mkdir as mkdir3, rm as rm2, writeFile as writeFile5 } from "fs/promises";
|
|
3913
|
-
import { join as
|
|
3919
|
+
import { join as join6, dirname } from "path";
|
|
3914
3920
|
|
|
3915
3921
|
// src/harness/opencode/plugin.ts
|
|
3916
3922
|
import { writeFile } from "fs/promises";
|
|
@@ -5358,15 +5364,64 @@ async function startToolServers(mcpServers, tempDir) {
|
|
|
5358
5364
|
// src/harness/pty/credentials.ts
|
|
5359
5365
|
import { chmod as chmod2, mkdir as mkdir2, readFile, rm, writeFile as writeFile4 } from "fs/promises";
|
|
5360
5366
|
import { homedir as homedir2 } from "os";
|
|
5367
|
+
import { join as join5 } from "path";
|
|
5368
|
+
|
|
5369
|
+
// src/harness/pty/credentials-marker.ts
|
|
5370
|
+
import { createHash } from "crypto";
|
|
5361
5371
|
import { join as join4 } from "path";
|
|
5372
|
+
function conveyorCredentialsMarkerPath() {
|
|
5373
|
+
return join4(claudeConfigHome(), ".conveyor-credentials.json");
|
|
5374
|
+
}
|
|
5375
|
+
function tokenFingerprint(accessToken) {
|
|
5376
|
+
return createHash("sha256").update(accessToken).digest("hex");
|
|
5377
|
+
}
|
|
5378
|
+
function buildCredentialsMarker(accessToken, now, previousHash) {
|
|
5379
|
+
const accessTokenSha256 = tokenFingerprint(accessToken);
|
|
5380
|
+
return JSON.stringify({
|
|
5381
|
+
accessTokenSha256,
|
|
5382
|
+
...previousHash && previousHash !== accessTokenSha256 ? { previousAccessTokenSha256: previousHash } : {},
|
|
5383
|
+
writtenAt: now
|
|
5384
|
+
});
|
|
5385
|
+
}
|
|
5386
|
+
function parseCredentialsMarker(raw) {
|
|
5387
|
+
if (!raw || raw.trim() === "") return [];
|
|
5388
|
+
try {
|
|
5389
|
+
const parsed = JSON.parse(raw);
|
|
5390
|
+
if (typeof parsed !== "object" || parsed === null) return [];
|
|
5391
|
+
const record = parsed;
|
|
5392
|
+
return [record.accessTokenSha256, record.previousAccessTokenSha256].filter(
|
|
5393
|
+
(hash) => typeof hash === "string" && hash.length > 0
|
|
5394
|
+
);
|
|
5395
|
+
} catch {
|
|
5396
|
+
return [];
|
|
5397
|
+
}
|
|
5398
|
+
}
|
|
5399
|
+
|
|
5400
|
+
// src/harness/pty/credentials.ts
|
|
5362
5401
|
var SYNTH_TOKEN_TTL_MS = 365 * 24 * 60 * 60 * 1e3;
|
|
5363
5402
|
var REFRESH_SKEW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
5364
5403
|
function claudeCredentialsPath() {
|
|
5365
|
-
return
|
|
5404
|
+
return join5(claudeConfigHome(), ".credentials.json");
|
|
5366
5405
|
}
|
|
5367
5406
|
function isConveyorCloudEnv(env = process.env) {
|
|
5368
5407
|
return Boolean(env.CLAUDESPACE_NAME || env.CODESPACE_NAME || env.CODESPACES);
|
|
5369
5408
|
}
|
|
5409
|
+
function parseClaudeOauthEnv(blob) {
|
|
5410
|
+
if (!blob) return null;
|
|
5411
|
+
try {
|
|
5412
|
+
const parsed = JSON.parse(Buffer.from(blob, "base64").toString("utf8"));
|
|
5413
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
5414
|
+
const record = parsed;
|
|
5415
|
+
if (typeof record.access !== "string" || record.access === "") return null;
|
|
5416
|
+
return {
|
|
5417
|
+
access: record.access,
|
|
5418
|
+
refresh: typeof record.refresh === "string" && record.refresh ? record.refresh : void 0,
|
|
5419
|
+
expires: typeof record.expires === "number" ? record.expires : void 0
|
|
5420
|
+
};
|
|
5421
|
+
} catch {
|
|
5422
|
+
return null;
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
5370
5425
|
function parseClaudeAiOauth(raw) {
|
|
5371
5426
|
if (!raw || raw.trim() === "") return null;
|
|
5372
5427
|
try {
|
|
@@ -5384,28 +5439,54 @@ function parseClaudeAiOauth(raw) {
|
|
|
5384
5439
|
return null;
|
|
5385
5440
|
}
|
|
5386
5441
|
}
|
|
5387
|
-
|
|
5442
|
+
var LOGIN_SCOPES = [
|
|
5443
|
+
"user:inference",
|
|
5444
|
+
"user:profile",
|
|
5445
|
+
"user:sessions:claude_code",
|
|
5446
|
+
"user:mcp_servers",
|
|
5447
|
+
"user:file_upload"
|
|
5448
|
+
];
|
|
5449
|
+
var LEGACY_SCOPES = ["user:inference", "user:profile"];
|
|
5450
|
+
function buildCredentialsFile(material, now) {
|
|
5451
|
+
const refresh = material.refresh;
|
|
5388
5452
|
return JSON.stringify({
|
|
5389
5453
|
claudeAiOauth: {
|
|
5390
|
-
accessToken:
|
|
5391
|
-
|
|
5392
|
-
|
|
5454
|
+
accessToken: material.access,
|
|
5455
|
+
...refresh ? { refreshToken: refresh } : {},
|
|
5456
|
+
// With a refresh token the CLI can recover from a real expiry, so report
|
|
5457
|
+
// the true one. Without, claim a far-future expiry (see SYNTH_TOKEN_TTL_MS)
|
|
5458
|
+
// because a refresh attempt would be unrecoverable.
|
|
5459
|
+
expiresAt: refresh && material.expires ? material.expires : now + SYNTH_TOKEN_TTL_MS,
|
|
5460
|
+
scopes: refresh ? LOGIN_SCOPES : LEGACY_SCOPES,
|
|
5393
5461
|
subscriptionType: "max"
|
|
5394
5462
|
}
|
|
5395
5463
|
});
|
|
5396
5464
|
}
|
|
5465
|
+
function buildSynthesizedCredentials(token, now) {
|
|
5466
|
+
return buildCredentialsFile({ access: token }, now);
|
|
5467
|
+
}
|
|
5468
|
+
function isConveyorOwnedCredentials(existing, markerHashes) {
|
|
5469
|
+
const hasRefresh = typeof existing.refreshToken === "string" && existing.refreshToken.length > 0;
|
|
5470
|
+
if (!hasRefresh) return true;
|
|
5471
|
+
if (markerHashes.length === 0) return false;
|
|
5472
|
+
if (typeof existing.accessToken !== "string") return false;
|
|
5473
|
+
return markerHashes.includes(tokenFingerprint(existing.accessToken));
|
|
5474
|
+
}
|
|
5397
5475
|
function planCredentialsWrite(input) {
|
|
5398
5476
|
if (!input.isCloud) return { action: "skip", reason: "not-cloud" };
|
|
5399
|
-
|
|
5400
|
-
|
|
5477
|
+
const material = parseClaudeOauthEnv(input.oauthBlob) ?? (input.token ? { access: input.token } : null);
|
|
5478
|
+
if (!material) return { action: "skip", reason: "no-token" };
|
|
5479
|
+
const markerHashes = parseCredentialsMarker(input.markerRaw ?? null);
|
|
5480
|
+
const contents = buildCredentialsFile(material, input.now);
|
|
5481
|
+
const marker = buildCredentialsMarker(material.access, input.now, markerHashes[0] ?? null);
|
|
5401
5482
|
const existing = parseClaudeAiOauth(input.existingRaw);
|
|
5402
|
-
if (!existing) return { action: "write", contents };
|
|
5403
|
-
if (
|
|
5483
|
+
if (!existing) return { action: "write", contents, marker };
|
|
5484
|
+
if (!isConveyorOwnedCredentials(existing, markerHashes)) {
|
|
5404
5485
|
return { action: "skip", reason: "foreign-credentials" };
|
|
5405
5486
|
}
|
|
5406
|
-
const fresh = existing.accessToken ===
|
|
5487
|
+
const fresh = material.refresh ? existing.accessToken === material.access : existing.accessToken === material.access && typeof existing.expiresAt === "number" && existing.expiresAt > input.now + REFRESH_SKEW_MS;
|
|
5407
5488
|
if (fresh) return { action: "skip", reason: "current" };
|
|
5408
|
-
return { action: "write", contents };
|
|
5489
|
+
return { action: "write", contents, marker };
|
|
5409
5490
|
}
|
|
5410
5491
|
async function readRaw(path2) {
|
|
5411
5492
|
try {
|
|
@@ -5460,19 +5541,25 @@ function fsWriteIo(path2, mode) {
|
|
|
5460
5541
|
async function ensureClaudeCredentials(env = process.env) {
|
|
5461
5542
|
const isCloud = isConveyorCloudEnv(env);
|
|
5462
5543
|
const token = env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
5463
|
-
|
|
5464
|
-
|
|
5544
|
+
const material = parseClaudeOauthEnv(env.CONVEYOR_CLAUDE_OAUTH);
|
|
5545
|
+
const accessToken = material?.access ?? token;
|
|
5546
|
+
if (isCloud && accessToken) {
|
|
5547
|
+
await sanitizeApprovedApiKeys(accessToken);
|
|
5465
5548
|
}
|
|
5466
5549
|
try {
|
|
5467
5550
|
const path2 = claudeCredentialsPath();
|
|
5551
|
+
const markerPath = conveyorCredentialsMarkerPath();
|
|
5468
5552
|
const plan = planCredentialsWrite({
|
|
5469
5553
|
isCloud,
|
|
5470
5554
|
token,
|
|
5555
|
+
oauthBlob: env.CONVEYOR_CLAUDE_OAUTH,
|
|
5471
5556
|
existingRaw: await readRaw(path2),
|
|
5557
|
+
markerRaw: await readRaw(markerPath),
|
|
5472
5558
|
now: Date.now()
|
|
5473
5559
|
});
|
|
5474
5560
|
if (plan.action === "skip") return;
|
|
5475
5561
|
await mkdir2(claudeConfigHome(), { recursive: true });
|
|
5562
|
+
await writeWithReadBackRetry(fsWriteIo(markerPath, 384), plan.marker);
|
|
5476
5563
|
const verified = await writeWithReadBackRetry(fsWriteIo(path2, 384), plan.contents);
|
|
5477
5564
|
if (!verified) {
|
|
5478
5565
|
process.stderr.write(
|
|
@@ -5525,7 +5612,7 @@ async function sanitizeApprovedApiKeys(oauthToken) {
|
|
|
5525
5612
|
}
|
|
5526
5613
|
function claudeJsonPath() {
|
|
5527
5614
|
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
5528
|
-
return configDir ?
|
|
5615
|
+
return configDir ? join5(configDir, ".claude.json") : join5(homedir2(), ".claude.json");
|
|
5529
5616
|
}
|
|
5530
5617
|
function asRecord(value) {
|
|
5531
5618
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
@@ -5618,7 +5705,7 @@ function planClaudeJsonSeed(existingRaw, trustCwd, oauthIdentity) {
|
|
|
5618
5705
|
return changed ? JSON.stringify(config) : null;
|
|
5619
5706
|
}
|
|
5620
5707
|
function conveyorOauthMarkerPath() {
|
|
5621
|
-
return
|
|
5708
|
+
return join5(claudeConfigHome(), "conveyor-oauth-account.json");
|
|
5622
5709
|
}
|
|
5623
5710
|
function parseOauthIdentity(raw) {
|
|
5624
5711
|
if (!raw || raw.trim() === "") return null;
|
|
@@ -5683,11 +5770,13 @@ async function removeConveyorCredentials(env = process.env) {
|
|
|
5683
5770
|
try {
|
|
5684
5771
|
if (!isConveyorCloudEnv(env)) return;
|
|
5685
5772
|
const path2 = claudeCredentialsPath();
|
|
5773
|
+
const markerPath = conveyorCredentialsMarkerPath();
|
|
5686
5774
|
const existing = parseClaudeAiOauth(await readRaw(path2));
|
|
5687
|
-
if (existing &&
|
|
5775
|
+
if (existing && !isConveyorOwnedCredentials(existing, parseCredentialsMarker(await readRaw(markerPath)))) {
|
|
5688
5776
|
return;
|
|
5689
5777
|
}
|
|
5690
5778
|
await rm(path2, { force: true });
|
|
5779
|
+
await rm(markerPath, { force: true });
|
|
5691
5780
|
} catch (err) {
|
|
5692
5781
|
const message = err instanceof Error ? err.message : String(err);
|
|
5693
5782
|
process.stderr.write(`[conveyor-agent] claude credentials removal failed: ${message}
|
|
@@ -6073,7 +6162,7 @@ var PtySession = class {
|
|
|
6073
6162
|
const { settingsPath, socketPath } = await this.startStructuredEventSources(sessionId);
|
|
6074
6163
|
await this.spawn(settingsPath, socketPath);
|
|
6075
6164
|
} else {
|
|
6076
|
-
this.tempDir = await mkdtemp(
|
|
6165
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6077
6166
|
await this.spawn();
|
|
6078
6167
|
this.pushEvent({
|
|
6079
6168
|
type: "system",
|
|
@@ -6118,7 +6207,7 @@ var PtySession = class {
|
|
|
6118
6207
|
* moment it is known, which is how the runner learns the resume target.
|
|
6119
6208
|
*/
|
|
6120
6209
|
async startOpenCodeEventSources() {
|
|
6121
|
-
this.tempDir = await mkdtemp(
|
|
6210
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6122
6211
|
const { servers, entries } = await startToolServers(
|
|
6123
6212
|
this.options.mcpServers ?? {},
|
|
6124
6213
|
this.tempDir
|
|
@@ -6128,7 +6217,7 @@ var PtySession = class {
|
|
|
6128
6217
|
let instructionsPath;
|
|
6129
6218
|
const systemPrompt = this.options.appendSystemPrompt;
|
|
6130
6219
|
if (systemPrompt && systemPrompt.trim() !== "") {
|
|
6131
|
-
instructionsPath =
|
|
6220
|
+
instructionsPath = join6(this.tempDir, "conveyor-instructions.md");
|
|
6132
6221
|
await writeFile5(instructionsPath, systemPrompt, "utf8");
|
|
6133
6222
|
}
|
|
6134
6223
|
this.opencodeSource = new OpenCodeEventSource(
|
|
@@ -6167,8 +6256,8 @@ var PtySession = class {
|
|
|
6167
6256
|
* paths spawn() must wire into the child's argv/env.
|
|
6168
6257
|
*/
|
|
6169
6258
|
async startStructuredEventSources(sessionId) {
|
|
6170
|
-
this.tempDir = await mkdtemp(
|
|
6171
|
-
const socketPath =
|
|
6259
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6260
|
+
const socketPath = join6(this.tempDir, "hook.sock");
|
|
6172
6261
|
this.socket = new HookSocketServer(
|
|
6173
6262
|
socketPath,
|
|
6174
6263
|
(progress) => this.handleProgress(progress),
|
|
@@ -6757,7 +6846,7 @@ var PtySession = class {
|
|
|
6757
6846
|
// src/harness/pty/config-home-health.ts
|
|
6758
6847
|
import { lstat, mkdir as mkdir4, symlink, unlink as unlink2 } from "fs/promises";
|
|
6759
6848
|
import { homedir as homedir3 } from "os";
|
|
6760
|
-
import { join as
|
|
6849
|
+
import { join as join7 } from "path";
|
|
6761
6850
|
var MOUNT_DISCONNECT_CODES = /* @__PURE__ */ new Set(["ENOTCONN", "EIO", "ESTALE", "ENXIO"]);
|
|
6762
6851
|
var MOUNT_DISCONNECT_MESSAGES = [
|
|
6763
6852
|
"socket is not connected",
|
|
@@ -6773,10 +6862,10 @@ function isMountDisconnectError(err) {
|
|
|
6773
6862
|
return MOUNT_DISCONNECT_MESSAGES.some((needle) => lower.includes(needle));
|
|
6774
6863
|
}
|
|
6775
6864
|
function podLocalConfigHome() {
|
|
6776
|
-
return
|
|
6865
|
+
return join7(homedir3(), ".claude-local");
|
|
6777
6866
|
}
|
|
6778
6867
|
function sharedConfigHomePath() {
|
|
6779
|
-
return
|
|
6868
|
+
return join7(homedir3(), ".claude");
|
|
6780
6869
|
}
|
|
6781
6870
|
function isConfigHomeFallbackActive() {
|
|
6782
6871
|
return claudeConfigHome() === podLocalConfigHome();
|
|
@@ -6807,7 +6896,7 @@ async function repointSharedConfigHomeSymlink(fallback, log) {
|
|
|
6807
6896
|
}
|
|
6808
6897
|
async function isConfigHomeMountDead(cwd) {
|
|
6809
6898
|
try {
|
|
6810
|
-
await mkdir4(
|
|
6899
|
+
await mkdir4(join7(claudeConfigHome(), "projects", projectSlug(cwd)), { recursive: true });
|
|
6811
6900
|
return false;
|
|
6812
6901
|
} catch (err) {
|
|
6813
6902
|
return isMountDisconnectError(err);
|
|
@@ -6816,7 +6905,7 @@ async function isConfigHomeMountDead(cwd) {
|
|
|
6816
6905
|
async function ensureUsableClaudeConfigHome(cwd, log) {
|
|
6817
6906
|
const configHome = claudeConfigHome();
|
|
6818
6907
|
try {
|
|
6819
|
-
await mkdir4(
|
|
6908
|
+
await mkdir4(join7(configHome, "projects", projectSlug(cwd)), { recursive: true });
|
|
6820
6909
|
return { configHome, fellBack: false };
|
|
6821
6910
|
} catch (err) {
|
|
6822
6911
|
if (!isMountDisconnectError(err)) throw err;
|
|
@@ -6830,7 +6919,7 @@ async function ensureUsableClaudeConfigHome(cwd, log) {
|
|
|
6830
6919
|
}
|
|
6831
6920
|
);
|
|
6832
6921
|
process.env.CLAUDE_CONFIG_DIR = fallback;
|
|
6833
|
-
await mkdir4(
|
|
6922
|
+
await mkdir4(join7(fallback, "projects", projectSlug(cwd)), { recursive: true });
|
|
6834
6923
|
await repointSharedConfigHomeSymlink(fallback, log);
|
|
6835
6924
|
return { configHome: fallback, fellBack: true };
|
|
6836
6925
|
}
|
|
@@ -7186,7 +7275,7 @@ import { spawn } from "child_process";
|
|
|
7186
7275
|
|
|
7187
7276
|
// src/harness/pty/adapters/types.ts
|
|
7188
7277
|
import { accessSync, constants, statSync } from "fs";
|
|
7189
|
-
import { join as
|
|
7278
|
+
import { join as join8 } from "path";
|
|
7190
7279
|
var TuiUnavailableError = class extends Error {
|
|
7191
7280
|
constructor(tui, message) {
|
|
7192
7281
|
super(message);
|
|
@@ -7210,7 +7299,7 @@ function findOnPath(binary, env = process.env) {
|
|
|
7210
7299
|
}
|
|
7211
7300
|
for (const dir of (env.PATH ?? "").split(":")) {
|
|
7212
7301
|
if (!dir) continue;
|
|
7213
|
-
const candidate =
|
|
7302
|
+
const candidate = join8(dir, binary);
|
|
7214
7303
|
if (isExecutable(candidate)) return candidate;
|
|
7215
7304
|
}
|
|
7216
7305
|
return null;
|
|
@@ -7218,18 +7307,18 @@ function findOnPath(binary, env = process.env) {
|
|
|
7218
7307
|
|
|
7219
7308
|
// src/harness/pty/adapters/opencode-auth.ts
|
|
7220
7309
|
import { promises as fs } from "fs";
|
|
7221
|
-
import { dirname as dirname2, join as
|
|
7310
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
7222
7311
|
import { homedir as homedir4 } from "os";
|
|
7223
7312
|
var logger = createServiceLogger("opencode-auth");
|
|
7224
7313
|
var OPENCODE_CODEX_PLUGIN = "opencode-openai-codex-auth@4.4.0";
|
|
7225
7314
|
var PLUGIN_PACKAGE = "opencode-openai-codex-auth";
|
|
7226
7315
|
function opencodeAuthPath(env) {
|
|
7227
|
-
const dataHome = env.XDG_DATA_HOME ??
|
|
7228
|
-
return
|
|
7316
|
+
const dataHome = env.XDG_DATA_HOME ?? join9(env.HOME ?? homedir4(), ".local", "share");
|
|
7317
|
+
return join9(dataHome, "opencode", "auth.json");
|
|
7229
7318
|
}
|
|
7230
7319
|
function opencodeConfigPath(env) {
|
|
7231
|
-
const configHome = env.XDG_CONFIG_HOME ??
|
|
7232
|
-
return
|
|
7320
|
+
const configHome = env.XDG_CONFIG_HOME ?? join9(env.HOME ?? homedir4(), ".config");
|
|
7321
|
+
return join9(configHome, "opencode", "opencode.json");
|
|
7233
7322
|
}
|
|
7234
7323
|
function parseOauthSeed(b64) {
|
|
7235
7324
|
if (!b64) return null;
|
|
@@ -7407,7 +7496,7 @@ function buildOpenCodeConfigContent(input) {
|
|
|
7407
7496
|
|
|
7408
7497
|
// src/harness/opencode/index.ts
|
|
7409
7498
|
import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile6 } from "fs/promises";
|
|
7410
|
-
import { join as
|
|
7499
|
+
import { join as join10 } from "path";
|
|
7411
7500
|
var MAX_STDERR_TAIL = 4e3;
|
|
7412
7501
|
var OpenCodeHeadlessHarness = class {
|
|
7413
7502
|
/** NDJSON from `--format json` is a trusted structured source. */
|
|
@@ -7429,7 +7518,7 @@ var OpenCodeHeadlessHarness = class {
|
|
|
7429
7518
|
const prompt = await collectPrompt(opts.prompt);
|
|
7430
7519
|
const binary = resolveOpenCodeBinary(process.env);
|
|
7431
7520
|
await prepareOpenCodeCredentials(process.env);
|
|
7432
|
-
this.tempDir = await mkdtemp2(
|
|
7521
|
+
this.tempDir = await mkdtemp2(join10(sessionTempBase(), "opencode-headless-"));
|
|
7433
7522
|
const { servers, entries } = await startToolServers(
|
|
7434
7523
|
opts.options.mcpServers ?? {},
|
|
7435
7524
|
this.tempDir
|
|
@@ -7511,7 +7600,7 @@ var OpenCodeHeadlessHarness = class {
|
|
|
7511
7600
|
*/
|
|
7512
7601
|
async writeSystemPrompt(text) {
|
|
7513
7602
|
if (!text || text.trim() === "") return null;
|
|
7514
|
-
const path2 =
|
|
7603
|
+
const path2 = join10(this.tempDir, "conveyor-instructions.md");
|
|
7515
7604
|
await writeFile6(path2, text, "utf8");
|
|
7516
7605
|
return path2;
|
|
7517
7606
|
}
|
|
@@ -7975,7 +8064,7 @@ function wrapBridgeWithDirectStream(inner, reporter, options = {}) {
|
|
|
7975
8064
|
}
|
|
7976
8065
|
|
|
7977
8066
|
// src/execution/query-executor.ts
|
|
7978
|
-
import { createHash } from "crypto";
|
|
8067
|
+
import { createHash as createHash2 } from "crypto";
|
|
7979
8068
|
import { existsSync as existsSync2, readFileSync as readFileSync2, truncateSync } from "fs";
|
|
7980
8069
|
|
|
7981
8070
|
// src/execution/chat-instructions.ts
|
|
@@ -11271,7 +11360,7 @@ function buildMutationTools(connection, config) {
|
|
|
11271
11360
|
}
|
|
11272
11361
|
|
|
11273
11362
|
// src/tools/attachment-tools.ts
|
|
11274
|
-
import { basename, extname, isAbsolute, join as
|
|
11363
|
+
import { basename, extname, isAbsolute, join as join11 } from "path";
|
|
11275
11364
|
var MIME_BY_EXT = {
|
|
11276
11365
|
".png": "image/png",
|
|
11277
11366
|
".jpg": "image/jpeg",
|
|
@@ -11322,7 +11411,7 @@ ${snippet}`;
|
|
|
11322
11411
|
function buildUploadAttachmentTool(connection, config) {
|
|
11323
11412
|
return defineContractTool(uploadAttachmentContract, async ({ path: path2, title, tags }) => {
|
|
11324
11413
|
try {
|
|
11325
|
-
const filePath = isAbsolute(path2) ? path2 :
|
|
11414
|
+
const filePath = isAbsolute(path2) ? path2 : join11(config.workspaceDir, path2);
|
|
11326
11415
|
const mimeType = inferMimeType(filePath);
|
|
11327
11416
|
const info = await statWorkspacePath(filePath);
|
|
11328
11417
|
if (!info.isFile) {
|
|
@@ -11834,7 +11923,7 @@ import { z as z16 } from "zod";
|
|
|
11834
11923
|
|
|
11835
11924
|
// src/execution/context-path-verifier.ts
|
|
11836
11925
|
import { readFile as readFile2 } from "fs/promises";
|
|
11837
|
-
import { isAbsolute as isAbsolute2, join as
|
|
11926
|
+
import { isAbsolute as isAbsolute2, join as join12, normalize } from "path";
|
|
11838
11927
|
var PROBLEM_TEXT = {
|
|
11839
11928
|
not_found: "does not exist in the repo",
|
|
11840
11929
|
expected_folder: "is a file, not a folder \u2014 use type 'file', 'rule', or 'doc'",
|
|
@@ -11879,7 +11968,7 @@ async function verifyContextPaths(links, workspaceDir) {
|
|
|
11879
11968
|
problems.push({ type: link.type, path: link.path, reason: shape });
|
|
11880
11969
|
continue;
|
|
11881
11970
|
}
|
|
11882
|
-
const absolutePath =
|
|
11971
|
+
const absolutePath = join12(workspaceDir, toRelativePath(link.path));
|
|
11883
11972
|
const stat = await statWorkspacePath(absolutePath);
|
|
11884
11973
|
const wantsDirectory = expectsDirectory(link.type);
|
|
11885
11974
|
if (!stat.exists) {
|
|
@@ -13008,6 +13097,7 @@ function applyCycledKeyEnv(envVars, env = process.env) {
|
|
|
13008
13097
|
for (const [key, value] of Object.entries(envVars)) {
|
|
13009
13098
|
env[key] = value;
|
|
13010
13099
|
}
|
|
13100
|
+
if (!envVars.CONVEYOR_CLAUDE_OAUTH) delete env.CONVEYOR_CLAUDE_OAUTH;
|
|
13011
13101
|
if (envVars.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
13012
13102
|
delete env.ANTHROPIC_API_KEY;
|
|
13013
13103
|
if (!envVars.CONVEYOR_AGENT_KEY) delete env.CONVEYOR_AGENT_KEY;
|
|
@@ -13486,7 +13576,7 @@ function buildHooks(host) {
|
|
|
13486
13576
|
};
|
|
13487
13577
|
}
|
|
13488
13578
|
function taskIdToSessionUuid(lineageKey) {
|
|
13489
|
-
const hash =
|
|
13579
|
+
const hash = createHash2("sha256").update(lineageKey).digest("hex");
|
|
13490
13580
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-8${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
|
|
13491
13581
|
}
|
|
13492
13582
|
function sessionLineageKey(taskId, agentMode, runnerMode) {
|
|
@@ -16192,6 +16282,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
16192
16282
|
}
|
|
16193
16283
|
});
|
|
16194
16284
|
this.connection.onApiKeyUpdate((data) => {
|
|
16285
|
+
delete process.env.CONVEYOR_CLAUDE_OAUTH;
|
|
16195
16286
|
if (data.isSubscription) {
|
|
16196
16287
|
process.env.CLAUDE_CODE_OAUTH_TOKEN = data.apiKey;
|
|
16197
16288
|
delete process.env.ANTHROPIC_API_KEY;
|
|
@@ -16343,12 +16434,12 @@ var SessionRunner = class _SessionRunner {
|
|
|
16343
16434
|
};
|
|
16344
16435
|
|
|
16345
16436
|
// src/setup/config.ts
|
|
16346
|
-
import { join as
|
|
16437
|
+
import { join as join13 } from "path";
|
|
16347
16438
|
var DEVCONTAINER_PATH = ".devcontainer/conveyor/devcontainer.json";
|
|
16348
16439
|
var DEVCONTAINER_PORT_DENY_LIST = /* @__PURE__ */ new Set([5432, 6379, 9200]);
|
|
16349
16440
|
async function loadForwardPorts(workspaceDir) {
|
|
16350
16441
|
try {
|
|
16351
|
-
const raw = await readWorkspaceFile(
|
|
16442
|
+
const raw = await readWorkspaceFile(join13(workspaceDir, DEVCONTAINER_PATH));
|
|
16352
16443
|
const parsed = JSON.parse(raw);
|
|
16353
16444
|
const ports = (parsed.forwardPorts ?? []).filter(
|
|
16354
16445
|
(p) => typeof p === "number" && !DEVCONTAINER_PORT_DENY_LIST.has(p)
|
|
@@ -16438,4 +16529,4 @@ export {
|
|
|
16438
16529
|
loadConveyorConfig,
|
|
16439
16530
|
unshallowRepo
|
|
16440
16531
|
};
|
|
16441
|
-
//# sourceMappingURL=chunk-
|
|
16532
|
+
//# sourceMappingURL=chunk-VF5BSGN4.js.map
|