@alan-ai-hq/agent-manager-darwin-arm64 0.1.139 → 0.1.140

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
@@ -22075,13 +22075,9 @@ So when a turn depends on something the repository cannot tell you \u2014 a valu
22075
22075
  What comes back is the answer, not a step towards it. Carry its specifics into what you write or change \u2014 the value, the constraint, the reason, the person \u2014 and say plainly when the evidence contradicts what was asked for. Retrieving a decision and then producing work that ignores it is worse than never having searched, because it looks informed.
22076
22076
 
22077
22077
  Skip it when nothing team-specific is at stake: source-code questions, general knowledge, mechanical work fully specified in the request, or an exact ID already in hand.`;
22078
- ALAN_PLATFORM_TOOL_ROUTING_PROMPT = `## Alan platform tools
22078
+ ALAN_PLATFORM_TOOL_ROUTING_PROMPT = `## Alan platform and GitHub
22079
22079
 
22080
- Use the matching Alan MCP tool to retrieve or change canonical Alan records \u2014 tasks, sessions, documents, artifacts, and their relationships \u2014 to perform Alan platform actions such as managing runs or machines, or to act through a provider identity connected to Alan. This applies whether the agent runs locally or in the cloud. Do not use a shell CLI, browser, raw HTTP, or local files to bypass an unavailable or unauthorized Alan MCP action; those paths bypass Alan's identity, authorization, audit trail, and task linkage.
22081
-
22082
- Use computer use and browser tools for authorized product debugging and QA, including inspecting the authenticated Alan app, its transient DOM and CSS state, and exercising UI flows in development or test environments. These tools are also available for ordinary browser and computer tasks outside Alan. Use local tools for repository, process, and log diagnostics. Exercising a UI for QA is not a substitute for carrying out a blocked platform record action.
22083
-
22084
- A tool missing from the currently offered set is not proof that it is unavailable. Use the host's tool-discovery mechanism once. If the tool is still not exposed, or its call reports unavailable or unauthorized, name the blocked capability and stop that platform action only; continue independent debugging and testing. Do not bypass a workflow or role tool allowlist.`;
22080
+ Use Alan MCP tools for canonical Alan records and platform actions: tasks, sessions, documents, artifacts, runs, and machines. Use the available repository tools for GitHub work, including git and gh when useful. If a cloud GitHub request reports github_not_connected, call request_github_connection in the current conversation and end the turn. The chat will offer GitHub authorization and resume after the user connects. Continue other independent work when possible.`;
22085
22081
  ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end \u2014 plan, write, review, test, deploy.
22086
22082
 
22087
22083
  ## How Alan is structured
@@ -22119,10 +22115,10 @@ Team
22119
22115
 
22120
22116
  ${ALAN_PLATFORM_TOOL_ROUTING_PROMPT}
22121
22117
 
22122
- ## Record & Entity Resolution (Tasks, PRs, Docs, Epics)
22118
+ ## Record & Entity Resolution (Tasks, Docs, Epics)
22123
22119
 
22124
- When the user refers to a specific task, pull request, document, or epic by human identifier (e.g. \`AL-2980\`, \`2980\`, \`#45\`), title, or topic phrase:
22125
- - **Always resolve it with \`find_records\` first** (pass \`kinds: ["task"]\`, \`["document"]\`, \`["pull_request"]\`, or \`["epic"]\`).
22120
+ When the user refers to a specific task, document, or epic by human identifier (e.g. \`AL-2980\`, \`2980\`), title, or topic phrase:
22121
+ - **Always resolve it with \`find_records\` first** (pass \`kinds: ["task"]\`, \`["document"]\`, or \`["epic"]\`).
22126
22122
  - **Never scan with \`list_tasks\` or \`list_epics\`** to locate a specific item whose number or title you were already given \u2014 list tools are strictly for paginating browsable boards of work, not for lookup.
22127
22123
  - Once \`find_records\` returns the entity, call \`get_task\` / \`get_epic\` / \`get_document\` with the resolved identifier or UUID if full relational details, comments, or subtasks are required.
22128
22124
 
@@ -22614,8 +22610,8 @@ function decode3(bytes, start, end) {
22614
22610
  }
22615
22611
  async function linuxStartTicks(pid) {
22616
22612
  try {
22617
- const stat21 = await (0, import_promises9.readFile)(`/proc/${pid}/stat`, "utf8");
22618
- const fields = stat21.slice(stat21.lastIndexOf(")") + 2).split(" ");
22613
+ const stat22 = await (0, import_promises9.readFile)(`/proc/${pid}/stat`, "utf8");
22614
+ const fields = stat22.slice(stat22.lastIndexOf(")") + 2).split(" ");
22619
22615
  return fields[19];
22620
22616
  } catch {
22621
22617
  return void 0;
@@ -24662,35 +24658,99 @@ var init_reduce = __esm({
24662
24658
  });
24663
24659
 
24664
24660
  // ../shared/dist/agent/acp/conversation-messages.js
24661
+ function hasProviderCopy(meta3) {
24662
+ return Object.keys(meta3).some((key) => PROVIDER_COPY_META_KEYS.has(key));
24663
+ }
24664
+ function withoutProviderCopies(meta3) {
24665
+ return Object.fromEntries(Object.entries(meta3).filter(([key]) => !PROVIDER_COPY_META_KEYS.has(key)));
24666
+ }
24667
+ function toolContentText(content) {
24668
+ if (!Array.isArray(content))
24669
+ return null;
24670
+ const parts4 = [];
24671
+ for (const block of content) {
24672
+ const inner = isRecord8(block) && block.type === "content" ? block.content : block;
24673
+ if (!isRecord8(inner) || typeof inner.text !== "string")
24674
+ return null;
24675
+ parts4.push(inner.text);
24676
+ }
24677
+ return parts4.join("\n");
24678
+ }
24679
+ function parsedFromRawOutput(update) {
24680
+ const name = typeof update.name === "string" ? update.name : typeof update.title === "string" ? update.title : "";
24681
+ if (isAskUserQuestionTool(name, update.rawInput))
24682
+ return true;
24683
+ const input2 = typeof update.rawInput === "string" ? update.rawInput : JSON.stringify(update.rawInput ?? null);
24684
+ return /search_?context/i.test(`${name} ${input2}`.replace(/search_?code_?context/gi, ""));
24685
+ }
24686
+ function repeatsContent(update) {
24687
+ const output2 = update.rawOutput;
24688
+ if (typeof output2 !== "string" || output2.length === 0)
24689
+ return false;
24690
+ return output2 === toolContentText(update.content) && !parsedFromRawOutput(update);
24691
+ }
24692
+ function withoutProviderCopiesOf(value2) {
24693
+ if (!value2._meta || !hasProviderCopy(value2._meta))
24694
+ return value2;
24695
+ return { ...value2, _meta: withoutProviderCopies(value2._meta) };
24696
+ }
24697
+ function pageUpdate(update) {
24698
+ const meta3 = isRecord8(update._meta) ? update._meta : void 0;
24699
+ const dropPayload = meta3 !== void 0 && hasProviderCopy(meta3);
24700
+ const dropOutput = repeatsContent(update);
24701
+ if (!dropPayload && !dropOutput)
24702
+ return update;
24703
+ const entries = Object.entries(update).filter(([key]) => !(dropOutput && key === "rawOutput") && !(dropPayload && key === "_meta"));
24704
+ const slim = {
24705
+ ...Object.fromEntries(entries),
24706
+ sessionUpdate: update.sessionUpdate
24707
+ };
24708
+ if (dropPayload && meta3 !== void 0) {
24709
+ slim._meta = withoutProviderCopies(meta3);
24710
+ }
24711
+ return slim;
24712
+ }
24713
+ function pageNode(node2) {
24714
+ return {
24715
+ ...node2,
24716
+ event: { ...node2.event, update: pageUpdate(node2.event.update) },
24717
+ children: node2.children.map(pageNode)
24718
+ };
24719
+ }
24665
24720
  function compactConversationMessageTurns(turns, keepNewestEntries) {
24666
24721
  return turns.map((turn, index) => ({
24667
24722
  ...turn,
24668
24723
  display: turn.display.map((displayTurn) => {
24724
+ const working = displayTurn.working.map(pageNode);
24669
24725
  if (!displayTurn.final)
24670
- return displayTurn;
24726
+ return { ...displayTurn, working };
24671
24727
  return {
24672
24728
  ...displayTurn,
24673
- working: displayTurn.working.map((node2) => node2.key === displayTurn.final?.key ? {
24729
+ working: working.map((node2) => node2.key === displayTurn.final?.key ? {
24674
24730
  ...node2,
24675
24731
  children: [],
24676
24732
  event: {
24677
24733
  ...node2.event,
24678
24734
  update: { ...node2.event.update, content: [] }
24679
24735
  }
24680
- } : node2)
24736
+ } : node2),
24737
+ final: pageNode(displayTurn.final)
24681
24738
  };
24682
24739
  }),
24683
24740
  state: {
24684
24741
  ...turn.state,
24742
+ // Readers use only media updates from `unknown`; a provider's command list alone was 77 KB.
24743
+ unknown: turn.state.unknown.filter((update) => MEDIA_SESSION_UPDATE_KINDS.has(update.sessionUpdate)),
24685
24744
  entries: index === 0 && keepNewestEntries ? turn.state.entries.map((entry) => {
24686
- if (entry.kind === "message")
24687
- return entry.role === "user" ? entry : { ...entry, content: [] };
24688
- const ask = isAskUserQuestionTool(entry.title || entry.toolKind, entry.rawInput);
24745
+ const kept = withoutProviderCopiesOf(entry);
24746
+ if (kept.kind === "message")
24747
+ return kept.role === "user" ? kept : { ...kept, content: [] };
24748
+ const ask = isAskUserQuestionTool(kept.title || kept.toolKind, kept.rawInput);
24689
24749
  return {
24690
- ...entry,
24750
+ ...kept,
24691
24751
  content: [],
24692
24752
  locations: [],
24693
- rawInput: ask ? entry.rawInput : void 0,
24753
+ rawInput: ask ? kept.rawInput : void 0,
24694
24754
  rawOutput: void 0
24695
24755
  };
24696
24756
  }) : []
@@ -24850,7 +24910,7 @@ function isConversationMessageTurn(value2) {
24850
24910
  function isConversationMessagesPage(value2) {
24851
24911
  return isRecord8(value2) && typeof value2.revision === "string" && typeof value2.streamCursor === "string" && (value2.before === null || typeof value2.before === "string") && Array.isArray(value2.turns) && value2.turns.every(isConversationMessageTurn);
24852
24912
  }
24853
- var LIVE_TURN_FRAMES, LIVE_TURN_EVENT, SENT_LIVE_TURNS;
24913
+ var PROVIDER_PAYLOAD_META_KEY, PROVIDER_EVENT_META_KEY, PROVIDER_COPY_META_KEYS, LIVE_TURN_FRAMES, LIVE_TURN_EVENT, SENT_LIVE_TURNS;
24854
24914
  var init_conversation_messages = __esm({
24855
24915
  "../shared/dist/agent/acp/conversation-messages.js"() {
24856
24916
  "use strict";
@@ -24861,6 +24921,13 @@ var init_conversation_messages = __esm({
24861
24921
  init_prepare_conversation_turns();
24862
24922
  init_reduce();
24863
24923
  init_transcript_http();
24924
+ init_types2();
24925
+ PROVIDER_PAYLOAD_META_KEY = "alan.dev/providerPayload";
24926
+ PROVIDER_EVENT_META_KEY = "alan.dev/providerEvent";
24927
+ PROVIDER_COPY_META_KEYS = /* @__PURE__ */ new Set([
24928
+ PROVIDER_PAYLOAD_META_KEY,
24929
+ PROVIDER_EVENT_META_KEY
24930
+ ]);
24864
24931
  LIVE_TURN_FRAMES = "patch";
24865
24932
  LIVE_TURN_EVENT = "live_turn";
24866
24933
  SENT_LIVE_TURNS = 8;
@@ -25091,7 +25158,7 @@ var init_acp = __esm({
25091
25158
  }
25092
25159
  });
25093
25160
 
25094
- // ../agent-core/dist/chunk-UGRKZTAD.js
25161
+ // ../agent-core/dist/chunk-XC5676SG.js
25095
25162
  function textBlock(text2) {
25096
25163
  return { type: "text", text: text2 };
25097
25164
  }
@@ -25322,13 +25389,13 @@ function withoutInlineMedia(update) {
25322
25389
  };
25323
25390
  }
25324
25391
  var PROVIDER_PAYLOAD_META, TOOL_RESULT_ONLY_META, PARENT_TOOL_CALL_META, SUBAGENT_LAUNCHER_META, SUBAGENT_TASK_ID_META, SUBAGENT_OUTPUT_FILE_META, USAGE_META, TODOS_META, NOTICE_KIND_META, ASK_USER_QUESTIONS_META, USER_ANSWER_META, AWAITING_TOOL_CALLS_META2, EXIT_PLAN_MODE_INPUT_META, BACKGROUND_TASK_META, TASK_PROGRESS_META, RATE_LIMIT_META, MODEL_META, TOOLS_META, SLASH_COMMANDS_META, TOOL_KIND_RULES, ANSWER_PREFIX, ACCEPT_WORDS, MIN_INLINE_MEDIA_CHARS, DATA_URL_PREFIX, BASE64_BODY;
25325
- var init_chunk_UGRKZTAD = __esm({
25326
- "../agent-core/dist/chunk-UGRKZTAD.js"() {
25392
+ var init_chunk_XC5676SG = __esm({
25393
+ "../agent-core/dist/chunk-XC5676SG.js"() {
25327
25394
  "use strict";
25328
25395
  init_chunk_YXWJW7I5();
25329
25396
  init_constants();
25330
25397
  init_acp();
25331
- PROVIDER_PAYLOAD_META = "alan.dev/providerPayload";
25398
+ PROVIDER_PAYLOAD_META = PROVIDER_PAYLOAD_META_KEY;
25332
25399
  TOOL_RESULT_ONLY_META = "alan.dev/toolResultOnly";
25333
25400
  PARENT_TOOL_CALL_META = "alan.dev/parentToolCallId";
25334
25401
  SUBAGENT_LAUNCHER_META = "alan.dev/subagentLauncher";
@@ -25373,12 +25440,12 @@ var init_chunk_UGRKZTAD = __esm({
25373
25440
  var init_acp2 = __esm({
25374
25441
  "../agent-core/dist/acp.js"() {
25375
25442
  "use strict";
25376
- init_chunk_UGRKZTAD();
25443
+ init_chunk_XC5676SG();
25377
25444
  init_chunk_YXWJW7I5();
25378
25445
  }
25379
25446
  });
25380
25447
 
25381
- // ../agent-core/dist/chunk-DALFHI4B.js
25448
+ // ../agent-core/dist/chunk-SBT5W7L4.js
25382
25449
  function isRecordValue(value2) {
25383
25450
  return value2 !== null;
25384
25451
  }
@@ -25557,10 +25624,10 @@ function readTranscriptTurns(transcript, chunk, baseOffset, skipped = []) {
25557
25624
  return { turns, consumedBytes: consumedEnd - baseOffset };
25558
25625
  }
25559
25626
  var import_fs3, NEWLINE2, TranscriptCursor, TranscriptLineLookup, CONTENT_UPDATES;
25560
- var init_chunk_DALFHI4B = __esm({
25561
- "../agent-core/dist/chunk-DALFHI4B.js"() {
25627
+ var init_chunk_SBT5W7L4 = __esm({
25628
+ "../agent-core/dist/chunk-SBT5W7L4.js"() {
25562
25629
  "use strict";
25563
- init_chunk_UGRKZTAD();
25630
+ init_chunk_XC5676SG();
25564
25631
  init_chunk_YXWJW7I5();
25565
25632
  import_fs3 = require("fs");
25566
25633
  NEWLINE2 = 10;
@@ -26113,7 +26180,7 @@ var init_chunk_54ZRJOQP = __esm({
26113
26180
  }
26114
26181
  });
26115
26182
 
26116
- // ../agent-core/dist/chunk-KHYYC5IN.js
26183
+ // ../agent-core/dist/chunk-VMGVHPBB.js
26117
26184
  function collectStrings(value2, out) {
26118
26185
  if (typeof value2 === "string") out.push(value2);
26119
26186
  else if (Array.isArray(value2)) for (const item of value2) collectStrings(item, out);
@@ -26205,8 +26272,8 @@ function readMediaFiles(candidates2, cwd, mimeByExt, maxBytes) {
26205
26272
  seen.add(path4);
26206
26273
  const mimeType = mimeByExt[(0, import_path3.extname)(path4).toLowerCase()];
26207
26274
  if (!mimeType) continue;
26208
- const stat21 = (0, import_fs4.statSync)(path4);
26209
- if (!stat21.isFile() || stat21.size <= 0 || stat21.size > maxBytes) continue;
26275
+ const stat22 = (0, import_fs4.statSync)(path4);
26276
+ if (!stat22.isFile() || stat22.size <= 0 || stat22.size > maxBytes) continue;
26210
26277
  files.push({ path: path4, mimeType, buffer: (0, import_fs4.readFileSync)(path4) });
26211
26278
  }
26212
26279
  return files;
@@ -26483,10 +26550,10 @@ function silentStartError(name, timeoutMs) {
26483
26550
  };
26484
26551
  }
26485
26552
  var import_crypto3, import_fs4, import_path3, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
26486
- var init_chunk_KHYYC5IN = __esm({
26487
- "../agent-core/dist/chunk-KHYYC5IN.js"() {
26553
+ var init_chunk_VMGVHPBB = __esm({
26554
+ "../agent-core/dist/chunk-VMGVHPBB.js"() {
26488
26555
  "use strict";
26489
- init_chunk_UGRKZTAD();
26556
+ init_chunk_XC5676SG();
26490
26557
  init_chunk_54ZRJOQP();
26491
26558
  init_chunk_M6YHY2EZ();
26492
26559
  init_chunk_YXWJW7I5();
@@ -28581,9 +28648,9 @@ var import_crypto6, import_fs5, import_path5, import_crypto7, import_promises31,
28581
28648
  var init_claude = __esm({
28582
28649
  "../agent-core/dist/providers/claude.js"() {
28583
28650
  "use strict";
28584
- init_chunk_DALFHI4B();
28585
- init_chunk_KHYYC5IN();
28586
- init_chunk_UGRKZTAD();
28651
+ init_chunk_SBT5W7L4();
28652
+ init_chunk_VMGVHPBB();
28653
+ init_chunk_XC5676SG();
28587
28654
  init_chunk_54ZRJOQP();
28588
28655
  init_chunk_J2KTV5FP();
28589
28656
  init_chunk_M6YHY2EZ();
@@ -31369,9 +31436,9 @@ var import_fs6, import_path6, import_crypto8, import_crypto9, import_crypto10, T
31369
31436
  var init_codex = __esm({
31370
31437
  "../agent-core/dist/providers/codex.js"() {
31371
31438
  "use strict";
31372
- init_chunk_DALFHI4B();
31373
- init_chunk_KHYYC5IN();
31374
- init_chunk_UGRKZTAD();
31439
+ init_chunk_SBT5W7L4();
31440
+ init_chunk_VMGVHPBB();
31441
+ init_chunk_XC5676SG();
31375
31442
  init_chunk_54ZRJOQP();
31376
31443
  init_chunk_J2KTV5FP();
31377
31444
  init_chunk_M6YHY2EZ();
@@ -42640,8 +42707,8 @@ var require_tar_stream = __commonJS({
42640
42707
  var init_dist = __esm({
42641
42708
  "../agent-core/dist/index.js"() {
42642
42709
  "use strict";
42643
- init_chunk_KHYYC5IN();
42644
- init_chunk_UGRKZTAD();
42710
+ init_chunk_VMGVHPBB();
42711
+ init_chunk_XC5676SG();
42645
42712
  init_chunk_54ZRJOQP();
42646
42713
  init_chunk_M6YHY2EZ();
42647
42714
  init_chunk_YXWJW7I5();
@@ -43387,8 +43454,8 @@ var import_promises48, import_path9, import_crypto12, import_promises49, CURSOR_
43387
43454
  var init_acp3 = __esm({
43388
43455
  "../agent-core/dist/providers/acp.js"() {
43389
43456
  "use strict";
43390
- init_chunk_KHYYC5IN();
43391
- init_chunk_UGRKZTAD();
43457
+ init_chunk_VMGVHPBB();
43458
+ init_chunk_XC5676SG();
43392
43459
  init_chunk_54ZRJOQP();
43393
43460
  init_chunk_J2KTV5FP();
43394
43461
  init_chunk_M6YHY2EZ();
@@ -45093,8 +45160,8 @@ var import_http10, import_crypto13, import_promises50, import_path10, import_pat
45093
45160
  var init_opencode = __esm({
45094
45161
  "../agent-core/dist/providers/opencode.js"() {
45095
45162
  "use strict";
45096
- init_chunk_KHYYC5IN();
45097
- init_chunk_UGRKZTAD();
45163
+ init_chunk_VMGVHPBB();
45164
+ init_chunk_XC5676SG();
45098
45165
  init_chunk_54ZRJOQP();
45099
45166
  init_chunk_J2KTV5FP();
45100
45167
  init_chunk_M6YHY2EZ();
@@ -45109,6 +45176,7 @@ var init_opencode = __esm({
45109
45176
  import_path11 = require("path");
45110
45177
  import_url2 = require("url");
45111
45178
  init_acp();
45179
+ init_acp();
45112
45180
  import_crypto14 = require("crypto");
45113
45181
  init_agent2();
45114
45182
  IDLE_SOCKET_MS3 = 4e3;
@@ -45427,7 +45495,7 @@ var init_opencode = __esm({
45427
45495
  ["DataPolicyError", "model_mismatch"]
45428
45496
  ]);
45429
45497
  OPENCODE_ABORTED_ERROR = "MessageAbortedError";
45430
- PROVIDER_EVENT_META = "alan.dev/providerEvent";
45498
+ PROVIDER_EVENT_META = PROVIDER_EVENT_META_KEY;
45431
45499
  TASK_TOOL_NAME = "task";
45432
45500
  TASK_RESULT_TAG = /<task_result>\n?([\s\S]*?)\n?<\/task_result>/;
45433
45501
  TASK_ERROR_TAG = /<task_error>\n?([\s\S]*?)\n?<\/task_error>/;
@@ -46901,8 +46969,8 @@ var import_crypto15, import_promises51, FACTORY_API_VERSION, FACTORY_PROTOCOL_VE
46901
46969
  var init_droid = __esm({
46902
46970
  "../agent-core/dist/providers/droid.js"() {
46903
46971
  "use strict";
46904
- init_chunk_KHYYC5IN();
46905
- init_chunk_UGRKZTAD();
46972
+ init_chunk_VMGVHPBB();
46973
+ init_chunk_XC5676SG();
46906
46974
  init_chunk_54ZRJOQP();
46907
46975
  init_chunk_J2KTV5FP();
46908
46976
  init_chunk_M6YHY2EZ();
@@ -48003,9 +48071,9 @@ var import_promises52, import_path12, import_fs8, import_path13, import_path14,
48003
48071
  var init_antigravity = __esm({
48004
48072
  "../agent-core/dist/providers/antigravity.js"() {
48005
48073
  "use strict";
48006
- init_chunk_DALFHI4B();
48007
- init_chunk_KHYYC5IN();
48008
- init_chunk_UGRKZTAD();
48074
+ init_chunk_SBT5W7L4();
48075
+ init_chunk_VMGVHPBB();
48076
+ init_chunk_XC5676SG();
48009
48077
  init_chunk_54ZRJOQP();
48010
48078
  init_chunk_M6YHY2EZ();
48011
48079
  init_chunk_ITTV3UIM();
@@ -48708,8 +48776,8 @@ var import_promises53, import_path15, import_crypto17, COMMAND_CODE_GRAMMAR_NAME
48708
48776
  var init_command_code = __esm({
48709
48777
  "../agent-core/dist/providers/command-code.js"() {
48710
48778
  "use strict";
48711
- init_chunk_KHYYC5IN();
48712
- init_chunk_UGRKZTAD();
48779
+ init_chunk_VMGVHPBB();
48780
+ init_chunk_XC5676SG();
48713
48781
  init_chunk_54ZRJOQP();
48714
48782
  init_chunk_J2KTV5FP();
48715
48783
  init_chunk_M6YHY2EZ();
@@ -54111,7 +54179,7 @@ var require_websocket_server = __commonJS({
54111
54179
  // package.json
54112
54180
  var package_default = {
54113
54181
  name: "@alan-ai-hq/agent-manager",
54114
- version: "0.1.139",
54182
+ version: "0.1.140",
54115
54183
  private: true,
54116
54184
  type: "module",
54117
54185
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -54161,7 +54229,7 @@ var package_default = {
54161
54229
 
54162
54230
  // src/cli/commands/compat.ts
54163
54231
  var import_node_crypto31 = require("crypto");
54164
- var import_promises66 = require("fs/promises");
54232
+ var import_promises67 = require("fs/promises");
54165
54233
  init_runtime_v2();
54166
54234
  init_zod();
54167
54235
 
@@ -56890,9 +56958,9 @@ function isProcessAlive(pid) {
56890
56958
  }
56891
56959
  }
56892
56960
  async function linuxStartTime(pid) {
56893
- const stat21 = await (0, import_promises13.readFile)(`/proc/${pid}/stat`, "utf8").catch(() => null);
56894
- if (stat21 === null) return null;
56895
- const fields = stat21.slice(stat21.lastIndexOf(")") + 2).split(" ");
56961
+ const stat22 = await (0, import_promises13.readFile)(`/proc/${pid}/stat`, "utf8").catch(() => null);
56962
+ if (stat22 === null) return null;
56963
+ const fields = stat22.slice(stat22.lastIndexOf(")") + 2).split(" ");
56896
56964
  return fields[19] ?? null;
56897
56965
  }
56898
56966
  async function linuxCommand(pid) {
@@ -65836,7 +65904,7 @@ async function openWorkspaces(options) {
65836
65904
 
65837
65905
  // src/cli/config.ts
65838
65906
  var import_node_os11 = require("os");
65839
- var import_node_path65 = require("path");
65907
+ var import_node_path66 = require("path");
65840
65908
  init_zod();
65841
65909
 
65842
65910
  // src/client/contract.ts
@@ -66563,9 +66631,9 @@ async function sendNativeHookSignal(discoveryPath, hookSignal, signal) {
66563
66631
 
66564
66632
  // src/sessions/index.ts
66565
66633
  var import_node_crypto30 = require("crypto");
66566
- var import_promises64 = require("fs/promises");
66634
+ var import_promises65 = require("fs/promises");
66567
66635
  var import_node_os10 = require("os");
66568
- var import_node_path64 = require("path");
66636
+ var import_node_path65 = require("path");
66569
66637
  init_runtime_v2();
66570
66638
 
66571
66639
  // src/holder/control-client.ts
@@ -66981,7 +67049,7 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
66981
67049
  var import_node_crypto29 = require("crypto");
66982
67050
  var import_node_fs21 = require("fs");
66983
67051
  var import_node_net3 = require("net");
66984
- var import_node_path63 = require("path");
67052
+ var import_node_path64 = require("path");
66985
67053
  init_runtime_v2();
66986
67054
 
66987
67055
  // src/holder/admission.ts
@@ -67735,14 +67803,42 @@ function createSessionFacts(options) {
67735
67803
  // src/holder/turn.ts
67736
67804
  init_acp2();
67737
67805
 
67806
+ // src/run-log/archive.ts
67807
+ var import_promises61 = require("fs/promises");
67808
+ var import_node_path59 = require("path");
67809
+ init_runtime_v2();
67810
+ async function openRunArchive(runsDir) {
67811
+ const path4 = (0, import_node_path59.join)((0, import_node_path59.dirname)(runsDir), "archived-runs.txt");
67812
+ const text2 = await (0, import_promises61.readFile)(path4, "utf8").catch((error61) => {
67813
+ if (errnoCode(error61) === "ENOENT") return "";
67814
+ throw error61;
67815
+ });
67816
+ const archived = /* @__PURE__ */ new Set();
67817
+ for (const line of text2.split("\n")) {
67818
+ const runId = runIdSchema.safeParse(line);
67819
+ if (runId.success) archived.add(runId.data);
67820
+ }
67821
+ return {
67822
+ has: (runId) => archived.has(runId),
67823
+ add: async (runIds) => {
67824
+ const added = runIds.filter((runId) => !archived.has(runId));
67825
+ if (added.length === 0) return;
67826
+ await (0, import_promises61.appendFile)(path4, `
67827
+ ${added.join("\n")}
67828
+ `, { mode: 384 });
67829
+ for (const runId of added) archived.add(runId);
67830
+ }
67831
+ };
67832
+ }
67833
+
67738
67834
  // src/run-log/complete.ts
67739
67835
  var import_node_crypto28 = require("crypto");
67740
67836
  var import_node_fs19 = require("fs");
67741
- var import_node_path60 = require("path");
67837
+ var import_node_path61 = require("path");
67742
67838
 
67743
67839
  // src/run-log/directory.ts
67744
- var import_promises61 = require("fs/promises");
67745
- var import_node_path59 = require("path");
67840
+ var import_promises62 = require("fs/promises");
67841
+ var import_node_path60 = require("path");
67746
67842
  init_runtime_v2();
67747
67843
  init_zod();
67748
67844
  var runMetaSchema = external_exports.object({
@@ -67768,17 +67864,17 @@ async function readRunMeta(path4) {
67768
67864
  return read.kind === "ok" ? read.value : null;
67769
67865
  }
67770
67866
  function runDirectory(runsDir, runId) {
67771
- const dir = (0, import_node_path59.join)(runsDir, runId);
67867
+ const dir = (0, import_node_path60.join)(runsDir, runId);
67772
67868
  return {
67773
67869
  dir,
67774
- log: (0, import_node_path59.join)(dir, "log.jsonl"),
67775
- upload: (0, import_node_path59.join)(dir, "upload.json"),
67776
- meta: (0, import_node_path59.join)(dir, "run.json")
67870
+ log: (0, import_node_path60.join)(dir, "log.jsonl"),
67871
+ upload: (0, import_node_path60.join)(dir, "upload.json"),
67872
+ meta: (0, import_node_path60.join)(dir, "run.json")
67777
67873
  };
67778
67874
  }
67779
67875
  async function isRunClaimed(runsDir, runId) {
67780
67876
  try {
67781
- return (await (0, import_promises61.stat)(runDirectory(runsDir, runId).log)).size > 0;
67877
+ return (await (0, import_promises62.stat)(runDirectory(runsDir, runId).log)).size > 0;
67782
67878
  } catch (error61) {
67783
67879
  if (errnoCode(error61) === "ENOENT") return false;
67784
67880
  throw error61;
@@ -67787,7 +67883,7 @@ async function isRunClaimed(runsDir, runId) {
67787
67883
 
67788
67884
  // src/run-log/complete.ts
67789
67885
  function writeLogFile(path4, dir, text2) {
67790
- const temp = (0, import_node_path60.join)(dir, `.log.${(0, import_node_crypto28.randomUUID)()}.tmp`);
67886
+ const temp = (0, import_node_path61.join)(dir, `.log.${(0, import_node_crypto28.randomUUID)()}.tmp`);
67791
67887
  const fd = (0, import_node_fs19.openSync)(temp, "wx", 384);
67792
67888
  try {
67793
67889
  (0, import_node_fs19.writeSync)(fd, text2);
@@ -67816,11 +67912,12 @@ async function writeCompleteRunLog(runsDir, meta3, records) {
67816
67912
  }
67817
67913
 
67818
67914
  // src/run-log/conversation-index.ts
67819
- var import_promises62 = require("fs/promises");
67820
- var import_node_path61 = require("path");
67915
+ var import_promises63 = require("fs/promises");
67916
+ var import_node_path62 = require("path");
67821
67917
  init_runtime_v2();
67822
67918
  init_zod();
67823
67919
  var ORDINALS_PER_SHARD = 1e3;
67920
+ var REBUILD_READ_CONCURRENCY = 32;
67824
67921
  var indexRecordSchema = external_exports.object({
67825
67922
  ordinal: external_exports.number().int().nonnegative(),
67826
67923
  nextOrdinal: external_exports.number().int().positive(),
@@ -67832,11 +67929,14 @@ var coverageSchema = external_exports.object({
67832
67929
  highestOrdinal: external_exports.number().int().nonnegative(),
67833
67930
  nextExpectedOrdinal: external_exports.number().int().positive()
67834
67931
  });
67932
+ function conversationsDirectory(runsDir) {
67933
+ return (0, import_node_path62.join)((0, import_node_path62.dirname)(runsDir), "conversations");
67934
+ }
67835
67935
  function indexDirectory(runsDir, conversationId) {
67836
- return (0, import_node_path61.join)((0, import_node_path61.dirname)(runsDir), "sessions", conversationId, "turn-index");
67936
+ return (0, import_node_path62.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
67837
67937
  }
67838
67938
  function shardPath(runsDir, conversationId, ordinal) {
67839
- return (0, import_node_path61.join)(
67939
+ return (0, import_node_path62.join)(
67840
67940
  indexDirectory(runsDir, conversationId),
67841
67941
  `${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
67842
67942
  );
@@ -67845,10 +67945,10 @@ async function indexConversationRun(runsDir, conversationId, ordinal, assistantO
67845
67945
  const nextOrdinal = assistantOrdinal + 1;
67846
67946
  if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
67847
67947
  const path4 = shardPath(runsDir, conversationId, ordinal);
67848
- await (0, import_promises62.mkdir)((0, import_node_path61.dirname)(path4), { recursive: true, mode: 448 });
67849
- await (0, import_promises62.appendFile)(path4, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
67948
+ await (0, import_promises63.mkdir)((0, import_node_path62.dirname)(path4), { recursive: true, mode: 448 });
67949
+ await (0, import_promises63.appendFile)(path4, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
67850
67950
  `, { mode: 384 });
67851
- const coveragePath = (0, import_node_path61.join)((0, import_node_path61.dirname)((0, import_node_path61.dirname)(path4)), "coverage.json");
67951
+ const coveragePath = (0, import_node_path62.join)((0, import_node_path62.dirname)((0, import_node_path62.dirname)(path4)), "coverage.json");
67852
67952
  const coverage = await readJsonFile(coveragePath, coverageSchema);
67853
67953
  const current = coverage.kind === "ok" ? coverage.value : null;
67854
67954
  const next = nextCoverage(current, ordinal, nextOrdinal);
@@ -67863,13 +67963,13 @@ function nextCoverage(current, ordinal, nextOrdinal) {
67863
67963
  return null;
67864
67964
  }
67865
67965
  async function readConversationIndexCoverage(runsDir, conversationId) {
67866
- const path4 = (0, import_node_path61.join)((0, import_node_path61.dirname)(indexDirectory(runsDir, conversationId)), "coverage.json");
67966
+ const path4 = (0, import_node_path62.join)((0, import_node_path62.dirname)(indexDirectory(runsDir, conversationId)), "coverage.json");
67867
67967
  const result = await readJsonFile(path4, coverageSchema);
67868
67968
  return result.kind === "ok" ? result.value : null;
67869
67969
  }
67870
67970
  async function readConversationRunIndex(runsDir, conversationId, before, limit) {
67871
67971
  const directory = indexDirectory(runsDir, conversationId);
67872
- const names = await (0, import_promises62.readdir)(directory).catch((error61) => {
67972
+ const names = await (0, import_promises63.readdir)(directory).catch((error61) => {
67873
67973
  if (error61.code === "ENOENT") return [];
67874
67974
  throw error61;
67875
67975
  });
@@ -67878,7 +67978,7 @@ async function readConversationRunIndex(runsDir, conversationId, before, limit)
67878
67978
  ).sort((left, right) => right - left);
67879
67979
  const selected = [];
67880
67980
  for (const shard of shards) {
67881
- const text2 = await (0, import_promises62.readFile)((0, import_node_path61.join)(directory, `${shard}.jsonl`), "utf8");
67981
+ const text2 = await (0, import_promises63.readFile)((0, import_node_path62.join)(directory, `${shard}.jsonl`), "utf8");
67882
67982
  const records = text2.split("\n").flatMap((line) => {
67883
67983
  if (!line) return [];
67884
67984
  const parsed = indexRecordSchema.parse(JSON.parse(line));
@@ -67892,9 +67992,82 @@ async function readConversationRunIndex(runsDir, conversationId, before, limit)
67892
67992
  }
67893
67993
  return selected;
67894
67994
  }
67995
+ async function readIndexableRun(runsDir, name) {
67996
+ const runId = runIdSchema.safeParse(name);
67997
+ if (!runId.success) return null;
67998
+ const meta3 = await readRunMeta(runDirectory(runsDir, runId.data).meta);
67999
+ const ordinal = meta3?.userMessage?.turnOrdinal;
68000
+ const assistantOrdinal = meta3?.assistantMessage?.turnOrdinal;
68001
+ if (!meta3 || ordinal == null || assistantOrdinal == null || assistantOrdinal < ordinal)
68002
+ return null;
68003
+ return { conversationId: meta3.conversationId, ordinal, assistantOrdinal, runId: runId.data };
68004
+ }
68005
+ async function readIndexableRuns(runsDir) {
68006
+ const names = await (0, import_promises63.readdir)(runsDir).catch(() => []);
68007
+ const byConversation = /* @__PURE__ */ new Map();
68008
+ let next = 0;
68009
+ const worker = async () => {
68010
+ while (next < names.length) {
68011
+ const run2 = await readIndexableRun(runsDir, names[next++]);
68012
+ if (run2 === null) continue;
68013
+ const runs = byConversation.get(run2.conversationId);
68014
+ if (runs === void 0) byConversation.set(run2.conversationId, [run2]);
68015
+ else runs.push(run2);
68016
+ }
68017
+ };
68018
+ await Promise.all(Array.from({ length: REBUILD_READ_CONCURRENCY }, worker));
68019
+ return byConversation;
68020
+ }
68021
+ async function writeConversationIndex(directory, runs) {
68022
+ runs.sort(
68023
+ (left, right) => left.ordinal - right.ordinal || left.assistantOrdinal - right.assistantOrdinal
68024
+ );
68025
+ const shards = /* @__PURE__ */ new Map();
68026
+ let coverage = null;
68027
+ for (const run2 of runs) {
68028
+ const nextOrdinal = run2.assistantOrdinal + 1;
68029
+ const shard = Math.floor(run2.ordinal / ORDINALS_PER_SHARD);
68030
+ const line = JSON.stringify({ ordinal: run2.ordinal, nextOrdinal, runId: run2.runId });
68031
+ const lines2 = shards.get(shard);
68032
+ if (lines2 === void 0) shards.set(shard, [line]);
68033
+ else lines2.push(line);
68034
+ coverage = nextCoverage(coverage, run2.ordinal, nextOrdinal) ?? coverage;
68035
+ }
68036
+ await (0, import_promises63.mkdir)((0, import_node_path62.join)(directory, "turn-index"), { recursive: true, mode: 448 });
68037
+ for (const [shard, lines2] of shards) {
68038
+ await (0, import_promises63.writeFile)((0, import_node_path62.join)(directory, "turn-index", `${shard}.jsonl`), `${lines2.join("\n")}
68039
+ `, {
68040
+ mode: 384
68041
+ });
68042
+ }
68043
+ await (0, import_promises63.writeFile)((0, import_node_path62.join)(directory, "coverage.json"), `${JSON.stringify(coverage)}
68044
+ `, {
68045
+ mode: 384
68046
+ });
68047
+ }
68048
+ async function rebuildConversationIndexes(runsDir) {
68049
+ const root = conversationsDirectory(runsDir);
68050
+ const exists6 = await (0, import_promises63.stat)(root).then(
68051
+ () => true,
68052
+ (error61) => {
68053
+ if (errnoCode(error61) === "ENOENT") return false;
68054
+ throw error61;
68055
+ }
68056
+ );
68057
+ if (exists6) return 0;
68058
+ const building = `${root}.rebuilding`;
68059
+ await (0, import_promises63.rm)(building, { recursive: true, force: true });
68060
+ await (0, import_promises63.mkdir)(building, { recursive: true, mode: 448 });
68061
+ const byConversation = await readIndexableRuns(runsDir);
68062
+ for (const [conversationId, runs] of byConversation) {
68063
+ await writeConversationIndex((0, import_node_path62.join)(building, conversationId), runs);
68064
+ }
68065
+ await (0, import_promises63.rename)(building, root);
68066
+ return byConversation.size;
68067
+ }
67895
68068
 
67896
68069
  // src/run-log/reader.ts
67897
- var import_promises63 = require("fs/promises");
68070
+ var import_promises64 = require("fs/promises");
67898
68071
  init_runtime_v2();
67899
68072
 
67900
68073
  // src/run-log/tail.ts
@@ -67917,7 +68090,7 @@ function firstRecordLength(bytes) {
67917
68090
  return bytes.indexOf(RUN_LOG_RECORD_SEPARATOR) + 1;
67918
68091
  }
67919
68092
  async function openRunLogReader(path4) {
67920
- const handle = await (0, import_promises63.open)(path4, "r");
68093
+ const handle = await (0, import_promises64.open)(path4, "r");
67921
68094
  const readAt = async (position, length) => {
67922
68095
  const buffer = Buffer.alloc(length);
67923
68096
  const { bytesRead } = await handle.read(buffer, 0, length, position);
@@ -67951,7 +68124,7 @@ async function openRunLogReader(path4) {
67951
68124
  };
67952
68125
  }
67953
68126
  async function readLastRecord(path4) {
67954
- const handle = await (0, import_promises63.open)(path4, "r").catch(() => null);
68127
+ const handle = await (0, import_promises64.open)(path4, "r").catch(() => null);
67955
68128
  if (handle === null) return null;
67956
68129
  try {
67957
68130
  const { size } = await handle.stat();
@@ -67985,7 +68158,7 @@ var decoder = new TextDecoder();
67985
68158
 
67986
68159
  // src/run-log/writer.ts
67987
68160
  var import_node_fs20 = require("fs");
67988
- var import_node_path62 = require("path");
68161
+ var import_node_path63 = require("path");
67989
68162
  init_runtime_v2();
67990
68163
  function lastSeq(fd, size) {
67991
68164
  for (const length of tailWindows(size)) {
@@ -68001,7 +68174,7 @@ function lastSeq(fd, size) {
68001
68174
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
68002
68175
  }
68003
68176
  function openRunLog(path4, clock) {
68004
- (0, import_node_fs20.mkdirSync)((0, import_node_path62.dirname)(path4), { recursive: true, mode: 448 });
68177
+ (0, import_node_fs20.mkdirSync)((0, import_node_path63.dirname)(path4), { recursive: true, mode: 448 });
68005
68178
  const fd = (0, import_node_fs20.openSync)(path4, "a+", 384);
68006
68179
  let size = (0, import_node_fs20.fstatSync)(fd).size;
68007
68180
  let seq = lastSeq(fd, size);
@@ -68337,7 +68510,7 @@ async function runHolder({
68337
68510
  try {
68338
68511
  const identity = await readProcessIdentity(process.pid);
68339
68512
  if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
68340
- const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path63.dirname)(launch.statusPath)), clock, log));
68513
+ const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path64.dirname)(launch.statusPath)), clock, log));
68341
68514
  const holder = {
68342
68515
  state: "idle",
68343
68516
  runId: null,
@@ -68631,7 +68804,7 @@ var DEFAULT_MAX_ACTIVE_RUNS = 32;
68631
68804
  var HOLDER_BUSY = "busy";
68632
68805
  async function listIds(dir, schema) {
68633
68806
  const ids = [];
68634
- for (const name of await (0, import_promises64.readdir)(dir).catch(() => [])) {
68807
+ for (const name of await (0, import_promises65.readdir)(dir).catch(() => [])) {
68635
68808
  const parsed = schema.safeParse(name);
68636
68809
  if (parsed.success) ids.push(parsed.data);
68637
68810
  }
@@ -68645,11 +68818,20 @@ function holderIdentity(status) {
68645
68818
  return command === void 0 ? { pid, startedAt } : { pid, startedAt, command };
68646
68819
  }
68647
68820
  function sessionFiles(paths, conversationId) {
68648
- const dir = (0, import_node_path64.join)(paths.sessions, conversationId);
68649
- return { dir, launch: (0, import_node_path64.join)(dir, "launch.json"), status: (0, import_node_path64.join)(dir, "holder.json") };
68821
+ const dir = (0, import_node_path65.join)(paths.sessions, conversationId);
68822
+ return { dir, launch: (0, import_node_path65.join)(dir, "launch.json"), status: (0, import_node_path65.join)(dir, "holder.json") };
68823
+ }
68824
+ async function removeHolderFiles(files) {
68825
+ for (const path4 of [files.launch, files.status, engineRecordsPath(files.dir)]) {
68826
+ await (0, import_promises65.rm)(path4, { force: true });
68827
+ }
68828
+ await (0, import_promises65.rmdir)(files.dir).catch((error61) => {
68829
+ if (!["ENOENT", "ENOTEMPTY", "EEXIST"].includes(errnoCode(error61) ?? "")) throw error61;
68830
+ });
68650
68831
  }
68651
68832
  async function openSessions(deps) {
68652
68833
  const { paths, clock, log } = deps;
68834
+ const recentRunIds = async () => (await listIds(paths.runs, runIdSchema)).filter((runId) => !deps.archive?.has(runId));
68653
68835
  const connections = /* @__PURE__ */ new Map();
68654
68836
  const starting = /* @__PURE__ */ new Map();
68655
68837
  const launched = /* @__PURE__ */ new Map();
@@ -68683,11 +68865,11 @@ async function openSessions(deps) {
68683
68865
  return status.kind === "ok" && await mayBeSameProcess(holderIdentity(status.value));
68684
68866
  };
68685
68867
  const discardSession = async (conversationId) => {
68686
- const { dir } = sessionFiles(paths, conversationId);
68687
- await reapLeftoverEngines(engineRecordsPath(dir), { clock, log, conversationId }).catch(
68868
+ const files = sessionFiles(paths, conversationId);
68869
+ await reapLeftoverEngines(engineRecordsPath(files.dir), { clock, log, conversationId }).catch(
68688
68870
  (error61) => log.warn("sessions.engine_reap_failed", { conversationId, error: error61 })
68689
68871
  );
68690
- await (0, import_promises64.rm)(dir, { recursive: true, force: true });
68872
+ await removeHolderFiles(files);
68691
68873
  };
68692
68874
  const retireIfGone = async (conversationId) => {
68693
68875
  const files = sessionFiles(paths, conversationId);
@@ -68701,7 +68883,7 @@ async function openSessions(deps) {
68701
68883
  }
68702
68884
  await discardSession(conversationId);
68703
68885
  for (const [runId, owner] of launched) if (owner === conversationId) launched.delete(runId);
68704
- for (const runId of await listIds(paths.runs, runIdSchema)) {
68886
+ for (const runId of await recentRunIds()) {
68705
68887
  const meta3 = await readRunMeta(runDirectory(paths.runs, runId).meta);
68706
68888
  if (meta3?.conversationId === conversationId) await markInterrupted(runId);
68707
68889
  }
@@ -68720,7 +68902,7 @@ async function openSessions(deps) {
68720
68902
  };
68721
68903
  const runsOf = async (conversationId) => {
68722
68904
  const found = [];
68723
- for (const runId of await listIds(paths.runs, runIdSchema)) {
68905
+ for (const runId of await recentRunIds()) {
68724
68906
  const dir = runDirectory(paths.runs, runId);
68725
68907
  if ((await readRunMeta(dir.meta))?.conversationId !== conversationId) continue;
68726
68908
  const last = await readLastRecord(dir.log);
@@ -68775,7 +68957,7 @@ async function openSessions(deps) {
68775
68957
  log.info("sessions.reattached", { conversationId });
68776
68958
  return;
68777
68959
  }
68778
- if (alive) await (0, import_promises64.rm)(files.dir, { recursive: true, force: true });
68960
+ if (alive) await removeHolderFiles(files);
68779
68961
  else await discardSession(conversationId);
68780
68962
  };
68781
68963
  const busyRunIds = async () => {
@@ -68796,7 +68978,7 @@ async function openSessions(deps) {
68796
68978
  for (const conversationId of legacy.keys()) {
68797
68979
  for (const runId of await unendedRunsOf(conversationId)) busy.add(runId);
68798
68980
  }
68799
- for (const runId of await listIds(paths.runs, runIdSchema)) {
68981
+ for (const runId of await recentRunIds()) {
68800
68982
  if (!busy.has(runId)) await markInterrupted(runId);
68801
68983
  }
68802
68984
  };
@@ -68833,7 +69015,7 @@ async function openSessions(deps) {
68833
69015
  const meta3 = await readRunMeta(dir.meta);
68834
69016
  const last = await readLastRecord(dir.log);
68835
69017
  if (meta3 === null || last === null) return null;
68836
- const logged = await (0, import_promises64.stat)(dir.log).catch((error61) => {
69018
+ const logged = await (0, import_promises65.stat)(dir.log).catch((error61) => {
68837
69019
  if (errnoCode(error61) === "ENOENT") return null;
68838
69020
  throw error61;
68839
69021
  });
@@ -68860,7 +69042,7 @@ async function openSessions(deps) {
68860
69042
  ({ run: run2 }) => notLoggedRun(run2.runId, run2.conversationId)
68861
69043
  );
68862
69044
  const logged = /* @__PURE__ */ new Set();
68863
- const onDisk = new Set(await listIds(paths.runs, runIdSchema));
69045
+ const onDisk = new Set(await recentRunIds());
68864
69046
  for (const runId of endedRuns.keys()) if (!onDisk.has(runId)) endedRuns.delete(runId);
68865
69047
  for (const runId of onDisk) {
68866
69048
  const run2 = starting.has(runId) ? null : await loggedRun(runId);
@@ -69143,7 +69325,7 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
69143
69325
  providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
69144
69326
  providerToolchain: ALAN_RUNTIME_PROVIDER_NODE !== void 0 && ALAN_RUNTIME_PROVIDER_NPM_CLI !== void 0 ? { node: ALAN_RUNTIME_PROVIDER_NODE, npmCli: ALAN_RUNTIME_PROVIDER_NPM_CLI } : null,
69145
69327
  home,
69146
- configHome: XDG_CONFIG_HOME ?? (0, import_node_path65.join)(home, ".config"),
69328
+ configHome: XDG_CONFIG_HOME ?? (0, import_node_path66.join)(home, ".config"),
69147
69329
  ...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
69148
69330
  gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
69149
69331
  workspaceRoot: ALAN_RUNTIME_WORKSPACE_ROOT ?? null,
@@ -69152,10 +69334,10 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
69152
69334
  };
69153
69335
  }
69154
69336
  function githubProxyConfig(env, home) {
69155
- const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path65.join)(home, ".config");
69337
+ const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path66.join)(home, ".config");
69156
69338
  return {
69157
69339
  githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
69158
- ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path65.join)(configHome, "gh")
69340
+ ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path66.join)(configHome, "gh")
69159
69341
  };
69160
69342
  }
69161
69343
  function serviceEnvironment2(env, profile) {
@@ -69213,9 +69395,9 @@ function takeEnrollmentCodeFromEnv(env = process.env) {
69213
69395
  }
69214
69396
 
69215
69397
  // src/cli/context.ts
69216
- var import_promises65 = require("fs/promises");
69398
+ var import_promises66 = require("fs/promises");
69217
69399
  var import_node_os12 = require("os");
69218
- var import_node_path66 = require("path");
69400
+ var import_node_path67 = require("path");
69219
69401
  var DESKTOP_BUNDLE_IDS = {
69220
69402
  production: ["com.alan-ai.desktop"],
69221
69403
  staging: ["com.alan-ai.desktop.staging"],
@@ -69255,7 +69437,7 @@ function serviceSpec({ config: config2, paths, self }) {
69255
69437
  profile: config2.profile,
69256
69438
  program: serviceCommand(config2.host, self, launcher),
69257
69439
  environment: config2.serviceEnvironment,
69258
- logPath: (0, import_node_path66.join)(paths.logs, "service.log"),
69440
+ logPath: (0, import_node_path67.join)(paths.logs, "service.log"),
69259
69441
  associatedBundleIds: DESKTOP_BUNDLE_IDS[config2.profile]
69260
69442
  };
69261
69443
  }
@@ -69263,7 +69445,7 @@ async function installedServiceSpec(ctx) {
69263
69445
  const spec = serviceSpec(ctx);
69264
69446
  if (ctx.config.host === "app") return spec;
69265
69447
  const layout = installLayout(ctx.config.installDir, ctx.config.profile);
69266
- const installed = await (0, import_promises65.access)(layout.launcher).then(
69448
+ const installed = await (0, import_promises66.access)(layout.launcher).then(
69267
69449
  () => true,
69268
69450
  () => false
69269
69451
  );
@@ -69391,7 +69573,7 @@ var manifestRevisionSchema = external_exports.object({ revision: external_export
69391
69573
  async function manifestRevision(path4) {
69392
69574
  let raw;
69393
69575
  try {
69394
- raw = JSON.parse(await (0, import_promises66.readFile)(path4, "utf8"));
69576
+ raw = JSON.parse(await (0, import_promises67.readFile)(path4, "utf8"));
69395
69577
  } catch (error61) {
69396
69578
  throw new RuntimeFault("invalid_file", `Cannot read the skill manifest at ${path4}`, {
69397
69579
  cause: error61
@@ -69445,8 +69627,8 @@ async function runSkills(argv) {
69445
69627
  }
69446
69628
 
69447
69629
  // src/cli/commands/doctor.ts
69448
- var import_promises69 = require("fs/promises");
69449
- var import_node_path70 = require("path");
69630
+ var import_promises70 = require("fs/promises");
69631
+ var import_node_path71 = require("path");
69450
69632
  init_runtime_v2();
69451
69633
 
69452
69634
  // src/identity/credential.ts
@@ -69623,18 +69805,18 @@ async function authorizeDevice(input2) {
69623
69805
  }
69624
69806
 
69625
69807
  // src/identity/enroll.ts
69626
- var import_promises67 = require("fs/promises");
69808
+ var import_promises68 = require("fs/promises");
69627
69809
  init_runtime_v2();
69628
69810
 
69629
69811
  // src/identity/installation.ts
69630
69812
  var import_node_crypto32 = require("crypto");
69631
- var import_node_path67 = require("path");
69813
+ var import_node_path68 = require("path");
69632
69814
  init_zod();
69633
69815
  var installationFileSchema = external_exports.object({
69634
69816
  installationId: external_exports.uuid()
69635
69817
  });
69636
69818
  function installationPath(paths) {
69637
- return (0, import_node_path67.join)(paths.stateDir, "installation.json");
69819
+ return (0, import_node_path68.join)(paths.stateDir, "installation.json");
69638
69820
  }
69639
69821
  async function ensureInstallationId(paths) {
69640
69822
  const path4 = installationPath(paths);
@@ -69727,13 +69909,13 @@ async function enrollFromGrantFile(input2) {
69727
69909
  clock: input2.clock,
69728
69910
  access: input2.access
69729
69911
  });
69730
- await (0, import_promises67.rm)(input2.grantPath, { force: true });
69912
+ await (0, import_promises68.rm)(input2.grantPath, { force: true });
69731
69913
  return machine;
69732
69914
  }
69733
69915
 
69734
69916
  // src/identity/migrate-v1.ts
69735
- var import_promises68 = require("fs/promises");
69736
- var import_node_path68 = require("path");
69917
+ var import_promises69 = require("fs/promises");
69918
+ var import_node_path69 = require("path");
69737
69919
  init_runtime_v2();
69738
69920
  init_zod();
69739
69921
  var EXIT_POLL_MS = 200;
@@ -69754,11 +69936,11 @@ var ownerLeaseSchema = external_exports.looseObject({ pid: external_exports.numb
69754
69936
  function legacyConfigPath(home, profile) {
69755
69937
  switch (profile) {
69756
69938
  case "production":
69757
- return (0, import_node_path68.join)(home, ".alan", "agent", "config.json");
69939
+ return (0, import_node_path69.join)(home, ".alan", "agent", "config.json");
69758
69940
  case "staging":
69759
- return (0, import_node_path68.join)(home, ".alan-staging", "agent", "config.json");
69941
+ return (0, import_node_path69.join)(home, ".alan-staging", "agent", "config.json");
69760
69942
  default:
69761
- return (0, import_node_path68.join)(home, ".alan-dev", "agent", "config.json");
69943
+ return (0, import_node_path69.join)(home, ".alan-dev", "agent", "config.json");
69762
69944
  }
69763
69945
  }
69764
69946
  async function findLegacyInstall(home, profile) {
@@ -69783,8 +69965,8 @@ async function scrubLegacyInstall(install2) {
69783
69965
  const scrubbed = { ...install2.config, migratedToRuntimeV2: true };
69784
69966
  for (const key of SCRUBBED_KEYS) delete scrubbed[key];
69785
69967
  await writeJsonFileAtomic(`${install2.configPath}.migrated-v1`, scrubbed);
69786
- await (0, import_promises68.rm)(install2.configPath, { force: true });
69787
- await (0, import_promises68.rm)(install2.ownerLeasePath, { force: true });
69968
+ await (0, import_promises69.rm)(install2.configPath, { force: true });
69969
+ await (0, import_promises69.rm)(install2.ownerLeasePath, { force: true });
69788
69970
  }
69789
69971
  async function exchangeCredential(deps) {
69790
69972
  const { config: config2 } = deps.install;
@@ -69893,7 +70075,7 @@ async function loadIdentity(paths, options = {}) {
69893
70075
  }
69894
70076
 
69895
70077
  // src/cli/commands/status.ts
69896
- var import_node_path69 = require("path");
70078
+ var import_node_path70 = require("path");
69897
70079
  async function serviceStatus(ctx) {
69898
70080
  try {
69899
70081
  return await createServiceManager(ctx.host, ctx.config.profile).status();
@@ -69920,7 +70102,7 @@ async function runtimeState(ctx) {
69920
70102
  const running = await readRunningRuntime(ctx.paths.lock);
69921
70103
  if (running === null) return { state: "offline", pid: null, localApi: null };
69922
70104
  const discovery = await readJsonFile(
69923
- (0, import_node_path69.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE),
70105
+ (0, import_node_path70.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE),
69924
70106
  localApiDiscoverySchema
69925
70107
  );
69926
70108
  const localApi = discovery.kind === "ok" && discovery.value.pid === running.pid ? {
@@ -70141,7 +70323,7 @@ async function runtimeCheck(ctx, status) {
70141
70323
  return check2("runtime", "warn", "No runtime is running for this profile");
70142
70324
  }
70143
70325
  const client = createRuntimeClient({
70144
- discoveryPath: (0, import_node_path70.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE)
70326
+ discoveryPath: (0, import_node_path71.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE)
70145
70327
  });
70146
70328
  try {
70147
70329
  const live = await client.status(AbortSignal.timeout(LOCAL_TIMEOUT_MS));
@@ -70168,7 +70350,7 @@ async function runtimeCheck(ctx, status) {
70168
70350
  }
70169
70351
  }
70170
70352
  async function probeHolder(dir, conversationId) {
70171
- const launch = await readJsonFile((0, import_node_path70.join)(dir, "launch.json"), holderLaunchSchema);
70353
+ const launch = await readJsonFile((0, import_node_path71.join)(dir, "launch.json"), holderLaunchSchema);
70172
70354
  if (launch.kind !== "ok") return null;
70173
70355
  try {
70174
70356
  const reply2 = await withTimeout(
@@ -70193,8 +70375,8 @@ async function probeHolder(dir, conversationId) {
70193
70375
  }
70194
70376
  }
70195
70377
  async function holdersCheck(ctx) {
70196
- const names = await (0, import_promises69.readdir)(ctx.paths.sessions).catch(() => []);
70197
- const holders = (await Promise.all(names.map((name) => probeHolder((0, import_node_path70.join)(ctx.paths.sessions, name), name)))).filter((facts) => facts !== null);
70378
+ const names = await (0, import_promises70.readdir)(ctx.paths.sessions).catch(() => []);
70379
+ const holders = (await Promise.all(names.map((name) => probeHolder((0, import_node_path71.join)(ctx.paths.sessions, name), name)))).filter((facts) => facts !== null);
70198
70380
  const dead = holders.filter((holder) => !holder.alive).length;
70199
70381
  return check2(
70200
70382
  "holders",
@@ -70205,10 +70387,10 @@ async function holdersCheck(ctx) {
70205
70387
  }
70206
70388
  async function freeBytesAt(path4) {
70207
70389
  try {
70208
- const stats = await (0, import_promises69.statfs)(path4);
70390
+ const stats = await (0, import_promises70.statfs)(path4);
70209
70391
  return { path: path4, freeBytes: stats.bavail * stats.bsize };
70210
70392
  } catch (error61) {
70211
- const parent = (0, import_node_path70.dirname)(path4);
70393
+ const parent = (0, import_node_path71.dirname)(path4);
70212
70394
  if (parent === path4) throw error61;
70213
70395
  return freeBytesAt(parent);
70214
70396
  }
@@ -70344,7 +70526,7 @@ async function runDoctor(argv, context = cliContext) {
70344
70526
  }
70345
70527
 
70346
70528
  // src/cli/commands/git-credential.ts
70347
- var import_promises70 = require("fs/promises");
70529
+ var import_promises71 = require("fs/promises");
70348
70530
  var import_node_net4 = require("net");
70349
70531
  var MAX_RESPONSE_BYTES = 64 * 1024;
70350
70532
  async function readAll(stream) {
@@ -70454,7 +70636,7 @@ async function configure(argv) {
70454
70636
  }
70455
70637
  async function configureGitGateway(config2, gatewayUrl, signal) {
70456
70638
  const { launcher } = installLayout(config2.installDir, config2.profile);
70457
- const installed = await (0, import_promises70.access)(launcher).then(
70639
+ const installed = await (0, import_promises71.access)(launcher).then(
70458
70640
  () => true,
70459
70641
  () => false
70460
70642
  );
@@ -70481,7 +70663,7 @@ async function runGitCredential(argv) {
70481
70663
  }
70482
70664
 
70483
70665
  // src/cli/commands/hold.ts
70484
- var import_node_path71 = require("path");
70666
+ var import_node_path72 = require("path");
70485
70667
  init_agent2();
70486
70668
  init_runtime_v2();
70487
70669
  async function machineAccess(paths, log, conversationId, transport) {
@@ -70539,7 +70721,7 @@ async function runHold(argv) {
70539
70721
  const config2 = loadRuntimeConfig();
70540
70722
  const paths = runtimePaths(config2.stateDir);
70541
70723
  const log = __using(_stack, openFileLog(
70542
- (0, import_node_path71.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
70724
+ (0, import_node_path72.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
70543
70725
  config2.logLevel,
70544
70726
  systemClock
70545
70727
  ));
@@ -70550,7 +70732,7 @@ async function runHold(argv) {
70550
70732
  );
70551
70733
  const transport = __using(_stack, createHttpTransport());
70552
70734
  const access7 = await machineAccess(paths, log, launch.value.conversationId, transport);
70553
- const credentialPath = (0, import_node_path71.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
70735
+ const credentialPath = (0, import_node_path72.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
70554
70736
  const managedMcp = __using(_stack, access7.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
70555
70737
  managedMcp: access7.managedMcp,
70556
70738
  conversationId: launch.value.conversationId,
@@ -70590,7 +70772,7 @@ async function runHold(argv) {
70590
70772
  }
70591
70773
 
70592
70774
  // src/cli/commands/hook.ts
70593
- var import_node_path72 = require("path");
70775
+ var import_node_path73 = require("path");
70594
70776
  var RUNTIME_ANSWER_MS = 2e3;
70595
70777
  var DEBUG_VARIABLE = "ALAN_HOOK_DEBUG";
70596
70778
  function flag(argv, name) {
@@ -70622,7 +70804,7 @@ async function forwardHook(argv, io) {
70622
70804
  return "transcript outside provider root";
70623
70805
  }
70624
70806
  const verdict = await io.send(
70625
- (0, import_node_path72.join)(io.stateDir, LOCAL_API_DISCOVERY_FILE),
70807
+ (0, import_node_path73.join)(io.stateDir, LOCAL_API_DISCOVERY_FILE),
70626
70808
  hookSignal,
70627
70809
  AbortSignal.timeout(RUNTIME_ANSWER_MS)
70628
70810
  );
@@ -70658,7 +70840,7 @@ async function runHook(argv, overrides = {}) {
70658
70840
  }
70659
70841
 
70660
70842
  // src/cli/commands/ingestion-hooks.ts
70661
- var import_promises71 = require("fs/promises");
70843
+ var import_promises72 = require("fs/promises");
70662
70844
  var CODEX_TRUST_NOTE = "Codex runs new hooks only after you review them: open /hooks in Codex.";
70663
70845
  function isAction(value2) {
70664
70846
  return value2 === "enable" || value2 === "disable" || value2 === "status";
@@ -70681,7 +70863,7 @@ function errorMessage2(error61) {
70681
70863
  return error61 instanceof Error ? error61.message : String(error61);
70682
70864
  }
70683
70865
  async function exists5(path4) {
70684
- return (0, import_promises71.access)(path4).then(
70866
+ return (0, import_promises72.access)(path4).then(
70685
70867
  () => true,
70686
70868
  () => false
70687
70869
  );
@@ -70784,10 +70966,10 @@ async function runIntegrationsCommand(argv) {
70784
70966
  }
70785
70967
 
70786
70968
  // src/cli/commands/legacy.ts
70787
- var import_node_path74 = require("path");
70969
+ var import_node_path75 = require("path");
70788
70970
 
70789
70971
  // src/cli/commands/setup.ts
70790
- var import_node_path73 = require("path");
70972
+ var import_node_path74 = require("path");
70791
70973
  init_zod();
70792
70974
 
70793
70975
  // src/cli/legacy.ts
@@ -70869,7 +71051,7 @@ async function grantFileCredential(argv, grantPath, ctx, deps) {
70869
71051
  return enrollFromGrantFile({
70870
71052
  paths: ctx.paths,
70871
71053
  storeKind: credentialStoreFlag(argv) ?? ctx.config.credentialStore,
70872
- grantPath: (0, import_node_path73.resolve)(grantPath),
71054
+ grantPath: (0, import_node_path74.resolve)(grantPath),
70873
71055
  clock: deps.clock,
70874
71056
  access: ctx.access
70875
71057
  });
@@ -70945,7 +71127,7 @@ async function runSetup(argv, signal) {
70945
71127
  var _stack = [];
70946
71128
  try {
70947
71129
  const ctx = cliContext();
70948
- const log = __using(_stack, openFileLog((0, import_node_path73.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71130
+ const log = __using(_stack, openFileLog((0, import_node_path74.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
70949
71131
  const result = await setupMachine(argv, ctx, {
70950
71132
  enrollment: (apiUrl) => createEnrollmentClient({ apiUrl }),
70951
71133
  isProcessAlive,
@@ -71028,7 +71210,7 @@ async function runToken(argv, signal) {
71028
71210
  );
71029
71211
  }
71030
71212
  const ctx = cliContext();
71031
- const log = __using(_stack, openFileLog((0, import_node_path74.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71213
+ const log = __using(_stack, openFileLog((0, import_node_path75.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71032
71214
  const result = await rotateMachineCredential(ctx, { clock: systemClock, log, signal });
71033
71215
  process.stdout.write(`${rotationMessage(result)}
71034
71216
  `);
@@ -71040,8 +71222,8 @@ async function runToken(argv, signal) {
71040
71222
  }
71041
71223
 
71042
71224
  // src/cli/commands/logout.ts
71043
- var import_promises72 = require("fs/promises");
71044
- var import_node_path75 = require("path");
71225
+ var import_promises73 = require("fs/promises");
71226
+ var import_node_path76 = require("path");
71045
71227
  init_runtime_v2();
71046
71228
  var RUNTIME_EXIT_WAIT_MS = 35e3;
71047
71229
  var TURN_END_WAIT_MS = 3e4;
@@ -71100,9 +71282,9 @@ async function stopHolder(launch, deps, outcome2) {
71100
71282
  }
71101
71283
  async function stopHeldRuns(ctx, deps, outcome2 = "aborted") {
71102
71284
  const stopped = [];
71103
- for (const name of await (0, import_promises72.readdir)(ctx.paths.sessions).catch(() => [])) {
71285
+ for (const name of await (0, import_promises73.readdir)(ctx.paths.sessions).catch(() => [])) {
71104
71286
  const launch = await readJsonFile(
71105
- (0, import_node_path75.join)(ctx.paths.sessions, name, "launch.json"),
71287
+ (0, import_node_path76.join)(ctx.paths.sessions, name, "launch.json"),
71106
71288
  holderLaunchSchema
71107
71289
  );
71108
71290
  if (launch.kind !== "ok") continue;
@@ -71139,13 +71321,13 @@ async function forgetMachineLocally(ctx) {
71139
71321
  const machine = await readMachineFile(ctx.paths);
71140
71322
  if (machine === null) return;
71141
71323
  await credentialStoreFor(ctx.paths, machine.credentialStore, ctx.access).clear();
71142
- await (0, import_promises72.rm)(ctx.paths.machine, { force: true });
71324
+ await (0, import_promises73.rm)(ctx.paths.machine, { force: true });
71143
71325
  }
71144
71326
  async function runLogout(argv, signal) {
71145
71327
  var _stack = [];
71146
71328
  try {
71147
71329
  const ctx = cliContext();
71148
- const log = __using(_stack, openFileLog((0, import_node_path75.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71330
+ const log = __using(_stack, openFileLog((0, import_node_path76.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71149
71331
  const result = await logoutMachine(argv, ctx, {
71150
71332
  api: (apiUrl, accessToken) => createApiClient({ apiUrl, accessToken }),
71151
71333
  stopHeldRuns,
@@ -71163,7 +71345,7 @@ async function runLogout(argv, signal) {
71163
71345
 
71164
71346
  // src/cli/commands/run.ts
71165
71347
  var import_node_fs23 = require("fs");
71166
- var import_node_path79 = require("path");
71348
+ var import_node_path80 = require("path");
71167
71349
 
71168
71350
  // src/local-api/app-attachments.ts
71169
71351
  function createAppAttachments(clock) {
@@ -71240,9 +71422,9 @@ function createRunAppends() {
71240
71422
 
71241
71423
  // src/local-api/server.ts
71242
71424
  var import_node_crypto34 = require("crypto");
71243
- var import_promises73 = require("fs/promises");
71425
+ var import_promises74 = require("fs/promises");
71244
71426
  var import_node_http4 = require("http");
71245
- var import_node_path76 = require("path");
71427
+ var import_node_path77 = require("path");
71246
71428
 
71247
71429
  // src/local-api/guard.ts
71248
71430
  var import_node_crypto33 = require("crypto");
@@ -71492,11 +71674,15 @@ async function readLocalConversationMessages(runsDir, conversationId, limit, bef
71492
71674
  (entry) => entry.runId === projection?.runId ? projection.read() : projectLocalRun(runsDir, entry.runId, conversationId, entry.ordinal)
71493
71675
  )
71494
71676
  );
71495
- if (turns.some((turn) => turn === null)) return null;
71496
- const completeTurns = turns.filter((turn) => turn !== null);
71677
+ const missing = turns.indexOf(null);
71678
+ const completeTurns = (missing === -1 ? turns : turns.slice(0, missing)).filter(
71679
+ (turn) => turn !== null
71680
+ );
71681
+ if (completeTurns.length === 0) return null;
71682
+ const oldestOrdinal = selected[completeTurns.length - 1].ordinal;
71497
71683
  return {
71498
71684
  turns: compactConversationMessageTurns(completeTurns, before === void 0),
71499
- before: selected.at(-1)?.ordinal === 0 ? null : String(selected.at(-1)?.ordinal),
71685
+ before: oldestOrdinal === 0 ? null : String(oldestOrdinal),
71500
71686
  revision: `local-${selected[0].runId}`,
71501
71687
  streamCursor: ""
71502
71688
  };
@@ -72276,7 +72462,7 @@ async function serveLocalApi(deps) {
72276
72462
  startedAtMs,
72277
72463
  runtimeVersion: deps.runtimeVersion
72278
72464
  };
72279
- const discoveryPath = (0, import_node_path76.join)(deps.stateDir, LOCAL_API_DISCOVERY_FILE);
72465
+ const discoveryPath = (0, import_node_path77.join)(deps.stateDir, LOCAL_API_DISCOVERY_FILE);
72280
72466
  await writeJsonFileAtomic(discoveryPath, discovery);
72281
72467
  const followers = startMaintenance({
72282
72468
  everyMs: limits.refreshEveryMs,
@@ -72310,7 +72496,7 @@ async function serveLocalApi(deps) {
72310
72496
  await watchedStatus[Symbol.asyncDispose]();
72311
72497
  const current = await readJsonFile(discoveryPath, localApiDiscoverySchema);
72312
72498
  if (current.kind === "ok" && current.value.token === token) {
72313
- await (0, import_promises73.rm)(discoveryPath, { force: true });
72499
+ await (0, import_promises74.rm)(discoveryPath, { force: true });
72314
72500
  }
72315
72501
  await closeServer(server);
72316
72502
  log.info("local_api.closed", {});
@@ -72395,7 +72581,7 @@ function machineFeatureActions(deps) {
72395
72581
  }
72396
72582
 
72397
72583
  // src/cli/commands/machine-plane.ts
72398
- var import_node_path78 = require("path");
72584
+ var import_node_path79 = require("path");
72399
72585
 
72400
72586
  // src/link/index.ts
72401
72587
  init_runtime_v2();
@@ -76063,7 +76249,7 @@ function refusalFailure(refusal2) {
76063
76249
  }
76064
76250
 
76065
76251
  // src/link/probe.ts
76066
- var import_promises74 = require("dns/promises");
76252
+ var import_promises75 = require("dns/promises");
76067
76253
  var import_node_net5 = require("net");
76068
76254
  var import_node_tls2 = require("tls");
76069
76255
  var PROBE_TIMEOUT_MS4 = 5e3;
@@ -76099,7 +76285,7 @@ async function connectOnce(url3, clock) {
76099
76285
  }
76100
76286
  async function probeEndpoint(url3, clock) {
76101
76287
  try {
76102
- await (0, import_promises74.lookup)(url3.hostname);
76288
+ await (0, import_promises75.lookup)(url3.hostname);
76103
76289
  } catch (error61) {
76104
76290
  const reason = classifyTransportFailure(error61);
76105
76291
  return reason === "other" ? "dns" : reason;
@@ -76548,7 +76734,7 @@ function createReconciler(host, lifecycle, log, signal) {
76548
76734
  }
76549
76735
 
76550
76736
  // src/uploader/index.ts
76551
- var import_promises75 = require("fs/promises");
76737
+ var import_promises76 = require("fs/promises");
76552
76738
  init_runtime_v2();
76553
76739
  init_zod();
76554
76740
  var RETRY_DELAYS_MS = [250, 500, 1e3, 2e3, 5e3, 1e4, 3e4];
@@ -76563,10 +76749,11 @@ var uploadProgressSchema = external_exports.object({
76563
76749
  function progressFromReceipt(receipt) {
76564
76750
  return { admittedOffset: receipt?.admittedOffset ?? 0, sealed: receipt?.finalized ?? false };
76565
76751
  }
76566
- function startUploader({ api, runsDir, clock, log }) {
76752
+ function startUploader({ api, runsDir, clock, log, archive }) {
76567
76753
  const controller = new AbortController();
76568
76754
  const active = /* @__PURE__ */ new Map();
76569
76755
  const again = /* @__PURE__ */ new Set();
76756
+ const sealed = /* @__PURE__ */ new Set();
76570
76757
  const reject = async (runId, progressPath, progress, rejection2) => {
76571
76758
  log.error("upload.rejected", { runId, status: rejection2.status, message: rejection2.message });
76572
76759
  if (rejection2.status === UNAUTHORIZED) return;
@@ -76654,6 +76841,7 @@ function startUploader({ api, runsDir, clock, log }) {
76654
76841
  failures = 0;
76655
76842
  progress = step.progress;
76656
76843
  if (progress.sealed) {
76844
+ sealed.add(runId);
76657
76845
  log.info("upload.sealed", { runId, bytes: progress.admittedOffset });
76658
76846
  return;
76659
76847
  }
@@ -76667,6 +76855,7 @@ function startUploader({ api, runsDir, clock, log }) {
76667
76855
  if (meta3 === null) return;
76668
76856
  const target = { conversationId: meta3.conversationId, runId };
76669
76857
  const progress = await progressOf(runId, target, dir.upload);
76858
+ if (progress?.sealed) sealed.add(runId);
76670
76859
  if (progress === null || progress.sealed) return;
76671
76860
  if (progress.parkedUntil !== void 0 && progress.parkedUntil > clock.now()) return;
76672
76861
  const reader = __using(_stack, await openRunLogReader(dir.log), true);
@@ -76691,40 +76880,44 @@ function startUploader({ api, runsDir, clock, log }) {
76691
76880
  });
76692
76881
  active.set(runId, task);
76693
76882
  };
76694
- const sweep2 = async () => {
76695
- for (const name of await (0, import_promises75.readdir)(runsDir).catch(() => [])) {
76883
+ const unsealedRunIds = async () => {
76884
+ const runIds = [];
76885
+ for (const name of await (0, import_promises76.readdir)(runsDir).catch(() => [])) {
76696
76886
  const runId = runIdSchema.safeParse(name);
76697
- if (runId.success) run2(runId.data);
76887
+ if (runId.success && !sealed.has(runId.data) && !archive?.has(runId.data))
76888
+ runIds.push(runId.data);
76698
76889
  }
76890
+ return runIds;
76699
76891
  };
76700
- const isPrunable = async (runId, options) => {
76892
+ const sweep2 = async () => {
76893
+ for (const runId of await unsealedRunIds()) run2(runId);
76894
+ };
76895
+ const isArchivable = async (runId, options) => {
76701
76896
  if (options.keep.has(runId) || active.has(runId)) return false;
76702
76897
  const dir = runDirectory(runsDir, runId);
76703
76898
  const progress = await readJsonFile(dir.upload, uploadProgressSchema);
76704
76899
  if (progress.kind !== "ok" || !progress.value.sealed) return false;
76705
- const sealedAt = (await (0, import_promises75.stat)(dir.upload)).mtimeMs;
76900
+ const sealedAt = (await (0, import_promises76.stat)(dir.upload)).mtimeMs;
76706
76901
  if (clock.now() - sealedAt < options.sealedForMs) return false;
76707
76902
  return (await readLastRecord(dir.log))?.update.sessionUpdate === "_alan/run.ended";
76708
76903
  };
76709
- const prune = async (options) => {
76710
- let removed = 0;
76711
- for (const name of await (0, import_promises75.readdir)(runsDir).catch(() => [])) {
76904
+ const archivable = async (options) => {
76905
+ const found = [];
76906
+ for (const name of await (0, import_promises76.readdir)(runsDir).catch(() => [])) {
76712
76907
  const runId = runIdSchema.safeParse(name);
76713
- if (!runId.success) continue;
76908
+ if (!runId.success || archive?.has(runId.data)) continue;
76714
76909
  try {
76715
- if (!await isPrunable(runId.data, options)) continue;
76716
- await (0, import_promises75.rm)(runDirectory(runsDir, runId.data).dir, { recursive: true, force: true });
76717
- removed += 1;
76910
+ if (await isArchivable(runId.data, options)) found.push(runId.data);
76718
76911
  } catch (error61) {
76719
- log.warn("upload.prune_failed", { runId: runId.data, error: error61 });
76912
+ log.warn("upload.archive_check_failed", { runId: runId.data, error: error61 });
76720
76913
  }
76721
76914
  }
76722
- return removed;
76915
+ return found;
76723
76916
  };
76724
76917
  return {
76725
76918
  notify: run2,
76726
- prune,
76727
76919
  sweep: sweep2,
76920
+ archivable,
76728
76921
  flush: async () => {
76729
76922
  await sweep2();
76730
76923
  while (active.size > 0 && !controller.signal.aborted) {
@@ -76911,12 +77104,12 @@ async function startMachineNativeIngest(deps) {
76911
77104
  }
76912
77105
 
76913
77106
  // src/cli/commands/run-updates.ts
76914
- var import_node_path77 = require("path");
77107
+ var import_node_path78 = require("path");
76915
77108
  init_runtime_v2();
76916
77109
  var UPDATE_CHECK_EVERY_MS = 6 * 60 * 60 * 1e3;
76917
77110
  var DEFERRED_RETRY_MS = 5 * 60 * 1e3;
76918
77111
  function isInstalledBundle(layout, bundlePath) {
76919
- return (0, import_node_path77.resolve)((0, import_node_path77.dirname)((0, import_node_path77.dirname)(bundlePath))) === (0, import_node_path77.resolve)(layout.versions);
77112
+ return (0, import_node_path78.resolve)((0, import_node_path78.dirname)((0, import_node_path78.dirname)(bundlePath))) === (0, import_node_path78.resolve)(layout.versions);
76920
77113
  }
76921
77114
  async function settleUpgradeOnStart({
76922
77115
  layout,
@@ -77023,7 +77216,7 @@ function startRuntimeUpdates(options) {
77023
77216
  layout,
77024
77217
  release: npmRelease,
77025
77218
  tarball: await options.downloader.download(npmRelease.dist.tarball, signal),
77026
- tmpDir: (0, import_node_path77.join)(layout.root, ".downloads")
77219
+ tmpDir: (0, import_node_path78.join)(layout.root, ".downloads")
77027
77220
  });
77028
77221
  await lifecycle.exclusive("upgrade", async () => {
77029
77222
  await recordPendingUpgrade(layout, currentVersion2, version2, clock.now());
@@ -77069,10 +77262,10 @@ var MAINTENANCE_EVERY_MS = 3e3;
77069
77262
  var CAPABILITY_RESCAN_MS = 15 * 6e4;
77070
77263
  var LOCAL_SKILLS_RESCAN_MS = 6e4;
77071
77264
  var CAPABILITY_MAX_AGE_MS = 6e4;
77265
+ var RUN_ARCHIVE_EVERY_MS = 6 * 60 * 6e4;
77266
+ var SEALED_RUN_ARCHIVE_MS = 7 * 24 * 60 * 6e4;
77072
77267
  var DESIRED_RESYNC_TICK_MS = 5e3;
77073
77268
  var UPLOAD_SWEEP_EVERY_MS = 3e4;
77074
- var RUN_PRUNE_EVERY_MS = 6 * 60 * 6e4;
77075
- var SEALED_RUN_RETENTION_MS = 7 * 24 * 60 * 6e4;
77076
77269
  function setupFor(state) {
77077
77270
  if (state.kind !== "stopped") return "ready";
77078
77271
  switch (state.failure.reason) {
@@ -77208,7 +77401,12 @@ async function startMachinePlane(deps) {
77208
77401
  return null;
77209
77402
  };
77210
77403
  const cliEnvironment = providerEnvironment2();
77211
- const uploader = stack.use(startUploader({ api, runsDir: paths.runs, clock, log }));
77404
+ await rebuildConversationIndexes(paths.runs).then(
77405
+ (rebuilt) => rebuilt > 0 && log.info("conversation_index.rebuilt", { conversations: rebuilt }),
77406
+ (error61) => log.warn("conversation_index.rebuild_failed", { error: error61 })
77407
+ );
77408
+ const archive = await openRunArchive(paths.runs);
77409
+ const uploader = stack.use(startUploader({ api, runsDir: paths.runs, clock, log, archive }));
77212
77410
  const nativeIngest = stack.use(
77213
77411
  await startMachineNativeIngest({
77214
77412
  stateDir: paths.stateDir,
@@ -77236,6 +77434,7 @@ async function startMachinePlane(deps) {
77236
77434
  maxActiveRuns: config2.maxActiveRuns,
77237
77435
  suspendPolicy: config2.sessionSuspend,
77238
77436
  openedConversation: () => openedConversation,
77437
+ archive,
77239
77438
  spawnHolder: (launchPath) => {
77240
77439
  spawnDetached(
77241
77440
  {
@@ -77248,7 +77447,7 @@ async function startMachinePlane(deps) {
77248
77447
  [ALAN_MANAGED_SESSION_ENV]: "1"
77249
77448
  },
77250
77449
  cwd: paths.stateDir,
77251
- outputPath: (0, import_node_path78.join)(paths.logs, "holders.log")
77450
+ outputPath: (0, import_node_path79.join)(paths.logs, "holders.log")
77252
77451
  },
77253
77452
  deps.holderIsolation
77254
77453
  );
@@ -77386,19 +77585,20 @@ async function startMachinePlane(deps) {
77386
77585
  })
77387
77586
  );
77388
77587
  await uploader.sweep();
77389
- const runsPrune = stack.use(
77588
+ const runsArchive = stack.use(
77390
77589
  startMaintenance({
77391
- everyMs: RUN_PRUNE_EVERY_MS,
77590
+ everyMs: RUN_ARCHIVE_EVERY_MS,
77392
77591
  jobs: [
77393
77592
  {
77394
- name: "runs.prune",
77593
+ name: "runs.archive",
77395
77594
  run: async (signal) => {
77396
77595
  const desired = await api.fetchDesired(signal);
77397
- const removed = await uploader.prune({
77398
- sealedForMs: SEALED_RUN_RETENTION_MS,
77596
+ const archived = await uploader.archivable({
77597
+ sealedForMs: SEALED_RUN_ARCHIVE_MS,
77399
77598
  keep: new Set(desired.runs.map((run2) => run2.runId))
77400
77599
  });
77401
- if (removed > 0) log.info("runs.pruned", { removed });
77600
+ await archive.add(archived);
77601
+ if (archived.length > 0) log.info("runs.archived", { archived: archived.length });
77402
77602
  }
77403
77603
  }
77404
77604
  ],
@@ -77406,10 +77606,11 @@ async function startMachinePlane(deps) {
77406
77606
  log
77407
77607
  })
77408
77608
  );
77409
- const pruneAtStart = async () => {
77410
- if ((await sessions.heldRuns()).some((run2) => run2.state === "ended")) await runsPrune.runNow();
77609
+ const archiveAtStart = async () => {
77610
+ if ((await sessions.heldRuns()).some((run2) => run2.state === "ended"))
77611
+ await runsArchive.runNow();
77411
77612
  };
77412
- pruneAtStart().catch((error61) => log.warn("runs.prune_failed", { error: error61 }));
77613
+ archiveAtStart().catch((error61) => log.warn("runs.archive_failed", { error: error61 }));
77413
77614
  const capabilities = createCapabilityPublisher({
77414
77615
  inventory: createCapabilityInventory({
77415
77616
  env: providerEnvironment2,
@@ -77479,7 +77680,7 @@ async function startMachinePlane(deps) {
77479
77680
  git: createGitRunner({ env: cliEnvironment }),
77480
77681
  clock,
77481
77682
  log,
77482
- dir: (0, import_node_path78.join)(paths.stateDir, "checkout-freshness")
77683
+ dir: (0, import_node_path79.join)(paths.stateDir, "checkout-freshness")
77483
77684
  },
77484
77685
  stopped.signal
77485
77686
  );
@@ -77773,7 +77974,7 @@ function lockWaitMs(argv) {
77773
77974
  }
77774
77975
  async function openManagedProviders(config2, paths) {
77775
77976
  const providerEnv = readCliEnvironment();
77776
- const bundledNpm = (0, import_node_path79.join)((0, import_node_path79.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
77977
+ const bundledNpm = (0, import_node_path80.join)((0, import_node_path80.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
77777
77978
  const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs23.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
77778
77979
  const npmPath = providerToolchain?.node ?? await resolveCommandOnPath("npm", providerEnv, process.platform);
77779
77980
  const npmOptions = npmPath === null || process.platform === "win32" && providerToolchain === null ? null : {
@@ -77781,7 +77982,7 @@ async function openManagedProviders(config2, paths) {
77781
77982
  ...providerToolchain === null ? {} : { argsBeforeNpm: [providerToolchain.npmCli] },
77782
77983
  env: providerEnv
77783
77984
  };
77784
- const providerNodeDir = providerToolchain?.node === void 0 ? void 0 : (0, import_node_path79.dirname)(providerToolchain.node);
77985
+ const providerNodeDir = providerToolchain?.node === void 0 ? void 0 : (0, import_node_path80.dirname)(providerToolchain.node);
77785
77986
  const probeEnv = providerNodeDir === void 0 ? providerEnv : {
77786
77987
  ...providerEnv,
77787
77988
  PATH: `${providerNodeDir}${pathDelimiter(process.platform)}${envValue(providerEnv, "PATH")}`
@@ -77791,7 +77992,7 @@ async function openManagedProviders(config2, paths) {
77791
77992
  throw new Error("Provider installer is unavailable on this computer");
77792
77993
  };
77793
77994
  const managed = createManagedProviderClis({
77794
- root: (0, import_node_path79.join)(paths.stateDir, "provider-clis"),
77995
+ root: (0, import_node_path80.join)(paths.stateDir, "provider-clis"),
77795
77996
  resolveVersion: npmOptions === null ? unavailable : createNpmVersionResolver(npmOptions),
77796
77997
  installPackage: npmOptions === null ? unavailable : createNpmPackageInstaller(npmOptions),
77797
77998
  probe: (executable, backendKind) => probeManagedProvider(executable, backendKind, canonicalProbeEnv)
@@ -77823,7 +78024,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
77823
78024
  waitMs: lockWaitMs(argv),
77824
78025
  signal: stop
77825
78026
  }));
77826
- const log = __using(_stack, openFileLog((0, import_node_path79.join)(paths.logs, "runtime.jsonl"), config2.logLevel, clock));
78027
+ const log = __using(_stack, openFileLog((0, import_node_path80.join)(paths.logs, "runtime.jsonl"), config2.logLevel, clock));
77827
78028
  const lifecycle = createLifecycleQueue({ clock, log });
77828
78029
  const install2 = installLayout(config2.installDir, config2.profile);
77829
78030
  const bundlePath = process.argv[1] ?? "";
@@ -77857,7 +78058,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
77857
78058
  openCliEnvironment({
77858
78059
  env: readCliEnvironment(),
77859
78060
  platform: process.platform,
77860
- lastKnownGoodFile: (0, import_node_path79.join)(paths.stateDir, "login-path.json"),
78061
+ lastKnownGoodFile: (0, import_node_path80.join)(paths.stateDir, "login-path.json"),
77861
78062
  clock,
77862
78063
  decorate: (env) => withPackagedAlanCodeEngine(env, bundlePath, process.platform)
77863
78064
  })
@@ -78034,17 +78235,17 @@ async function runServiceCommand(argv, ctx = cliContext()) {
78034
78235
  }
78035
78236
 
78036
78237
  // src/cli/commands/upgrade.ts
78037
- var import_promises76 = require("fs/promises");
78038
- var import_node_path80 = require("path");
78238
+ var import_promises77 = require("fs/promises");
78239
+ var import_node_path81 = require("path");
78039
78240
  function isNotNewer(version2, installed) {
78040
78241
  return installed !== null && isReleaseVersion(version2) && isReleaseVersion(installed) && compareVersions(version2, installed) <= 0;
78041
78242
  }
78042
78243
  async function installFromSource(source) {
78043
78244
  const { layout, from, ifNewer } = source;
78044
- const isTarball = (await (0, import_promises76.stat)(from)).isFile();
78045
- const downloads = (0, import_node_path80.join)(layout.root, ".downloads");
78046
- if (isTarball) await (0, import_promises76.mkdir)(downloads, { recursive: true, mode: 448 });
78047
- const scratch = isTarball ? await (0, import_promises76.mkdtemp)((0, import_node_path80.join)(downloads, "upgrade-")) : null;
78245
+ const isTarball = (await (0, import_promises77.stat)(from)).isFile();
78246
+ const downloads = (0, import_node_path81.join)(layout.root, ".downloads");
78247
+ if (isTarball) await (0, import_promises77.mkdir)(downloads, { recursive: true, mode: 448 });
78248
+ const scratch = isTarball ? await (0, import_promises77.mkdtemp)((0, import_node_path81.join)(downloads, "upgrade-")) : null;
78048
78249
  try {
78049
78250
  const sourceDir = scratch === null ? from : await extractPackageTarball(from, scratch);
78050
78251
  const version2 = await readPackageVersion(sourceDir);
@@ -78052,7 +78253,7 @@ async function installFromSource(source) {
78052
78253
  if (ifNewer && isNotNewer(version2, installed)) return { kind: "skipped", version: version2, installed };
78053
78254
  return { kind: "installed", ...await installVersion(layout, sourceDir) };
78054
78255
  } finally {
78055
- if (scratch !== null) await (0, import_promises76.rm)(scratch, { recursive: true, force: true });
78256
+ if (scratch !== null) await (0, import_promises77.rm)(scratch, { recursive: true, force: true });
78056
78257
  }
78057
78258
  }
78058
78259
  async function runUpgrade(argv) {
@@ -78064,7 +78265,7 @@ async function runUpgrade(argv) {
78064
78265
  const layout = installLayout(config2.installDir, config2.profile);
78065
78266
  const outcome2 = await installFromSource({
78066
78267
  layout,
78067
- from: (0, import_node_path80.resolve)(from),
78268
+ from: (0, import_node_path81.resolve)(from),
78068
78269
  ifNewer: hasFlag(argv, "--if-newer")
78069
78270
  });
78070
78271
  if (outcome2.kind === "skipped") {