@alan-ai-hq/agent-manager-darwin-arm64 0.1.152 → 0.1.153

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/alan-agent.cjs CHANGED
@@ -19801,6 +19801,10 @@ var init_agent_context = __esm({
19801
19801
  installCommand: external_exports.string().max(8192).nullable(),
19802
19802
  startCommand: external_exports.string().max(8192).nullable(),
19803
19803
  imageBuildId: external_exports.guid().nullable(),
19804
+ /** The repository whose `.alan/` the image build reads; a branch build swaps only its branch. */
19805
+ primaryRepository: machinePathSchema.optional(),
19806
+ /** Where install steps and the start command run: the repository, or the workspace with several. */
19807
+ setupDirectory: machinePathSchema.optional(),
19804
19808
  /** The newest build when it is not the one sessions boot from. */
19805
19809
  pendingBuild: agentContextBuildSchema.optional(),
19806
19810
  /** Saved variable names; values never leave the API. */
@@ -20371,7 +20375,7 @@ var init_run_context = __esm({
20371
20375
  });
20372
20376
 
20373
20377
  // ../shared/dist/runtime-v2/desired-state.js
20374
- var repoLocalPathSchema, requestedCheckoutSchema, runSpecSchema, desiredRunSchema, desiredStateSchema;
20378
+ var repoLocalPathSchema, requestedCheckoutSchema, runSpecSchema, desiredRunSchema, pendingUploadSchema, desiredStateSchema;
20375
20379
  var init_desired_state = __esm({
20376
20380
  "../shared/dist/runtime-v2/desired-state.js"() {
20377
20381
  "use strict";
@@ -20441,10 +20445,17 @@ var init_desired_state = __esm({
20441
20445
  spec: runSpecSchema,
20442
20446
  abortRequested: external_exports.boolean()
20443
20447
  });
20448
+ pendingUploadSchema = external_exports.object({
20449
+ runId: runIdSchema,
20450
+ conversationId: conversationIdSchema,
20451
+ admittedOffset: external_exports.number().int().nonnegative()
20452
+ });
20444
20453
  desiredStateSchema = external_exports.object({
20445
20454
  runs: external_exports.array(desiredRunSchema),
20446
20455
  /** The machine's saved workspaces; replaces the previous server list on every read. */
20447
- approvedWorkspacePaths: external_exports.array(machinePathSchema).max(2e3).optional()
20456
+ approvedWorkspacePaths: external_exports.array(machinePathSchema).max(2e3).optional(),
20457
+ /** Absent from an older server: the runtime then uploads only on its own doorbell. */
20458
+ pendingUploads: external_exports.array(pendingUploadSchema).optional()
20448
20459
  });
20449
20460
  }
20450
20461
  });
@@ -25615,15 +25626,6 @@ var init_transcript_fold = __esm({
25615
25626
  }
25616
25627
  });
25617
25628
 
25618
- // ../shared/dist/agent/acp/transcript-live.js
25619
- var TRANSCRIPT_LIVE_BATCH_BYTES;
25620
- var init_transcript_live = __esm({
25621
- "../shared/dist/agent/acp/transcript-live.js"() {
25622
- "use strict";
25623
- TRANSCRIPT_LIVE_BATCH_BYTES = 32 * 1024;
25624
- }
25625
- });
25626
-
25627
25629
  // ../shared/dist/agent/acp/index.js
25628
25630
  var init_acp = __esm({
25629
25631
  "../shared/dist/agent/acp/index.js"() {
@@ -25644,7 +25646,6 @@ var init_acp = __esm({
25644
25646
  init_transcript_fold();
25645
25647
  init_transcript_http();
25646
25648
  init_transcript_ingestion();
25647
- init_transcript_live();
25648
25649
  init_types2();
25649
25650
  }
25650
25651
  });
@@ -26999,7 +27000,7 @@ function hostProcess(child, tree, options, handlers) {
26999
27000
  lastScan: Number.NEGATIVE_INFINITY,
27000
27001
  lastOutputAt: void 0
27001
27002
  };
27002
- const terminate = () => tree.terminate({ graceMs: options.terminateGraceMs });
27003
+ const terminate2 = () => tree.terminate({ graceMs: options.terminateGraceMs });
27003
27004
  const heard = () => {
27004
27005
  flags.lastOutputAt = options.clock.monotonic();
27005
27006
  };
@@ -27030,14 +27031,14 @@ function hostProcess(child, tree, options, handlers) {
27030
27031
  if (first === "eof" && !await settlesWithin(processExit, clock, stdoutDrainMs)) {
27031
27032
  flags.outputClosedEarly = !flags.closing;
27032
27033
  log.warn(`${name}.stdout_closed_while_running`, { pid: child.pid });
27033
- await terminate();
27034
+ await terminate2();
27034
27035
  }
27035
27036
  if (first === "exit" && !await settlesWithin(outputEnded, clock, stdoutDrainMs)) {
27036
27037
  log.warn(`${name}.stdout_held_after_exit`, { pid: child.pid });
27037
- await terminate();
27038
+ await terminate2();
27038
27039
  }
27039
27040
  const exit = await processExit;
27040
- await terminate();
27041
+ await terminate2();
27041
27042
  child.stdout.destroy();
27042
27043
  child.stderr.destroy();
27043
27044
  child.stdin.destroy();
@@ -27050,7 +27051,7 @@ function hostProcess(child, tree, options, handlers) {
27050
27051
  },
27051
27052
  writer,
27052
27053
  exited: watch(),
27053
- terminate,
27054
+ terminate: terminate2,
27054
27055
  scanDescendants: (force) => {
27055
27056
  const now = options.clock.monotonic();
27056
27057
  if (!force && now - flags.lastScan < options.descendantScanMs) return;
@@ -27551,7 +27552,7 @@ var init_chunk_J2KTV5FP = __esm({
27551
27552
  }
27552
27553
  });
27553
27554
 
27554
- // ../agent-core/dist/chunk-GI3ZGXTY.js
27555
+ // ../agent-core/dist/chunk-GW6CC6A3.js
27555
27556
  function repositories(input2, context) {
27556
27557
  const problems = new Map(input2.problems.map((problem) => [problem.path, problem]));
27557
27558
  const listed = context?.repositories ?? [];
@@ -27612,7 +27613,12 @@ function environmentInstructions(environment, cwd) {
27612
27613
  );
27613
27614
  } else if (build?.status === "failed") {
27614
27615
  lines2.push(
27615
- `The latest image build (${build.id}) failed; sessions still boot from the previous image.`
27616
+ environment.imageBuildId ? `The latest image build (${build.id}) failed; sessions still boot from the previous image.` : `The latest image build (${build.id}) failed; this environment has no image yet.`
27617
+ );
27618
+ }
27619
+ if (environment.primaryRepository && environment.setupDirectory) {
27620
+ lines2.push(
27621
+ `Image builds read .alan/ from ${environment.primaryRepository}; install steps and the start command run from ${environment.setupDirectory}.`
27616
27622
  );
27617
27623
  }
27618
27624
  if (environment.variables.length > 0) {
@@ -27639,6 +27645,12 @@ function sessionKind(input2, context) {
27639
27645
  if (input2.spec.workflowExecutionId) return "workflow";
27640
27646
  return input2.spec.taskId ? "task" : "chat";
27641
27647
  }
27648
+ function setupPathsOf(environment) {
27649
+ return {
27650
+ ...environment.primaryRepository ? { primaryRepository: environment.primaryRepository } : {},
27651
+ ...environment.setupDirectory ? { setupDirectory: environment.setupDirectory } : {}
27652
+ };
27653
+ }
27642
27654
  function environmentOf(input2, context) {
27643
27655
  const environment = context?.environment;
27644
27656
  if (!environment) return void 0;
@@ -27649,6 +27661,7 @@ function environmentOf(input2, context) {
27649
27661
  installCommand: environment.installCommand,
27650
27662
  startCommand: environment.startCommand,
27651
27663
  imageBuildId: environment.imageBuildId,
27664
+ ...setupPathsOf(environment),
27652
27665
  ...environment.pendingBuild ? { pendingBuild: environment.pendingBuild } : {},
27653
27666
  variables: environment.variables,
27654
27667
  ...start ? { start: start.state === "not_configured" ? start : { ...start, log: input2.startLogPath } } : {}
@@ -27674,6 +27687,7 @@ function knownContext(snapshot) {
27674
27687
  installCommand: environment.installCommand,
27675
27688
  startCommand: environment.startCommand,
27676
27689
  imageBuildId: environment.imageBuildId,
27690
+ ...setupPathsOf(environment),
27677
27691
  ...environment.pendingBuild ? { pendingBuild: environment.pendingBuild } : {},
27678
27692
  variables: environment.variables
27679
27693
  }
@@ -27711,7 +27725,7 @@ function isScalar(value2) {
27711
27725
  }
27712
27726
  function scalar(value2) {
27713
27727
  if (typeof value2 !== "string") return String(value2);
27714
- return PLAIN_SCALAR.test(value2) ? value2 : JSON.stringify(value2);
27728
+ return PLAIN_SCALAR.test(value2) ? value2 : JSON.stringify(value2).replaceAll("<", "\\u003c");
27715
27729
  }
27716
27730
  function snakeCase(key) {
27717
27731
  return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
@@ -28165,8 +28179,8 @@ ${body}` : body;
28165
28179
  return spec.mode === "plan" ? planModePrefix(prefixed) : prefixed;
28166
28180
  }
28167
28181
  var startCommandStateSchema, repositorySnapshotSchema, environmentSnapshotSchema, agentContextSnapshotSchema, BRANCH_REASONS, PLAIN_SCALAR, COMMAND_PREVIEW_CHARS, MAX_PARSED_ATTACHMENTS, MAX_PARSED_ATTACHMENT_CHARS, MAX_METADATA_CHARS, UNAVAILABLE, READ_ONLY_MODES, AGENT_MODES;
28168
- var init_chunk_GI3ZGXTY = __esm({
28169
- "../agent-core/dist/chunk-GI3ZGXTY.js"() {
28182
+ var init_chunk_GW6CC6A3 = __esm({
28183
+ "../agent-core/dist/chunk-GW6CC6A3.js"() {
28170
28184
  "use strict";
28171
28185
  init_runtime_v2();
28172
28186
  init_zod();
@@ -28195,6 +28209,8 @@ var init_chunk_GI3ZGXTY = __esm({
28195
28209
  installCommand: external_exports.string().nullable(),
28196
28210
  startCommand: external_exports.string().nullable(),
28197
28211
  imageBuildId: external_exports.string().nullable(),
28212
+ primaryRepository: external_exports.string().optional(),
28213
+ setupDirectory: external_exports.string().optional(),
28198
28214
  pendingBuild: agentContextBuildSchema.optional(),
28199
28215
  variables: external_exports.array(external_exports.string()),
28200
28216
  start: external_exports.intersection(startCommandStateSchema, external_exports.object({ log: external_exports.string().optional() })).optional()
@@ -29512,7 +29528,7 @@ var init_claude = __esm({
29512
29528
  init_chunk_ZCTKXKYY();
29513
29529
  init_chunk_J2KTV5FP();
29514
29530
  init_chunk_XE7BX6YP();
29515
- init_chunk_GI3ZGXTY();
29531
+ init_chunk_GW6CC6A3();
29516
29532
  init_chunk_YXWJW7I5();
29517
29533
  init_effort();
29518
29534
  import_crypto6 = require("crypto");
@@ -32374,7 +32390,7 @@ var init_codex = __esm({
32374
32390
  init_chunk_ZCTKXKYY();
32375
32391
  init_chunk_J2KTV5FP();
32376
32392
  init_chunk_XE7BX6YP();
32377
- init_chunk_GI3ZGXTY();
32393
+ init_chunk_GW6CC6A3();
32378
32394
  init_chunk_YXWJW7I5();
32379
32395
  import_fs6 = require("fs");
32380
32396
  import_path6 = require("path");
@@ -42834,9 +42850,9 @@ var require_streamx = __commonJS({
42834
42850
  }
42835
42851
  });
42836
42852
 
42837
- // ../../node_modules/tar-stream/headers.js
42853
+ // ../shared/node_modules/tar-stream/headers.js
42838
42854
  var require_headers = __commonJS({
42839
- "../../node_modules/tar-stream/headers.js"(exports2) {
42855
+ "../shared/node_modules/tar-stream/headers.js"(exports2) {
42840
42856
  "use strict";
42841
42857
  var b4a = require_b4a();
42842
42858
  var ZEROS = "0000000000000000000";
@@ -43097,9 +43113,9 @@ var require_headers = __commonJS({
43097
43113
  }
43098
43114
  });
43099
43115
 
43100
- // ../../node_modules/tar-stream/extract.js
43116
+ // ../shared/node_modules/tar-stream/extract.js
43101
43117
  var require_extract = __commonJS({
43102
- "../../node_modules/tar-stream/extract.js"(exports2, module2) {
43118
+ "../shared/node_modules/tar-stream/extract.js"(exports2, module2) {
43103
43119
  "use strict";
43104
43120
  var { Writable, Readable: Readable2, getStreamError } = require_streamx();
43105
43121
  var FIFO = require_fast_fifo();
@@ -43442,9 +43458,9 @@ var require_extract = __commonJS({
43442
43458
  }
43443
43459
  });
43444
43460
 
43445
- // ../../node_modules/tar-stream/constants.js
43461
+ // ../shared/node_modules/tar-stream/constants.js
43446
43462
  var require_constants = __commonJS({
43447
- "../../node_modules/tar-stream/constants.js"(exports2, module2) {
43463
+ "../shared/node_modules/tar-stream/constants.js"(exports2, module2) {
43448
43464
  "use strict";
43449
43465
  var constants5 = {
43450
43466
  // just for envs without fs
@@ -43463,9 +43479,9 @@ var require_constants = __commonJS({
43463
43479
  }
43464
43480
  });
43465
43481
 
43466
- // ../../node_modules/tar-stream/pack.js
43482
+ // ../shared/node_modules/tar-stream/pack.js
43467
43483
  var require_pack = __commonJS({
43468
- "../../node_modules/tar-stream/pack.js"(exports2, module2) {
43484
+ "../shared/node_modules/tar-stream/pack.js"(exports2, module2) {
43469
43485
  "use strict";
43470
43486
  var { Readable: Readable2, Writable, getStreamError } = require_streamx();
43471
43487
  var b4a = require_b4a();
@@ -43698,9 +43714,9 @@ var require_pack = __commonJS({
43698
43714
  }
43699
43715
  });
43700
43716
 
43701
- // ../../node_modules/tar-stream/index.js
43717
+ // ../shared/node_modules/tar-stream/index.js
43702
43718
  var require_tar_stream = __commonJS({
43703
- "../../node_modules/tar-stream/index.js"(exports2) {
43719
+ "../shared/node_modules/tar-stream/index.js"(exports2) {
43704
43720
  "use strict";
43705
43721
  exports2.extract = require_extract();
43706
43722
  exports2.pack = require_pack();
@@ -44463,7 +44479,7 @@ var init_acp3 = __esm({
44463
44479
  init_chunk_ZCTKXKYY();
44464
44480
  init_chunk_J2KTV5FP();
44465
44481
  init_chunk_XE7BX6YP();
44466
- init_chunk_GI3ZGXTY();
44482
+ init_chunk_GW6CC6A3();
44467
44483
  init_chunk_YXWJW7I5();
44468
44484
  import_promises50 = require("fs/promises");
44469
44485
  import_path9 = require("path");
@@ -46328,7 +46344,7 @@ var init_opencode = __esm({
46328
46344
  init_chunk_ZCTKXKYY();
46329
46345
  init_chunk_J2KTV5FP();
46330
46346
  init_chunk_XE7BX6YP();
46331
- init_chunk_GI3ZGXTY();
46347
+ init_chunk_GW6CC6A3();
46332
46348
  init_chunk_YXWJW7I5();
46333
46349
  import_http10 = require("http");
46334
46350
  init_runtime_v2();
@@ -48162,7 +48178,7 @@ var init_droid = __esm({
48162
48178
  init_chunk_ZCTKXKYY();
48163
48179
  init_chunk_J2KTV5FP();
48164
48180
  init_chunk_XE7BX6YP();
48165
- init_chunk_GI3ZGXTY();
48181
+ init_chunk_GW6CC6A3();
48166
48182
  init_chunk_YXWJW7I5();
48167
48183
  init_runtime_v2();
48168
48184
  import_crypto16 = require("crypto");
@@ -49271,7 +49287,7 @@ var init_antigravity = __esm({
49271
49287
  init_chunk_XC5676SG();
49272
49288
  init_chunk_ZCTKXKYY();
49273
49289
  init_chunk_XE7BX6YP();
49274
- init_chunk_GI3ZGXTY();
49290
+ init_chunk_GW6CC6A3();
49275
49291
  init_chunk_YXWJW7I5();
49276
49292
  import_promises54 = require("fs/promises");
49277
49293
  import_path12 = require("path");
@@ -49976,7 +49992,7 @@ var init_command_code = __esm({
49976
49992
  init_chunk_ZCTKXKYY();
49977
49993
  init_chunk_J2KTV5FP();
49978
49994
  init_chunk_XE7BX6YP();
49979
- init_chunk_GI3ZGXTY();
49995
+ init_chunk_GW6CC6A3();
49980
49996
  init_chunk_YXWJW7I5();
49981
49997
  import_promises55 = require("fs/promises");
49982
49998
  import_path15 = require("path");
@@ -55374,7 +55390,7 @@ var require_websocket_server = __commonJS({
55374
55390
  // package.json
55375
55391
  var package_default = {
55376
55392
  name: "@alan-ai-hq/agent-manager",
55377
- version: "0.1.152",
55393
+ version: "0.1.153",
55378
55394
  private: true,
55379
55395
  type: "module",
55380
55396
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -57601,7 +57617,7 @@ function createGitRunner(options) {
57601
57617
  const stderr = new OutputBuffer();
57602
57618
  const total = { bytes: 0 };
57603
57619
  const closed = new AbortController();
57604
- const terminate = async () => {
57620
+ const terminate2 = async () => {
57605
57621
  await killProcessTree(child.pid, { signal: "SIGTERM", child, platform: platform3 });
57606
57622
  try {
57607
57623
  await systemClock.sleep(killGraceMs, closed.signal);
@@ -57615,7 +57631,7 @@ function createGitRunner(options) {
57615
57631
  const stop = (next) => {
57616
57632
  if (ending !== null) return;
57617
57633
  ending = next;
57618
- if (next.kind !== "exited" && next.kind !== "spawn_failed") void terminate();
57634
+ if (next.kind !== "exited" && next.kind !== "spawn_failed") void terminate2();
57619
57635
  };
57620
57636
  const onTimeout = () => stop({ kind: "timed_out" });
57621
57637
  const onAbort = () => stop({ kind: "aborted" });
@@ -57859,6 +57875,20 @@ async function readCheckoutFreshness(dir, path4) {
57859
57875
  }
57860
57876
  }
57861
57877
 
57878
+ // ../shared/dist/git-hosts.js
57879
+ var EXACT_HOSTS = {
57880
+ "github.com": "github",
57881
+ "www.github.com": "github",
57882
+ // Alan's GitLab credential is a gitlab.com OAuth token; no other GitLab host may receive it.
57883
+ "gitlab.com": "gitlab",
57884
+ "www.gitlab.com": "gitlab",
57885
+ "bitbucket.org": "bitbucket",
57886
+ "www.bitbucket.org": "bitbucket",
57887
+ "dev.azure.com": "azure-devops",
57888
+ "ssh.dev.azure.com": "azure-devops"
57889
+ };
57890
+ var GIT_GATEWAY_HTTPS_HOSTS = Object.keys(EXACT_HOSTS).filter((host) => !host.startsWith("ssh."));
57891
+
57862
57892
  // src/capabilities/git/credential-config.ts
57863
57893
  init_runtime_v2();
57864
57894
  var PROACTIVE_AUTH_MIN_VERSION = [2, 46];
@@ -57900,14 +57930,16 @@ async function configureGitCredentialHelper(input2) {
57900
57930
  await git(["config", "--global", "--add", `credential.${scope}.helper`, ""]);
57901
57931
  await git(["config", "--global", "--add", `credential.${scope}.helper`, helper]);
57902
57932
  await git(["config", "--global", `credential.${scope}.useHttpPath`, "true"]);
57903
- await unset(`url.${scope}github.com/.insteadOf`);
57904
- await git([
57905
- "config",
57906
- "--global",
57907
- "--add",
57908
- `url.${scope}github.com/.insteadOf`,
57909
- "https://github.com/"
57910
- ]);
57933
+ for (const host of GIT_GATEWAY_HTTPS_HOSTS) {
57934
+ await unset(`url.${scope}${host}/.insteadOf`);
57935
+ await git([
57936
+ "config",
57937
+ "--global",
57938
+ "--add",
57939
+ `url.${scope}${host}/.insteadOf`,
57940
+ `https://${host}/`
57941
+ ]);
57942
+ }
57911
57943
  const version2 = parseGitVersion((await git(["version"])).stdout);
57912
57944
  const proactiveAuth = supportsProactiveAuth(version2);
57913
57945
  if (proactiveAuth) {
@@ -58607,6 +58639,99 @@ function removeStaleEndpoint(endpoint) {
58607
58639
  if (!endpoint.startsWith("\\\\.\\pipe\\")) (0, import_node_fs6.rmSync)(endpoint, { force: true });
58608
58640
  }
58609
58641
 
58642
+ // src/platform/legacy-daemons.ts
58643
+ var LIST_TIMEOUT_MS = 15e3;
58644
+ var WINDOWS_PROCESS_QUERY = "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,CommandLine | ConvertTo-Json -Compress";
58645
+ var LEGACY_ENTRY = /(?:[\\/]agent-manager[\\/]dist[\\/]index\.cjs|[\\/]alan-agent[\\/]index\.cjs|[\\/]bin[\\/]alan-agent)["']?(?=\s)/i;
58646
+ var DAEMON_VERB = /\s["']?daemon["']?(?=\s|$)/;
58647
+ var PROFILE_FLAG = /\s--profile(?:=|\s+)["']?([\w-]+)/;
58648
+ var RUNTIME_V2 = /alan-agent\.cjs|alan-agent(?:-[\w-]+)?\.cmd/i;
58649
+ function parsePsOutput(stdout) {
58650
+ const processes = [];
58651
+ for (const line of stdout.split("\n")) {
58652
+ const match = /^\s*(\d+)\s+(\d+)\s+(.+)$/.exec(line);
58653
+ if (match?.[1] === void 0 || match[2] === void 0 || match[3] === void 0) continue;
58654
+ processes.push({ pid: Number(match[1]), ppid: Number(match[2]), command: match[3].trim() });
58655
+ }
58656
+ return processes;
58657
+ }
58658
+ function isWindowsProcessRow(value2) {
58659
+ return typeof value2 === "object" && value2 !== null;
58660
+ }
58661
+ function parseWindowsProcesses(stdout) {
58662
+ let parsed;
58663
+ try {
58664
+ parsed = JSON.parse(stdout);
58665
+ } catch {
58666
+ return [];
58667
+ }
58668
+ const rows = Array.isArray(parsed) ? parsed : [parsed];
58669
+ const processes = [];
58670
+ for (const row of rows) {
58671
+ if (!isWindowsProcessRow(row)) continue;
58672
+ const { ProcessId: pid, ParentProcessId: ppid, CommandLine: command } = row;
58673
+ if (typeof pid !== "number" || typeof ppid !== "number" || typeof command !== "string") {
58674
+ continue;
58675
+ }
58676
+ processes.push({ pid, ppid, command });
58677
+ }
58678
+ return processes;
58679
+ }
58680
+ async function listProcesses2(exec, platform3) {
58681
+ if (platform3 === "win32") {
58682
+ const result2 = await exec({
58683
+ command: "powershell.exe",
58684
+ args: ["-NoProfile", "-NonInteractive", "-Command", WINDOWS_PROCESS_QUERY],
58685
+ timeoutMs: LIST_TIMEOUT_MS
58686
+ });
58687
+ return result2.status === 0 ? parseWindowsProcesses(result2.stdout) : [];
58688
+ }
58689
+ const result = await exec({
58690
+ command: "ps",
58691
+ args: ["-axww", "-o", "pid=,ppid=,command="],
58692
+ timeoutMs: LIST_TIMEOUT_MS
58693
+ });
58694
+ return result.status === 0 ? parsePsOutput(result.stdout) : [];
58695
+ }
58696
+ function isLegacyDaemonCommand(command) {
58697
+ if (RUNTIME_V2.test(command)) return false;
58698
+ const entry = LEGACY_ENTRY.exec(command);
58699
+ if (entry === null) return false;
58700
+ return DAEMON_VERB.test(command.slice(entry.index + entry[0].length));
58701
+ }
58702
+ function legacyDaemonProfile(command) {
58703
+ return PROFILE_FLAG.exec(command)?.[1] ?? "production";
58704
+ }
58705
+ function legacyProfileClass(profile) {
58706
+ return profile === "production" || profile === "staging" ? profile : "development";
58707
+ }
58708
+ function hasRuntimeV2Descendant(pid, processes, seen = /* @__PURE__ */ new Set()) {
58709
+ for (const child of processes) {
58710
+ if (child.ppid !== pid || seen.has(child.pid)) continue;
58711
+ seen.add(child.pid);
58712
+ if (RUNTIME_V2.test(child.command) || hasRuntimeV2Descendant(child.pid, processes, seen)) {
58713
+ return true;
58714
+ }
58715
+ }
58716
+ return false;
58717
+ }
58718
+ function findLegacyDaemons(processes, options) {
58719
+ const profile = legacyProfileClass(options.profile);
58720
+ return processes.filter(
58721
+ (entry) => !options.exclude.has(entry.pid) && isLegacyDaemonCommand(entry.command) && legacyProfileClass(legacyDaemonProfile(entry.command)) === profile && !hasRuntimeV2Descendant(entry.pid, processes)
58722
+ );
58723
+ }
58724
+ function signalProcess(pid, signal) {
58725
+ try {
58726
+ process.kill(pid, signal);
58727
+ return true;
58728
+ } catch (error61) {
58729
+ const code = errnoCode(error61);
58730
+ if (code === "ESRCH" || code === "EPERM") return false;
58731
+ throw error61;
58732
+ }
58733
+ }
58734
+
58610
58735
  // src/platform/node-flags.ts
58611
58736
  var SERVICE_NODE_FLAGS = [
58612
58737
  "--max-semi-space-size=1",
@@ -63835,7 +63960,7 @@ function captureProbe(command, args, options) {
63835
63960
  windowsVerbatimArguments: launch.windowsVerbatimArguments
63836
63961
  });
63837
63962
  child.stdin?.end();
63838
- const terminate = () => {
63963
+ const terminate2 = () => {
63839
63964
  if (platform3 !== "win32" && child.pid !== void 0) {
63840
63965
  try {
63841
63966
  process.kill(-child.pid, "SIGKILL");
@@ -63860,7 +63985,7 @@ function captureProbe(command, args, options) {
63860
63985
  };
63861
63986
  void systemClock.sleep(options.timeoutMs ?? DEFAULT_TIMEOUT_MS2, deadlineController.signal).then(
63862
63987
  () => {
63863
- terminate();
63988
+ terminate2();
63864
63989
  child.stdout.destroy();
63865
63990
  child.stderr.destroy();
63866
63991
  finish(void 0);
@@ -63868,7 +63993,7 @@ function captureProbe(command, args, options) {
63868
63993
  () => void 0
63869
63994
  );
63870
63995
  const abort = () => {
63871
- terminate();
63996
+ terminate2();
63872
63997
  child.stdout.destroy();
63873
63998
  child.stderr.destroy();
63874
63999
  finish(void 0);
@@ -63879,7 +64004,7 @@ function captureProbe(command, args, options) {
63879
64004
  bytes += chunk.length;
63880
64005
  if (bytes > limit) {
63881
64006
  overflowed = true;
63882
- terminate();
64007
+ terminate2();
63883
64008
  finish(void 0);
63884
64009
  return;
63885
64010
  }
@@ -68609,7 +68734,7 @@ var import_promises58 = require("fs/promises");
68609
68734
  var import_node_path56 = require("path");
68610
68735
 
68611
68736
  // ../agent-core/dist/prompt.js
68612
- init_chunk_GI3ZGXTY();
68737
+ init_chunk_GW6CC6A3();
68613
68738
 
68614
68739
  // src/holder/agent-context.ts
68615
68740
  async function readText4(path4) {
@@ -71315,6 +71440,8 @@ init_runtime_v2();
71315
71440
  init_zod();
71316
71441
  var EXIT_POLL_MS = 200;
71317
71442
  var LEGACY_EXIT_WAIT_MS = 15e3;
71443
+ var TERMINATE_GRACE_MS = 5e3;
71444
+ var KILL_SETTLE_MS = 2e3;
71318
71445
  var SCRUBBED_KEYS = [
71319
71446
  "runtimeToken",
71320
71447
  "runtimeRenewalToken",
@@ -71342,20 +71469,53 @@ async function findLegacyInstall(home, profile) {
71342
71469
  const configPath = legacyConfigPath(home, profile);
71343
71470
  const config2 = await readJsonFile(configPath, legacyConfigSchema);
71344
71471
  if (config2.kind !== "ok") return null;
71345
- return { configPath, ownerLeasePath: `${configPath}.daemon-owner.json`, config: config2.value };
71472
+ return {
71473
+ profile,
71474
+ configPath,
71475
+ ownerLeasePath: `${configPath}.daemon-owner.json`,
71476
+ config: config2.value
71477
+ };
71346
71478
  }
71347
71479
  async function readOwnerPid(path4) {
71348
71480
  const lease = await readJsonFile(path4, ownerLeaseSchema);
71349
71481
  return lease.kind === "ok" ? lease.value.pid : null;
71350
71482
  }
71351
- async function waitForExit(pid, deps) {
71352
- const deadline = deps.clock.monotonic() + (deps.exitWaitMs ?? LEGACY_EXIT_WAIT_MS);
71353
- while (deps.isProcessAlive(pid)) {
71483
+ async function waitForExit(pids, waitMs, deps) {
71484
+ const deadline = deps.clock.monotonic() + waitMs;
71485
+ while (pids.some((pid) => deps.isProcessAlive(pid))) {
71354
71486
  if (deps.clock.monotonic() >= deadline) return false;
71355
71487
  await deps.clock.sleep(EXIT_POLL_MS, deps.signal);
71356
71488
  }
71357
71489
  return true;
71358
71490
  }
71491
+ function strayDaemons(processes, install2) {
71492
+ const exclude = /* @__PURE__ */ new Set([process.pid, process.ppid]);
71493
+ return findLegacyDaemons(processes, { profile: install2.profile, exclude }).map(
71494
+ (entry) => entry.pid
71495
+ );
71496
+ }
71497
+ async function terminate(pids, deps) {
71498
+ deps.log.warn("legacy.stopping_v1", { pids });
71499
+ for (const pid of pids) deps.signalProcess(pid, "SIGTERM");
71500
+ if (await waitForExit(pids, TERMINATE_GRACE_MS, deps)) return null;
71501
+ for (const pid of pids) {
71502
+ if (deps.isProcessAlive(pid)) deps.signalProcess(pid, "SIGKILL");
71503
+ }
71504
+ await waitForExit(pids, KILL_SETTLE_MS, deps);
71505
+ return pids.find((pid) => deps.isProcessAlive(pid)) ?? null;
71506
+ }
71507
+ async function stopLegacyDaemons(deps, leasePid) {
71508
+ const leaseRunning = leasePid !== null && !await waitForExit([leasePid], deps.exitWaitMs ?? LEGACY_EXIT_WAIT_MS, deps);
71509
+ const processes = await deps.listProcesses();
71510
+ const targets = strayDaemons(processes, deps.install);
71511
+ if (leaseRunning && !targets.includes(leasePid)) {
71512
+ const listed = processes.find((entry) => entry.pid === leasePid);
71513
+ if (listed === void 0) return deps.isProcessAlive(leasePid) ? leasePid : null;
71514
+ if (isLegacyDaemonCommand(listed.command)) targets.push(leasePid);
71515
+ else deps.log.info("legacy.lease_pid_reused", { pid: leasePid });
71516
+ }
71517
+ return targets.length === 0 ? null : terminate(targets, deps);
71518
+ }
71359
71519
  async function scrubLegacyInstall(install2) {
71360
71520
  const scrubbed = { ...install2.config, migratedToRuntimeV2: true };
71361
71521
  for (const key of SCRUBBED_KEYS) delete scrubbed[key];
@@ -71386,12 +71546,16 @@ async function migrateFromV1(deps) {
71386
71546
  const { install: install2, log } = deps;
71387
71547
  const pid = await readOwnerPid(install2.ownerLeasePath);
71388
71548
  if (deps.dryRun === true) {
71549
+ const strays = strayDaemons(await deps.listProcesses(), install2).filter(
71550
+ (stray) => stray !== pid
71551
+ );
71389
71552
  return {
71390
71553
  kind: "planned",
71391
71554
  steps: [
71392
71555
  `check that ${install2.config.apiUrl} serves the v2 machine routes`,
71393
71556
  "remove the v1 service",
71394
- pid === null ? "no v1 daemon lease" : `wait for v1 pid ${pid} to exit`,
71557
+ pid === null ? "no v1 daemon lease" : `wait for v1 pid ${pid} to exit, then stop it (SIGTERM, then SIGKILL)`,
71558
+ strays.length === 0 ? "no other v1 daemon running" : `stop the other v1 daemons (pids ${strays.join(", ")}): SIGTERM, then SIGKILL`,
71395
71559
  deps.setup === void 0 ? `renew the v1 credential of machine ${install2.config.runtimeId}` : `register machine ${install2.config.runtimeId} with the setup token`,
71396
71560
  "write machine.json and the credential",
71397
71561
  `scrub ${install2.configPath}`
@@ -71404,9 +71568,10 @@ async function migrateFromV1(deps) {
71404
71568
  }
71405
71569
  const removal = await deps.removeService();
71406
71570
  log.info("legacy.service_removed", { found: removal.found });
71407
- if (pid !== null && !await waitForExit(pid, deps)) {
71408
- log.warn("legacy.v1_still_running", { pid });
71409
- return { kind: "v1_still_running", pid };
71571
+ const running = await stopLegacyDaemons(deps, pid);
71572
+ if (running !== null) {
71573
+ log.warn("legacy.v1_still_running", { pid: running });
71574
+ return { kind: "v1_still_running", pid: running };
71410
71575
  }
71411
71576
  const grant = await exchangeCredential(deps);
71412
71577
  if (typeof grant === "string") {
@@ -72377,6 +72542,8 @@ async function adoptLegacyInstall(ctx, deps, adoption) {
72377
72542
  install: install2,
72378
72543
  removeService: () => removeLegacyService(ctx.host, ctx.config.profile),
72379
72544
  isProcessAlive: deps.isProcessAlive,
72545
+ listProcesses: () => listProcesses2(ctx.host.exec, ctx.host.platform),
72546
+ signalProcess,
72380
72547
  enrollment: deps.enrollment(install2.config.apiUrl),
72381
72548
  saveGrant: async (grant) => {
72382
72549
  await saveGrant({
@@ -78183,6 +78350,7 @@ init_zod();
78183
78350
  var RETRY_DELAYS_MS = [250, 500, 1e3, 2e3, 5e3, 1e4, 3e4];
78184
78351
  var PARK_MS = 5 * 6e4;
78185
78352
  var UNAUTHORIZED = 401;
78353
+ var RETRY_JITTER = 0.2;
78186
78354
  var uploadProgressSchema = external_exports.object({
78187
78355
  admittedOffset: external_exports.number().int().nonnegative(),
78188
78356
  sealed: external_exports.boolean(),
@@ -78190,17 +78358,50 @@ var uploadProgressSchema = external_exports.object({
78190
78358
  parkedUntil: external_exports.number().int().nonnegative().optional()
78191
78359
  });
78192
78360
  function progressFromReceipt(receipt) {
78193
- return { admittedOffset: receipt?.admittedOffset ?? 0, sealed: receipt?.finalized ?? false };
78361
+ return {
78362
+ admittedOffset: receipt?.admittedOffset ?? 0,
78363
+ sealed: receipt !== null && (receipt.finalized || receipt.finalOffset !== null)
78364
+ };
78194
78365
  }
78195
- function startUploader({ api, runsDir, clock, log, archive }) {
78366
+ function startUploader({
78367
+ api,
78368
+ runsDir,
78369
+ clock,
78370
+ log,
78371
+ archive,
78372
+ random = Math.random,
78373
+ onUnauthorized
78374
+ }) {
78196
78375
  const controller = new AbortController();
78197
78376
  const active = /* @__PURE__ */ new Map();
78198
78377
  const again = /* @__PURE__ */ new Set();
78199
78378
  const sealed = /* @__PURE__ */ new Set();
78200
78379
  const receiptBackoff = /* @__PURE__ */ new Map();
78380
+ let pendingRuns = /* @__PURE__ */ new Map();
78381
+ const retrying = /* @__PURE__ */ new Set();
78382
+ let renewing = null;
78383
+ const retryDelay = (failures) => {
78384
+ const base = RETRY_DELAYS_MS[Math.min(failures, RETRY_DELAYS_MS.length - 1)] ?? 3e4;
78385
+ return Math.round(base * (1 - RETRY_JITTER + 2 * RETRY_JITTER * random()));
78386
+ };
78387
+ const renewCredential = () => {
78388
+ if (onUnauthorized === void 0) return Promise.resolve();
78389
+ renewing ??= onUnauthorized().catch((error61) => log.warn("upload.renew_failed", { error: error61 })).finally(() => {
78390
+ renewing = null;
78391
+ });
78392
+ return renewing;
78393
+ };
78394
+ const deferReceipt = (runId) => {
78395
+ const failures = (receiptBackoff.get(runId)?.failures ?? 0) + 1;
78396
+ receiptBackoff.set(runId, { failures, notBefore: clock.now() + retryDelay(failures) });
78397
+ };
78201
78398
  const reject = async (runId, progressPath, progress, rejection2) => {
78202
78399
  log.error("upload.rejected", { runId, status: rejection2.status, message: rejection2.message });
78203
- if (rejection2.status === UNAUTHORIZED) return;
78400
+ if (rejection2.status === UNAUTHORIZED) {
78401
+ await renewCredential();
78402
+ deferReceipt(runId);
78403
+ return;
78404
+ }
78204
78405
  const parkedUntil = clock.now() + PARK_MS;
78205
78406
  await writeJsonFileAtomic(progressPath, { ...progress, parkedUntil });
78206
78407
  log.warn("upload.parked", { runId, parkedUntil });
@@ -78208,6 +78409,12 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78208
78409
  const progressOf = async (runId, target, path4) => {
78209
78410
  const stored = await readJsonFile(path4, uploadProgressSchema);
78210
78411
  if (stored.kind === "ok") return stored.value;
78412
+ const listed = pendingRuns.get(runId);
78413
+ if (listed !== void 0) {
78414
+ const progress = { admittedOffset: listed.admittedOffset, sealed: false };
78415
+ await writeJsonFileAtomic(path4, progress);
78416
+ return progress;
78417
+ }
78211
78418
  const receipt = await api.readReceipt(target, controller.signal);
78212
78419
  switch (receipt.kind) {
78213
78420
  case "read": {
@@ -78217,16 +78424,14 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78217
78424
  admittedOffset: receipt.receipt?.admittedOffset ?? 0
78218
78425
  });
78219
78426
  const progress = progressFromReceipt(receipt.receipt);
78220
- if (progress.sealed) await writeJsonFileAtomic(path4, progress);
78427
+ await writeJsonFileAtomic(path4, progress);
78221
78428
  return progress;
78222
78429
  }
78223
78430
  case "rejected":
78224
78431
  await reject(runId, path4, progressFromReceipt(null), receipt);
78225
78432
  return null;
78226
78433
  case "retry": {
78227
- const failures = (receiptBackoff.get(runId)?.failures ?? 0) + 1;
78228
- const delayMs = RETRY_DELAYS_MS[Math.min(failures, RETRY_DELAYS_MS.length - 1)] ?? 3e4;
78229
- receiptBackoff.set(runId, { failures, notBefore: clock.now() + delayMs });
78434
+ deferReceipt(runId);
78230
78435
  throw new RuntimeFault("io_failed", `Receipt request failed: ${receipt.status}`);
78231
78436
  }
78232
78437
  default:
@@ -78254,7 +78459,9 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78254
78459
  case "offset_conflict": {
78255
78460
  const receipt = await api.readReceipt(upload2.target, controller.signal);
78256
78461
  if (receipt.kind === "read") {
78257
- return { kind: "advanced", progress: progressFromReceipt(receipt.receipt) };
78462
+ const next = progressFromReceipt(receipt.receipt);
78463
+ await writeJsonFileAtomic(upload2.progressPath, next);
78464
+ return { kind: "advanced", progress: next };
78258
78465
  }
78259
78466
  return receipt.kind === "retry" ? receipt : { kind: "rejected", rejection: receipt };
78260
78467
  }
@@ -78267,7 +78474,7 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78267
78474
  }
78268
78475
  };
78269
78476
  const backOff = async (runId, status, failures) => {
78270
- const delay4 = RETRY_DELAYS_MS[Math.min(failures, RETRY_DELAYS_MS.length - 1)] ?? 3e4;
78477
+ const delay4 = retryDelay(failures);
78271
78478
  log.warn("upload.retrying", { runId, status, delayMs: delay4 });
78272
78479
  await clock.sleep(delay4, controller.signal);
78273
78480
  };
@@ -78277,10 +78484,10 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78277
78484
  let failures = 0;
78278
78485
  while (!controller.signal.aborted) {
78279
78486
  const step = await sendNext(runUpload, progress);
78280
- if (step.kind === "caught_up") return;
78487
+ if (step.kind === "caught_up") return "settled";
78281
78488
  if (step.kind === "rejected") {
78282
78489
  await reject(runId, runUpload.progressPath, progress, step.rejection);
78283
- return;
78490
+ return "retry_later";
78284
78491
  }
78285
78492
  if (step.kind === "retry") {
78286
78493
  await backOff(runId, step.status, failures);
@@ -78288,29 +78495,40 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78288
78495
  continue;
78289
78496
  }
78290
78497
  failures = 0;
78498
+ receiptBackoff.delete(runId);
78291
78499
  progress = step.progress;
78292
78500
  if (progress.sealed) {
78293
78501
  sealed.add(runId);
78294
78502
  log.info("upload.sealed", { runId, bytes: progress.admittedOffset });
78295
- return;
78503
+ return "settled";
78296
78504
  }
78297
78505
  }
78506
+ return "settled";
78298
78507
  };
78299
78508
  const upload = async (runId) => {
78300
78509
  var _stack = [];
78301
78510
  try {
78302
78511
  const dir = runDirectory(runsDir, runId);
78303
78512
  const meta3 = await readRunMeta(dir.meta);
78304
- if (meta3 === null) return;
78513
+ if (meta3 === null) return "settled";
78305
78514
  const target = { conversationId: meta3.conversationId, runId };
78306
78515
  const backoff = receiptBackoff.get(runId);
78307
- if (backoff !== void 0 && backoff.notBefore > clock.now()) return;
78516
+ if (backoff !== void 0 && backoff.notBefore > clock.now()) return "retry_later";
78308
78517
  const progress = await progressOf(runId, target, dir.upload);
78309
- if (progress?.sealed) sealed.add(runId);
78310
- if (progress === null || progress.sealed) return;
78311
- if (progress.parkedUntil !== void 0 && progress.parkedUntil > clock.now()) return;
78518
+ if (progress === null) return "retry_later";
78519
+ if (progress.sealed) {
78520
+ sealed.add(runId);
78521
+ return "settled";
78522
+ }
78523
+ if (progress.parkedUntil !== void 0 && progress.parkedUntil > clock.now()) {
78524
+ return "retry_later";
78525
+ }
78312
78526
  const reader = __using(_stack, await openRunLogReader(dir.log), true);
78313
- await drain({ target, reader, logPath: dir.log, progressPath: dir.upload }, progress);
78527
+ const attempt2 = await drain(
78528
+ { target, reader, logPath: dir.log, progressPath: dir.upload },
78529
+ progress
78530
+ );
78531
+ return attempt2;
78314
78532
  } catch (_) {
78315
78533
  var _error = _, _hasError = true;
78316
78534
  } finally {
@@ -78323,7 +78541,11 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78323
78541
  again.add(runId);
78324
78542
  return;
78325
78543
  }
78326
- const task = upload(runId).catch((error61) => {
78544
+ const task = upload(runId).then((attempt2) => {
78545
+ if (attempt2 === "settled") retrying.delete(runId);
78546
+ else retrying.add(runId);
78547
+ }).catch((error61) => {
78548
+ retrying.add(runId);
78327
78549
  if (!controller.signal.aborted) log.warn("upload.failed", { runId, error: error61 });
78328
78550
  }).finally(() => {
78329
78551
  active.delete(runId);
@@ -78331,17 +78553,25 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78331
78553
  });
78332
78554
  active.set(runId, task);
78333
78555
  };
78556
+ const isDone = (runId) => sealed.has(runId) || archive?.has(runId) === true;
78334
78557
  const unsealedRunIds = async () => {
78335
78558
  const runIds = [];
78336
78559
  for (const name of await (0, import_promises78.readdir)(runsDir).catch(() => [])) {
78337
78560
  const runId = runIdSchema.safeParse(name);
78338
- if (runId.success && !sealed.has(runId.data) && !archive?.has(runId.data))
78339
- runIds.push(runId.data);
78561
+ if (runId.success && !isDone(runId.data)) runIds.push(runId.data);
78340
78562
  }
78341
78563
  return runIds;
78342
78564
  };
78565
+ const hasProgress = async (runId) => await (0, import_promises78.stat)(runDirectory(runsDir, runId).upload).catch(() => null) !== null;
78343
78566
  const sweep2 = async () => {
78344
- for (const runId of await unsealedRunIds()) run2(runId);
78567
+ for (const runId of await unsealedRunIds()) {
78568
+ if (!await hasProgress(runId)) run2(runId);
78569
+ }
78570
+ };
78571
+ const retryPending = () => {
78572
+ for (const runId of /* @__PURE__ */ new Set([...pendingRuns.keys(), ...retrying])) {
78573
+ if (!isDone(runId)) run2(runId);
78574
+ }
78345
78575
  };
78346
78576
  const isArchivable = async (runId, options) => {
78347
78577
  if (options.keep.has(runId) || active.has(runId)) return false;
@@ -78368,9 +78598,15 @@ function startUploader({ api, runsDir, clock, log, archive }) {
78368
78598
  return {
78369
78599
  notify: run2,
78370
78600
  sweep: sweep2,
78601
+ pending: (uploads) => {
78602
+ pendingRuns = new Map(
78603
+ uploads.map((upload2) => [upload2.runId, upload2])
78604
+ );
78605
+ },
78606
+ retryPending,
78371
78607
  archivable,
78372
78608
  flush: async () => {
78373
- await sweep2();
78609
+ for (const runId of await unsealedRunIds()) run2(runId);
78374
78610
  while (active.size > 0 && !controller.signal.aborted) {
78375
78611
  await Promise.allSettled([...active.values()]);
78376
78612
  }
@@ -78719,7 +78955,7 @@ var CAPABILITY_MAX_AGE_MS = 6e4;
78719
78955
  var RUN_ARCHIVE_EVERY_MS = 6 * 60 * 6e4;
78720
78956
  var SEALED_RUN_ARCHIVE_MS = 7 * 24 * 60 * 6e4;
78721
78957
  var DESIRED_RESYNC_TICK_MS = 5e3;
78722
- var UPLOAD_SWEEP_EVERY_MS = 3e4;
78958
+ var UPLOAD_RETRY_EVERY_MS = 3e4;
78723
78959
  function setupFor(state) {
78724
78960
  if (state.kind !== "stopped") return "ready";
78725
78961
  switch (state.failure.reason) {
@@ -78760,6 +78996,13 @@ async function startMachinePlane(deps) {
78760
78996
  accessToken: identity.accessToken,
78761
78997
  transport
78762
78998
  });
78999
+ const renewAfterRejection = async () => {
79000
+ const renewal = await lifecycle.exclusive(
79001
+ "renew",
79002
+ () => identity.renewAfterRejection(stopped.signal)
79003
+ );
79004
+ if (renewal.kind === "revoked") deps.onRevoked();
79005
+ };
78763
79006
  const sessionsOpened = Promise.withResolvers();
78764
79007
  const planeOpened = Promise.withResolvers();
78765
79008
  const boot = { sessionsMs: 0, openedMs: 0 };
@@ -78780,7 +79023,8 @@ async function startMachinePlane(deps) {
78780
79023
  void skills.sync();
78781
79024
  desiredSync.received({
78782
79025
  runs: ack.desired.runs,
78783
- ...ack.approvedWorkspacePaths === void 0 ? {} : { approvedWorkspacePaths: ack.approvedWorkspacePaths }
79026
+ ...ack.approvedWorkspacePaths === void 0 ? {} : { approvedWorkspacePaths: ack.approvedWorkspacePaths },
79027
+ ...ack.desired.pendingUploads === void 0 ? {} : { pendingUploads: ack.desired.pendingUploads }
78784
79028
  });
78785
79029
  },
78786
79030
  onPoke: (poke) => {
@@ -78800,13 +79044,7 @@ async function startMachinePlane(deps) {
78800
79044
  refreshDesired();
78801
79045
  },
78802
79046
  onConnectRefused: (error61) => updates.connectRefused(error61),
78803
- refreshCredential: async () => {
78804
- const renewal = await lifecycle.exclusive(
78805
- "renew",
78806
- () => identity.renewAfterRejection(stopped.signal)
78807
- );
78808
- if (renewal.kind === "revoked") deps.onRevoked();
78809
- },
79047
+ refreshCredential: renewAfterRejection,
78810
79048
  onStateChange: deps.onStatusChange,
78811
79049
  answerWorkspaceQuery: (request2) => workspaces.answer(request2),
78812
79050
  respond: (request2) => sessions.respond(request2),
@@ -78860,7 +79098,16 @@ async function startMachinePlane(deps) {
78860
79098
  (error61) => log.warn("conversation_index.rebuild_failed", { error: error61 })
78861
79099
  );
78862
79100
  const archive = await openRunArchive(paths.runs);
78863
- const uploader = stack.use(startUploader({ api, runsDir: paths.runs, clock, log, archive }));
79101
+ const uploader = stack.use(
79102
+ startUploader({
79103
+ api,
79104
+ runsDir: paths.runs,
79105
+ clock,
79106
+ log,
79107
+ archive,
79108
+ onUnauthorized: renewAfterRejection
79109
+ })
79110
+ );
78864
79111
  const nativeIngest = stack.use(
78865
79112
  await startMachineNativeIngest({
78866
79113
  stateDir: paths.stateDir,
@@ -79034,8 +79281,8 @@ async function startMachinePlane(deps) {
79034
79281
  );
79035
79282
  stack.use(
79036
79283
  startMaintenance({
79037
- everyMs: UPLOAD_SWEEP_EVERY_MS,
79038
- jobs: [{ name: "uploader.sweep", run: () => uploader.sweep() }],
79284
+ everyMs: UPLOAD_RETRY_EVERY_MS,
79285
+ jobs: [{ name: "uploader.retry_pending", run: () => uploader.retryPending() }],
79039
79286
  clock,
79040
79287
  log
79041
79288
  })
@@ -79149,6 +79396,7 @@ async function startMachinePlane(deps) {
79149
79396
  const desiredSync = createDesiredSync({
79150
79397
  read: (etag, signal) => api.fetchDesiredIfChanged(etag, signal),
79151
79398
  apply: (desired) => {
79399
+ uploader.pending(desired.pendingUploads ?? []);
79152
79400
  void workspaces.learn(desired.runs, desired.approvedWorkspacePaths);
79153
79401
  void reconciler.reconcile(desired.runs);
79154
79402
  },
@@ -79789,8 +80037,9 @@ the code matches, and approve. Setup waits (polling every 5 s, slower if Alan as
79789
80037
  continues once approved; the code expires after 10 minutes and works once.
79790
80038
 
79791
80039
  A previous Alan agent (v1, \`ai.tryalan.agent\`) is moved over first, once its API is
79792
- confirmed to serve this runtime: its service is stopped and removed, setup waits until
79793
- its process has exited, and only then renews its credential, so a v1 daemon can never
80040
+ confirmed to serve this runtime: its service is stopped and removed, setup waits up to
80041
+ 15 s for its process to exit, then stops it and any other v1 daemon of the profile
80042
+ (SIGTERM, then SIGKILL), and only then renews its credential, so a v1 daemon can never
79794
80043
  trip the server's reuse detection. Its config.json is kept as config.json.migrated-v1
79795
80044
  with the tokens removed. Without --token, a v1 install is moved by renewing its
79796
80045
  credential, and a computer that is already set up just gets its service re-installed.
package/alan-holder.cjs CHANGED
@@ -19798,6 +19798,10 @@ var init_agent_context = __esm({
19798
19798
  installCommand: external_exports.string().max(8192).nullable(),
19799
19799
  startCommand: external_exports.string().max(8192).nullable(),
19800
19800
  imageBuildId: external_exports.guid().nullable(),
19801
+ /** The repository whose `.alan/` the image build reads; a branch build swaps only its branch. */
19802
+ primaryRepository: machinePathSchema.optional(),
19803
+ /** Where install steps and the start command run: the repository, or the workspace with several. */
19804
+ setupDirectory: machinePathSchema.optional(),
19801
19805
  /** The newest build when it is not the one sessions boot from. */
19802
19806
  pendingBuild: agentContextBuildSchema.optional(),
19803
19807
  /** Saved variable names; values never leave the API. */
@@ -20368,7 +20372,7 @@ var init_run_context = __esm({
20368
20372
  });
20369
20373
 
20370
20374
  // ../shared/dist/runtime-v2/desired-state.js
20371
- var repoLocalPathSchema, requestedCheckoutSchema, runSpecSchema, desiredRunSchema, desiredStateSchema;
20375
+ var repoLocalPathSchema, requestedCheckoutSchema, runSpecSchema, desiredRunSchema, pendingUploadSchema, desiredStateSchema;
20372
20376
  var init_desired_state = __esm({
20373
20377
  "../shared/dist/runtime-v2/desired-state.js"() {
20374
20378
  "use strict";
@@ -20438,10 +20442,17 @@ var init_desired_state = __esm({
20438
20442
  spec: runSpecSchema,
20439
20443
  abortRequested: external_exports.boolean()
20440
20444
  });
20445
+ pendingUploadSchema = external_exports.object({
20446
+ runId: runIdSchema,
20447
+ conversationId: conversationIdSchema,
20448
+ admittedOffset: external_exports.number().int().nonnegative()
20449
+ });
20441
20450
  desiredStateSchema = external_exports.object({
20442
20451
  runs: external_exports.array(desiredRunSchema),
20443
20452
  /** The machine's saved workspaces; replaces the previous server list on every read. */
20444
- approvedWorkspacePaths: external_exports.array(machinePathSchema).max(2e3).optional()
20453
+ approvedWorkspacePaths: external_exports.array(machinePathSchema).max(2e3).optional(),
20454
+ /** Absent from an older server: the runtime then uploads only on its own doorbell. */
20455
+ pendingUploads: external_exports.array(pendingUploadSchema).optional()
20445
20456
  });
20446
20457
  }
20447
20458
  });
@@ -23923,15 +23934,6 @@ var init_transcript_fold = __esm({
23923
23934
  }
23924
23935
  });
23925
23936
 
23926
- // ../shared/dist/agent/acp/transcript-live.js
23927
- var TRANSCRIPT_LIVE_BATCH_BYTES;
23928
- var init_transcript_live = __esm({
23929
- "../shared/dist/agent/acp/transcript-live.js"() {
23930
- "use strict";
23931
- TRANSCRIPT_LIVE_BATCH_BYTES = 32 * 1024;
23932
- }
23933
- });
23934
-
23935
23937
  // ../shared/dist/agent/acp/index.js
23936
23938
  var init_acp = __esm({
23937
23939
  "../shared/dist/agent/acp/index.js"() {
@@ -23952,7 +23954,6 @@ var init_acp = __esm({
23952
23954
  init_transcript_fold();
23953
23955
  init_transcript_http();
23954
23956
  init_transcript_ingestion();
23955
- init_transcript_live();
23956
23957
  init_types2();
23957
23958
  }
23958
23959
  });
@@ -25673,7 +25674,7 @@ var init_chunk_J2KTV5FP = __esm({
25673
25674
  }
25674
25675
  });
25675
25676
 
25676
- // ../agent-core/dist/chunk-GI3ZGXTY.js
25677
+ // ../agent-core/dist/chunk-GW6CC6A3.js
25677
25678
  function repositories(input2, context) {
25678
25679
  const problems = new Map(input2.problems.map((problem) => [problem.path, problem]));
25679
25680
  const listed = context?.repositories ?? [];
@@ -25734,7 +25735,12 @@ function environmentInstructions(environment, cwd) {
25734
25735
  );
25735
25736
  } else if (build?.status === "failed") {
25736
25737
  lines.push(
25737
- `The latest image build (${build.id}) failed; sessions still boot from the previous image.`
25738
+ environment.imageBuildId ? `The latest image build (${build.id}) failed; sessions still boot from the previous image.` : `The latest image build (${build.id}) failed; this environment has no image yet.`
25739
+ );
25740
+ }
25741
+ if (environment.primaryRepository && environment.setupDirectory) {
25742
+ lines.push(
25743
+ `Image builds read .alan/ from ${environment.primaryRepository}; install steps and the start command run from ${environment.setupDirectory}.`
25738
25744
  );
25739
25745
  }
25740
25746
  if (environment.variables.length > 0) {
@@ -25761,6 +25767,12 @@ function sessionKind(input2, context) {
25761
25767
  if (input2.spec.workflowExecutionId) return "workflow";
25762
25768
  return input2.spec.taskId ? "task" : "chat";
25763
25769
  }
25770
+ function setupPathsOf(environment) {
25771
+ return {
25772
+ ...environment.primaryRepository ? { primaryRepository: environment.primaryRepository } : {},
25773
+ ...environment.setupDirectory ? { setupDirectory: environment.setupDirectory } : {}
25774
+ };
25775
+ }
25764
25776
  function environmentOf(input2, context) {
25765
25777
  const environment = context?.environment;
25766
25778
  if (!environment) return void 0;
@@ -25771,6 +25783,7 @@ function environmentOf(input2, context) {
25771
25783
  installCommand: environment.installCommand,
25772
25784
  startCommand: environment.startCommand,
25773
25785
  imageBuildId: environment.imageBuildId,
25786
+ ...setupPathsOf(environment),
25774
25787
  ...environment.pendingBuild ? { pendingBuild: environment.pendingBuild } : {},
25775
25788
  variables: environment.variables,
25776
25789
  ...start ? { start: start.state === "not_configured" ? start : { ...start, log: input2.startLogPath } } : {}
@@ -25796,6 +25809,7 @@ function knownContext(snapshot) {
25796
25809
  installCommand: environment.installCommand,
25797
25810
  startCommand: environment.startCommand,
25798
25811
  imageBuildId: environment.imageBuildId,
25812
+ ...setupPathsOf(environment),
25799
25813
  ...environment.pendingBuild ? { pendingBuild: environment.pendingBuild } : {},
25800
25814
  variables: environment.variables
25801
25815
  }
@@ -25833,7 +25847,7 @@ function isScalar(value) {
25833
25847
  }
25834
25848
  function scalar(value) {
25835
25849
  if (typeof value !== "string") return String(value);
25836
- return PLAIN_SCALAR.test(value) ? value : JSON.stringify(value);
25850
+ return PLAIN_SCALAR.test(value) ? value : JSON.stringify(value).replaceAll("<", "\\u003c");
25837
25851
  }
25838
25852
  function snakeCase(key) {
25839
25853
  return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
@@ -26287,8 +26301,8 @@ ${body}` : body;
26287
26301
  return spec.mode === "plan" ? planModePrefix(prefixed) : prefixed;
26288
26302
  }
26289
26303
  var startCommandStateSchema, repositorySnapshotSchema, environmentSnapshotSchema, agentContextSnapshotSchema, BRANCH_REASONS, PLAIN_SCALAR, COMMAND_PREVIEW_CHARS, MAX_PARSED_ATTACHMENTS, MAX_PARSED_ATTACHMENT_CHARS, MAX_METADATA_CHARS, UNAVAILABLE, READ_ONLY_MODES, AGENT_MODES;
26290
- var init_chunk_GI3ZGXTY = __esm({
26291
- "../agent-core/dist/chunk-GI3ZGXTY.js"() {
26304
+ var init_chunk_GW6CC6A3 = __esm({
26305
+ "../agent-core/dist/chunk-GW6CC6A3.js"() {
26292
26306
  "use strict";
26293
26307
  init_runtime_v2();
26294
26308
  init_zod();
@@ -26317,6 +26331,8 @@ var init_chunk_GI3ZGXTY = __esm({
26317
26331
  installCommand: external_exports.string().nullable(),
26318
26332
  startCommand: external_exports.string().nullable(),
26319
26333
  imageBuildId: external_exports.string().nullable(),
26334
+ primaryRepository: external_exports.string().optional(),
26335
+ setupDirectory: external_exports.string().optional(),
26320
26336
  pendingBuild: agentContextBuildSchema.optional(),
26321
26337
  variables: external_exports.array(external_exports.string()),
26322
26338
  start: external_exports.intersection(startCommandStateSchema, external_exports.object({ log: external_exports.string().optional() })).optional()
@@ -27440,7 +27456,7 @@ var init_claude = __esm({
27440
27456
  init_chunk_ZCTKXKYY();
27441
27457
  init_chunk_J2KTV5FP();
27442
27458
  init_chunk_XE7BX6YP();
27443
- init_chunk_GI3ZGXTY();
27459
+ init_chunk_GW6CC6A3();
27444
27460
  init_chunk_YXWJW7I5();
27445
27461
  init_effort();
27446
27462
  import_crypto6 = require("crypto");
@@ -29658,7 +29674,7 @@ var init_codex = __esm({
29658
29674
  init_chunk_ZCTKXKYY();
29659
29675
  init_chunk_J2KTV5FP();
29660
29676
  init_chunk_XE7BX6YP();
29661
- init_chunk_GI3ZGXTY();
29677
+ init_chunk_GW6CC6A3();
29662
29678
  init_chunk_YXWJW7I5();
29663
29679
  import_fs6 = require("fs");
29664
29680
  import_path6 = require("path");
@@ -39246,7 +39262,7 @@ var init_acp3 = __esm({
39246
39262
  init_chunk_ZCTKXKYY();
39247
39263
  init_chunk_J2KTV5FP();
39248
39264
  init_chunk_XE7BX6YP();
39249
- init_chunk_GI3ZGXTY();
39265
+ init_chunk_GW6CC6A3();
39250
39266
  init_chunk_YXWJW7I5();
39251
39267
  import_promises24 = require("fs/promises");
39252
39268
  import_path9 = require("path");
@@ -41111,7 +41127,7 @@ var init_opencode = __esm({
41111
41127
  init_chunk_ZCTKXKYY();
41112
41128
  init_chunk_J2KTV5FP();
41113
41129
  init_chunk_XE7BX6YP();
41114
- init_chunk_GI3ZGXTY();
41130
+ init_chunk_GW6CC6A3();
41115
41131
  init_chunk_YXWJW7I5();
41116
41132
  import_http4 = require("http");
41117
41133
  init_runtime_v2();
@@ -42945,7 +42961,7 @@ var init_droid = __esm({
42945
42961
  init_chunk_ZCTKXKYY();
42946
42962
  init_chunk_J2KTV5FP();
42947
42963
  init_chunk_XE7BX6YP();
42948
- init_chunk_GI3ZGXTY();
42964
+ init_chunk_GW6CC6A3();
42949
42965
  init_chunk_YXWJW7I5();
42950
42966
  init_runtime_v2();
42951
42967
  import_crypto16 = require("crypto");
@@ -44054,7 +44070,7 @@ var init_antigravity = __esm({
44054
44070
  init_chunk_XC5676SG();
44055
44071
  init_chunk_ZCTKXKYY();
44056
44072
  init_chunk_XE7BX6YP();
44057
- init_chunk_GI3ZGXTY();
44073
+ init_chunk_GW6CC6A3();
44058
44074
  init_chunk_YXWJW7I5();
44059
44075
  import_promises28 = require("fs/promises");
44060
44076
  import_path12 = require("path");
@@ -44759,7 +44775,7 @@ var init_command_code = __esm({
44759
44775
  init_chunk_ZCTKXKYY();
44760
44776
  init_chunk_J2KTV5FP();
44761
44777
  init_chunk_XE7BX6YP();
44762
- init_chunk_GI3ZGXTY();
44778
+ init_chunk_GW6CC6A3();
44763
44779
  init_chunk_YXWJW7I5();
44764
44780
  import_promises29 = require("fs/promises");
44765
44781
  import_path15 = require("path");
@@ -47832,7 +47848,7 @@ var import_promises32 = require("fs/promises");
47832
47848
  var import_node_path21 = require("path");
47833
47849
 
47834
47850
  // ../agent-core/dist/prompt.js
47835
- init_chunk_GI3ZGXTY();
47851
+ init_chunk_GW6CC6A3();
47836
47852
 
47837
47853
  // src/holder/agent-context.ts
47838
47854
  async function readText2(path) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alan-ai-hq/agent-manager-darwin-arm64",
3
- "version": "0.1.152",
3
+ "version": "0.1.153",
4
4
  "description": "Alan machine runtime (alan-agent) for one platform: the official Node.js binary, the runtime bundle and its launcher. Installed by @alan-ai-hq/agent-manager.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://tryalan.ai",