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