@rallycry/conveyor-agent 11.0.45 → 11.0.47

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.
@@ -11,14 +11,14 @@ import {
11
11
  readAgentVersion,
12
12
  refreshSkillsAfterCheckout,
13
13
  runPreReadyBinds
14
- } from "./chunk-37J5MMQT.js";
14
+ } from "./chunk-V5WR2F2P.js";
15
15
  import "./chunk-EKTPDG3G.js";
16
16
  import {
17
17
  GitPrepJob,
18
18
  defaultGit,
19
19
  ensureDir,
20
20
  reportBootMilestone
21
- } from "./chunk-Q4FQOJ7D.js";
21
+ } from "./chunk-VIUZS7V4.js";
22
22
  import "./chunk-W4LZ7R6Z.js";
23
23
  import "./chunk-372R6E4C.js";
24
24
  import "./chunk-SQM2BQ7H.js";
@@ -8,10 +8,10 @@ import {
8
8
  readWorkspaceBytes,
9
9
  statWorkspacePath,
10
10
  workspacePathExists
11
- } from "./chunk-IBLFLCFK.js";
11
+ } from "./chunk-KXB55NJP.js";
12
12
  import {
13
13
  reportBootMilestone
14
- } from "./chunk-Q4FQOJ7D.js";
14
+ } from "./chunk-VIUZS7V4.js";
15
15
  import {
16
16
  runSetupCommand,
17
17
  runStartCommand,
@@ -2,7 +2,7 @@ import {
2
2
  mapChatHistory,
3
3
  readAgentVersion,
4
4
  refreshSkillsAfterCheckout
5
- } from "./chunk-37J5MMQT.js";
5
+ } from "./chunk-V5WR2F2P.js";
6
6
  import {
7
7
  MAX_BETWEEN_TURN_BUFFER,
8
8
  MAX_DIAGNOSTIC_OUTPUT,
@@ -37,7 +37,6 @@ import {
37
37
  CARD_DESCRIPTION_FIELD_HINT,
38
38
  CONTEXT_LINK_LOCATOR_MAX,
39
39
  CRITICAL_AUTOMATED_SOURCES,
40
- CodespacePortVisibility,
41
40
  DEFAULT_CI_WAIT_TIMEOUT_MINUTES,
42
41
  DEFAULT_CODEX_CODING_MODEL,
43
42
  DEFAULT_LIFECYCLE_CONFIG,
@@ -98,11 +97,10 @@ import {
98
97
  statWorkspacePath,
99
98
  updateRemoteToken,
100
99
  verifyGitCredential
101
- } from "./chunk-IBLFLCFK.js";
100
+ } from "./chunk-KXB55NJP.js";
102
101
  import {
103
- registerBootMilestoneSocketFallback,
104
102
  reportBootMilestone
105
- } from "./chunk-Q4FQOJ7D.js";
103
+ } from "./chunk-VIUZS7V4.js";
106
104
  import {
107
105
  describeTokenFile,
108
106
  ghHostsExternallyOwned,
@@ -2746,7 +2744,7 @@ function claudeCredentialsPath() {
2746
2744
  return join7(claudeConfigHome(), ".credentials.json");
2747
2745
  }
2748
2746
  function isConveyorCloudEnv(env = process.env) {
2749
- return Boolean(env.CLAUDESPACE_NAME || env.CODESPACE_NAME || env.CODESPACES);
2747
+ return Boolean(env.CLAUDESPACE_NAME);
2750
2748
  }
2751
2749
  async function readRaw(path) {
2752
2750
  try {
@@ -5862,7 +5860,7 @@ function composerOverrides(runMode, env = process.env) {
5862
5860
  }
5863
5861
 
5864
5862
  // src/execution/query-executor.ts
5865
- import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
5863
+ import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
5866
5864
  import {
5867
5865
  closeSync,
5868
5866
  existsSync,
@@ -5906,7 +5904,7 @@ Respond to them with post_to_chat (your turn output is NOT shown in chat).`
5906
5904
  // src/execution/relaunch-hold.ts
5907
5905
  function findLastAgentMessageIndex(history) {
5908
5906
  for (let i = history.length - 1; i >= 0; i--) {
5909
- if (history[i].role === "assistant") return i;
5907
+ if (history[i].role === "assistant" && history[i].kind !== "lifecycle") return i;
5910
5908
  }
5911
5909
  return -1;
5912
5910
  }
@@ -5970,6 +5968,11 @@ function formatFileSize(bytes) {
5970
5968
  if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)}KB`;
5971
5969
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
5972
5970
  }
5971
+ function notInlinedRef(file) {
5972
+ const link = file.downloadUrl && isCapabilityServableMime(file.mimeType) ? file.downloadUrl : void 0;
5973
+ if (!file.fileId) return link ?? "read it with get_attachment (see list_task_files)";
5974
+ return `read it with get_attachment("${file.fileId}")${link ? ` or download: ${link}` : ""}`;
5975
+ }
5973
5976
  function formatChatFile(file) {
5974
5977
  const sizeStr = file.fileSize ? `, ${formatFileSize(file.fileSize)}` : "";
5975
5978
  if (file.content && file.contentEncoding === "utf-8") {
@@ -5981,7 +5984,7 @@ function formatChatFile(file) {
5981
5984
  ];
5982
5985
  }
5983
5986
  if (!file.content) {
5984
- return [`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]: ${file.downloadUrl}`];
5987
+ return [`[Attached: ${file.fileName} (${file.mimeType}${sizeStr})]: ${notInlinedRef(file)}`];
5985
5988
  }
5986
5989
  if (file.content && file.contentEncoding === "base64") {
5987
5990
  const link = file.downloadUrl ? ` or download: ${file.downloadUrl}` : "";
@@ -6018,7 +6021,7 @@ function formatTaskFile(file) {
6018
6021
  ];
6019
6022
  }
6020
6023
  if (!file.content) {
6021
- return [`- **${file.fileName}** (${file.mimeType}): ${file.downloadUrl}`];
6024
+ return [`- **${file.fileName}** (${file.mimeType}): ${notInlinedRef(file)}`];
6022
6025
  }
6023
6026
  return [];
6024
6027
  }
@@ -6367,8 +6370,8 @@ var PACK_RUNNER_FOOTER = [
6367
6370
  function resolveSinglePodPackBranch(context) {
6368
6371
  return context.githubBranch || context.baseBranch;
6369
6372
  }
6370
- function isPackRunnerSession(mode, isAuto, isParentTask) {
6371
- return mode === "pack" || mode === "pm" && !!isAuto && !!isParentTask;
6373
+ function isPackRunnerSession(mode) {
6374
+ return mode === "pack";
6372
6375
  }
6373
6376
  function buildSinglePodPackPrompt(context, setupLog) {
6374
6377
  const packBranch = resolveSinglePodPackBranch(context);
@@ -6937,7 +6940,7 @@ Git:`,
6937
6940
  function buildSystemPrompt(mode, context, config, setupLog, agentMode) {
6938
6941
  const isPm = mode === "pm";
6939
6942
  const isPmActive = isPm && agentMode === "building";
6940
- if (isPackRunnerSession(mode, config.isAuto, context.isParentTask)) {
6943
+ if (isPackRunnerSession(mode)) {
6941
6944
  return buildSinglePodPackPrompt(context, setupLog);
6942
6945
  }
6943
6946
  const parts = isPmActive ? buildActivePreamble(context, config.workspaceDir) : isPm ? buildPmPreamble(context) : buildTaskAgentPreamble(context, config.workspaceDir, config.runtimeTui, agentMode);
@@ -7236,7 +7239,7 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
7236
7239
  return parts;
7237
7240
  }
7238
7241
  async function buildInitialPrompt(mode, context, isAuto, agentMode) {
7239
- const isPackRunner = isPackRunnerSession(mode, isAuto, context.isParentTask);
7242
+ const isPackRunner = isPackRunnerSession(mode);
7240
7243
  if (!isPackRunner) {
7241
7244
  const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode, isAuto);
7242
7245
  if (sessionRelaunch) {
@@ -8091,7 +8094,7 @@ var listTaskFilesContract = defineToolContract({
8091
8094
  var getAttachmentContract = defineToolContract({
8092
8095
  name: "get_attachment",
8093
8096
  agent: {
8094
- description: "Fetch one task file's content plus metadata by file ID. This is the way to read attachment bytes: a document `downloadUrl` (anything that is not an image or video) answers 404 without a signed-in project member's session, so do not curl or WebFetch it from the pod. Call list_task_files first to discover IDs and check sizes \u2014 large binaries may be truncated by the service's size limit. Pass task_id when the file is attached to another card in this project, such as the pack parent.",
8097
+ description: "Fetch one task file by ID. Text and images under the inline size caps come back inline. Any other file (PDF, Word, Excel, zip, large logs) is saved into this pod, and the result names the local path: open it with the Read tool or Bash. A document downloadUrl answers 404 without a signed-in project member's session, so do not curl or WebFetch it. Call list_task_files first to discover IDs and sizes. Pass task_id when the file is attached to another card in this project, such as the pack parent.",
8095
8098
  fields: {
8096
8099
  fileId: f.string({ desc: "The file ID to retrieve" }),
8097
8100
  task_id: agentTaskIdOrSlug
@@ -9511,6 +9514,97 @@ function formatCliEvent(e) {
9511
9514
  return formatter ? formatter(e) : JSON.stringify(e);
9512
9515
  }
9513
9516
 
9517
+ // src/tools/attachment-download.ts
9518
+ import { createHash as createHash4, randomUUID as randomUUID2 } from "crypto";
9519
+ import { createWriteStream } from "fs";
9520
+ import { mkdir as mkdir6, rename, rm as rm4 } from "fs/promises";
9521
+ import { basename as basename2, join as join17 } from "path";
9522
+ import { Readable, Transform } from "stream";
9523
+ import { pipeline } from "stream/promises";
9524
+ var DOWNLOAD_TIMEOUT_MS = 12e4;
9525
+ var AttachmentSaveError = class extends Error {
9526
+ constructor(code) {
9527
+ super(`Attachment save failed: ${code}`);
9528
+ this.code = code;
9529
+ this.name = "AttachmentSaveError";
9530
+ }
9531
+ code;
9532
+ };
9533
+ function attachmentsRoot() {
9534
+ return join17(sessionTempBase(), "conveyor-attachments");
9535
+ }
9536
+ function safeAttachmentId(fileId) {
9537
+ if (/^[A-Za-z0-9_-]{1,64}$/.test(fileId)) return fileId;
9538
+ return createHash4("sha256").update(fileId).digest("hex").slice(0, 32);
9539
+ }
9540
+ function safeAttachmentName(fileName) {
9541
+ const cleaned = basename2(fileName).replace(/[^A-Za-z0-9._-]/g, "_").replace(/^[.-]+/, "").slice(-120);
9542
+ return cleaned || "attachment";
9543
+ }
9544
+ function byteCap(limit) {
9545
+ let seen = 0;
9546
+ const stream = new Transform({
9547
+ transform(chunk, _enc, callback) {
9548
+ seen += chunk.length;
9549
+ if (seen > limit) callback(new AttachmentSaveError("too_large"));
9550
+ else callback(null, chunk);
9551
+ }
9552
+ });
9553
+ return Object.assign(stream, { bytes: () => seen });
9554
+ }
9555
+ function classify(err) {
9556
+ if (err instanceof AttachmentSaveError) return err;
9557
+ if (err instanceof Error) {
9558
+ if (err.name === "TimeoutError" || err.name === "AbortError") {
9559
+ return new AttachmentSaveError("timeout");
9560
+ }
9561
+ if ("syscall" in err && typeof err.syscall === "string" && "path" in err) {
9562
+ return new AttachmentSaveError("write_failed");
9563
+ }
9564
+ }
9565
+ return new AttachmentSaveError("network");
9566
+ }
9567
+ async function fetchAttachment(url) {
9568
+ let res;
9569
+ try {
9570
+ res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
9571
+ } catch (err) {
9572
+ throw classify(err);
9573
+ }
9574
+ if (!res.ok) throw new AttachmentSaveError(`http_${res.status}`);
9575
+ const declared = Number(res.headers.get("content-length"));
9576
+ if (Number.isFinite(declared) && declared > MAX_FILE_SIZE_BYTES) {
9577
+ throw new AttachmentSaveError("too_large");
9578
+ }
9579
+ if (!res.body) throw new AttachmentSaveError("network");
9580
+ return res;
9581
+ }
9582
+ async function saveAttachmentToDisk(input) {
9583
+ const res = await fetchAttachment(input.url);
9584
+ const dir = join17(attachmentsRoot(), safeAttachmentId(input.fileId));
9585
+ const dest = join17(dir, safeAttachmentName(input.fileName));
9586
+ const part = `${dest}.${randomUUID2()}.part`;
9587
+ try {
9588
+ await mkdir6(dir, { recursive: true, mode: 448 });
9589
+ } catch {
9590
+ throw new AttachmentSaveError("write_failed");
9591
+ }
9592
+ const cap = byteCap(MAX_FILE_SIZE_BYTES);
9593
+ try {
9594
+ await pipeline(
9595
+ Readable.fromWeb(res.body),
9596
+ cap,
9597
+ createWriteStream(part, { mode: 384 })
9598
+ );
9599
+ await rename(part, dest);
9600
+ } catch (err) {
9601
+ await rm4(part, { force: true }).catch(() => {
9602
+ });
9603
+ throw classify(err);
9604
+ }
9605
+ return { path: dest, bytes: cap.bytes() };
9606
+ }
9607
+
9514
9608
  // src/tools/task-context-tools.ts
9515
9609
  function buildReadTaskChatTool(connection) {
9516
9610
  return defineContractTool(
@@ -9699,18 +9793,23 @@ function buildGetAttachmentTool(connection) {
9699
9793
  const file = await connection.call("getTaskFile", {
9700
9794
  sessionId: connection.sessionId,
9701
9795
  fileId,
9702
- ...task_id ? { taskId: task_id } : {}
9796
+ ...task_id ? { taskId: task_id } : {},
9797
+ agentDownload: true
9703
9798
  });
9704
- const { content: rawContent, ...metadata } = file;
9705
- const content = [
9706
- { type: "text", text: JSON.stringify(metadata, null, 2) }
9707
- ];
9799
+ const { content: rawContent, agentDownloadUrl, ...metadata } = file;
9708
9800
  if (rawContent && file.contentEncoding === "base64" && isImageMimeType(file.mimeType)) {
9709
- content.push(imageBlock(rawContent, file.mimeType));
9710
- } else if (rawContent) {
9711
- content[0] = { type: "text", text: JSON.stringify(file, null, 2) };
9801
+ return {
9802
+ content: [
9803
+ { type: "text", text: JSON.stringify(metadata, null, 2) },
9804
+ imageBlock(rawContent, file.mimeType)
9805
+ ]
9806
+ };
9712
9807
  }
9713
- return { content };
9808
+ if (rawContent) {
9809
+ return textResult(JSON.stringify({ ...metadata, content: rawContent }, null, 2));
9810
+ }
9811
+ if (!agentDownloadUrl) return textResult(JSON.stringify(metadata, null, 2));
9812
+ return textResult(await saveForAgent(metadata, agentDownloadUrl));
9714
9813
  } catch (error) {
9715
9814
  return textResult(
9716
9815
  `Failed to get task file: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -9720,6 +9819,26 @@ function buildGetAttachmentTool(connection) {
9720
9819
  { annotations: { readOnlyHint: true } }
9721
9820
  );
9722
9821
  }
9822
+ async function saveForAgent(metadata, url) {
9823
+ const { downloadUrl: _documentLink, ...rest } = metadata;
9824
+ const shown = isCapabilityServableMime(metadata.mimeType) ? metadata : rest;
9825
+ const header = JSON.stringify(shown, null, 2);
9826
+ try {
9827
+ const saved = await saveAttachmentToDisk({
9828
+ url,
9829
+ fileId: metadata.id,
9830
+ fileName: metadata.fileName
9831
+ });
9832
+ return `${header}
9833
+
9834
+ Saved to ${saved.path} (${saved.bytes} bytes). Open it with the Read tool (a PDF over 10 pages needs the pages parameter) or process it with Bash.`;
9835
+ } catch (error) {
9836
+ const code = error instanceof AttachmentSaveError ? error.code : "network";
9837
+ return `${header}
9838
+
9839
+ Could not save the file (${code}). Call get_attachment again; each call mints a fresh 5-minute link.`;
9840
+ }
9841
+ }
9723
9842
  function buildTaskContextTools(connection) {
9724
9843
  return [
9725
9844
  buildReadTaskChatTool(connection),
@@ -10264,7 +10383,7 @@ function buildMutationTools(connection, config) {
10264
10383
  }
10265
10384
 
10266
10385
  // src/tools/attachment-tools.ts
10267
- import { basename as basename2, extname, isAbsolute, join as join17 } from "path";
10386
+ import { basename as basename3, extname, isAbsolute, join as join18 } from "path";
10268
10387
  var MIME_BY_EXT = {
10269
10388
  ".png": "image/png",
10270
10389
  ".jpg": "image/jpeg",
@@ -10343,7 +10462,7 @@ function buildUploadAttachmentTool(connection, config) {
10343
10462
  async ({ path, title, comment, tags, showcase, supersedes }) => {
10344
10463
  const caption = title ?? comment;
10345
10464
  try {
10346
- const filePath = isAbsolute(path) ? path : join17(config.workspaceDir, path);
10465
+ const filePath = isAbsolute(path) ? path : join18(config.workspaceDir, path);
10347
10466
  const mimeType = inferMimeType(filePath);
10348
10467
  const info = await statWorkspacePath(filePath);
10349
10468
  if (!info.isFile) {
@@ -10354,7 +10473,7 @@ function buildUploadAttachmentTool(connection, config) {
10354
10473
  `File is ${info.size} bytes \u2014 exceeds the ${MAX_FILE_SIZE_BYTES} byte (25MB) upload limit.`
10355
10474
  );
10356
10475
  }
10357
- const fileName = basename2(filePath);
10476
+ const fileName = basename3(filePath);
10358
10477
  const { fileId, uploadUrl } = await connection.call("requestFileUpload", {
10359
10478
  sessionId: connection.sessionId,
10360
10479
  fileName,
@@ -11003,7 +11122,7 @@ import { z as z9 } from "zod";
11003
11122
 
11004
11123
  // src/execution/context-path-verifier.ts
11005
11124
  import { readFile as readFile4 } from "fs/promises";
11006
- import { isAbsolute as isAbsolute2, join as join18, normalize } from "path";
11125
+ import { isAbsolute as isAbsolute2, join as join19, normalize } from "path";
11007
11126
  var PROBLEM_TEXT = {
11008
11127
  not_found: "does not exist in the repo",
11009
11128
  expected_folder: "is a file, not a folder \u2014 use type 'file', 'rule', or 'doc'",
@@ -11048,7 +11167,7 @@ async function verifyContextPaths(links, workspaceDir) {
11048
11167
  problems.push({ type: link.type, path: link.path, reason: shape });
11049
11168
  continue;
11050
11169
  }
11051
- const absolutePath = join18(workspaceDir, toRelativePath(link.path));
11170
+ const absolutePath = join19(workspaceDir, toRelativePath(link.path));
11052
11171
  const stat = await statWorkspacePath(absolutePath);
11053
11172
  const wantsDirectory = expectsDirectory(link.type);
11054
11173
  if (!stat.exists) {
@@ -11999,7 +12118,7 @@ function buildEvaluateTools(connection, projectId) {
11999
12118
 
12000
12119
  // src/tools/site-asset-tools.ts
12001
12120
  import crypto from "crypto";
12002
- import { extname as extname2, isAbsolute as isAbsolute3, join as join19 } from "path";
12121
+ import { extname as extname2, isAbsolute as isAbsolute3, join as join20 } from "path";
12003
12122
  var MAX_SITE_ASSET_BYTES = 25 * 1024 * 1024;
12004
12123
  function buildSiteAssetTools(connection, config, projectId) {
12005
12124
  const list = defineContractTool(listSiteAssetTargetsContract, async () => {
@@ -12016,7 +12135,7 @@ function buildSiteAssetTools(connection, config, projectId) {
12016
12135
  const upload = defineContractTool(uploadSiteAssetsContract, async ({ siteId, paths }) => {
12017
12136
  const results = [];
12018
12137
  for (const requestedPath of [...paths].sort()) {
12019
- const path = isAbsolute3(requestedPath) ? requestedPath : join19(config.workspaceDir, requestedPath);
12138
+ const path = isAbsolute3(requestedPath) ? requestedPath : join20(config.workspaceDir, requestedPath);
12020
12139
  try {
12021
12140
  const info = await statWorkspacePath(path);
12022
12141
  if (!info.isFile) throw new Error("not a file");
@@ -13343,7 +13462,7 @@ function buildHooks(host) {
13343
13462
  };
13344
13463
  }
13345
13464
  function taskIdToSessionUuid(lineageKey) {
13346
- const hash = createHash4("sha256").update(lineageKey).digest("hex");
13465
+ const hash = createHash5("sha256").update(lineageKey).digest("hex");
13347
13466
  return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-8${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
13348
13467
  }
13349
13468
  function sessionLineageKey(taskId, agentMode, runnerMode) {
@@ -13480,12 +13599,6 @@ function buildQueryOptions(host, context) {
13480
13599
  context,
13481
13600
  {
13482
13601
  ...host.config,
13483
- // ModeController's live value, NOT the boot-frozen `config.isAuto` the
13484
- // spread carries: the pack gate reads this, and the turn prompt below
13485
- // gates on `host.isAuto`. Letting the two read different sources is how
13486
- // a codespace parent card got "you cannot write or edit files" beside
13487
- // "run /conveyor-build".
13488
- isAuto: host.isAuto,
13489
13602
  runtimeTui: process.env.CONVEYOR_TUI
13490
13603
  },
13491
13604
  host.setupLog,
@@ -13957,7 +14070,7 @@ function freshSessionOptions(host, context, options) {
13957
14070
  markSpawnedTranscript(host.config.workspaceDir, lineageUuid);
13958
14071
  return { ...options, sessionId: lineageUuid };
13959
14072
  }
13960
- return { ...options, sessionId: randomUUID2() };
14073
+ return { ...options, sessionId: randomUUID3() };
13961
14074
  }
13962
14075
  async function buildRetryQuery(host, context, options, lastErrorWasImage) {
13963
14076
  if (lastErrorWasImage) {
@@ -15224,11 +15337,9 @@ var SessionRunner = class _SessionRunner {
15224
15337
  this.config = config;
15225
15338
  this.callbacks = callbacks;
15226
15339
  this.connection = new AgentConnection(config.connection);
15227
- const portVisibility = new CodespacePortVisibility();
15228
15340
  this.portDiscovery = deps.portDiscovery ?? new PortDiscovery({
15229
15341
  report: (ports) => this.connection.reportDiscoveredPorts(ports),
15230
- annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports),
15231
- onReported: (ports) => portVisibility.ensureVisible(ports.map(({ port }) => port))
15342
+ annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports)
15232
15343
  });
15233
15344
  const initialMode = config.agentMode ?? (config.runnerMode === "pm" ? config.isAuto ? "auto" : "discovery" : "building");
15234
15345
  this.mode = new ModeController(initialMode, config.runnerMode, config.isAuto);
@@ -15561,7 +15672,6 @@ var SessionRunner = class _SessionRunner {
15561
15672
  await this.setState("connected");
15562
15673
  this.connection.sendEvent({ type: "connected", sessionId: this.sessionId });
15563
15674
  this.wireConnectionCallbacks();
15564
- registerBootMilestoneSocketFallback((key) => this.connection.reportBootMilestone(key));
15565
15675
  this.lifecycle.startHeartbeat();
15566
15676
  this.loopLag.start();
15567
15677
  this.connection.startHeartbeatWorker(this.loopLag.sharedBuffer);
@@ -16743,7 +16853,7 @@ ${outcome.failures.join("\n")}
16743
16853
  }
16744
16854
  };
16745
16855
 
16746
- // src/setup/codespace.ts
16856
+ // src/setup/unshallow.ts
16747
16857
  import { execSync } from "child_process";
16748
16858
  function unshallowRepo(workspaceDir) {
16749
16859
  try {
@@ -3,7 +3,7 @@ import {
3
3
  DEFAULT_RETRY_DELAY_MS,
4
4
  FETCH_TIMEOUT_MS,
5
5
  GIT_PREP_MAX_RETRIES
6
- } from "./chunk-Q4FQOJ7D.js";
6
+ } from "./chunk-VIUZS7V4.js";
7
7
  import {
8
8
  gitCredentialHelper,
9
9
  sleep,
@@ -25,117 +25,6 @@ import {
25
25
  workbenchEnabled
26
26
  } from "./chunk-KMB3BU4S.js";
27
27
 
28
- // src/setup/bootstrap.ts
29
- var BOOTSTRAP_TIMEOUT_MS = 3e4;
30
- var RETRY_DELAYS_MS = [5e3, 1e4, 2e4];
31
- function emitFailureEvent(payload) {
32
- process.stderr.write(JSON.stringify(payload) + "\n");
33
- }
34
- async function singleBootstrapAttempt(apiUrl, instanceName, bootstrapToken, timeoutMs) {
35
- const controller = new AbortController();
36
- const timer = setTimeout(() => controller.abort(), timeoutMs);
37
- try {
38
- const headers = {};
39
- if (bootstrapToken) headers["x-codespace-token"] = bootstrapToken;
40
- const response = await fetch(`${apiUrl}/api/codespace/bootstrap/${instanceName}`, {
41
- headers,
42
- signal: controller.signal
43
- });
44
- if (!response.ok) {
45
- const errorText = await response.text().catch(() => "");
46
- return {
47
- ok: false,
48
- status: response.status,
49
- errorText: errorText.slice(0, 500),
50
- reason: response.status === 401 || response.status === 403 ? "auth_rejected" : "http_error"
51
- };
52
- }
53
- const body = await response.json();
54
- return { ok: true, body };
55
- } catch (err) {
56
- const message = err instanceof Error ? err.message : String(err);
57
- const reason = controller.signal.aborted ? "timeout" : "network_error";
58
- return { ok: false, errorText: message.slice(0, 500), reason };
59
- } finally {
60
- clearTimeout(timer);
61
- }
62
- }
63
- function buildFailure(reason, attempts, status, detail) {
64
- const out = { ok: false, reason, attempts };
65
- if (status === void 0) {
66
- } else {
67
- out.status = status;
68
- }
69
- if (detail) out.detail = detail;
70
- return out;
71
- }
72
- function isRetryable(reason, retryOnHttpError) {
73
- if (reason === "timeout" || reason === "network_error") return true;
74
- return retryOnHttpError === true && reason === "http_error";
75
- }
76
- async function fetchBootstrap(opts) {
77
- const timeoutMs = opts.timeoutMs ?? BOOTSTRAP_TIMEOUT_MS;
78
- const delays = opts.retryDelaysMs ?? RETRY_DELAYS_MS;
79
- const maxAttempts = delays.length + 1;
80
- const hasBootstrapToken = Boolean(opts.bootstrapToken);
81
- const hasTaskToken = Boolean(process.env.CONVEYOR_TASK_TOKEN);
82
- let lastReason = "unknown";
83
- let lastStatus;
84
- let lastDetail;
85
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
86
- const result = await singleBootstrapAttempt(
87
- opts.apiUrl,
88
- opts.instanceName,
89
- opts.bootstrapToken,
90
- timeoutMs
91
- );
92
- if (result.ok && result.body) {
93
- return { ok: true, config: result.body, attempts: attempt };
94
- }
95
- lastReason = result.reason ?? "unknown";
96
- lastStatus = result.status;
97
- lastDetail = result.errorText;
98
- const failurePayload = {
99
- event: "bootstrap_failed",
100
- reason: lastReason,
101
- apiUrl: opts.apiUrl,
102
- instanceName: opts.instanceName,
103
- hasBootstrapToken,
104
- hasTaskToken,
105
- attempt
106
- };
107
- if (lastStatus === void 0) {
108
- } else {
109
- failurePayload.status = lastStatus;
110
- }
111
- if (lastDetail) failurePayload.detail = lastDetail;
112
- emitFailureEvent(failurePayload);
113
- if (!isRetryable(lastReason, opts.retryOnHttpError) || attempt >= maxAttempts) {
114
- return buildFailure(lastReason, attempt, lastStatus, lastDetail);
115
- }
116
- await sleep(delays[attempt - 1]);
117
- }
118
- return buildFailure(lastReason, maxAttempts, lastStatus, lastDetail);
119
- }
120
- function applyBootstrapToEnv(config) {
121
- for (const [key, value] of Object.entries(config.envVars ?? {})) {
122
- process.env[key] = value;
123
- }
124
- if (config.mode === "project") {
125
- if (config.projectToken) process.env.CONVEYOR_PROJECT_TOKEN = config.projectToken;
126
- if (config.projectId) process.env.CONVEYOR_PROJECT_ID = config.projectId;
127
- if (config.workspaceBranch) process.env.CONVEYOR_WORKSPACE_BRANCH = config.workspaceBranch;
128
- return;
129
- }
130
- if (config.taskId) process.env.CONVEYOR_TASK_ID = config.taskId;
131
- if (config.sessionId) process.env.CONVEYOR_SESSION_ID = config.sessionId;
132
- if (config.taskToken) process.env.CONVEYOR_TASK_TOKEN = config.taskToken;
133
- if (config.agentMode !== void 0) process.env.CONVEYOR_AGENT_MODE = config.agentMode;
134
- if (config.isAuto !== void 0) process.env.CONVEYOR_IS_AUTO = config.isAuto;
135
- if (config.runnerMode) process.env.CONVEYOR_MODE = config.runnerMode;
136
- if (config.taskBranch) process.env.CONVEYOR_TASK_BRANCH = config.taskBranch;
137
- }
138
-
139
28
  // src/utils/logger.ts
140
29
  function createServiceLogger(service) {
141
30
  const prefix = `[conveyor-agent:${service}]`;
@@ -236,9 +125,6 @@ function applyBundleGithubToken(bundle, self) {
236
125
  syncGithubTokenFiles(bundle.githubToken);
237
126
  return { written: true };
238
127
  }
239
- function syncBundleGithubToken(token) {
240
- syncGithubTokenFiles(token);
241
- }
242
128
 
243
129
  // src/connection/event-batch.ts
244
130
  var MAX_EVENT_BATCH_BYTES = 256 * 1024;
@@ -1239,15 +1125,6 @@ var AgentConnection = class _AgentConnection {
1239
1125
  async reportDiscoveredPorts(ports) {
1240
1126
  await this.call("reportDiscoveredPorts", { sessionId: this.config.sessionId, ports });
1241
1127
  }
1242
- /** Boot-milestone report over the socket — the codespace-parity fallback
1243
- * for the GKE pod bootstrap-token route. Fire-and-forget: a failed report
1244
- * must never delay or fail the boot path. */
1245
- reportBootMilestone(key) {
1246
- void this.call("reportBootMilestone", { sessionId: this.config.sessionId, key }).catch(
1247
- () => {
1248
- }
1249
- );
1250
- }
1251
1128
  // ── Typing indicators ───────────────────────────────────────────────
1252
1129
  sendTypingStart() {
1253
1130
  this.sendEvent({ type: "agent_typing_start" });
@@ -1336,9 +1213,8 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
1336
1213
  refreshFromBootstrap() {
1337
1214
  const none = Promise.resolve({ refreshedClaude: false, refreshedTaskToken: false });
1338
1215
  const podBootstrapToken = process.env.POD_BOOTSTRAP_TOKEN;
1339
- const codespaceName = process.env.CODESPACE_NAME;
1340
1216
  const apiUrl = this.config.apiUrl;
1341
- if (!apiUrl || !podBootstrapToken && !codespaceName) {
1217
+ if (!apiUrl || !podBootstrapToken) {
1342
1218
  return none;
1343
1219
  }
1344
1220
  const now = Date.now();
@@ -1346,50 +1222,7 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
1346
1222
  return none;
1347
1223
  }
1348
1224
  this.lastTaskTokenRefreshAt = now;
1349
- if (podBootstrapToken) {
1350
- return this.refreshFromV3Bootstrap(apiUrl, podBootstrapToken);
1351
- }
1352
- if (!codespaceName) return none;
1353
- return this.refreshFromCodespaceBootstrap(apiUrl, codespaceName);
1354
- }
1355
- /** Legacy GitHub Codespaces refresh path — keys on instance name. */
1356
- async refreshFromCodespaceBootstrap(apiUrl, codespaceName) {
1357
- const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;
1358
- const result = await fetchBootstrap({
1359
- apiUrl,
1360
- instanceName: codespaceName,
1361
- bootstrapToken
1362
- // Do not retry on http errors during a runtime refresh — a 401/403
1363
- // means the token is consumed / session terminal and retrying won't
1364
- // help. Network/timeout still retry inside fetchBootstrap.
1365
- });
1366
- if (!result.ok) {
1367
- logger.warn("bootstrap refresh abandoned \u2014 pod credentials will go stale", {
1368
- path: "codespace",
1369
- reason: result.reason,
1370
- status: result.status,
1371
- attempts: result.attempts,
1372
- detail: result.detail
1373
- });
1374
- return { refreshedClaude: false, refreshedTaskToken: false };
1375
- }
1376
- const previousTaskToken = process.env.CONVEYOR_TASK_TOKEN;
1377
- applyBootstrapToEnv(result.config);
1378
- const env = result.config.envVars ?? {};
1379
- syncBundleGithubToken(env.CONVEYOR_GITHUB_TOKEN ?? env.GH_TOKEN ?? env.GITHUB_TOKEN);
1380
- const refreshedTaskToken = result.config.mode !== "project" && Boolean(result.config.taskToken) && result.config.taskToken !== previousTaskToken;
1381
- if (refreshedTaskToken && result.config.taskToken) {
1382
- this.config.taskToken = result.config.taskToken;
1383
- if (this.socket) {
1384
- const auth = this.socket.auth;
1385
- if (auth && typeof auth === "object") {
1386
- auth.taskToken = result.config.taskToken;
1387
- }
1388
- }
1389
- this.heartbeatWorker?.postMessage({ taskToken: result.config.taskToken });
1390
- }
1391
- const refreshedClaude = Boolean(result.config.envVars?.CLAUDE_CODE_OAUTH_TOKEN);
1392
- return { refreshedClaude, refreshedTaskToken };
1225
+ return this.refreshFromV3Bootstrap(apiUrl, podBootstrapToken);
1393
1226
  }
1394
1227
  /**
1395
1228
  * v3 refresh: re-fetch the full bootstrap bundle from the pod's bound v3
@@ -1538,7 +1371,7 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
1538
1371
  }
1539
1372
  };
1540
1373
 
1541
- // ../shared/dist/chunk-VSUBG7GR.js
1374
+ // ../shared/dist/chunk-DXAS5XD4.js
1542
1375
  import { z } from "zod";
1543
1376
  import { z as z2 } from "zod";
1544
1377
  var DEFAULT_SONNET_MODEL = "claude-sonnet-5-5";
@@ -2289,7 +2122,9 @@ var GetTaskFilesRequestSchema = z5.object({
2289
2122
  var GetTaskFileRequestSchema = z5.object({
2290
2123
  sessionId: z5.string(),
2291
2124
  fileId: z5.string(),
2292
- taskId: z5.string().optional()
2125
+ taskId: z5.string().optional(),
2126
+ /** Ask for a short-lived `agentDownloadUrl` when the bytes are not inlined. */
2127
+ agentDownload: z5.boolean().optional()
2293
2128
  });
2294
2129
  var DeleteTaskFileRequestSchema = z5.object({
2295
2130
  sessionId: z5.string(),
@@ -2429,10 +2264,6 @@ var ReportDiscoveredPortsRequestSchema = z5.object({
2429
2264
  sessionId: z5.string(),
2430
2265
  ports: z5.array(DiscoveredPortSchema).max(64)
2431
2266
  });
2432
- var ReportBootMilestoneRequestSchema = z5.object({
2433
- sessionId: z5.string(),
2434
- key: z5.string().max(64)
2435
- });
2436
2267
  var CreateSubtaskRequestSchema = z5.object({
2437
2268
  sessionId: z5.string(),
2438
2269
  title: z5.string().min(1),
@@ -3985,6 +3816,8 @@ When you write prose a person will read \u2014 chat messages, plan updates, PR t
3985
3816
  - Define a technical term on first use when a non-engineer will read the message.
3986
3817
  - Never drop a condition, number, or scope qualifier to shorten a sentence. Precision beats brevity.
3987
3818
  These rules do NOT apply to code, code comments, commit messages, or quoted output.`;
3819
+ var PROJECT_ARCHIVE_RETENTION_DAYS = 30;
3820
+ var RETENTION_MS = PROJECT_ARCHIVE_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
3988
3821
  var CLAUDESPACE_WORKLOAD_LABEL = "rc-workload";
3989
3822
  var CLAUDESPACE_WORKLOAD_VALUE = "claudespace";
3990
3823
  var CONVEYOR_POD_SELECTOR = `${CLAUDESPACE_WORKLOAD_LABEL}=${CLAUDESPACE_WORKLOAD_VALUE}`;
@@ -5481,71 +5314,7 @@ var PortDiscovery = class {
5481
5314
  }
5482
5315
  };
5483
5316
 
5484
- // src/runner/codespace-port-visibility.ts
5485
- import { execFile as execFile3 } from "child_process";
5486
- var GH_TIMEOUT_MS = 15e3;
5487
- var VISIBILITIES = ["org", "public"];
5488
- function runGh(args) {
5489
- return new Promise((resolve) => {
5490
- execFile3("gh", [...args], { timeout: GH_TIMEOUT_MS }, (error, _stdout, stderr) => {
5491
- resolve({ ok: !error, stderr: (stderr || (error ? String(error.message) : "")).trim() });
5492
- });
5493
- });
5494
- }
5495
- function isCodespaceEnvironment(env = process.env) {
5496
- return env.CODESPACES === "true" && !!env.CODESPACE_NAME;
5497
- }
5498
- var CodespacePortVisibility = class {
5499
- env;
5500
- run;
5501
- log;
5502
- /** Ports already attempted (success or failure) — one try per process. */
5503
- attempted = /* @__PURE__ */ new Set();
5504
- constructor(options = {}) {
5505
- this.env = options.env ?? process.env;
5506
- this.run = options.run ?? runGh;
5507
- this.log = options.log ?? ((m) => process.stderr.write(`[conveyor-agent] ${m}
5508
- `));
5509
- }
5510
- /** Flip every not-yet-attempted port. Resolves even when everything fails. */
5511
- async ensureVisible(ports) {
5512
- if (!isCodespaceEnvironment(this.env)) return;
5513
- const codespaceName = this.env.CODESPACE_NAME;
5514
- for (const port of ports) {
5515
- if (this.attempted.has(port)) continue;
5516
- this.attempted.add(port);
5517
- await this.flip(port, codespaceName);
5518
- }
5519
- }
5520
- async flip(port, codespaceName) {
5521
- let lastError = "";
5522
- for (const visibility of VISIBILITIES) {
5523
- const result = await this.run([
5524
- "codespace",
5525
- "ports",
5526
- "visibility",
5527
- `${port}:${visibility}`,
5528
- "-c",
5529
- codespaceName
5530
- ]).catch((error) => ({
5531
- ok: false,
5532
- stderr: error instanceof Error ? error.message : String(error)
5533
- }));
5534
- if (result.ok) {
5535
- this.log(`Forwarded port ${port} set to ${visibility} visibility`);
5536
- return;
5537
- }
5538
- lastError = result.stderr;
5539
- }
5540
- this.log(
5541
- `Could not change visibility of forwarded port ${port} \u2014 the preview URL may 404 for other users${lastError ? `: ${lastError}` : ""}`
5542
- );
5543
- }
5544
- };
5545
-
5546
5317
  export {
5547
- fetchBootstrap,
5548
- applyBootstrapToEnv,
5549
5318
  createServiceLogger,
5550
5319
  AgentConnection,
5551
5320
  DEFAULT_SONNET_MODEL,
@@ -5619,6 +5388,5 @@ export {
5619
5388
  buildSessionPreviewPorts,
5620
5389
  loadAndAnnotateDiscoveredPorts,
5621
5390
  loadConveyorConfig,
5622
- PortDiscovery,
5623
- CodespacePortVisibility
5391
+ PortDiscovery
5624
5392
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  redactToken
3
- } from "./chunk-Q4FQOJ7D.js";
3
+ } from "./chunk-VIUZS7V4.js";
4
4
 
5
5
  // src/boot/graphify.ts
6
6
  var USER_HOME_MOUNT = "/mnt/conveyor-users";
@@ -42,6 +42,9 @@ function mapChatHistory(messages) {
42
42
  userName: m.user?.name ?? void 0,
43
43
  createdAt: m.createdAt,
44
44
  ...m.source ? { source: m.source } : {},
45
+ // The relaunch batch reads `kind` to skip server bookkeeping rows; dropping
46
+ // it here made that check dead in every pod (relaunch-hold.ts).
47
+ ...m.kind ? { kind: m.kind } : {},
45
48
  ...m.files && m.files.length > 0 ? {
46
49
  files: m.files.map((f) => ({
47
50
  fileId: f.id,
@@ -371,21 +371,11 @@ var GitPrepJob = class {
371
371
 
372
372
  // src/setup/boot-milestone.ts
373
373
  var REPORT_TIMEOUT_MS = 5e3;
374
- var socketFallback = null;
375
- function registerBootMilestoneSocketFallback(fn) {
376
- socketFallback = fn;
377
- }
378
374
  async function reportBootMilestone(opts) {
379
375
  const env = opts.env ?? process.env;
380
376
  const apiUrl = env.CONVEYOR_API_URL;
381
377
  const token = env.POD_BOOTSTRAP_TOKEN;
382
- if (!apiUrl || !token) {
383
- try {
384
- socketFallback?.(opts.key);
385
- } catch {
386
- }
387
- return false;
388
- }
378
+ if (!apiUrl || !token) return false;
389
379
  const fetchFn = opts.fetchFn ?? fetch;
390
380
  const controller = new AbortController();
391
381
  const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? REPORT_TIMEOUT_MS);
@@ -416,6 +406,5 @@ export {
416
406
  GIT_PREP_MAX_RETRIES,
417
407
  DEFAULT_RETRY_DELAY_MS,
418
408
  GitPrepJob,
419
- registerBootMilestoneSocketFallback,
420
409
  reportBootMilestone
421
410
  };
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  WorkspaceCommandSupervisor,
8
8
  startWorkspaceCommandsAfterConnect,
9
9
  stopWorkspaceCommands
10
- } from "./chunk-IIYEASRQ.js";
10
+ } from "./chunk-4A6GCJGG.js";
11
11
  import {
12
12
  PtyHarness,
13
13
  SessionRunner,
@@ -27,8 +27,8 @@ import {
27
27
  runUsageProbe,
28
28
  sampleKeyUsage,
29
29
  usesNativeUsageReporting
30
- } from "./chunk-NHKEFOCV.js";
31
- import "./chunk-37J5MMQT.js";
30
+ } from "./chunk-7Y3IY5QQ.js";
31
+ import "./chunk-V5WR2F2P.js";
32
32
  import {
33
33
  inheritedEnv,
34
34
  resolvePtySpawn,
@@ -36,19 +36,16 @@ import {
36
36
  } from "./chunk-EKTPDG3G.js";
37
37
  import {
38
38
  AgentConnection,
39
- CodespacePortVisibility,
40
39
  DEFAULT_LIFECYCLE_CONFIG,
41
40
  DEFAULT_SONNET_MODEL,
42
41
  Lifecycle,
43
42
  PortDiscovery,
44
43
  RUNNER_MODES,
45
- applyBootstrapToEnv,
46
44
  createServiceLogger,
47
- fetchBootstrap,
48
45
  loadAndAnnotateDiscoveredPorts,
49
46
  loadConveyorConfig
50
- } from "./chunk-IBLFLCFK.js";
51
- import "./chunk-Q4FQOJ7D.js";
47
+ } from "./chunk-KXB55NJP.js";
48
+ import "./chunk-VIUZS7V4.js";
52
49
  import "./chunk-W4LZ7R6Z.js";
53
50
  import "./chunk-372R6E4C.js";
54
51
  import "./chunk-IA45XHOA.js";
@@ -415,11 +412,9 @@ var AdhocSessionRunner = class {
415
412
  buildAdhocPtyBridge(this.connection, () => this.lifecycle.startIdleTimer()),
416
413
  resolveTuiAdapter(resolveAdhocTui(process.env))
417
414
  );
418
- const portVisibility = new CodespacePortVisibility();
419
415
  this.portDiscovery = deps?.portDiscovery ?? new PortDiscovery({
420
416
  report: (ports) => this.connection.reportDiscoveredPorts(ports),
421
- annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports),
422
- onReported: (ports) => portVisibility.ensureVisible(ports.map(({ port }) => port))
417
+ annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports)
423
418
  });
424
419
  this.commandSupervisor = deps?.commandSupervisor ?? new WorkspaceCommandSupervisor({
425
420
  config: loadConveyorConfig(),
@@ -1217,7 +1212,7 @@ function wireSpawnChildren(mode, connection, supervisors, logger7) {
1217
1212
 
1218
1213
  // src/cli.ts
1219
1214
  if (process.argv[2] === "boot") {
1220
- const { runBoot } = await import("./boot-T5HQVF3W.js");
1215
+ const { runBoot } = await import("./boot-ZPXDDZDF.js");
1221
1216
  process.exit(await runBoot(process.argv.slice(3)));
1222
1217
  }
1223
1218
  if (isLegacyEntrypointLaunch(process.env)) {
@@ -1249,39 +1244,6 @@ function logAgentExit(reason, opts) {
1249
1244
  });
1250
1245
  logger6[exitLogLevel(reason)]("agent_exit", payload);
1251
1246
  }
1252
- async function bootstrapFromCodespace(apiUrl, instanceName) {
1253
- const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;
1254
- const apiUrlFromEnv = Boolean(process.env.CONVEYOR_API_URL);
1255
- logger6.info("Bootstrapping from codespace", {
1256
- codespace: instanceName,
1257
- apiUrl,
1258
- apiUrlFromEnv,
1259
- bootstrapTokenPresent: Boolean(bootstrapToken)
1260
- });
1261
- const result = await fetchBootstrap({
1262
- apiUrl,
1263
- instanceName,
1264
- bootstrapToken
1265
- });
1266
- if (!result.ok) {
1267
- logger6.error("Bootstrap failed after retries", {
1268
- reason: result.reason,
1269
- attempts: result.attempts,
1270
- status: result.status,
1271
- detail: result.detail,
1272
- apiUrl,
1273
- apiUrlFromEnv,
1274
- bootstrapTokenPresent: Boolean(bootstrapToken),
1275
- hint: apiUrlFromEnv ? "Verify the codespace was created by this Conveyor deployment and that the bootstrap token is current." : "CONVEYOR_API_URL was not set as a codespace secret \u2014 agent fell back to the built-in default. Re-create the codespace, or push CONVEYOR_API_URL via project settings."
1276
- });
1277
- process.exit(1);
1278
- }
1279
- applyBootstrapToEnv(result.config);
1280
- logger6.info("Bootstrap complete", {
1281
- taskId: result.config.taskId,
1282
- attempts: result.attempts
1283
- });
1284
- }
1285
1247
  function isExpectedAbortError(error) {
1286
1248
  const message2 = error.message || "";
1287
1249
  const hasAbortMessage = /operation aborted/i.test(message2) || /abort/i.test(message2);
@@ -1347,15 +1309,6 @@ if (process.env.CONVEYOR_MODE === "workbench") {
1347
1309
  }
1348
1310
  var DEFAULT_CONVEYOR_API_URL = "https://api.conveyor.rallycryapp.com";
1349
1311
  var conveyorApiUrl = process.env.CONVEYOR_API_URL || DEFAULT_CONVEYOR_API_URL;
1350
- var INSTANCE_NAME = process.env.CODESPACE_NAME || process.env.CLAUDESPACE_NAME;
1351
- if (INSTANCE_NAME && !process.env.CONVEYOR_TASK_TOKEN) {
1352
- if (!conveyorApiUrl) {
1353
- logger6.error("Could not resolve CONVEYOR_API_URL for codespace bootstrap");
1354
- process.exit(1);
1355
- }
1356
- await bootstrapFromCodespace(conveyorApiUrl, INSTANCE_NAME);
1357
- conveyorApiUrl = process.env.CONVEYOR_API_URL ?? conveyorApiUrl;
1358
- }
1359
1312
  var CONVEYOR_TASK_TOKEN = process.env.CONVEYOR_TASK_TOKEN;
1360
1313
  var CONVEYOR_TASK_ID = process.env.CONVEYOR_TASK_ID;
1361
1314
  var CONVEYOR_WORKSPACE = process.env.CONVEYOR_WORKSPACE ?? process.cwd();
@@ -1455,7 +1408,7 @@ if (!CONVEYOR_TASK_TOKEN || !CONVEYOR_TASK_ID) {
1455
1408
  logger6.error(" CONVEYOR_TASK_TOKEN - JWT token for task authentication");
1456
1409
  logger6.error(" CONVEYOR_TASK_ID - ID of the task to execute");
1457
1410
  logger6.error("");
1458
- logger6.error("CONVEYOR_API_URL is provided via codespace secret or bootstrap.");
1411
+ logger6.error("CONVEYOR_API_URL defaults to the hosted API when unset.");
1459
1412
  logger6.error("");
1460
1413
  logger6.error("Optional:");
1461
1414
  logger6.error(" CONVEYOR_MODE - Runner mode: 'task' (default), 'pack', or 'pm'");
@@ -1470,7 +1423,7 @@ if (!RUNNER_MODES.includes(CONVEYOR_MODE)) {
1470
1423
  process.exit(1);
1471
1424
  }
1472
1425
  if (CONVEYOR_MODE === "serving") {
1473
- const { runServingSession } = await import("./serve-boot-G4LZGJ6W.js");
1426
+ const { runServingSession } = await import("./serve-boot-TPZ6CPCQ.js");
1474
1427
  exitContext.runnerMode = "serving";
1475
1428
  exitContext.sessionId = process.env.CONVEYOR_SESSION_ID ?? exitContext.sessionId;
1476
1429
  const outcome = await runServingSession({
@@ -1530,8 +1483,8 @@ var runner = new SessionRunner(
1530
1483
  connection: {
1531
1484
  apiUrl: conveyorApiUrl ?? "",
1532
1485
  taskToken: CONVEYOR_TASK_TOKEN,
1533
- // CONVEYOR_SESSION_ID is the CodespaceSession ID for BaseService ACL.
1534
- // Falls back to CONVEYOR_TASK_ID for backward compat (codespace bootstrap sets only task ID).
1486
+ // CONVEYOR_SESSION_ID is the WorkspaceSession ID for BaseService ACL.
1487
+ // Falls back to CONVEYOR_TASK_ID for backward compat.
1535
1488
  sessionId: process.env.CONVEYOR_SESSION_ID ?? CONVEYOR_TASK_ID,
1536
1489
  runnerMode: CONVEYOR_MODE
1537
1490
  },
package/dist/index.d.ts CHANGED
@@ -361,10 +361,6 @@ declare class AgentConnection {
361
361
  * Throws on failure so the PortDiscovery poller can retry on its next
362
362
  * tick (a swallowed error here would silently drop the delta). */
363
363
  reportDiscoveredPorts(ports: WorkspaceDiscoveredPort[]): Promise<void>;
364
- /** Boot-milestone report over the socket — the codespace-parity fallback
365
- * for the GKE pod bootstrap-token route. Fire-and-forget: a failed report
366
- * must never delay or fail the boot path. */
367
- reportBootMilestone(key: string): void;
368
364
  sendTypingStart(): void;
369
365
  sendTypingStop(): void;
370
366
  emitRateLimitPause(resetsAt: string): void;
@@ -418,8 +414,6 @@ declare class AgentConnection {
418
414
  private lastTaskTokenRefreshAt;
419
415
  refreshTaskTokenFromBootstrap(): Promise<boolean>;
420
416
  private refreshFromBootstrap;
421
- /** Legacy GitHub Codespaces refresh path — keys on instance name. */
422
- private refreshFromCodespaceBootstrap;
423
417
  /**
424
418
  * v3 refresh: re-fetch the full bootstrap bundle from the pod's bound v3
425
419
  * route and swap the credentials in place. The GitHub installation token
@@ -594,7 +588,7 @@ interface LifecycleConfig {
594
588
  /** Periodic WIP git flush interval (default: 2 min). Covers ungraceful
595
589
  * pod termination (OOMKilled, node eviction) where preStop doesn't run.
596
590
  * Set to `0` to disable the timer entirely — used for environments with
597
- * persistent state (local, workspace, GitHub Codespaces) that don't lose
591
+ * persistent state (local, workspace) that don't lose
598
592
  * in-flight work on a crash. */
599
593
  gitFlushIntervalMs: number;
600
594
  /** Claude key usage sample interval (default: 5 min). Polls the Anthropic
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  SessionRunner,
3
3
  unshallowRepo
4
- } from "./chunk-NHKEFOCV.js";
5
- import "./chunk-37J5MMQT.js";
4
+ } from "./chunk-7Y3IY5QQ.js";
5
+ import "./chunk-V5WR2F2P.js";
6
6
  import "./chunk-EKTPDG3G.js";
7
7
  import {
8
8
  AgentConnection,
@@ -17,8 +17,8 @@ import {
17
17
  stageAndCommit,
18
18
  updateRemoteToken,
19
19
  workspacePathExists
20
- } from "./chunk-IBLFLCFK.js";
21
- import "./chunk-Q4FQOJ7D.js";
20
+ } from "./chunk-KXB55NJP.js";
21
+ import "./chunk-VIUZS7V4.js";
22
22
  import {
23
23
  runAuthTokenCommand,
24
24
  runSetupCommand,
@@ -1,9 +1,8 @@
1
1
  import {
2
2
  WorkspaceCommandSupervisor
3
- } from "./chunk-IIYEASRQ.js";
3
+ } from "./chunk-4A6GCJGG.js";
4
4
  import {
5
5
  AgentConnection,
6
- CodespacePortVisibility,
7
6
  DEFAULT_LIFECYCLE_CONFIG,
8
7
  Lifecycle,
9
8
  PortDiscovery,
@@ -12,8 +11,8 @@ import {
12
11
  ensureOnTaskBranch,
13
12
  loadAndAnnotateDiscoveredPorts,
14
13
  loadConveyorConfig
15
- } from "./chunk-IBLFLCFK.js";
16
- import "./chunk-Q4FQOJ7D.js";
14
+ } from "./chunk-KXB55NJP.js";
15
+ import "./chunk-VIUZS7V4.js";
17
16
  import "./chunk-W4LZ7R6Z.js";
18
17
  import "./chunk-IA45XHOA.js";
19
18
  import "./chunk-SQM2BQ7H.js";
@@ -36,11 +35,9 @@ var ServeSessionRunner = class {
36
35
  this.config = config;
37
36
  this.callbacks = callbacks;
38
37
  this.connection = deps?.connection ?? new AgentConnection(config.connection);
39
- const portVisibility = new CodespacePortVisibility();
40
38
  this.portDiscovery = deps?.portDiscovery ?? new PortDiscovery({
41
39
  report: (ports) => this.connection.reportDiscoveredPorts(ports),
42
- annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports),
43
- onReported: (ports) => portVisibility.ensureVisible(ports.map(({ port }) => port))
40
+ annotate: (ports) => loadAndAnnotateDiscoveredPorts(config.workspaceDir, ports)
44
41
  });
45
42
  this.commandSupervisor = deps?.commandSupervisor ?? new WorkspaceCommandSupervisor({
46
43
  config: loadConveyorConfig(),
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@rallycry/conveyor-agent",
3
- "version": "11.0.45",
3
+ "version": "11.0.47",
4
4
  "description": "Conveyor Agent Runner v10 - PTY harness for the task chat (SDK harness for audit/project-chat). Agent-as-User architecture with BaseService patterns. Works locally too.",
5
5
  "keywords": [
6
6
  "agent",
7
7
  "claude",
8
- "codespace",
9
8
  "conveyor",
10
9
  "v10"
11
10
  ],
@@ -39,7 +38,7 @@
39
38
  },
40
39
  "dependencies": {
41
40
  "@anthropic-ai/claude-agent-sdk": "^0.3.284",
42
- "@modelcontextprotocol/sdk": "^1.30.1",
41
+ "@modelcontextprotocol/sdk": "^1.32.1",
43
42
  "node-pty": "^1.1.0",
44
43
  "socket.io-client": "^4.8.4",
45
44
  "tar": "^7.5.22",
@@ -71,7 +71,7 @@ mutation applied before the reply — is a stalled run, not a paused one.
71
71
  4. Skip, and list under "deliberately not touched":
72
72
  - rows with `parentTaskId` set — prune the pack parent; its children follow
73
73
  the parent's disposition;
74
- - rows with a non-null `codespaceStatus` — something is running on it;
74
+ - rows with a non-null `workspaceStatus` (`codespaceStatus` on older servers) — something is running on it;
75
75
  - rows with a `githubPRUrl` — work exists; that is a review question, not
76
76
  a prune question.
77
77
  5. `mcp__conveyor__list_tags` once — the project's vocabulary, and whether a