@rallycry/conveyor-agent 10.13.58 → 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.
- package/dist/{chunk-HYP7BK2B.js → chunk-VF5BSGN4.js} +157 -50
- package/dist/chunk-VF5BSGN4.js.map +1 -0
- package/dist/cli.js +172 -8
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-HYP7BK2B.js.map +0 -1
|
@@ -3301,6 +3301,10 @@ var FIREBASE_EMULATOR_COMMAND = [
|
|
|
3301
3301
|
EOF
|
|
3302
3302
|
exec firebase emulators:start --only=auth --project=rally-cry-dev`
|
|
3303
3303
|
];
|
|
3304
|
+
var FIREBASE_EMULATOR_ENV = {
|
|
3305
|
+
METADATA_SERVER_DETECTION: "none",
|
|
3306
|
+
GOOGLE_APPLICATION_CREDENTIALS: "/dev/null"
|
|
3307
|
+
};
|
|
3304
3308
|
var CATALOG = {
|
|
3305
3309
|
postgresql: {
|
|
3306
3310
|
name: "postgresql",
|
|
@@ -3386,6 +3390,10 @@ var CATALOG = {
|
|
|
3386
3390
|
requests: { cpuMillicores: 25, memoryMi: 32, ephemeralMi: 256 },
|
|
3387
3391
|
limits: { cpuMillicores: 50, memoryMi: 64, ephemeralMi: 256 }
|
|
3388
3392
|
},
|
|
3393
|
+
connectionEnv: {
|
|
3394
|
+
REDIS_URL: "redis://redis:6379",
|
|
3395
|
+
AUTH_REDIS_URL: "redis://redis:6379"
|
|
3396
|
+
},
|
|
3389
3397
|
statefulBake: false,
|
|
3390
3398
|
// Redis holds no baked state, so the bake runs the stock image CMD.
|
|
3391
3399
|
bake: {},
|
|
@@ -3431,6 +3439,9 @@ var CATALOG = {
|
|
|
3431
3439
|
requests: { cpuMillicores: 500, memoryMi: 1024, ephemeralMi: 256 },
|
|
3432
3440
|
limits: { cpuMillicores: 2e3, memoryMi: 1024, ephemeralMi: 256 }
|
|
3433
3441
|
},
|
|
3442
|
+
connectionEnv: {
|
|
3443
|
+
ELASTICSEARCH_URL: "http://elasticsearch:9200"
|
|
3444
|
+
},
|
|
3434
3445
|
statefulBake: true,
|
|
3435
3446
|
bake: {
|
|
3436
3447
|
// No lock-clearing command at bake time: the bake starts from the stock
|
|
@@ -3500,8 +3511,7 @@ var CATALOG = {
|
|
|
3500
3511
|
// for this container only: google-auth-library skips metadata detection
|
|
3501
3512
|
// and finds no key file, firebase-tools logs "not authenticated" and
|
|
3502
3513
|
// starts the emulator immediately. The agent container keeps its WI.
|
|
3503
|
-
|
|
3504
|
-
GOOGLE_APPLICATION_CREDENTIALS: "/dev/null"
|
|
3514
|
+
...FIREBASE_EMULATOR_ENV
|
|
3505
3515
|
},
|
|
3506
3516
|
resources: {
|
|
3507
3517
|
requests: { cpuMillicores: 100, memoryMi: 256, ephemeralMi: 256 },
|
|
@@ -3523,8 +3533,18 @@ var CATALOG = {
|
|
|
3523
3533
|
// The emulator writes its config at startup, so the bake needs the same
|
|
3524
3534
|
// inline command the runtime uses.
|
|
3525
3535
|
command: FIREBASE_EMULATOR_COMMAND,
|
|
3536
|
+
environment: FIREBASE_EMULATOR_ENV,
|
|
3526
3537
|
healthcheck: {
|
|
3527
|
-
|
|
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.
|
|
3544
|
+
test: [
|
|
3545
|
+
"CMD-SHELL",
|
|
3546
|
+
`node -e "fetch('http://localhost:9099/').then((response) => process.exit(response.ok ? 0 : 1)).catch(() => process.exit(1))"`
|
|
3547
|
+
],
|
|
3528
3548
|
intervalSec: 3,
|
|
3529
3549
|
timeoutSec: 5,
|
|
3530
3550
|
retries: 20
|
|
@@ -3896,7 +3916,7 @@ var ClaudeCodeHarness = class {
|
|
|
3896
3916
|
// src/harness/pty/session.ts
|
|
3897
3917
|
import { randomUUID } from "crypto";
|
|
3898
3918
|
import { mkdtemp, mkdir as mkdir3, rm as rm2, writeFile as writeFile5 } from "fs/promises";
|
|
3899
|
-
import { join as
|
|
3919
|
+
import { join as join6, dirname } from "path";
|
|
3900
3920
|
|
|
3901
3921
|
// src/harness/opencode/plugin.ts
|
|
3902
3922
|
import { writeFile } from "fs/promises";
|
|
@@ -5344,15 +5364,64 @@ async function startToolServers(mcpServers, tempDir) {
|
|
|
5344
5364
|
// src/harness/pty/credentials.ts
|
|
5345
5365
|
import { chmod as chmod2, mkdir as mkdir2, readFile, rm, writeFile as writeFile4 } from "fs/promises";
|
|
5346
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";
|
|
5347
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
|
|
5348
5401
|
var SYNTH_TOKEN_TTL_MS = 365 * 24 * 60 * 60 * 1e3;
|
|
5349
5402
|
var REFRESH_SKEW_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
5350
5403
|
function claudeCredentialsPath() {
|
|
5351
|
-
return
|
|
5404
|
+
return join5(claudeConfigHome(), ".credentials.json");
|
|
5352
5405
|
}
|
|
5353
5406
|
function isConveyorCloudEnv(env = process.env) {
|
|
5354
5407
|
return Boolean(env.CLAUDESPACE_NAME || env.CODESPACE_NAME || env.CODESPACES);
|
|
5355
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
|
+
}
|
|
5356
5425
|
function parseClaudeAiOauth(raw) {
|
|
5357
5426
|
if (!raw || raw.trim() === "") return null;
|
|
5358
5427
|
try {
|
|
@@ -5370,28 +5439,54 @@ function parseClaudeAiOauth(raw) {
|
|
|
5370
5439
|
return null;
|
|
5371
5440
|
}
|
|
5372
5441
|
}
|
|
5373
|
-
|
|
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;
|
|
5374
5452
|
return JSON.stringify({
|
|
5375
5453
|
claudeAiOauth: {
|
|
5376
|
-
accessToken:
|
|
5377
|
-
|
|
5378
|
-
|
|
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,
|
|
5379
5461
|
subscriptionType: "max"
|
|
5380
5462
|
}
|
|
5381
5463
|
});
|
|
5382
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
|
+
}
|
|
5383
5475
|
function planCredentialsWrite(input) {
|
|
5384
5476
|
if (!input.isCloud) return { action: "skip", reason: "not-cloud" };
|
|
5385
|
-
|
|
5386
|
-
|
|
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);
|
|
5387
5482
|
const existing = parseClaudeAiOauth(input.existingRaw);
|
|
5388
|
-
if (!existing) return { action: "write", contents };
|
|
5389
|
-
if (
|
|
5483
|
+
if (!existing) return { action: "write", contents, marker };
|
|
5484
|
+
if (!isConveyorOwnedCredentials(existing, markerHashes)) {
|
|
5390
5485
|
return { action: "skip", reason: "foreign-credentials" };
|
|
5391
5486
|
}
|
|
5392
|
-
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;
|
|
5393
5488
|
if (fresh) return { action: "skip", reason: "current" };
|
|
5394
|
-
return { action: "write", contents };
|
|
5489
|
+
return { action: "write", contents, marker };
|
|
5395
5490
|
}
|
|
5396
5491
|
async function readRaw(path2) {
|
|
5397
5492
|
try {
|
|
@@ -5446,19 +5541,25 @@ function fsWriteIo(path2, mode) {
|
|
|
5446
5541
|
async function ensureClaudeCredentials(env = process.env) {
|
|
5447
5542
|
const isCloud = isConveyorCloudEnv(env);
|
|
5448
5543
|
const token = env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
5449
|
-
|
|
5450
|
-
|
|
5544
|
+
const material = parseClaudeOauthEnv(env.CONVEYOR_CLAUDE_OAUTH);
|
|
5545
|
+
const accessToken = material?.access ?? token;
|
|
5546
|
+
if (isCloud && accessToken) {
|
|
5547
|
+
await sanitizeApprovedApiKeys(accessToken);
|
|
5451
5548
|
}
|
|
5452
5549
|
try {
|
|
5453
5550
|
const path2 = claudeCredentialsPath();
|
|
5551
|
+
const markerPath = conveyorCredentialsMarkerPath();
|
|
5454
5552
|
const plan = planCredentialsWrite({
|
|
5455
5553
|
isCloud,
|
|
5456
5554
|
token,
|
|
5555
|
+
oauthBlob: env.CONVEYOR_CLAUDE_OAUTH,
|
|
5457
5556
|
existingRaw: await readRaw(path2),
|
|
5557
|
+
markerRaw: await readRaw(markerPath),
|
|
5458
5558
|
now: Date.now()
|
|
5459
5559
|
});
|
|
5460
5560
|
if (plan.action === "skip") return;
|
|
5461
5561
|
await mkdir2(claudeConfigHome(), { recursive: true });
|
|
5562
|
+
await writeWithReadBackRetry(fsWriteIo(markerPath, 384), plan.marker);
|
|
5462
5563
|
const verified = await writeWithReadBackRetry(fsWriteIo(path2, 384), plan.contents);
|
|
5463
5564
|
if (!verified) {
|
|
5464
5565
|
process.stderr.write(
|
|
@@ -5511,7 +5612,7 @@ async function sanitizeApprovedApiKeys(oauthToken) {
|
|
|
5511
5612
|
}
|
|
5512
5613
|
function claudeJsonPath() {
|
|
5513
5614
|
const configDir = process.env.CLAUDE_CONFIG_DIR;
|
|
5514
|
-
return configDir ?
|
|
5615
|
+
return configDir ? join5(configDir, ".claude.json") : join5(homedir2(), ".claude.json");
|
|
5515
5616
|
}
|
|
5516
5617
|
function asRecord(value) {
|
|
5517
5618
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
@@ -5604,7 +5705,7 @@ function planClaudeJsonSeed(existingRaw, trustCwd, oauthIdentity) {
|
|
|
5604
5705
|
return changed ? JSON.stringify(config) : null;
|
|
5605
5706
|
}
|
|
5606
5707
|
function conveyorOauthMarkerPath() {
|
|
5607
|
-
return
|
|
5708
|
+
return join5(claudeConfigHome(), "conveyor-oauth-account.json");
|
|
5608
5709
|
}
|
|
5609
5710
|
function parseOauthIdentity(raw) {
|
|
5610
5711
|
if (!raw || raw.trim() === "") return null;
|
|
@@ -5669,11 +5770,13 @@ async function removeConveyorCredentials(env = process.env) {
|
|
|
5669
5770
|
try {
|
|
5670
5771
|
if (!isConveyorCloudEnv(env)) return;
|
|
5671
5772
|
const path2 = claudeCredentialsPath();
|
|
5773
|
+
const markerPath = conveyorCredentialsMarkerPath();
|
|
5672
5774
|
const existing = parseClaudeAiOauth(await readRaw(path2));
|
|
5673
|
-
if (existing &&
|
|
5775
|
+
if (existing && !isConveyorOwnedCredentials(existing, parseCredentialsMarker(await readRaw(markerPath)))) {
|
|
5674
5776
|
return;
|
|
5675
5777
|
}
|
|
5676
5778
|
await rm(path2, { force: true });
|
|
5779
|
+
await rm(markerPath, { force: true });
|
|
5677
5780
|
} catch (err) {
|
|
5678
5781
|
const message = err instanceof Error ? err.message : String(err);
|
|
5679
5782
|
process.stderr.write(`[conveyor-agent] claude credentials removal failed: ${message}
|
|
@@ -6059,7 +6162,7 @@ var PtySession = class {
|
|
|
6059
6162
|
const { settingsPath, socketPath } = await this.startStructuredEventSources(sessionId);
|
|
6060
6163
|
await this.spawn(settingsPath, socketPath);
|
|
6061
6164
|
} else {
|
|
6062
|
-
this.tempDir = await mkdtemp(
|
|
6165
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6063
6166
|
await this.spawn();
|
|
6064
6167
|
this.pushEvent({
|
|
6065
6168
|
type: "system",
|
|
@@ -6104,7 +6207,7 @@ var PtySession = class {
|
|
|
6104
6207
|
* moment it is known, which is how the runner learns the resume target.
|
|
6105
6208
|
*/
|
|
6106
6209
|
async startOpenCodeEventSources() {
|
|
6107
|
-
this.tempDir = await mkdtemp(
|
|
6210
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6108
6211
|
const { servers, entries } = await startToolServers(
|
|
6109
6212
|
this.options.mcpServers ?? {},
|
|
6110
6213
|
this.tempDir
|
|
@@ -6114,7 +6217,7 @@ var PtySession = class {
|
|
|
6114
6217
|
let instructionsPath;
|
|
6115
6218
|
const systemPrompt = this.options.appendSystemPrompt;
|
|
6116
6219
|
if (systemPrompt && systemPrompt.trim() !== "") {
|
|
6117
|
-
instructionsPath =
|
|
6220
|
+
instructionsPath = join6(this.tempDir, "conveyor-instructions.md");
|
|
6118
6221
|
await writeFile5(instructionsPath, systemPrompt, "utf8");
|
|
6119
6222
|
}
|
|
6120
6223
|
this.opencodeSource = new OpenCodeEventSource(
|
|
@@ -6153,8 +6256,8 @@ var PtySession = class {
|
|
|
6153
6256
|
* paths spawn() must wire into the child's argv/env.
|
|
6154
6257
|
*/
|
|
6155
6258
|
async startStructuredEventSources(sessionId) {
|
|
6156
|
-
this.tempDir = await mkdtemp(
|
|
6157
|
-
const socketPath =
|
|
6259
|
+
this.tempDir = await mkdtemp(join6(sessionTempBase(), "conveyor-pty-"));
|
|
6260
|
+
const socketPath = join6(this.tempDir, "hook.sock");
|
|
6158
6261
|
this.socket = new HookSocketServer(
|
|
6159
6262
|
socketPath,
|
|
6160
6263
|
(progress) => this.handleProgress(progress),
|
|
@@ -6743,7 +6846,7 @@ var PtySession = class {
|
|
|
6743
6846
|
// src/harness/pty/config-home-health.ts
|
|
6744
6847
|
import { lstat, mkdir as mkdir4, symlink, unlink as unlink2 } from "fs/promises";
|
|
6745
6848
|
import { homedir as homedir3 } from "os";
|
|
6746
|
-
import { join as
|
|
6849
|
+
import { join as join7 } from "path";
|
|
6747
6850
|
var MOUNT_DISCONNECT_CODES = /* @__PURE__ */ new Set(["ENOTCONN", "EIO", "ESTALE", "ENXIO"]);
|
|
6748
6851
|
var MOUNT_DISCONNECT_MESSAGES = [
|
|
6749
6852
|
"socket is not connected",
|
|
@@ -6759,10 +6862,10 @@ function isMountDisconnectError(err) {
|
|
|
6759
6862
|
return MOUNT_DISCONNECT_MESSAGES.some((needle) => lower.includes(needle));
|
|
6760
6863
|
}
|
|
6761
6864
|
function podLocalConfigHome() {
|
|
6762
|
-
return
|
|
6865
|
+
return join7(homedir3(), ".claude-local");
|
|
6763
6866
|
}
|
|
6764
6867
|
function sharedConfigHomePath() {
|
|
6765
|
-
return
|
|
6868
|
+
return join7(homedir3(), ".claude");
|
|
6766
6869
|
}
|
|
6767
6870
|
function isConfigHomeFallbackActive() {
|
|
6768
6871
|
return claudeConfigHome() === podLocalConfigHome();
|
|
@@ -6793,7 +6896,7 @@ async function repointSharedConfigHomeSymlink(fallback, log) {
|
|
|
6793
6896
|
}
|
|
6794
6897
|
async function isConfigHomeMountDead(cwd) {
|
|
6795
6898
|
try {
|
|
6796
|
-
await mkdir4(
|
|
6899
|
+
await mkdir4(join7(claudeConfigHome(), "projects", projectSlug(cwd)), { recursive: true });
|
|
6797
6900
|
return false;
|
|
6798
6901
|
} catch (err) {
|
|
6799
6902
|
return isMountDisconnectError(err);
|
|
@@ -6802,7 +6905,7 @@ async function isConfigHomeMountDead(cwd) {
|
|
|
6802
6905
|
async function ensureUsableClaudeConfigHome(cwd, log) {
|
|
6803
6906
|
const configHome = claudeConfigHome();
|
|
6804
6907
|
try {
|
|
6805
|
-
await mkdir4(
|
|
6908
|
+
await mkdir4(join7(configHome, "projects", projectSlug(cwd)), { recursive: true });
|
|
6806
6909
|
return { configHome, fellBack: false };
|
|
6807
6910
|
} catch (err) {
|
|
6808
6911
|
if (!isMountDisconnectError(err)) throw err;
|
|
@@ -6816,7 +6919,7 @@ async function ensureUsableClaudeConfigHome(cwd, log) {
|
|
|
6816
6919
|
}
|
|
6817
6920
|
);
|
|
6818
6921
|
process.env.CLAUDE_CONFIG_DIR = fallback;
|
|
6819
|
-
await mkdir4(
|
|
6922
|
+
await mkdir4(join7(fallback, "projects", projectSlug(cwd)), { recursive: true });
|
|
6820
6923
|
await repointSharedConfigHomeSymlink(fallback, log);
|
|
6821
6924
|
return { configHome: fallback, fellBack: true };
|
|
6822
6925
|
}
|
|
@@ -7172,7 +7275,7 @@ import { spawn } from "child_process";
|
|
|
7172
7275
|
|
|
7173
7276
|
// src/harness/pty/adapters/types.ts
|
|
7174
7277
|
import { accessSync, constants, statSync } from "fs";
|
|
7175
|
-
import { join as
|
|
7278
|
+
import { join as join8 } from "path";
|
|
7176
7279
|
var TuiUnavailableError = class extends Error {
|
|
7177
7280
|
constructor(tui, message) {
|
|
7178
7281
|
super(message);
|
|
@@ -7196,7 +7299,7 @@ function findOnPath(binary, env = process.env) {
|
|
|
7196
7299
|
}
|
|
7197
7300
|
for (const dir of (env.PATH ?? "").split(":")) {
|
|
7198
7301
|
if (!dir) continue;
|
|
7199
|
-
const candidate =
|
|
7302
|
+
const candidate = join8(dir, binary);
|
|
7200
7303
|
if (isExecutable(candidate)) return candidate;
|
|
7201
7304
|
}
|
|
7202
7305
|
return null;
|
|
@@ -7204,18 +7307,18 @@ function findOnPath(binary, env = process.env) {
|
|
|
7204
7307
|
|
|
7205
7308
|
// src/harness/pty/adapters/opencode-auth.ts
|
|
7206
7309
|
import { promises as fs } from "fs";
|
|
7207
|
-
import { dirname as dirname2, join as
|
|
7310
|
+
import { dirname as dirname2, join as join9 } from "path";
|
|
7208
7311
|
import { homedir as homedir4 } from "os";
|
|
7209
7312
|
var logger = createServiceLogger("opencode-auth");
|
|
7210
7313
|
var OPENCODE_CODEX_PLUGIN = "opencode-openai-codex-auth@4.4.0";
|
|
7211
7314
|
var PLUGIN_PACKAGE = "opencode-openai-codex-auth";
|
|
7212
7315
|
function opencodeAuthPath(env) {
|
|
7213
|
-
const dataHome = env.XDG_DATA_HOME ??
|
|
7214
|
-
return
|
|
7316
|
+
const dataHome = env.XDG_DATA_HOME ?? join9(env.HOME ?? homedir4(), ".local", "share");
|
|
7317
|
+
return join9(dataHome, "opencode", "auth.json");
|
|
7215
7318
|
}
|
|
7216
7319
|
function opencodeConfigPath(env) {
|
|
7217
|
-
const configHome = env.XDG_CONFIG_HOME ??
|
|
7218
|
-
return
|
|
7320
|
+
const configHome = env.XDG_CONFIG_HOME ?? join9(env.HOME ?? homedir4(), ".config");
|
|
7321
|
+
return join9(configHome, "opencode", "opencode.json");
|
|
7219
7322
|
}
|
|
7220
7323
|
function parseOauthSeed(b64) {
|
|
7221
7324
|
if (!b64) return null;
|
|
@@ -7393,7 +7496,7 @@ function buildOpenCodeConfigContent(input) {
|
|
|
7393
7496
|
|
|
7394
7497
|
// src/harness/opencode/index.ts
|
|
7395
7498
|
import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile6 } from "fs/promises";
|
|
7396
|
-
import { join as
|
|
7499
|
+
import { join as join10 } from "path";
|
|
7397
7500
|
var MAX_STDERR_TAIL = 4e3;
|
|
7398
7501
|
var OpenCodeHeadlessHarness = class {
|
|
7399
7502
|
/** NDJSON from `--format json` is a trusted structured source. */
|
|
@@ -7415,7 +7518,7 @@ var OpenCodeHeadlessHarness = class {
|
|
|
7415
7518
|
const prompt = await collectPrompt(opts.prompt);
|
|
7416
7519
|
const binary = resolveOpenCodeBinary(process.env);
|
|
7417
7520
|
await prepareOpenCodeCredentials(process.env);
|
|
7418
|
-
this.tempDir = await mkdtemp2(
|
|
7521
|
+
this.tempDir = await mkdtemp2(join10(sessionTempBase(), "opencode-headless-"));
|
|
7419
7522
|
const { servers, entries } = await startToolServers(
|
|
7420
7523
|
opts.options.mcpServers ?? {},
|
|
7421
7524
|
this.tempDir
|
|
@@ -7497,7 +7600,7 @@ var OpenCodeHeadlessHarness = class {
|
|
|
7497
7600
|
*/
|
|
7498
7601
|
async writeSystemPrompt(text) {
|
|
7499
7602
|
if (!text || text.trim() === "") return null;
|
|
7500
|
-
const path2 =
|
|
7603
|
+
const path2 = join10(this.tempDir, "conveyor-instructions.md");
|
|
7501
7604
|
await writeFile6(path2, text, "utf8");
|
|
7502
7605
|
return path2;
|
|
7503
7606
|
}
|
|
@@ -7961,7 +8064,7 @@ function wrapBridgeWithDirectStream(inner, reporter, options = {}) {
|
|
|
7961
8064
|
}
|
|
7962
8065
|
|
|
7963
8066
|
// src/execution/query-executor.ts
|
|
7964
|
-
import { createHash } from "crypto";
|
|
8067
|
+
import { createHash as createHash2 } from "crypto";
|
|
7965
8068
|
import { existsSync as existsSync2, readFileSync as readFileSync2, truncateSync } from "fs";
|
|
7966
8069
|
|
|
7967
8070
|
// src/execution/chat-instructions.ts
|
|
@@ -11257,7 +11360,7 @@ function buildMutationTools(connection, config) {
|
|
|
11257
11360
|
}
|
|
11258
11361
|
|
|
11259
11362
|
// src/tools/attachment-tools.ts
|
|
11260
|
-
import { basename, extname, isAbsolute, join as
|
|
11363
|
+
import { basename, extname, isAbsolute, join as join11 } from "path";
|
|
11261
11364
|
var MIME_BY_EXT = {
|
|
11262
11365
|
".png": "image/png",
|
|
11263
11366
|
".jpg": "image/jpeg",
|
|
@@ -11308,7 +11411,7 @@ ${snippet}`;
|
|
|
11308
11411
|
function buildUploadAttachmentTool(connection, config) {
|
|
11309
11412
|
return defineContractTool(uploadAttachmentContract, async ({ path: path2, title, tags }) => {
|
|
11310
11413
|
try {
|
|
11311
|
-
const filePath = isAbsolute(path2) ? path2 :
|
|
11414
|
+
const filePath = isAbsolute(path2) ? path2 : join11(config.workspaceDir, path2);
|
|
11312
11415
|
const mimeType = inferMimeType(filePath);
|
|
11313
11416
|
const info = await statWorkspacePath(filePath);
|
|
11314
11417
|
if (!info.isFile) {
|
|
@@ -11820,7 +11923,7 @@ import { z as z16 } from "zod";
|
|
|
11820
11923
|
|
|
11821
11924
|
// src/execution/context-path-verifier.ts
|
|
11822
11925
|
import { readFile as readFile2 } from "fs/promises";
|
|
11823
|
-
import { isAbsolute as isAbsolute2, join as
|
|
11926
|
+
import { isAbsolute as isAbsolute2, join as join12, normalize } from "path";
|
|
11824
11927
|
var PROBLEM_TEXT = {
|
|
11825
11928
|
not_found: "does not exist in the repo",
|
|
11826
11929
|
expected_folder: "is a file, not a folder \u2014 use type 'file', 'rule', or 'doc'",
|
|
@@ -11865,7 +11968,7 @@ async function verifyContextPaths(links, workspaceDir) {
|
|
|
11865
11968
|
problems.push({ type: link.type, path: link.path, reason: shape });
|
|
11866
11969
|
continue;
|
|
11867
11970
|
}
|
|
11868
|
-
const absolutePath =
|
|
11971
|
+
const absolutePath = join12(workspaceDir, toRelativePath(link.path));
|
|
11869
11972
|
const stat = await statWorkspacePath(absolutePath);
|
|
11870
11973
|
const wantsDirectory = expectsDirectory(link.type);
|
|
11871
11974
|
if (!stat.exists) {
|
|
@@ -12994,6 +13097,7 @@ function applyCycledKeyEnv(envVars, env = process.env) {
|
|
|
12994
13097
|
for (const [key, value] of Object.entries(envVars)) {
|
|
12995
13098
|
env[key] = value;
|
|
12996
13099
|
}
|
|
13100
|
+
if (!envVars.CONVEYOR_CLAUDE_OAUTH) delete env.CONVEYOR_CLAUDE_OAUTH;
|
|
12997
13101
|
if (envVars.CLAUDE_CODE_OAUTH_TOKEN) {
|
|
12998
13102
|
delete env.ANTHROPIC_API_KEY;
|
|
12999
13103
|
if (!envVars.CONVEYOR_AGENT_KEY) delete env.CONVEYOR_AGENT_KEY;
|
|
@@ -13472,7 +13576,7 @@ function buildHooks(host) {
|
|
|
13472
13576
|
};
|
|
13473
13577
|
}
|
|
13474
13578
|
function taskIdToSessionUuid(lineageKey) {
|
|
13475
|
-
const hash =
|
|
13579
|
+
const hash = createHash2("sha256").update(lineageKey).digest("hex");
|
|
13476
13580
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-8${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
|
|
13477
13581
|
}
|
|
13478
13582
|
function sessionLineageKey(taskId, agentMode, runnerMode) {
|
|
@@ -16178,6 +16282,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
16178
16282
|
}
|
|
16179
16283
|
});
|
|
16180
16284
|
this.connection.onApiKeyUpdate((data) => {
|
|
16285
|
+
delete process.env.CONVEYOR_CLAUDE_OAUTH;
|
|
16181
16286
|
if (data.isSubscription) {
|
|
16182
16287
|
process.env.CLAUDE_CODE_OAUTH_TOKEN = data.apiKey;
|
|
16183
16288
|
delete process.env.ANTHROPIC_API_KEY;
|
|
@@ -16329,12 +16434,12 @@ var SessionRunner = class _SessionRunner {
|
|
|
16329
16434
|
};
|
|
16330
16435
|
|
|
16331
16436
|
// src/setup/config.ts
|
|
16332
|
-
import { join as
|
|
16437
|
+
import { join as join13 } from "path";
|
|
16333
16438
|
var DEVCONTAINER_PATH = ".devcontainer/conveyor/devcontainer.json";
|
|
16334
16439
|
var DEVCONTAINER_PORT_DENY_LIST = /* @__PURE__ */ new Set([5432, 6379, 9200]);
|
|
16335
16440
|
async function loadForwardPorts(workspaceDir) {
|
|
16336
16441
|
try {
|
|
16337
|
-
const raw = await readWorkspaceFile(
|
|
16442
|
+
const raw = await readWorkspaceFile(join13(workspaceDir, DEVCONTAINER_PATH));
|
|
16338
16443
|
const parsed = JSON.parse(raw);
|
|
16339
16444
|
const ports = (parsed.forwardPorts ?? []).filter(
|
|
16340
16445
|
(p) => typeof p === "number" && !DEVCONTAINER_PORT_DENY_LIST.has(p)
|
|
@@ -16398,6 +16503,8 @@ export {
|
|
|
16398
16503
|
PtyHarness,
|
|
16399
16504
|
resolveTuiKindFromEnv,
|
|
16400
16505
|
resolveTuiAdapter,
|
|
16506
|
+
readWorkspaceBytes,
|
|
16507
|
+
statWorkspacePath,
|
|
16401
16508
|
workspacePathExists,
|
|
16402
16509
|
GIT_TIMEOUT_MS,
|
|
16403
16510
|
hasUncommittedChanges,
|
|
@@ -16422,4 +16529,4 @@ export {
|
|
|
16422
16529
|
loadConveyorConfig,
|
|
16423
16530
|
unshallowRepo
|
|
16424
16531
|
};
|
|
16425
|
-
//# sourceMappingURL=chunk-
|
|
16532
|
+
//# sourceMappingURL=chunk-VF5BSGN4.js.map
|