@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 join5, dirname } from "path";
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 join4(claudeConfigHome(), ".credentials.json");
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
- function buildSynthesizedCredentials(token, now) {
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: token,
5391
- expiresAt: now + SYNTH_TOKEN_TTL_MS,
5392
- scopes: ["user:inference", "user:profile"],
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
- if (!input.token) return { action: "skip", reason: "no-token" };
5400
- const contents = buildSynthesizedCredentials(input.token, input.now);
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 (typeof existing.refreshToken === "string" && existing.refreshToken.length > 0) {
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 === input.token && typeof existing.expiresAt === "number" && existing.expiresAt > input.now + REFRESH_SKEW_MS;
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
- if (isCloud && token) {
5464
- await sanitizeApprovedApiKeys(token);
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 ? join4(configDir, ".claude.json") : join4(homedir2(), ".claude.json");
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 join4(claudeConfigHome(), "conveyor-oauth-account.json");
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 && typeof existing.refreshToken === "string" && existing.refreshToken.length > 0) {
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(join5(sessionTempBase(), "conveyor-pty-"));
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(join5(sessionTempBase(), "conveyor-pty-"));
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 = join5(this.tempDir, "conveyor-instructions.md");
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(join5(sessionTempBase(), "conveyor-pty-"));
6171
- const socketPath = join5(this.tempDir, "hook.sock");
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 join6 } from "path";
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 join6(homedir3(), ".claude-local");
6866
+ return join7(homedir3(), ".claude-local");
6777
6867
  }
6778
6868
  function sharedConfigHomePath() {
6779
- return join6(homedir3(), ".claude");
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(join6(claudeConfigHome(), "projects", projectSlug(cwd)), { recursive: true });
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(join6(configHome, "projects", projectSlug(cwd)), { recursive: true });
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(join6(fallback, "projects", projectSlug(cwd)), { recursive: true });
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 join7 } from "path";
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 = join7(dir, binary);
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 join8 } from "path";
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 ?? join8(env.HOME ?? homedir4(), ".local", "share");
7228
- return join8(dataHome, "opencode", "auth.json");
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 ?? join8(env.HOME ?? homedir4(), ".config");
7232
- return join8(configHome, "opencode", "opencode.json");
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 join9 } from "path";
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(join9(sessionTempBase(), "opencode-headless-"));
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 = join9(this.tempDir, "conveyor-instructions.md");
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 join10 } from "path";
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 : join10(config.workspaceDir, 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 join11, normalize } from "path";
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 = join11(workspaceDir, toRelativePath(link.path));
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 = createHash("sha256").update(lineageKey).digest("hex");
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 join12 } from "path";
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(join12(workspaceDir, DEVCONTAINER_PATH));
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-JCRP6K6T.js.map
16533
+ //# sourceMappingURL=chunk-LXSQ3AQN.js.map