@alan-ai-hq/agent-manager-darwin-arm64 0.1.143 → 0.1.144

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.
Files changed (3) hide show
  1. package/alan-agent.cjs +895 -631
  2. package/alan-holder.cjs +424 -367
  3. package/package.json +1 -1
package/alan-agent.cjs CHANGED
@@ -21524,37 +21524,15 @@ Platform Documents are the default destination and source of truth for PM work.
21524
21524
 
21525
21525
  Do NOT call \`create_plan\`, \`create_document_artifact\`, or another artifact-creation tool unless the user explicitly asks for an **artifact**. If \`create_document\` is unavailable or fails, report that blocker; do not silently substitute an artifact.
21526
21526
 
21527
- ## Platform knowledge lookups
21527
+ ## Evidence and source selection
21528
21528
 
21529
- The Alan platform is where product truth lives: tasks, subtasks, decisions, events, sessions, artifacts, context, and Documents. For that platform knowledge, local files and shell commands are a **last resort**, not a starting point. Browser and computer use remain available for authorized UI inspection and QA.
21529
+ Follow the shared tool-choice guidance. Use platform Documents for team requirements, PRDs, specifications, and decisions: resolve named records with \`find_records\`, browse with \`list_documents\`, and read with \`get_document\`. Use task, session, and artifact tools for their respective records.
21530
21530
 
21531
- **Before every platform knowledge lookup, ask: does the platform know this?** If a platform MCP tool could plausibly answer the question, you MUST call it before any \`Read\`, \`Glob\`, \`Grep\`, or \`Bash\`. Reaching for a local tool first is a mistake even when it would be faster or you already know the file path. Inspecting transient UI state is product QA, not a platform knowledge lookup.
21531
+ Use browser and computer tools to inspect live interfaces, and local read-only tools for repository documentation, source, logs, and version history when relevant. Prefer the source the user names. Words such as "notes" or "docs" alone do not forbid repository inspection; use the available context to identify the likely source.
21532
21532
 
21533
- | What you want | Use this | Not this |
21534
- |---|---|---|
21535
- | Requirements, PRDs, specs, notes, any written knowledge | \`list_documents\`, \`find_records\`, \`get_document\` | reading \`docs/\`, \`notes/\`, \`README.md\` |
21536
- | Scope, status, priority, or history of work | \`get_task\`, \`list_subtasks\`, \`list_tasks\` | \`git log\`, commit messages |
21537
- | What was decided and why | \`list_task_decisions\`, \`list_task_events\` | code comments, in-repo ADRs |
21538
- | What an agent did or is doing | \`list_sessions\`, \`get_session_context\` | \`git log\`, diffing the worktree |
21539
- | Prior agent context | \`list_task_events\`, \`get_session_context\` | scratch files |
21540
- | Outputs of completed work | \`list_artifacts\`, \`get_artifact\` | build output, generated files |
21541
- | Where code lives or how it works | \`search_code_context\` first, then \`Read\` the cited files | \`Grep\`/\`Glob\` sweeps |
21533
+ When a platform search is empty or unavailable, continue with other relevant permitted sources and state any evidence gap. Do not treat repository evidence as proof of a missing platform record, and do not bypass denied platform actions. Ask one targeted question only when the ambiguity prevents useful progress.
21542
21534
 
21543
- **If you do fall back to a local tool, say so out loud** \u2014 name the platform tool you tried and what it returned (nothing, unavailable, insufficient). A silent local read is a violation of this rule. If no platform tool was tried, you have not earned the local read.
21544
-
21545
- Code is the exception that proves the rule: understanding how something works legitimately ends in reading source. Even then, start with \`search_code_context\` and read only the files it cites.
21546
-
21547
- **Default for written knowledge: platform Documents.** Any request to find, check, consult, review, summarize, or answer from written knowledge resolves against platform Documents \u2014 use \`list_documents\` or \`find_records\` with \`kinds=["document"]\` to locate it, then \`get_document\` to read it. If a document ID is already known, call \`get_document\` directly.
21548
-
21549
- This applies no matter which word the user uses. Treat all of these as the same request: docs, documentation, documents, notes, PRD, spec, requirements, design doc, plan, proposal, RFC, wiki, runbook, onboarding, guidelines, "what did we decide", "what did we write down", "what do we have on X". The noun never changes where you look.
21550
-
21551
- **Local repository files are off-limits for knowledge lookup** unless the user unambiguously points you at the repository. Do not read \`README.md\`, \`AGENTS.md\`, \`notes/\`, \`docs/\`, or any other in-repo file as a fallback, as corroboration, because no platform document matched, or because the user's wording happens to match a directory name.
21552
-
21553
- A bare noun is never a pointer to the repository. "Check the notes" means platform Documents, not \`notes/\`. "Check the docs" means platform Documents, not \`docs/\`. Only these count as pointing at the repository:
21554
- - an explicit location \u2014 "in the repo", "in the codebase", "local files", "on disk", "in the worktree"
21555
- - a concrete path or filename \u2014 \`notes/foo.md\`, \`AGENTS.md\`, "the readme"
21556
-
21557
- When platform Documents do not cover the question, stop and say so, then offer to check the repository. Do not read local files first, and do not guess. Cite which document answered the question.
21535
+ For team code discovery, follow the shared \`search_code_context\` guidance, verify cited files locally, and use focused local searches when needed.
21558
21536
 
21559
21537
  ## Your primary tools
21560
21538
 
@@ -22066,18 +22044,23 @@ var init_system_prompt = __esm({
22066
22044
  init_agent_definitions();
22067
22045
  ALAN_CONTEXT_SEARCH_PROMPT = `## Memory (non-code context)
22068
22046
 
22069
- The codebase records what the system does. It does not record why it is that way, what was ruled out, what an outside constraint forbids, or what someone was left owed. That record lives in \`search_context\` \u2014 this team's decisions, constraints, procedures, ownership, rejected approaches and unfinished work.
22047
+ Use \`search_context\` first for team-specific decisions, constraints, ownership, history, or unfinished work when the exact source is unknown. Skip it for source-code questions, general knowledge, fully specified mechanical work, or a known record ID.
22070
22048
 
22071
- Before answering or acting on a question about a past decision, ownership, history, or unfinished work whose exact source is unknown, call \`search_context\` first.
22049
+ Apply relevant retrieved decisions and cite their source. Compare them with current evidence; retrieved context can be incomplete or stale. If search is empty or unavailable, continue with other relevant permitted sources and explain any remaining evidence gap.
22072
22050
 
22073
- So when a turn depends on something the repository cannot tell you \u2014 a value chosen rather than tuned, an approach that may already have been tried, a boundary another team owns, work someone else left half-done \u2014 recover it before you answer or act. Reading the code, or the document someone named, does not settle it: those answer a different question, and one turn can need both.
22051
+ For questions about recent activity, inspect available evidence for the relevant time window. Use records for task history, browser tools for live interfaces, and source, logs, or version history for implementation changes. A reference to "recently" or "a few days ago" calls for evidence, not an answer from memory.`;
22052
+ ALAN_PLATFORM_TOOL_ROUTING_PROMPT = `## Tool choice
22074
22053
 
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.
22054
+ Choose tools by the evidence or action the request needs, whether the agent runs locally or in the cloud:
22055
+ - Use Alan MCP for canonical Alan records (tasks, sessions, documents, artifacts, and their relationships), platform actions such as managing runs or machines, and actions through a provider identity connected to Alan.
22056
+ - Use computer use and browser tools for live websites and interfaces, including the authenticated Alan app, transient DOM and CSS state, and product QA in development or test environments. When the user asks you to inspect a website or interface, use the available browser or computer tools without asking for permission again for ordinary inspection.
22057
+ - Use local file, shell, and diagnostic tools for repository source, version history, processes, logs, and runtime behavior. MCP is not a prerequisite for browser inspection or local diagnostics. Follow the codebase-index guidance for team code discovery.
22076
22058
 
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 and GitHub
22059
+ 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.
22079
22060
 
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.`;
22061
+ An empty search result is not a permission denial. Continue gathering evidence from relevant permitted sources rather than refusing the request because one source cannot answer. Distinguish observed facts from inference and name remaining evidence gaps.
22062
+
22063
+ If a needed tool is not exposed, use the host's tool-discovery mechanism once when available before claiming the capability is unavailable. If a canonical platform action remains unavailable or unauthorized, report it and stop that platform action only; continue independent debugging and testing. Do not use a shell CLI, browser, raw HTTP, or local files to bypass that action or its identity and authorization requirements. Do not bypass a workflow or role tool allowlist.`;
22081
22064
  ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end \u2014 plan, write, review, test, deploy.
22082
22065
 
22083
22066
  ## How Alan is structured
@@ -22101,7 +22084,7 @@ Team
22101
22084
  - Listen first. Don't jump to solutions. One question at a time, not a list.
22102
22085
  - Scan available context (task, subtasks, code, history) before asking questions you can answer yourself.
22103
22086
  - Challenge when off \u2014 never silently implement the wrong thing.
22104
- - Human leads, you propose. Proactive on reversible actions. Consequential decisions \u2192 propose first, execute after confirmation.
22087
+ - Act on the user's request and make reasonable implementation and tool choices within its scope. Do not ask again for permission already granted. Ask only when essential information is missing or an action requires additional authority.
22105
22088
  - Own mistakes. Wrong ID, jumped too fast \u2014 say so and fix it.
22106
22089
  - Write for a human reader. Task, subtask and epic descriptions, documents, artifacts and comments are read by people in the app, not parsed by agents. Lead with the outcome in one sentence, then short sections with headings and bullet lists. Spell out internal shorthand, and keep commit hashes, IDs and migration numbers out of sentences \u2014 put them in a trailing "References" list when they matter.
22107
22090
  - Think visually, proactively \u2014 not only when asked. Mermaid over paragraphs for architecture, flows, state, and schema. The same applies to data: when you're about to present a comparison, trend, breakdown, or status across several items, reach for a \`\`\`chart fence instead of a paragraph of numbers or a markdown table, even if the user never said the word "chart."
@@ -22554,7 +22537,7 @@ function plan(command, args, options) {
22554
22537
  function captureOutput(command, args, options) {
22555
22538
  const launch = plan(command, args, options);
22556
22539
  if (launch === void 0) return Promise.resolve(NEVER_STARTED);
22557
- return new Promise((resolve12) => {
22540
+ return new Promise((resolve13) => {
22558
22541
  (0, import_child_process.execFile)(
22559
22542
  launch.file,
22560
22543
  [...launch.args],
@@ -22568,7 +22551,7 @@ function captureOutput(command, args, options) {
22568
22551
  },
22569
22552
  (error61, stdout, stderr) => {
22570
22553
  const code = error61 && typeof error61.code === "number" ? error61.code : error61 ? void 0 : 0;
22571
- resolve12({ stdout, stderr, exitCode: code });
22554
+ resolve13({ stdout, stderr, exitCode: code });
22572
22555
  }
22573
22556
  );
22574
22557
  });
@@ -22618,10 +22601,10 @@ async function linuxStartTicks(pid) {
22618
22601
  }
22619
22602
  }
22620
22603
  function psStartTime(pid) {
22621
- return new Promise((resolve12) => {
22604
+ return new Promise((resolve13) => {
22622
22605
  (0, import_child_process2.execFile)("ps", ["-o", "lstart=", "-p", String(pid)], { timeout: 2e3 }, (error61, stdout) => {
22623
22606
  const text2 = stdout.trim();
22624
- resolve12(error61 || !text2 ? void 0 : text2);
22607
+ resolve13(error61 || !text2 ? void 0 : text2);
22625
22608
  });
22626
22609
  });
22627
22610
  }
@@ -22650,12 +22633,12 @@ function parseProcessList(text2) {
22650
22633
  }
22651
22634
  function listProcesses(platform3 = process.platform) {
22652
22635
  if (platform3 === "win32") return Promise.resolve([]);
22653
- return new Promise((resolve12) => {
22636
+ return new Promise((resolve13) => {
22654
22637
  (0, import_child_process3.execFile)(
22655
22638
  "ps",
22656
22639
  ["-A", "-o", "pid=,ppid=,pgid=,lstart="],
22657
22640
  { timeout: 5e3, maxBuffer: 8 * 1024 * 1024 },
22658
- (error61, stdout) => resolve12(error61 ? [] : parseProcessList(stdout))
22641
+ (error61, stdout) => resolve13(error61 ? [] : parseProcessList(stdout))
22659
22642
  );
22660
22643
  });
22661
22644
  }
@@ -22695,11 +22678,11 @@ async function taskkill(pid, options) {
22695
22678
  stdio: "ignore",
22696
22679
  windowsHide: true
22697
22680
  });
22698
- const exited = new Promise((resolve12) => {
22699
- killer.once("error", (error210) => resolve12(error210));
22681
+ const exited = new Promise((resolve13) => {
22682
+ killer.once("error", (error210) => resolve13(error210));
22700
22683
  killer.once(
22701
22684
  "exit",
22702
- (code, signal) => resolve12(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22685
+ (code, signal) => resolve13(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22703
22686
  );
22704
22687
  });
22705
22688
  const timedOut = clock.sleep(options.timeoutMs ?? DEFAULT_TASKKILL_TIMEOUT_MS, timeout.signal).then(() => new Error("taskkill timed out")).catch(() => void 0);
@@ -22955,10 +22938,10 @@ function spawnCli(options) {
22955
22938
  function waitForSpawn(child, command) {
22956
22939
  if (isWindowsJob(child)) return waitForWindowsJob(child, command);
22957
22940
  if (child.pid !== void 0) return Promise.resolve();
22958
- return new Promise((resolve12, reject) => {
22941
+ return new Promise((resolve13, reject) => {
22959
22942
  const onSpawn = () => {
22960
22943
  child.off("error", onError);
22961
- resolve12();
22944
+ resolve13();
22962
22945
  };
22963
22946
  const onError = (error61) => {
22964
22947
  child.off("spawn", onSpawn);
@@ -23349,69 +23332,47 @@ var init_models = __esm({
23349
23332
  maxOutputTokens: 16384
23350
23333
  },
23351
23334
  {
23352
- id: "z-ai/glm-4.7-flash",
23353
- name: "GLM 4.7 Flash",
23354
- description: "Fast GLM coding via Alan",
23335
+ id: "z-ai/glm-5.3",
23336
+ name: "GLM 5.3",
23337
+ description: "Z.ai's flagship for coding, agents and long-horizon work",
23355
23338
  enabled: true,
23356
23339
  isDefault: false,
23357
23340
  sortOrder: 30,
23358
- upstreamModelId: "z-ai/glm-4.7-flash",
23359
- contextWindow: 2e5,
23360
- maxOutputTokens: 8192
23361
- },
23362
- {
23363
- id: "z-ai/glm-4.7",
23364
- name: "GLM 4.7",
23365
- description: "GLM coding and multi-step agent work",
23366
- enabled: true,
23367
- isDefault: false,
23368
- sortOrder: 40,
23369
- upstreamModelId: "z-ai/glm-4.7",
23370
- contextWindow: 2e5,
23341
+ upstreamModelId: "z-ai/glm-5.3",
23342
+ contextWindow: 1048576,
23371
23343
  maxOutputTokens: 16384
23372
23344
  },
23373
23345
  {
23374
- id: "qwen/qwen3-coder-flash",
23375
- name: "Qwen3 Coder Flash",
23376
- description: "Fast Qwen coder via Alan",
23346
+ id: "z-ai/glm-5.3-flash",
23347
+ name: "GLM 5.3 Flash",
23348
+ description: "Fast multimodal GLM via Alan",
23377
23349
  enabled: true,
23378
23350
  isDefault: false,
23379
- sortOrder: 50,
23380
- upstreamModelId: "qwen/qwen3-coder-flash",
23381
- contextWindow: 128e3,
23382
- maxOutputTokens: 8192
23383
- },
23384
- {
23385
- id: "qwen/qwen3-coder",
23386
- name: "Qwen3 Coder",
23387
- description: "Open-weight oriented coding",
23388
- enabled: true,
23389
- isDefault: false,
23390
- sortOrder: 60,
23391
- upstreamModelId: "qwen/qwen3-coder",
23392
- contextWindow: 128e3,
23351
+ sortOrder: 40,
23352
+ upstreamModelId: "z-ai/glm-5.3-flash",
23353
+ contextWindow: 1048576,
23393
23354
  maxOutputTokens: 8192
23394
23355
  },
23395
23356
  {
23396
- id: "moonshotai/kimi-k2.6",
23397
- name: "Kimi K2.6",
23398
- description: "Fast Kimi for long-horizon coding",
23357
+ id: "qwen/qwen3.8-27b",
23358
+ name: "Qwen3.8 27B",
23359
+ description: "Qwen3.8 open-weight coding and agentic work",
23399
23360
  enabled: true,
23400
23361
  isDefault: false,
23401
- sortOrder: 70,
23402
- upstreamModelId: "moonshotai/kimi-k2.6",
23403
- contextWindow: 262144,
23362
+ sortOrder: 50,
23363
+ upstreamModelId: "qwen/qwen3.8-27b",
23364
+ contextWindow: 1e6,
23404
23365
  maxOutputTokens: 16384
23405
23366
  },
23406
23367
  {
23407
- id: "moonshotai/kimi-k2.7-code",
23408
- name: "Kimi K2.7 Code",
23409
- description: "Kimi coding specialist",
23368
+ id: "moonshotai/kimi-k3",
23369
+ name: "Kimi K3",
23370
+ description: "Moonshot's 2.8T open-weight flagship",
23410
23371
  enabled: true,
23411
23372
  isDefault: false,
23412
- sortOrder: 80,
23413
- upstreamModelId: "moonshotai/kimi-k2.7-code",
23414
- contextWindow: 262144,
23373
+ sortOrder: 60,
23374
+ upstreamModelId: "moonshotai/kimi-k3",
23375
+ contextWindow: 1048576,
23415
23376
  maxOutputTokens: 16384
23416
23377
  },
23417
23378
  {
@@ -23420,7 +23381,7 @@ var init_models = __esm({
23420
23381
  description: "Fast Nemotron via Alan",
23421
23382
  enabled: true,
23422
23383
  isDefault: false,
23423
- sortOrder: 90,
23384
+ sortOrder: 70,
23424
23385
  upstreamModelId: "nvidia/nemotron-3-nano-30b-a3b",
23425
23386
  contextWindow: 262144,
23426
23387
  maxOutputTokens: 8192
@@ -23431,7 +23392,7 @@ var init_models = __esm({
23431
23392
  description: "Mid-tier Nemotron via Alan",
23432
23393
  enabled: true,
23433
23394
  isDefault: false,
23434
- sortOrder: 100,
23395
+ sortOrder: 80,
23435
23396
  upstreamModelId: "nvidia/nemotron-3-super-120b-a12b",
23436
23397
  contextWindow: 262144,
23437
23398
  maxOutputTokens: 16384
@@ -23442,18 +23403,29 @@ var init_models = __esm({
23442
23403
  description: "Largest Nemotron via Alan",
23443
23404
  enabled: true,
23444
23405
  isDefault: false,
23445
- sortOrder: 110,
23406
+ sortOrder: 90,
23446
23407
  upstreamModelId: "nvidia/nemotron-3-ultra-550b-a55b",
23447
23408
  contextWindow: 262144,
23448
23409
  maxOutputTokens: 16384
23449
23410
  },
23411
+ {
23412
+ id: "nvidia/nemotron-3.5-lightning",
23413
+ name: "Nemotron 3.5 Lightning",
23414
+ description: "Small, fast Nemotron for high-volume work",
23415
+ enabled: true,
23416
+ isDefault: false,
23417
+ sortOrder: 100,
23418
+ upstreamModelId: "nvidia/nemotron-3.5-lightning",
23419
+ contextWindow: 262144,
23420
+ maxOutputTokens: 8192
23421
+ },
23450
23422
  {
23451
23423
  id: "meta/muse-spark-1.3-contributor",
23452
23424
  name: "Muse Spark 1.3 Contributor",
23453
23425
  description: "Cost-efficient Muse Spark (contributor tier)",
23454
23426
  enabled: true,
23455
23427
  isDefault: false,
23456
- sortOrder: 120,
23428
+ sortOrder: 110,
23457
23429
  upstreamModelId: "meta/muse-spark-1.3-contributor",
23458
23430
  contextWindow: 1048576,
23459
23431
  maxOutputTokens: 16384
@@ -23464,7 +23436,7 @@ var init_models = __esm({
23464
23436
  description: "Meta Muse Spark multimodal agentic coding",
23465
23437
  enabled: true,
23466
23438
  isDefault: false,
23467
- sortOrder: 130,
23439
+ sortOrder: 120,
23468
23440
  upstreamModelId: "meta/muse-spark-1.3",
23469
23441
  contextWindow: 1048576,
23470
23442
  maxOutputTokens: 16384
@@ -23475,7 +23447,7 @@ var init_models = __esm({
23475
23447
  description: "Prior Muse Spark contributor tier",
23476
23448
  enabled: true,
23477
23449
  isDefault: false,
23478
- sortOrder: 140,
23450
+ sortOrder: 130,
23479
23451
  upstreamModelId: "meta/muse-spark-1.2-contributor",
23480
23452
  contextWindow: 1048576,
23481
23453
  maxOutputTokens: 16384
@@ -26388,8 +26360,8 @@ function createJsonRpcPeer(writer, handlers) {
26388
26360
  },
26389
26361
  request: (method, params = {}) => {
26390
26362
  const id = counter.next++;
26391
- return new Promise((resolve12, reject) => {
26392
- pending.set(id, { method, resolve: resolve12, reject });
26363
+ return new Promise((resolve13, reject) => {
26364
+ pending.set(id, { method, resolve: resolve13, reject });
26393
26365
  writer.write({ id, method, params }).catch((error61) => {
26394
26366
  pending.delete(id);
26395
26367
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -26502,7 +26474,7 @@ function createNdjsonWriter(stream) {
26502
26474
  get writable() {
26503
26475
  return stream.writable && !stream.destroyed && failure6.error === void 0;
26504
26476
  },
26505
- write: (value2) => new Promise((resolve12, reject) => {
26477
+ write: (value2) => new Promise((resolve13, reject) => {
26506
26478
  if (failure6.error) {
26507
26479
  reject(failure6.error);
26508
26480
  return;
@@ -26514,7 +26486,7 @@ function createNdjsonWriter(stream) {
26514
26486
  stream.write(`${JSON.stringify(value2)}
26515
26487
  `, (error61) => {
26516
26488
  if (error61) reject(error61);
26517
- else resolve12();
26489
+ else resolve13();
26518
26490
  });
26519
26491
  }),
26520
26492
  end: () => {
@@ -26530,11 +26502,11 @@ function hostProcess(child, tree, options, handlers) {
26530
26502
  const stderr = new LineSplitter((line) => handlers.onStderrLine(line));
26531
26503
  child.stderr.on("data", (chunk) => stderr.push(chunk));
26532
26504
  child.stderr.once("end", () => stderr.flush());
26533
- const processExit = new Promise((resolve12) => {
26534
- child.once("exit", (code, signal) => resolve12({ code, signal }));
26505
+ const processExit = new Promise((resolve13) => {
26506
+ child.once("exit", (code, signal) => resolve13({ code, signal }));
26535
26507
  });
26536
- const outputEnded = new Promise((resolve12) => {
26537
- child.stdout.once("close", () => resolve12());
26508
+ const outputEnded = new Promise((resolve13) => {
26509
+ child.stdout.once("close", () => resolve13());
26538
26510
  });
26539
26511
  const watch = async () => {
26540
26512
  const { clock, stdoutDrainMs, log, name } = options;
@@ -26823,13 +26795,13 @@ var init_chunk_VMGVHPBB = __esm({
26823
26795
  const turnId = input2.turnId;
26824
26796
  let finish = () => {
26825
26797
  };
26826
- const done = new Promise((resolve12) => {
26798
+ const done = new Promise((resolve13) => {
26827
26799
  finish = (outcome2) => {
26828
26800
  if (this.#current?.id !== turnId) return;
26829
26801
  this.#current = void 0;
26830
26802
  if (this.#state === "busy") this.#state = "idle";
26831
26803
  this.#emit({ type: "turn_ended", turnId, outcome: outcome2 });
26832
- resolve12({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
26804
+ resolve13({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
26833
26805
  };
26834
26806
  });
26835
26807
  const pending = {
@@ -27057,7 +27029,7 @@ var init_chunk_J2KTV5FP = __esm({
27057
27029
  }
27058
27030
  });
27059
27031
 
27060
- // ../agent-core/dist/chunk-ITTV3UIM.js
27032
+ // ../agent-core/dist/chunk-VX6QVMKD.js
27061
27033
  function truncate(value2, limit) {
27062
27034
  const normalized2 = Array.from(value2, (character) => {
27063
27035
  const code = character.charCodeAt(0);
@@ -27146,7 +27118,7 @@ function currentUserSection(user, visibility) {
27146
27118
  if (user.name) lines2.push(`- **Name**: ${user.name}`);
27147
27119
  lines2.push(`- **Email**: ${user.email}`, `- **User ID**: ${user.id}`, "");
27148
27120
  lines2.push(
27149
- visibility === "team" ? "This session is shared with the team. When creating tasks or assigning work, create them on this team. The person above started the session." : visibility === "private" ? "This session is private to this person. When creating tasks or assigning work, default to assigning to this user unless explicitly instructed otherwise." : "This is the person who initiated this conversation. When creating tasks or assigning work, default to assigning to this user unless explicitly instructed otherwise."
27121
+ visibility === "team" ? "This session is shared with the team. The person above sent the current request. When creating tasks or assigning work, create them on this team." : visibility === "private" ? "This session is private to this person. When creating tasks or assigning work, default to assigning to this user unless explicitly instructed otherwise." : "This is the person who initiated this conversation. When creating tasks or assigning work, default to assigning to this user unless explicitly instructed otherwise."
27150
27122
  );
27151
27123
  return lines2.join("\n");
27152
27124
  }
@@ -27418,8 +27390,8 @@ ${body}` : body;
27418
27390
  return spec.mode === "plan" ? planModePrefix(prefixed) : prefixed;
27419
27391
  }
27420
27392
  var MAX_PARSED_ATTACHMENTS, MAX_PARSED_ATTACHMENT_CHARS, MAX_METADATA_CHARS, UNAVAILABLE, READ_ONLY_MODES, AGENT_MODES;
27421
- var init_chunk_ITTV3UIM = __esm({
27422
- "../agent-core/dist/chunk-ITTV3UIM.js"() {
27393
+ var init_chunk_VX6QVMKD = __esm({
27394
+ "../agent-core/dist/chunk-VX6QVMKD.js"() {
27423
27395
  "use strict";
27424
27396
  init_agent2();
27425
27397
  MAX_PARSED_ATTACHMENTS = 3;
@@ -27535,6 +27507,7 @@ function buildClaudeArgs(input2) {
27535
27507
  ...capabilities.supportsThinkingDisplay ? ["--thinking-display", "summarized"] : [],
27536
27508
  // Without it the whole answer lands in one frame at turn end.
27537
27509
  ...capabilities.supportsPartialMessages ? ["--include-partial-messages"] : [],
27510
+ ...capabilities.supportsPluginDir ? (input2.pluginDirs ?? []).flatMap((dir) => ["--plugin-dir", dir]) : [],
27538
27511
  ...option("--resume", input2.resumeId),
27539
27512
  "--chrome",
27540
27513
  ...input2.extraArgs ?? []
@@ -27547,18 +27520,21 @@ function createClaudeCapabilityProbe(probe = createFlagProbe()) {
27547
27520
  supportsApproveMcps,
27548
27521
  supportsThinkingDisplay,
27549
27522
  supportsPartialMessages,
27550
- supportsReplayUserMessages
27523
+ supportsReplayUserMessages,
27524
+ supportsPluginDir
27551
27525
  ] = await Promise.all([
27552
27526
  needsApproveMcps ? probe.supportsFlag(command, "--approve-mcps", env) : false,
27553
27527
  probe.supportsHiddenChoiceFlag(command, "--thinking-display", env),
27554
27528
  probe.supportsFlag(command, "--include-partial-messages", env),
27555
- probe.supportsFlag(command, "--replay-user-messages", env)
27529
+ probe.supportsFlag(command, "--replay-user-messages", env),
27530
+ probe.supportsFlag(command, "--plugin-dir", env)
27556
27531
  ]);
27557
27532
  return {
27558
27533
  supportsApproveMcps,
27559
27534
  supportsThinkingDisplay,
27560
27535
  supportsPartialMessages,
27561
- supportsReplayUserMessages
27536
+ supportsReplayUserMessages,
27537
+ supportsPluginDir
27562
27538
  };
27563
27539
  }
27564
27540
  };
@@ -28446,6 +28422,7 @@ function planClaudeSession(run2, context) {
28446
28422
  ...run2.selectedEffortLevel === void 0 ? {} : { effortLevel: run2.selectedEffortLevel },
28447
28423
  ...prompts.systemPrompt === void 0 ? {} : { systemPrompt: prompts.systemPrompt },
28448
28424
  ...prompts.systemPromptAppend === void 0 ? {} : { appendSystemPrompt: prompts.systemPromptAppend },
28425
+ ...context.pluginDirs?.length ? { pluginDirs: context.pluginDirs } : {},
28449
28426
  ...context.managedMcp === void 0 ? {} : {
28450
28427
  mcp: {
28451
28428
  alanMcpUrl: context.managedMcp.url,
@@ -28694,7 +28671,7 @@ var init_claude = __esm({
28694
28671
  init_chunk_54ZRJOQP();
28695
28672
  init_chunk_J2KTV5FP();
28696
28673
  init_chunk_M6YHY2EZ();
28697
- init_chunk_ITTV3UIM();
28674
+ init_chunk_VX6QVMKD();
28698
28675
  init_chunk_YXWJW7I5();
28699
28676
  init_effort();
28700
28677
  import_crypto6 = require("crypto");
@@ -29417,8 +29394,8 @@ var init_claude = __esm({
29417
29394
  }
29418
29395
  async #awaitTaskStop(requestId, taskId) {
29419
29396
  const timer = new AbortController();
29420
- const answered = new Promise((resolve12) => {
29421
- this.#taskStops.set(requestId, resolve12);
29397
+ const answered = new Promise((resolve13) => {
29398
+ this.#taskStops.set(requestId, resolve13);
29422
29399
  });
29423
29400
  const timeoutMs = this.#options.stopTaskTimeoutMs;
29424
29401
  const timedOut = this.#options.clock.sleep(timeoutMs, timer.signal).then(
@@ -29491,17 +29468,17 @@ var init_claude = __esm({
29491
29468
  };
29492
29469
  let markStarted = () => {
29493
29470
  };
29494
- const whenStarted = new Promise((resolve12) => {
29495
- markStarted = resolve12;
29471
+ const whenStarted = new Promise((resolve13) => {
29472
+ markStarted = resolve13;
29496
29473
  });
29497
- const done = new Promise((resolve12) => {
29474
+ const done = new Promise((resolve13) => {
29498
29475
  finish = (outcome2) => {
29499
29476
  if (this.#current?.id !== id) return;
29500
29477
  this.#current = void 0;
29501
29478
  this.#lastTurn = turn;
29502
29479
  if (this.#state === "busy") this.#state = "idle";
29503
29480
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
29504
- resolve12({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
29481
+ resolve13({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
29505
29482
  };
29506
29483
  });
29507
29484
  const active = {
@@ -29619,8 +29596,8 @@ var init_claude = __esm({
29619
29596
  void removeLaunchFiles(this.#launchFiles).catch((error61) => {
29620
29597
  this.#options.log.warn("claude.launch_files_cleanup_failed", { error: error61 });
29621
29598
  });
29622
- for (const resolve12 of this.#taskStops.values()) {
29623
- resolve12({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
29599
+ for (const resolve13 of this.#taskStops.values()) {
29600
+ resolve13({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
29624
29601
  }
29625
29602
  const active = this.#current;
29626
29603
  if (active) {
@@ -31482,7 +31459,7 @@ var init_codex = __esm({
31482
31459
  init_chunk_54ZRJOQP();
31483
31460
  init_chunk_J2KTV5FP();
31484
31461
  init_chunk_M6YHY2EZ();
31485
- init_chunk_ITTV3UIM();
31462
+ init_chunk_VX6QVMKD();
31486
31463
  init_chunk_YXWJW7I5();
31487
31464
  import_fs6 = require("fs");
31488
31465
  import_path6 = require("path");
@@ -32101,10 +32078,10 @@ var init_codex = __esm({
32101
32078
  };
32102
32079
  let identify = () => {
32103
32080
  };
32104
- const identified = new Promise((resolve12) => {
32105
- identify = resolve12;
32081
+ const identified = new Promise((resolve13) => {
32082
+ identify = resolve13;
32106
32083
  });
32107
- const done = new Promise((resolve12) => {
32084
+ const done = new Promise((resolve13) => {
32108
32085
  finish = (outcome2) => {
32109
32086
  if (this.#current?.id !== id) return;
32110
32087
  this.#current = void 0;
@@ -32112,7 +32089,7 @@ var init_codex = __esm({
32112
32089
  if (this.#state === "busy") this.#state = "idle";
32113
32090
  this.#host.scanDescendants(true);
32114
32091
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
32115
- resolve12({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
32092
+ resolve13({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
32116
32093
  };
32117
32094
  });
32118
32095
  const active = {
@@ -32625,6 +32602,11 @@ function alanCodeConfigContent(existing, input2) {
32625
32602
  return JSON.stringify({
32626
32603
  $schema: "https://opencode.ai/config.json",
32627
32604
  ...config2,
32605
+ // OpenCode writes a whole working-tree diff into every user message summary and re-persists
32606
+ // the message on each update, so a large diff lands in the shared store many times over:
32607
+ // 3.4 GB of a dev machine's engine database was these patches, against 82 sessions. Alan
32608
+ // does not use the engine's undo/revert, so the tracking stays off.
32609
+ snapshot: false,
32628
32610
  model: `${ALAN_CODE_ENGINE_PROVIDER_ID}/${input2.modelId}`,
32629
32611
  enabled_providers: [ALAN_CODE_ENGINE_PROVIDER_ID],
32630
32612
  provider: {
@@ -32650,7 +32632,7 @@ function alanCodeConfigContent(existing, input2) {
32650
32632
  });
32651
32633
  }
32652
32634
  function readBody2(response) {
32653
- return new Promise((resolve12, reject) => {
32635
+ return new Promise((resolve13, reject) => {
32654
32636
  const chunks = [];
32655
32637
  let size = 0;
32656
32638
  response.on("data", (chunk) => {
@@ -32658,7 +32640,7 @@ function readBody2(response) {
32658
32640
  if (size > MAX_CATALOG_BYTES) response.destroy(new Error("catalog too large"));
32659
32641
  else chunks.push(chunk);
32660
32642
  });
32661
- response.on("end", () => resolve12(Buffer.concat(chunks).toString("utf8")));
32643
+ response.on("end", () => resolve13(Buffer.concat(chunks).toString("utf8")));
32662
32644
  response.on("error", reject);
32663
32645
  });
32664
32646
  }
@@ -32674,13 +32656,13 @@ function parseResponseBody(text2, status) {
32674
32656
  }
32675
32657
  function getJson(url3, headers, timeout, signal) {
32676
32658
  const request2 = url3.protocol === "https:" ? import_https.request : import_http9.request;
32677
- return new Promise((resolve12, reject) => {
32659
+ return new Promise((resolve13, reject) => {
32678
32660
  const outgoing = request2(url3, { method: "GET", headers, timeout, signal }, (response) => {
32679
32661
  const status = response.statusCode ?? 0;
32680
32662
  readBody2(response).then((text2) => {
32681
32663
  const body = parseResponseBody(text2, status);
32682
32664
  if (status < 200 || status >= 300) reject(new CatalogResponseError(status, body));
32683
- else resolve12(body);
32665
+ else resolve13(body);
32684
32666
  }).catch(reject);
32685
32667
  });
32686
32668
  outgoing.on("timeout", () => outgoing.destroy(new Error("catalog timed out")));
@@ -41556,8 +41538,8 @@ var require_streamx = __commonJS({
41556
41538
  return this;
41557
41539
  },
41558
41540
  next() {
41559
- return new Promise(function(resolve12, reject) {
41560
- promiseResolve = resolve12;
41541
+ return new Promise(function(resolve13, reject) {
41542
+ promiseResolve = resolve13;
41561
41543
  promiseReject = reject;
41562
41544
  const data = stream.read();
41563
41545
  if (data !== null) ondata(data);
@@ -41590,11 +41572,11 @@ var require_streamx = __commonJS({
41590
41572
  }
41591
41573
  function destroy(err) {
41592
41574
  stream.destroy(err);
41593
- return new Promise((resolve12, reject) => {
41594
- if (stream._duplexState & DESTROYED) return resolve12({ value: void 0, done: true });
41575
+ return new Promise((resolve13, reject) => {
41576
+ if (stream._duplexState & DESTROYED) return resolve13({ value: void 0, done: true });
41595
41577
  stream.once("close", function() {
41596
41578
  if (err) reject(err);
41597
- else resolve12({ value: void 0, done: true });
41579
+ else resolve13({ value: void 0, done: true });
41598
41580
  });
41599
41581
  });
41600
41582
  }
@@ -41638,8 +41620,8 @@ var require_streamx = __commonJS({
41638
41620
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
41639
41621
  if (writes === 0) return Promise.resolve(true);
41640
41622
  if (state.drains === null) state.drains = [];
41641
- return new Promise((resolve12) => {
41642
- state.drains.push({ writes, resolve: resolve12 });
41623
+ return new Promise((resolve13) => {
41624
+ state.drains.push({ writes, resolve: resolve13 });
41643
41625
  });
41644
41626
  }
41645
41627
  write(data) {
@@ -41744,10 +41726,10 @@ var require_streamx = __commonJS({
41744
41726
  cb(null);
41745
41727
  }
41746
41728
  function pipelinePromise(...streams) {
41747
- return new Promise((resolve12, reject) => {
41729
+ return new Promise((resolve13, reject) => {
41748
41730
  return pipeline(...streams, (err) => {
41749
41731
  if (err) return reject(err);
41750
- resolve12();
41732
+ resolve13();
41751
41733
  });
41752
41734
  });
41753
41735
  }
@@ -42419,16 +42401,16 @@ var require_extract = __commonJS({
42419
42401
  entryCallback = null;
42420
42402
  cb(err);
42421
42403
  }
42422
- function onnext(resolve12, reject) {
42404
+ function onnext(resolve13, reject) {
42423
42405
  if (error61) {
42424
42406
  return reject(error61);
42425
42407
  }
42426
42408
  if (entryStream) {
42427
- resolve12({ value: entryStream, done: false });
42409
+ resolve13({ value: entryStream, done: false });
42428
42410
  entryStream = null;
42429
42411
  return;
42430
42412
  }
42431
- promiseResolve = resolve12;
42413
+ promiseResolve = resolve13;
42432
42414
  promiseReject = reject;
42433
42415
  consumeCallback(null);
42434
42416
  if (extract2._finished && promiseResolve) {
@@ -42456,11 +42438,11 @@ var require_extract = __commonJS({
42456
42438
  function destroy(err) {
42457
42439
  extract2.destroy(err);
42458
42440
  consumeCallback(err);
42459
- return new Promise((resolve12, reject) => {
42460
- if (extract2.destroyed) return resolve12({ value: void 0, done: true });
42441
+ return new Promise((resolve13, reject) => {
42442
+ if (extract2.destroyed) return resolve13({ value: void 0, done: true });
42461
42443
  extract2.once("close", function() {
42462
42444
  if (err) reject(err);
42463
- else resolve12({ value: void 0, done: true });
42445
+ else resolve13({ value: void 0, done: true });
42464
42446
  });
42465
42447
  });
42466
42448
  }
@@ -42842,7 +42824,7 @@ function within(root, path4) {
42842
42824
  }
42843
42825
  async function resolveReal(path4) {
42844
42826
  try {
42845
- return await (0, import_promises48.realpath)(path4);
42827
+ return await (0, import_promises49.realpath)(path4);
42846
42828
  } catch {
42847
42829
  const parent = (0, import_path9.dirname)(path4);
42848
42830
  if (parent === path4) return path4;
@@ -42871,14 +42853,14 @@ function createWorkspaceFs(roots, writable) {
42871
42853
  return {
42872
42854
  read: async (params) => {
42873
42855
  const path4 = await confined(params);
42874
- const bytes = await (0, import_promises48.readFile)(path4);
42856
+ const bytes = await (0, import_promises49.readFile)(path4);
42875
42857
  if (bytes.byteLength > MAX_READ_BYTES) throw new FsDenied(`${path4} is too large to read`);
42876
42858
  return { content: sliceLines(bytes.toString("utf8"), params) };
42877
42859
  },
42878
42860
  write: async (params) => {
42879
42861
  if (!writable) throw new FsDenied("This session is read-only");
42880
42862
  const path4 = await confined(params);
42881
- await (0, import_promises48.writeFile)(path4, asString(params.content));
42863
+ await (0, import_promises49.writeFile)(path4, asString(params.content));
42882
42864
  return {};
42883
42865
  }
42884
42866
  };
@@ -43481,7 +43463,7 @@ async function acpTurnInput(run2, context) {
43481
43463
  const encoded = await Promise.all(
43482
43464
  images.map(async (image) => ({
43483
43465
  mimeType: image.mimeType,
43484
- data: (await (0, import_promises49.readFile)(image.path)).toString("base64")
43466
+ data: (await (0, import_promises50.readFile)(image.path)).toString("base64")
43485
43467
  }))
43486
43468
  );
43487
43469
  return {
@@ -43490,7 +43472,7 @@ async function acpTurnInput(run2, context) {
43490
43472
  ...encoded.length ? { images: encoded, imagePaths: images.map((image) => image.path) } : {}
43491
43473
  };
43492
43474
  }
43493
- var import_promises48, import_path9, import_crypto12, import_promises49, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES2, READ_KINDS, ALLOW_KINDS, REJECT_KINDS, CANCELLED_PERMISSION, STOP_REASONS, CHUNKS, ECHOES, AcpTurn, STDERR_TAIL_LINES4, MAX_BETWEEN_UPDATES2, AcpSession, DEFAULTS3, CLIENT_INFO2, TASK_BACKGROUNDED, TASK_COMPLETED, SESSION_NOTIFICATION, KILLED_STATUSES, SUCCESS_STATUSES, SUBAGENT_ID, grokTaskDialect, grokAcpProfile, kimiAcpProfile, ACP_PROFILES, ACP_MODES;
43475
+ var import_promises49, import_path9, import_crypto12, import_promises50, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES2, READ_KINDS, ALLOW_KINDS, REJECT_KINDS, CANCELLED_PERMISSION, STOP_REASONS, CHUNKS, ECHOES, AcpTurn, STDERR_TAIL_LINES4, MAX_BETWEEN_UPDATES2, AcpSession, DEFAULTS3, CLIENT_INFO2, TASK_BACKGROUNDED, TASK_COMPLETED, SESSION_NOTIFICATION, KILLED_STATUSES, SUCCESS_STATUSES, SUBAGENT_ID, grokTaskDialect, grokAcpProfile, kimiAcpProfile, ACP_PROFILES, ACP_MODES;
43494
43476
  var init_acp3 = __esm({
43495
43477
  "../agent-core/dist/providers/acp.js"() {
43496
43478
  "use strict";
@@ -43499,14 +43481,14 @@ var init_acp3 = __esm({
43499
43481
  init_chunk_54ZRJOQP();
43500
43482
  init_chunk_J2KTV5FP();
43501
43483
  init_chunk_M6YHY2EZ();
43502
- init_chunk_ITTV3UIM();
43484
+ init_chunk_VX6QVMKD();
43503
43485
  init_chunk_YXWJW7I5();
43504
- import_promises48 = require("fs/promises");
43486
+ import_promises49 = require("fs/promises");
43505
43487
  import_path9 = require("path");
43506
43488
  init_effort();
43507
43489
  init_acp();
43508
43490
  import_crypto12 = require("crypto");
43509
- import_promises49 = require("fs/promises");
43491
+ import_promises50 = require("fs/promises");
43510
43492
  init_agent2();
43511
43493
  CURSOR_ASK_QUESTION = "cursor/ask_question";
43512
43494
  copilotAcpProfile = {
@@ -44022,7 +44004,7 @@ var init_acp3 = __esm({
44022
44004
  const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile);
44023
44005
  let finish = () => {
44024
44006
  };
44025
- const done = new Promise((resolve12) => {
44007
+ const done = new Promise((resolve13) => {
44026
44008
  finish = (outcome2) => {
44027
44009
  if (this.#current?.id !== id) return;
44028
44010
  this.#current = void 0;
@@ -44030,7 +44012,7 @@ var init_acp3 = __esm({
44030
44012
  if (this.#state === "busy") this.#state = "idle";
44031
44013
  this.#host.scanDescendants(true);
44032
44014
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
44033
- resolve12({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
44015
+ resolve13({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
44034
44016
  };
44035
44017
  });
44036
44018
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -44726,10 +44708,14 @@ function openCodeConfigContent(input2) {
44726
44708
  enabled: true
44727
44709
  };
44728
44710
  }
44711
+ const skills = asRecord(config2.skills) ?? {};
44712
+ const ownPaths = Array.isArray(skills.paths) ? skills.paths : [];
44713
+ const skillPaths = input2.skillPaths ?? [];
44729
44714
  return JSON.stringify({
44730
44715
  ...config2,
44731
44716
  ...input2.readOnly ? {} : { permission: "allow" },
44732
- ...Object.keys(mcp).length ? { mcp } : {}
44717
+ ...Object.keys(mcp).length ? { mcp } : {},
44718
+ ...skillPaths.length ? { skills: { ...skills, paths: [...ownPaths, ...skillPaths] } } : {}
44733
44719
  });
44734
44720
  }
44735
44721
  function storedParts(message2) {
@@ -45024,7 +45010,7 @@ async function sameDirectory(left, right) {
45024
45010
  }
45025
45011
  async function canonicalDirectory(directory) {
45026
45012
  try {
45027
- return await (0, import_promises50.realpath)(directory);
45013
+ return await (0, import_promises51.realpath)(directory);
45028
45014
  } catch {
45029
45015
  return (0, import_path10.resolve)(directory);
45030
45016
  }
@@ -45049,6 +45035,57 @@ async function openSession(session, client, spec, log) {
45049
45035
  const id = await client.createSession({ title: spec.title, permission: NON_INTERACTIVE_RULES });
45050
45036
  return { id, resumed: false };
45051
45037
  }
45038
+ function isOpenTimeout(error61) {
45039
+ return error61 instanceof CoreFault && error61.code === "protocol_violation";
45040
+ }
45041
+ async function openOnce(spec, password, options) {
45042
+ const attempt2 = { abandoned: false };
45043
+ const { session, url: url3 } = await withDeadline3(
45044
+ startServer(spec, password, options, attempt2),
45045
+ options.clock,
45046
+ options.openTimeoutMs,
45047
+ "report a listening URL"
45048
+ ).catch(async (error61) => {
45049
+ attempt2.abandoned = true;
45050
+ await attempt2.current?.suspend().catch(() => void 0);
45051
+ throw error61;
45052
+ });
45053
+ try {
45054
+ const client = new OpenCodeClient(url3, password, options.engine.label);
45055
+ const opened = await withDeadline3(
45056
+ openSession(session, client, spec, options.log),
45057
+ options.clock,
45058
+ options.openTimeoutMs,
45059
+ "open a session"
45060
+ );
45061
+ session.attach(
45062
+ opened.id,
45063
+ spec.prompt,
45064
+ expiredSignInNotices(spec.env, options.clock.now()),
45065
+ opened.resumed
45066
+ );
45067
+ } catch (error61) {
45068
+ await session.suspend().catch(() => void 0);
45069
+ throw error61;
45070
+ }
45071
+ options.log.info("opencode.opened", {
45072
+ pid: session.pid,
45073
+ sessionId: session.providerSessionId,
45074
+ resumeFailed: session.resumeFailed
45075
+ });
45076
+ return session;
45077
+ }
45078
+ async function openWithRetries(spec, password, options) {
45079
+ for (let tries = 1; ; tries += 1) {
45080
+ try {
45081
+ return await openOnce(spec, password, options);
45082
+ } catch (error61) {
45083
+ if (!isOpenTimeout(error61) || tries >= options.openAttempts) throw error61;
45084
+ options.log.warn("opencode.open_retry", { tries });
45085
+ await options.clock.sleep(options.reconnectDelayMs);
45086
+ }
45087
+ }
45088
+ }
45052
45089
  function createOpenCodeDriver(options = {}) {
45053
45090
  const resolved = {
45054
45091
  clock: options.clock ?? systemClock2,
@@ -45058,6 +45095,7 @@ function createOpenCodeDriver(options = {}) {
45058
45095
  stdoutDrainMs: options.stdoutDrainMs ?? DEFAULTS4.stdoutDrainMs,
45059
45096
  descendantScanMs: options.descendantScanMs ?? DEFAULTS4.descendantScanMs,
45060
45097
  openTimeoutMs: options.openTimeoutMs ?? DEFAULTS4.openTimeoutMs,
45098
+ openAttempts: options.openAttempts ?? DEFAULTS4.openAttempts,
45061
45099
  startAttempts: options.startAttempts ?? DEFAULTS4.startAttempts,
45062
45100
  reconnectAttempts: options.reconnectAttempts ?? DEFAULTS4.reconnectAttempts,
45063
45101
  reconnectDelayMs: options.reconnectDelayMs ?? DEFAULTS4.reconnectDelayMs,
@@ -45073,45 +45111,16 @@ function createOpenCodeDriver(options = {}) {
45073
45111
  };
45074
45112
  const spec = { ...planned, env: launchEnv(planned, authorization) };
45075
45113
  const password = options.password?.() ?? (0, import_crypto13.randomBytes)(24).toString("base64url");
45076
- const attempt2 = { abandoned: false };
45077
- const { session, url: url3 } = await withDeadline3(
45078
- startServer(spec, password, resolved, attempt2),
45079
- resolved.clock,
45080
- resolved.openTimeoutMs,
45081
- "report a listening URL"
45082
- ).catch(async (error61) => {
45083
- attempt2.abandoned = true;
45084
- await attempt2.current?.suspend().catch(() => void 0);
45085
- await removeAuthorization();
45086
- throw error61;
45087
- });
45088
- void session.exited.then(removeAuthorization).catch((error61) => {
45089
- resolved.log.warn("opencode.authorization_cleanup_failed", { error: error61 });
45090
- });
45091
45114
  try {
45092
- const client = new OpenCodeClient(url3, password, resolved.engine.label);
45093
- const opened = await withDeadline3(
45094
- openSession(session, client, spec, resolved.log),
45095
- resolved.clock,
45096
- resolved.openTimeoutMs,
45097
- "open a session"
45098
- );
45099
- session.attach(
45100
- opened.id,
45101
- spec.prompt,
45102
- expiredSignInNotices(spec.env, resolved.clock.now()),
45103
- opened.resumed
45104
- );
45115
+ const session = await openWithRetries(spec, password, resolved);
45116
+ void session.exited.then(removeAuthorization).catch((error61) => {
45117
+ resolved.log.warn("opencode.authorization_cleanup_failed", { error: error61 });
45118
+ });
45119
+ return session;
45105
45120
  } catch (error61) {
45106
- await session.suspend().catch(() => void 0);
45121
+ await removeAuthorization();
45107
45122
  throw error61;
45108
45123
  }
45109
- resolved.log.info("opencode.opened", {
45110
- pid: session.pid,
45111
- sessionId: session.providerSessionId,
45112
- resumeFailed: session.resumeFailed
45113
- });
45114
- return session;
45115
45124
  }
45116
45125
  };
45117
45126
  }
@@ -45144,6 +45153,7 @@ function planOpenCodeSession(run2, context) {
45144
45153
  const config2 = {
45145
45154
  existing: baseEnv[OPENCODE_CONFIG_ENV],
45146
45155
  readOnly,
45156
+ ...context.skillPaths?.length ? { skillPaths: context.skillPaths } : {},
45147
45157
  mcp: {
45148
45158
  conversationId: run2.conversationId,
45149
45159
  externalServers: mcp.servers,
@@ -45196,7 +45206,7 @@ function openCodeTurnInput(run2, context) {
45196
45206
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
45197
45207
  };
45198
45208
  }
45199
- var import_http10, import_crypto13, import_promises50, import_path10, import_path11, import_url2, import_crypto14, IDLE_SOCKET_MS3, OpenCodeHttpError, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
45209
+ var import_http10, import_crypto13, import_promises51, import_path10, import_path11, import_url2, import_crypto14, IDLE_SOCKET_MS3, OpenCodeHttpError, OpenCodeClient, OPENCODE_CONFIG_ENV, OPENCODE_ENGINE, TEXT_PARTS, STEP_PARTS, STOPPED_BY_USER, OpenCodeSubagents, NAMED_KINDS, OPENCODE_ABORTED_ERROR, PROVIDER_EVENT_META, TASK_TOOL_NAME, TASK_RESULT_TAG, TASK_ERROR_TAG, PERMISSION_DENIED, FILE_OPERATIONS2, PartReader, NOTHING, NON_INTERACTIVE_PERMISSIONS, CONTENT_FILTER_FINISHES, OUTPUT_PARTS, OpenCodeTurn, LISTENING, OUTPUT_TAIL_LINES, IMAGE_TYPES, OpenCodeSession, OPENCODE_MIN_VERSION, OPENCODE_REQUIREMENT, OPENCODE_TESTED_LINE, OPENCODE_SUPPORTED_MAJOR, DEFAULTS4, STORE_LOCKED, NON_INTERACTIVE_RULES, TITLE_LENGTH, MAX_VARIANT_LENGTH;
45200
45210
  var init_opencode = __esm({
45201
45211
  "../agent-core/dist/providers/opencode.js"() {
45202
45212
  "use strict";
@@ -45205,12 +45215,12 @@ var init_opencode = __esm({
45205
45215
  init_chunk_54ZRJOQP();
45206
45216
  init_chunk_J2KTV5FP();
45207
45217
  init_chunk_M6YHY2EZ();
45208
- init_chunk_ITTV3UIM();
45218
+ init_chunk_VX6QVMKD();
45209
45219
  init_chunk_YXWJW7I5();
45210
45220
  import_http10 = require("http");
45211
45221
  init_runtime_v2();
45212
45222
  import_crypto13 = require("crypto");
45213
- import_promises50 = require("fs/promises");
45223
+ import_promises51 = require("fs/promises");
45214
45224
  import_path10 = require("path");
45215
45225
  init_agent2();
45216
45226
  import_path11 = require("path");
@@ -46296,6 +46306,7 @@ var init_opencode = __esm({
46296
46306
  stdoutDrainMs: 2e3,
46297
46307
  descendantScanMs: 5e3,
46298
46308
  openTimeoutMs: 6e4,
46309
+ openAttempts: 2,
46299
46310
  startAttempts: 3,
46300
46311
  reconnectAttempts: 3,
46301
46312
  reconnectDelayMs: 500,
@@ -46374,6 +46385,7 @@ function createAlanCodeHolderDriver(options) {
46374
46385
  engineRoot,
46375
46386
  requestedModel: spec.model
46376
46387
  };
46388
+ const skills = options.installedSkills?.() ?? null;
46377
46389
  const planned = planOpenCodeSession(spec, {
46378
46390
  command: engine.command,
46379
46391
  cwd: spec.projectPath ?? options.defaultCwd,
@@ -46383,7 +46395,8 @@ function createAlanCodeHolderDriver(options) {
46383
46395
  },
46384
46396
  providerEnv: inputs.providerEnv,
46385
46397
  ...managedMcp === void 0 ? {} : { managedMcp },
46386
- ...resumeId === void 0 ? {} : { resumeSessionId: resumeId }
46398
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
46399
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
46387
46400
  });
46388
46401
  return {
46389
46402
  spec: { opencode: planned.spec, profile },
@@ -46434,14 +46447,18 @@ function createClaudeHolderDriver(options) {
46434
46447
  {
46435
46448
  harness: "claude_cli",
46436
46449
  displayName: "Claude CLI",
46437
- plan: (spec, inputs, resumeId, managedMcp) => planClaudeSession(spec, {
46438
- command: options.command ?? "claude",
46439
- cwd: spec.projectPath ?? options.defaultCwd,
46440
- cliEnv: options.cliEnvironment,
46441
- providerEnv: inputs.providerEnv,
46442
- ...managedMcp === void 0 ? {} : { managedMcp },
46443
- ...resumeId === void 0 ? {} : { resumeId }
46444
- }),
46450
+ plan: (spec, inputs, resumeId, managedMcp) => {
46451
+ const skills = options.installedSkills?.() ?? null;
46452
+ return planClaudeSession(spec, {
46453
+ command: options.command ?? "claude",
46454
+ cwd: spec.projectPath ?? options.defaultCwd,
46455
+ cliEnv: options.cliEnvironment,
46456
+ providerEnv: inputs.providerEnv,
46457
+ ...managedMcp === void 0 ? {} : { managedMcp },
46458
+ ...resumeId === void 0 ? {} : { resumeId },
46459
+ ...skills === null ? {} : { pluginDirs: [skills.pluginDir] }
46460
+ });
46461
+ },
46445
46462
  canResume: (planned, resumeId) => claudeSessionLogExists({
46446
46463
  sessionId: resumeId,
46447
46464
  cwd: planned.spec.cwd,
@@ -46478,7 +46495,7 @@ __export(codex_exports, {
46478
46495
  createCodexHolderDriver: () => createCodexHolderDriver
46479
46496
  });
46480
46497
  function sha2563(value2) {
46481
- return (0, import_node_crypto26.createHash)("sha256").update(value2).digest("hex");
46498
+ return (0, import_node_crypto27.createHash)("sha256").update(value2).digest("hex");
46482
46499
  }
46483
46500
  function createCodexLogin(broker) {
46484
46501
  const state = {};
@@ -46553,11 +46570,11 @@ function createCodexHolderDriver(options) {
46553
46570
  }
46554
46571
  );
46555
46572
  }
46556
- var import_node_crypto26;
46573
+ var import_node_crypto27;
46557
46574
  var init_codex2 = __esm({
46558
46575
  "src/holder/drivers/codex.ts"() {
46559
46576
  "use strict";
46560
- import_node_crypto26 = require("crypto");
46577
+ import_node_crypto27 = require("crypto");
46561
46578
  init_dist();
46562
46579
  init_codex();
46563
46580
  init_persistent();
@@ -46664,8 +46681,8 @@ function createDroidPeer(writer, handlers) {
46664
46681
  },
46665
46682
  request: (method, params = {}) => {
46666
46683
  const id = `alan-${counter.next++}`;
46667
- return new Promise((resolve12, reject) => {
46668
- pending.set(id, { method, resolve: resolve12, reject });
46684
+ return new Promise((resolve13, reject) => {
46685
+ pending.set(id, { method, resolve: resolve13, reject });
46669
46686
  writer.write(envelope("request", { id, method, params })).catch((error61) => {
46670
46687
  pending.delete(id);
46671
46688
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -47000,12 +47017,12 @@ async function droidTurnInput(run2, context) {
47000
47017
  const encoded = await Promise.all(
47001
47018
  images.map(async (image) => ({
47002
47019
  mimeType: image.mimeType,
47003
- data: (await (0, import_promises51.readFile)(image.path)).toString("base64")
47020
+ data: (await (0, import_promises52.readFile)(image.path)).toString("base64")
47004
47021
  }))
47005
47022
  );
47006
47023
  return { turnId: run2.runId, text: text2, ...encoded.length ? { images: encoded } : {} };
47007
47024
  }
47008
- var import_crypto15, import_promises51, FACTORY_API_VERSION, FACTORY_PROTOCOL_VERSION, SUBAGENT_TOOLS, TASK_OUTPUT_TOOLS, TASK_STOP_TOOLS, SILENT2, DroidTurn, STDERR_TAIL_LINES5, UNSUPPORTED_REQUEST2, DroidSession, DEFAULTS5, DROID_REQUIREMENT, DROID_JSONRPC_ARGS;
47025
+ var import_crypto15, import_promises52, FACTORY_API_VERSION, FACTORY_PROTOCOL_VERSION, SUBAGENT_TOOLS, TASK_OUTPUT_TOOLS, TASK_STOP_TOOLS, SILENT2, DroidTurn, STDERR_TAIL_LINES5, UNSUPPORTED_REQUEST2, DroidSession, DEFAULTS5, DROID_REQUIREMENT, DROID_JSONRPC_ARGS;
47009
47026
  var init_droid = __esm({
47010
47027
  "../agent-core/dist/providers/droid.js"() {
47011
47028
  "use strict";
@@ -47014,11 +47031,11 @@ var init_droid = __esm({
47014
47031
  init_chunk_54ZRJOQP();
47015
47032
  init_chunk_J2KTV5FP();
47016
47033
  init_chunk_M6YHY2EZ();
47017
- init_chunk_ITTV3UIM();
47034
+ init_chunk_VX6QVMKD();
47018
47035
  init_chunk_YXWJW7I5();
47019
47036
  init_runtime_v2();
47020
47037
  import_crypto15 = require("crypto");
47021
- import_promises51 = require("fs/promises");
47038
+ import_promises52 = require("fs/promises");
47022
47039
  init_agent2();
47023
47040
  FACTORY_API_VERSION = "1.0.0";
47024
47041
  FACTORY_PROTOCOL_VERSION = "1.187.0";
@@ -47290,14 +47307,14 @@ var init_droid = __esm({
47290
47307
  const turn = new DroidTurn(sessionId, this.#memory);
47291
47308
  let finish = () => {
47292
47309
  };
47293
- const done = new Promise((resolve12) => {
47310
+ const done = new Promise((resolve13) => {
47294
47311
  finish = (outcome2) => {
47295
47312
  if (this.#current?.id !== id) return;
47296
47313
  this.#current = void 0;
47297
47314
  if (this.#state === "busy") this.#state = "idle";
47298
47315
  this.#host.scanDescendants(true);
47299
47316
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
47300
- resolve12({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
47317
+ resolve13({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
47301
47318
  };
47302
47319
  });
47303
47320
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -47445,14 +47462,18 @@ function createOpenCodeHolderDriver(options) {
47445
47462
  {
47446
47463
  harness: "opencode_serve",
47447
47464
  displayName: "OpenCode server",
47448
- plan: (spec, inputs, resumeId, managedMcp) => planOpenCodeSession(spec, {
47449
- command: options.command ?? "opencode",
47450
- cwd: spec.projectPath ?? options.defaultCwd,
47451
- cliEnv: options.cliEnvironment,
47452
- providerEnv: inputs.providerEnv,
47453
- ...managedMcp === void 0 ? {} : { managedMcp },
47454
- ...resumeId === void 0 ? {} : { resumeSessionId: resumeId }
47455
- }),
47465
+ plan: (spec, inputs, resumeId, managedMcp) => {
47466
+ const skills = options.installedSkills?.() ?? null;
47467
+ return planOpenCodeSession(spec, {
47468
+ command: options.command ?? "opencode",
47469
+ cwd: spec.projectPath ?? options.defaultCwd,
47470
+ cliEnv: options.cliEnvironment,
47471
+ providerEnv: inputs.providerEnv,
47472
+ ...managedMcp === void 0 ? {} : { managedMcp },
47473
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
47474
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
47475
+ });
47476
+ },
47456
47477
  canResume: () => true,
47457
47478
  open: async (spec) => {
47458
47479
  const session = await sessions.open(spec);
@@ -47489,7 +47510,7 @@ function settingsPath(env) {
47489
47510
  async function readSettings2(path4) {
47490
47511
  let raw;
47491
47512
  try {
47492
- raw = (await (0, import_promises52.readFile)(path4, "utf8")).trim();
47513
+ raw = (await (0, import_promises53.readFile)(path4, "utf8")).trim();
47493
47514
  } catch {
47494
47515
  return {};
47495
47516
  }
@@ -47507,8 +47528,8 @@ async function selectAntigravityApiKeyMode(env) {
47507
47528
  const settings2 = await readSettings2(path4);
47508
47529
  if (settings2 === "malformed") return "malformed";
47509
47530
  if (settings2.modelProvider === "gemini") return "already_selected";
47510
- await (0, import_promises52.mkdir)((0, import_path12.dirname)(path4), { recursive: true });
47511
- await (0, import_promises52.writeFile)(path4, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
47531
+ await (0, import_promises53.mkdir)((0, import_path12.dirname)(path4), { recursive: true });
47532
+ await (0, import_promises53.writeFile)(path4, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
47512
47533
  return "selected";
47513
47534
  }
47514
47535
  function readAntigravityCapabilities(version2, help) {
@@ -48107,7 +48128,7 @@ function antigravityTurnInput(run2, context) {
48107
48128
  });
48108
48129
  return { turnId: run2.runId, text: appendImagePathReferences(text2, images) };
48109
48130
  }
48110
- var import_promises52, import_path12, import_fs8, import_path13, import_path14, import_url3, import_crypto16, NO_ANTIGRAVITY_CAPABILITIES, INSTRUCTIONS_FILE, MAX_INSTRUCTION_CHARS, SHORTENED_NOTE, DIFF_BLOCK_START, DIFF_BLOCK_END, HUNK_HEADER, TRANSCRIPT_FILE, FULL_TRANSCRIPT_FILE, LOG_DIRS, TOOL_RESULT_TYPES, BrainTranscript, AntigravityTranscripts, ANTIGRAVITY_GRAMMAR_NAME, AntigravityGrammar, ignored, HANDLERS, SUCCESSFUL_STATUSES, SESSION_START_TYPES, RESULT_TYPES, SUBAGENT_START_TYPES, RESUME_FORKED, EXITED_WITHOUT_RESULT, AntigravityTurn, DEFAULTS6, AntigravitySession, WINDOWS_LINE_MARGIN;
48131
+ var import_promises53, import_path12, import_fs8, import_path13, import_path14, import_url3, import_crypto16, NO_ANTIGRAVITY_CAPABILITIES, INSTRUCTIONS_FILE, MAX_INSTRUCTION_CHARS, SHORTENED_NOTE, DIFF_BLOCK_START, DIFF_BLOCK_END, HUNK_HEADER, TRANSCRIPT_FILE, FULL_TRANSCRIPT_FILE, LOG_DIRS, TOOL_RESULT_TYPES, BrainTranscript, AntigravityTranscripts, ANTIGRAVITY_GRAMMAR_NAME, AntigravityGrammar, ignored, HANDLERS, SUCCESSFUL_STATUSES, SESSION_START_TYPES, RESULT_TYPES, SUBAGENT_START_TYPES, RESUME_FORKED, EXITED_WITHOUT_RESULT, AntigravityTurn, DEFAULTS6, AntigravitySession, WINDOWS_LINE_MARGIN;
48111
48132
  var init_antigravity = __esm({
48112
48133
  "../agent-core/dist/providers/antigravity.js"() {
48113
48134
  "use strict";
@@ -48116,9 +48137,9 @@ var init_antigravity = __esm({
48116
48137
  init_chunk_XC5676SG();
48117
48138
  init_chunk_54ZRJOQP();
48118
48139
  init_chunk_M6YHY2EZ();
48119
- init_chunk_ITTV3UIM();
48140
+ init_chunk_VX6QVMKD();
48120
48141
  init_chunk_YXWJW7I5();
48121
- import_promises52 = require("fs/promises");
48142
+ import_promises53 = require("fs/promises");
48122
48143
  import_path12 = require("path");
48123
48144
  init_type_guards();
48124
48145
  import_fs8 = require("fs");
@@ -48618,7 +48639,7 @@ function parseConfig(raw) {
48618
48639
  }
48619
48640
  async function writeCommandCodeProjectMcp(cwd, mcp) {
48620
48641
  const path4 = (0, import_path15.join)(cwd, ".mcp.json");
48621
- const original = await (0, import_promises53.readFile)(path4, "utf8").catch(() => null);
48642
+ const original = await (0, import_promises54.readFile)(path4, "utf8").catch(() => null);
48622
48643
  const config2 = parseConfig(original);
48623
48644
  const next = {
48624
48645
  ...config2,
@@ -48635,12 +48656,12 @@ async function writeCommandCodeProjectMcp(cwd, mcp) {
48635
48656
  }
48636
48657
  }
48637
48658
  };
48638
- await (0, import_promises53.mkdir)(cwd, { recursive: true });
48639
- await (0, import_promises53.writeFile)(path4, `${JSON.stringify(next, null, 2)}
48659
+ await (0, import_promises54.mkdir)(cwd, { recursive: true });
48660
+ await (0, import_promises54.writeFile)(path4, `${JSON.stringify(next, null, 2)}
48640
48661
  `);
48641
48662
  return async () => {
48642
- if (original === null) await (0, import_promises53.rm)(path4, { force: true });
48643
- else await (0, import_promises53.writeFile)(path4, original);
48663
+ if (original === null) await (0, import_promises54.rm)(path4, { force: true });
48664
+ else await (0, import_promises54.writeFile)(path4, original);
48644
48665
  };
48645
48666
  }
48646
48667
  function commandCodeString(value2) {
@@ -48812,7 +48833,7 @@ function commandCodeTurnInput(run2, context) {
48812
48833
  });
48813
48834
  return { turnId: run2.runId, text: appendImagePathReferences(text2, images) };
48814
48835
  }
48815
- var import_promises53, import_path15, import_crypto17, COMMAND_CODE_GRAMMAR_NAME, SILENT3, CommandCodeGrammar, SHELL_TOOL, STOP_TOOLS, REPORTED_STATUS, SHELL_STATUS, SWEEP_INTERVAL_MS, CommandCodeBackgroundTasks, EXITED_WITHOUT_RESULT2, CommandCodeTurn, COMMAND_CODE_MAX_TURNS, DEFAULTS7, CommandCodeSession;
48836
+ var import_promises54, import_path15, import_crypto17, COMMAND_CODE_GRAMMAR_NAME, SILENT3, CommandCodeGrammar, SHELL_TOOL, STOP_TOOLS, REPORTED_STATUS, SHELL_STATUS, SWEEP_INTERVAL_MS, CommandCodeBackgroundTasks, EXITED_WITHOUT_RESULT2, CommandCodeTurn, COMMAND_CODE_MAX_TURNS, DEFAULTS7, CommandCodeSession;
48816
48837
  var init_command_code = __esm({
48817
48838
  "../agent-core/dist/providers/command-code.js"() {
48818
48839
  "use strict";
@@ -48821,9 +48842,9 @@ var init_command_code = __esm({
48821
48842
  init_chunk_54ZRJOQP();
48822
48843
  init_chunk_J2KTV5FP();
48823
48844
  init_chunk_M6YHY2EZ();
48824
- init_chunk_ITTV3UIM();
48845
+ init_chunk_VX6QVMKD();
48825
48846
  init_chunk_YXWJW7I5();
48826
- import_promises53 = require("fs/promises");
48847
+ import_promises54 = require("fs/promises");
48827
48848
  import_path15 = require("path");
48828
48849
  init_agent2();
48829
48850
  init_runtime_v2();
@@ -54219,7 +54240,7 @@ var require_websocket_server = __commonJS({
54219
54240
  // package.json
54220
54241
  var package_default = {
54221
54242
  name: "@alan-ai-hq/agent-manager",
54222
- version: "0.1.143",
54243
+ version: "0.1.144",
54223
54244
  private: true,
54224
54245
  type: "module",
54225
54246
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -54268,8 +54289,8 @@ var package_default = {
54268
54289
  };
54269
54290
 
54270
54291
  // src/cli/commands/compat.ts
54271
- var import_node_crypto31 = require("crypto");
54272
- var import_promises67 = require("fs/promises");
54292
+ var import_node_crypto32 = require("crypto");
54293
+ var import_promises68 = require("fs/promises");
54273
54294
  init_runtime_v2();
54274
54295
  init_zod();
54275
54296
 
@@ -54428,8 +54449,8 @@ async function writeJsonFileAtomic(path4, value2) {
54428
54449
  var LIFECYCLE_DRAIN_MS = 5e3;
54429
54450
  function createGate() {
54430
54451
  const opened = {};
54431
- const promise2 = new Promise((resolve12) => {
54432
- opened.resolve = resolve12;
54452
+ const promise2 = new Promise((resolve13) => {
54453
+ opened.resolve = resolve13;
54433
54454
  });
54434
54455
  return { promise: promise2, open: () => opened.resolve?.() };
54435
54456
  }
@@ -54656,7 +54677,7 @@ function transportFailure(request2, error61) {
54656
54677
  });
54657
54678
  }
54658
54679
  function readBody(incoming, url3, maxBytes) {
54659
- return new Promise((resolve12, reject) => {
54680
+ return new Promise((resolve13, reject) => {
54660
54681
  const declared = Number(incoming.headers["content-length"] ?? "0");
54661
54682
  if (maxBytes !== void 0 && declared > maxBytes) {
54662
54683
  incoming.destroy();
@@ -54675,7 +54696,7 @@ function readBody(incoming, url3, maxBytes) {
54675
54696
  chunks.push(chunk);
54676
54697
  });
54677
54698
  incoming.on("error", reject);
54678
- incoming.on("end", () => resolve12(Buffer.concat(chunks)));
54699
+ incoming.on("end", () => resolve13(Buffer.concat(chunks)));
54679
54700
  });
54680
54701
  }
54681
54702
  function isConnectionReset(error61) {
@@ -54683,7 +54704,7 @@ function isConnectionReset(error61) {
54683
54704
  }
54684
54705
  function exchange(request2, agents, attempt2 = 0) {
54685
54706
  const { signal, url: url3 } = request2;
54686
- return new Promise((resolve12, reject) => {
54707
+ return new Promise((resolve13, reject) => {
54687
54708
  if (signal.aborted) {
54688
54709
  reject(signal.reason);
54689
54710
  return;
@@ -54710,7 +54731,7 @@ function exchange(request2, agents, attempt2 = 0) {
54710
54731
  const stale = outgoing.reusedSocket && !responded && isConnectionReset(error61);
54711
54732
  if (stale && attempt2 < STALE_SOCKET_RETRIES && !signal.aborted) {
54712
54733
  settle();
54713
- resolve12(exchange(request2, agents, attempt2 + 1));
54734
+ resolve13(exchange(request2, agents, attempt2 + 1));
54714
54735
  return;
54715
54736
  }
54716
54737
  fail(error61);
@@ -54723,7 +54744,7 @@ function exchange(request2, agents, attempt2 = 0) {
54723
54744
  readBody(incoming, url3, isRedirect(status) ? void 0 : request2.maxBodyBytes).then(
54724
54745
  (body) => {
54725
54746
  settle();
54726
- resolve12({ status, headers: incoming.headers, body });
54747
+ resolve13({ status, headers: incoming.headers, body });
54727
54748
  },
54728
54749
  fail
54729
54750
  );
@@ -54968,8 +54989,8 @@ function isBodyless(method) {
54968
54989
  return method === "GET" || method === "HEAD";
54969
54990
  }
54970
54991
  function exchange2(send2, options, input2) {
54971
- return new Promise((resolve12, reject) => {
54972
- const outgoing = send2({ ...options, method: input2.method, signal: input2.signal }, resolve12);
54992
+ return new Promise((resolve13, reject) => {
54993
+ const outgoing = send2({ ...options, method: input2.method, signal: input2.signal }, resolve13);
54973
54994
  outgoing.on("error", reject);
54974
54995
  if (isBodyless(input2.method)) {
54975
54996
  input2.body.resume();
@@ -56438,7 +56459,7 @@ function createGitRunner(options) {
56438
56459
  }
56439
56460
  await killProcessTree(child.pid, { signal: "SIGKILL", child, platform: platform3 });
56440
56461
  };
56441
- return new Promise((resolve12, reject) => {
56462
+ return new Promise((resolve13, reject) => {
56442
56463
  let ending = null;
56443
56464
  const stop = (next) => {
56444
56465
  if (ending !== null) return;
@@ -56463,7 +56484,7 @@ function createGitRunner(options) {
56463
56484
  signal.removeEventListener("abort", onAbort);
56464
56485
  const final = ending ?? last;
56465
56486
  if (final.kind === "exited") {
56466
- resolve12({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
56487
+ resolve13({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
56467
56488
  } else {
56468
56489
  reject(faultFor(final, command));
56469
56490
  }
@@ -57980,7 +58001,7 @@ function statusOf(error61) {
57980
58001
  }
57981
58002
  return 1;
57982
58003
  }
57983
- var systemExec = (request2) => new Promise((resolve12) => {
58004
+ var systemExec = (request2) => new Promise((resolve13) => {
57984
58005
  const child = (0, import_node_child_process6.execFile)(
57985
58006
  request2.command,
57986
58007
  [...request2.args],
@@ -57991,7 +58012,7 @@ var systemExec = (request2) => new Promise((resolve12) => {
57991
58012
  windowsHide: true
57992
58013
  },
57993
58014
  (error61, stdout, stderr) => {
57994
- resolve12({ status: statusOf(error61), stdout, stderr });
58015
+ resolve13({ status: statusOf(error61), stdout, stderr });
57995
58016
  }
57996
58017
  );
57997
58018
  child.stdin?.on("error", () => {
@@ -59181,11 +59202,11 @@ async function startGitCredentialServer(options) {
59181
59202
  });
59182
59203
  });
59183
59204
  removeStaleEndpoint(options.endpoint);
59184
- await new Promise((resolve12, reject) => {
59205
+ await new Promise((resolve13, reject) => {
59185
59206
  server.once("error", reject);
59186
59207
  server.listen(options.endpoint, () => {
59187
59208
  server.off("error", reject);
59188
- resolve12();
59209
+ resolve13();
59189
59210
  });
59190
59211
  });
59191
59212
  options.log.info("git.credential_server_listening", { endpoint: options.endpoint });
@@ -59193,7 +59214,7 @@ async function startGitCredentialServer(options) {
59193
59214
  endpoint: options.endpoint,
59194
59215
  [Symbol.asyncDispose]: async () => {
59195
59216
  closing.abort();
59196
- await new Promise((resolve12) => server.close(() => resolve12()));
59217
+ await new Promise((resolve13) => server.close(() => resolve13()));
59197
59218
  removeStaleEndpoint(options.endpoint);
59198
59219
  }
59199
59220
  };
@@ -59267,13 +59288,13 @@ authorityKeyIdentifier = keyid
59267
59288
  `;
59268
59289
  }
59269
59290
  function openssl(args, cwd) {
59270
- return new Promise((resolve12, reject) => {
59291
+ return new Promise((resolve13, reject) => {
59271
59292
  (0, import_node_child_process9.execFile)(
59272
59293
  "openssl",
59273
59294
  [...args],
59274
59295
  { cwd, timeout: OPENSSL_TIMEOUT_MS },
59275
59296
  (error61, _stdout, stderr) => {
59276
- if (error61 === null) resolve12();
59297
+ if (error61 === null) resolve13();
59277
59298
  else
59278
59299
  reject(new Error(`openssl ${args[0] ?? ""} failed: ${stderr.trim() || error61.message}`));
59279
59300
  }
@@ -59450,21 +59471,21 @@ function relayTo(forward, log) {
59450
59471
  };
59451
59472
  }
59452
59473
  function listen(server, target) {
59453
- return new Promise((resolve12, reject) => {
59474
+ return new Promise((resolve13, reject) => {
59454
59475
  server.once("error", reject);
59455
59476
  const done = () => {
59456
59477
  server.off("error", reject);
59457
- resolve12();
59478
+ resolve13();
59458
59479
  };
59459
59480
  if (typeof target === "string") server.listen(target, done);
59460
59481
  else server.listen(target.port, target.host, done);
59461
59482
  });
59462
59483
  }
59463
59484
  function close(server, sockets = /* @__PURE__ */ new Set()) {
59464
- return new Promise((resolve12) => {
59485
+ return new Promise((resolve13) => {
59465
59486
  for (const socket of sockets) socket.destroy();
59466
59487
  server.closeAllConnections();
59467
- server.close(() => resolve12());
59488
+ server.close(() => resolve13());
59468
59489
  });
59469
59490
  }
59470
59491
  function portOf(server) {
@@ -62247,7 +62268,7 @@ async function startNativeIngest(deps) {
62247
62268
  };
62248
62269
  const settleIdle = () => {
62249
62270
  if (workers.size > 0) return;
62250
- for (const resolve12 of idleWaiters) resolve12();
62271
+ for (const resolve13 of idleWaiters) resolve13();
62251
62272
  idleWaiters.clear();
62252
62273
  };
62253
62274
  const retryDelay = (worker) => {
@@ -62490,7 +62511,7 @@ async function startNativeIngest(deps) {
62490
62511
  sweep: sweep2,
62491
62512
  whenIdle: () => {
62492
62513
  if (workers.size === 0) return Promise.resolve();
62493
- return new Promise((resolve12) => idleWaiters.add(resolve12));
62514
+ return new Promise((resolve13) => idleWaiters.add(resolve13));
62494
62515
  },
62495
62516
  [Symbol.asyncDispose]: async () => {
62496
62517
  shutdown.abort();
@@ -62638,7 +62659,7 @@ function captureProbe(command, args, options) {
62638
62659
  const launch = directLaunch(command, args, options);
62639
62660
  if (launch === void 0) return Promise.resolve({ stdout: "", stderr: "", exitCode: void 0 });
62640
62661
  const env = platform3 === "win32" ? withWindowsHelper(canonicalWindowsEnvironment(options.env)) : options.env;
62641
- return new Promise((resolve12) => {
62662
+ return new Promise((resolve13) => {
62642
62663
  const limit = options.maxBufferBytes ?? DEFAULT_MAX_BYTES;
62643
62664
  const stdout = [];
62644
62665
  const stderr = [];
@@ -62673,7 +62694,7 @@ function captureProbe(command, args, options) {
62673
62694
  settled2 = true;
62674
62695
  deadlineController.abort();
62675
62696
  options.signal?.removeEventListener("abort", abort);
62676
- resolve12({
62697
+ resolve13({
62677
62698
  stdout: Buffer.concat(stdout).toString("utf8"),
62678
62699
  stderr: Buffer.concat(stderr).toString("utf8"),
62679
62700
  exitCode
@@ -62805,7 +62826,7 @@ function cursorAccountLabel(output2) {
62805
62826
  function waitForAbort(signal) {
62806
62827
  if (signal.aborted) return Promise.resolve();
62807
62828
  return new Promise(
62808
- (resolve12) => signal.addEventListener("abort", () => resolve12(), { once: true })
62829
+ (resolve13) => signal.addEventListener("abort", () => resolve13(), { once: true })
62809
62830
  );
62810
62831
  }
62811
62832
  function idlePrompt(signal) {
@@ -62883,14 +62904,14 @@ async function codexLabel(executable, env) {
62883
62904
  windowsVerbatimArguments: launch.windowsVerbatimArguments
62884
62905
  });
62885
62906
  const timeout = AbortSignal.timeout(ACCOUNT_TIMEOUT_MS);
62886
- return new Promise((resolve12) => {
62907
+ return new Promise((resolve13) => {
62887
62908
  let finished = false;
62888
62909
  let buffer = "";
62889
62910
  const finish = (label) => {
62890
62911
  if (finished) return;
62891
62912
  finished = true;
62892
62913
  child.kill();
62893
- resolve12(label);
62914
+ resolve13(label);
62894
62915
  };
62895
62916
  const send2 = (value2) => {
62896
62917
  child.stdin.write(`${JSON.stringify(value2)}
@@ -63399,11 +63420,11 @@ async function resolveCliEnvironment(options) {
63399
63420
  }
63400
63421
  async function openCliEnvironment(options) {
63401
63422
  const decorate = options.decorate ?? ((env) => env);
63402
- const resolve12 = async () => {
63423
+ const resolve13 = async () => {
63403
63424
  const resolved = await resolveCliEnvironmentDetailed(options);
63404
63425
  return { env: decorate(resolved.env), source: resolved.source };
63405
63426
  };
63406
- let state = await resolve12();
63427
+ let state = await resolve13();
63407
63428
  let retryAt = options.clock.now() + DEGRADED_RETRY_MS;
63408
63429
  return {
63409
63430
  current: () => state.env,
@@ -63412,7 +63433,7 @@ async function openCliEnvironment(options) {
63412
63433
  if (state.source === "login_shell" || options.platform === "win32") return false;
63413
63434
  if (options.clock.now() < retryAt) return false;
63414
63435
  retryAt = options.clock.now() + DEGRADED_RETRY_MS;
63415
- const next = await resolve12();
63436
+ const next = await resolve13();
63416
63437
  const changed = envValue(next.env, "PATH") !== envValue(state.env, "PATH");
63417
63438
  state = next;
63418
63439
  return changed;
@@ -63489,11 +63510,11 @@ async function installVersion2(backendKind, requested, options, signal) {
63489
63510
  }
63490
63511
  return exact;
63491
63512
  }
63492
- const resolve12 = options.resolveVersion;
63493
- if (resolve12 === void 0) throw new Error("Latest version lookup is unavailable");
63513
+ const resolve13 = options.resolveVersion;
63514
+ if (resolve13 === void 0) throw new Error("Latest version lookup is unavailable");
63494
63515
  const packageName = packageFor(backendKind).name;
63495
63516
  return checkedVersion(
63496
- await resolve12(backendKind === "opencode_serve" ? `${packageName}@1` : packageName, signal)
63517
+ await resolve13(backendKind === "opencode_serve" ? `${packageName}@1` : packageName, signal)
63497
63518
  );
63498
63519
  }
63499
63520
  function selection(root, backendKind, version2) {
@@ -63942,10 +63963,10 @@ function createIgnoreMatcher(path4) {
63942
63963
  const expression = globToRegExp(pattern);
63943
63964
  return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
63944
63965
  }
63945
- function isIgnored(normalizedPath, basename10, isDirectory5, configured) {
63946
- if (isDirectory5 && ALWAYS_IGNORED_DIRECTORIES.has(basename10))
63966
+ function isIgnored(normalizedPath, basename11, isDirectory5, configured) {
63967
+ if (isDirectory5 && ALWAYS_IGNORED_DIRECTORIES.has(basename11))
63947
63968
  return true;
63948
- if (!isDirectory5 && ALWAYS_IGNORED_FILES.has(basename10))
63969
+ if (!isDirectory5 && ALWAYS_IGNORED_FILES.has(basename11))
63949
63970
  return true;
63950
63971
  return configured.some((matches) => matches(normalizedPath));
63951
63972
  }
@@ -64202,7 +64223,7 @@ var MAX_DIAGNOSTICS = 100;
64202
64223
  function createLocalSkillScanCache() {
64203
64224
  return { inspections: /* @__PURE__ */ new Map(), lastCompleteRevision: null };
64204
64225
  }
64205
- async function scanSkillRoots(input2, cache2) {
64226
+ async function scanSkillRoots(input2, cache2, managedRoots = []) {
64206
64227
  const attemptId = (0, import_node_crypto19.randomUUID)();
64207
64228
  const ignoredPaths = input2.ignoredPaths ?? [];
64208
64229
  const resolvedRoots = resolveScanRoots(input2.roots, input2.enabledProviderKinds ?? []);
@@ -64210,7 +64231,8 @@ async function scanSkillRoots(input2, cache2) {
64210
64231
  input: input2,
64211
64232
  cache: cache2,
64212
64233
  visited: /* @__PURE__ */ new Set(),
64213
- declaredRoots: await canonicalDirectories(resolvedRoots.map((root) => root.directory))
64234
+ declaredRoots: await canonicalDirectories(resolvedRoots.map((root) => root.directory)),
64235
+ managedRoots: await canonicalDirectories(managedRoots)
64214
64236
  };
64215
64237
  const candidates2 = [];
64216
64238
  const diagnostics = [];
@@ -64316,6 +64338,7 @@ function invalid(resolvedRoot, name, error61) {
64316
64338
  async function scanRootAsPackage(pass, resolvedRoot) {
64317
64339
  if (!await exists3(import_node_path40.default.join(resolvedRoot.directory, "SKILL.md"))) return null;
64318
64340
  const canonical = await (0, import_promises38.realpath)(resolvedRoot.directory).catch(() => resolvedRoot.directory);
64341
+ if (isManaged(pass, canonical)) return { candidates: [], diagnostics: [], incomplete: false };
64319
64342
  try {
64320
64343
  const inspected = await inspectCached(pass, canonical, null);
64321
64344
  return {
@@ -64379,6 +64402,7 @@ async function scanEntry(pass, resolvedRoot, canonicalRoot, name) {
64379
64402
  const message2 = `Could not resolve Skill ${name}`;
64380
64403
  return { kind: "diagnostic", diagnostic: { code: "SOURCE_UNREADABLE", message: message2, rootLabel } };
64381
64404
  }
64405
+ if (isManaged(pass, canonical)) return null;
64382
64406
  const roots = pass.declaredRoots.length > 0 ? pass.declaredRoots : [canonicalRoot];
64383
64407
  if (!roots.some((root) => isWithinDirectory2(root, canonical))) {
64384
64408
  const message2 = `Skill ${name} resolves outside every declared Skill source`;
@@ -64405,12 +64429,12 @@ function resolveScanRoots(roots, enabledProviderKinds) {
64405
64429
  const resolved = [];
64406
64430
  for (const root of roots) {
64407
64431
  if (root.kind === "repository") {
64408
- for (const [index, relative5] of skillRepositorySourceDirectories(
64432
+ for (const [index, relative6] of skillRepositorySourceDirectories(
64409
64433
  enabledProviderKinds
64410
64434
  ).entries()) {
64411
64435
  resolved.push({
64412
64436
  root,
64413
- directory: import_node_path40.default.join(root.path, relative5),
64437
+ directory: import_node_path40.default.join(root.path, relative6),
64414
64438
  order: `1:${root.repositoryId}:${String(index).padStart(2, "0")}`
64415
64439
  });
64416
64440
  }
@@ -64461,12 +64485,12 @@ async function fingerprintPackage(root) {
64461
64485
  const entries = await (0, import_promises38.readdir)(directory, { withFileTypes: true });
64462
64486
  entries.sort((left, right) => Buffer.compare(Buffer.from(left.name), Buffer.from(right.name)));
64463
64487
  for (const entry of entries) {
64464
- const relative5 = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
64488
+ const relative6 = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
64465
64489
  const absolute = import_node_path40.default.join(directory, entry.name);
64466
64490
  const metadata = await (0, import_promises38.lstat)(absolute);
64467
64491
  const kind = entryKind(entry);
64468
- hash2.update(relative5.normalize("NFC")).update(`\0${kind}\0${metadata.size}\0${metadata.mtimeMs}\0${metadata.mode & 511}\0`);
64469
- if (entry.isDirectory()) await visit2(absolute, relative5);
64492
+ hash2.update(relative6.normalize("NFC")).update(`\0${kind}\0${metadata.size}\0${metadata.mtimeMs}\0${metadata.mode & 511}\0`);
64493
+ if (entry.isDirectory()) await visit2(absolute, relative6);
64470
64494
  }
64471
64495
  };
64472
64496
  await visit2(root, "");
@@ -64483,9 +64507,12 @@ async function canonicalDirectories(directories) {
64483
64507
  );
64484
64508
  return [...new Set(canonical)];
64485
64509
  }
64510
+ function isManaged(pass, canonical) {
64511
+ return pass.managedRoots.some((root) => isWithinDirectory2(root, canonical));
64512
+ }
64486
64513
  function isWithinDirectory2(parent, candidate) {
64487
- const relative5 = import_node_path40.default.relative(parent, candidate);
64488
- return relative5 !== ".." && !relative5.startsWith(`..${import_node_path40.default.sep}`) && !import_node_path40.default.isAbsolute(relative5);
64514
+ const relative6 = import_node_path40.default.relative(parent, candidate);
64515
+ return relative6 !== ".." && !relative6.startsWith(`..${import_node_path40.default.sep}`) && !import_node_path40.default.isAbsolute(relative6);
64489
64516
  }
64490
64517
  async function exists3(candidate) {
64491
64518
  try {
@@ -64689,7 +64716,7 @@ function optionalStringArray(value2, field3) {
64689
64716
  }
64690
64717
  return value2;
64691
64718
  }
64692
- async function scanLocalSkills(home, context, cache2, mode = "incremental") {
64719
+ async function scanLocalSkills(home, context, cache2, mode = "incremental", managedRoots = []) {
64693
64720
  const resolved = await resolveLocalScanInput(home, context, mode);
64694
64721
  if (resolved.kind === "invalid_config") {
64695
64722
  return failedLocalSkillScan(
@@ -64698,7 +64725,7 @@ async function scanLocalSkills(home, context, cache2, mode = "incremental") {
64698
64725
  `Invalid Skill source configuration: ${resolved.diagnostic}`
64699
64726
  );
64700
64727
  }
64701
- return scanSkillRoots(resolved.input, cache2);
64728
+ return scanSkillRoots(resolved.input, cache2, managedRoots);
64702
64729
  }
64703
64730
 
64704
64731
  // src/capabilities/skills/store.ts
@@ -64730,9 +64757,12 @@ function skillsLayout(stateDir, home) {
64730
64757
  return {
64731
64758
  root,
64732
64759
  installedFile: (0, import_node_path42.join)(root, "installed.json"),
64760
+ retiredFile: (0, import_node_path42.join)(root, "retired.json"),
64733
64761
  localFile: (0, import_node_path42.join)(root, "local.json"),
64734
64762
  versionsDir: (0, import_node_path42.join)(root, "versions"),
64735
64763
  tmpDir: (0, import_node_path42.join)(root, "tmp"),
64764
+ pluginDir: (0, import_node_path42.join)(root, "alan-plugin"),
64765
+ pluginSkillsDir: (0, import_node_path42.join)(root, "alan-plugin", "skills"),
64736
64766
  nativeDir: home === void 0 || home === "" ? null : (0, import_node_path42.join)(home, ".agents", "skills")
64737
64767
  };
64738
64768
  }
@@ -64855,12 +64885,19 @@ async function availableSkillIndex(layout) {
64855
64885
  candidates2.push({ directory: (0, import_node_path42.join)(layout.nativeDir, entry.name) });
64856
64886
  }
64857
64887
  }
64858
- for (const candidate of candidates2.slice(0, 2e3)) {
64859
- const skill = await inspectIndexedSkill(candidate.directory, candidate.contentHash);
64860
- if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
64888
+ const bounded = candidates2.slice(0, 2e3);
64889
+ for (let start = 0; start < bounded.length; start += INDEX_CONCURRENCY) {
64890
+ const batch = bounded.slice(start, start + INDEX_CONCURRENCY);
64891
+ const inspected = await Promise.all(
64892
+ batch.map((candidate) => inspectIndexedSkill(candidate.directory, candidate.contentHash))
64893
+ );
64894
+ for (const skill of inspected) {
64895
+ if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
64896
+ }
64861
64897
  }
64862
64898
  return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
64863
64899
  }
64900
+ var INDEX_CONCURRENCY = 8;
64864
64901
  async function inspectIndexedSkill(directory, contentHash) {
64865
64902
  try {
64866
64903
  const inspected = await inspectSkillPackage(directory, { expectedName: null });
@@ -65044,8 +65081,8 @@ async function collectStream(stream) {
65044
65081
  return import_node_buffer2.Buffer.concat(chunks);
65045
65082
  }
65046
65083
  function addArchiveEntry(archive, header, bytes) {
65047
- return new Promise((resolve12, reject) => {
65048
- archive.entry(header, bytes, (error61) => error61 ? reject(error61) : resolve12());
65084
+ return new Promise((resolve13, reject) => {
65085
+ archive.entry(header, bytes, (error61) => error61 ? reject(error61) : resolve13());
65049
65086
  });
65050
65087
  }
65051
65088
  async function decompressBounded(archiveBytes) {
@@ -65071,7 +65108,7 @@ async function extractTar(tarBytes, destination) {
65071
65108
  const extractor = (0, import_tar_stream.extract)();
65072
65109
  let fileCount = 0;
65073
65110
  let totalBytes = 0;
65074
- const completion = new Promise((resolve12, reject) => {
65111
+ const completion = new Promise((resolve13, reject) => {
65075
65112
  extractor.on("entry", (header, stream, next) => {
65076
65113
  void extractEntry(header, stream, destination, {
65077
65114
  addFile(size) {
@@ -65086,7 +65123,7 @@ async function extractTar(tarBytes, destination) {
65086
65123
  }
65087
65124
  }).then(next, (error61) => extractor.destroy(error61 instanceof Error ? error61 : new Error(String(error61))));
65088
65125
  });
65089
- extractor.once("finish", resolve12);
65126
+ extractor.once("finish", resolve13);
65090
65127
  extractor.once("error", reject);
65091
65128
  });
65092
65129
  import_node_stream.Readable.from(tarBytes).pipe(extractor);
@@ -65163,34 +65200,222 @@ async function publishLocalSkill(options) {
65163
65200
  };
65164
65201
  }
65165
65202
 
65166
- // src/capabilities/skills/sync.ts
65203
+ // src/capabilities/skills/native-index.ts
65167
65204
  var import_node_crypto23 = require("crypto");
65205
+ var import_node_fs16 = require("fs");
65168
65206
  var import_promises44 = require("fs/promises");
65169
65207
  var import_node_path45 = require("path");
65208
+ var ALAN_SKILLS_PLUGIN_NAME = "alan";
65209
+ var PLUGIN_MANIFEST = `${JSON.stringify(
65210
+ {
65211
+ name: ALAN_SKILLS_PLUGIN_NAME,
65212
+ description: "Skills Alan installed on this machine for you and your team."
65213
+ },
65214
+ null,
65215
+ 2
65216
+ )}
65217
+ `;
65218
+ async function entryKind2(path4) {
65219
+ try {
65220
+ return (await (0, import_promises44.lstat)(path4)).isSymbolicLink() ? "link" : "other";
65221
+ } catch (error61) {
65222
+ if (errnoCode(error61) === "ENOENT") return "missing";
65223
+ throw error61;
65224
+ }
65225
+ }
65226
+ async function linkTarget(path4) {
65227
+ return (0, import_promises44.readlink)(path4).catch(() => null);
65228
+ }
65229
+ async function removeLink(path4) {
65230
+ try {
65231
+ await (0, import_promises44.unlink)(path4);
65232
+ } catch (error61) {
65233
+ const code = errnoCode(error61);
65234
+ if (code === "ENOENT") return;
65235
+ if (code !== "EPERM" && code !== "EISDIR") throw error61;
65236
+ await (0, import_promises44.rmdir)(path4);
65237
+ }
65238
+ }
65239
+ async function placeLink(plan2, platform3) {
65240
+ if (await linkTarget(plan2.path) === plan2.target) return false;
65241
+ const staged = (0, import_node_path45.join)((0, import_node_path45.dirname)(plan2.path), `.${(0, import_node_path45.basename)(plan2.path)}.${(0, import_node_crypto23.randomUUID)()}.tmp`);
65242
+ await (0, import_promises44.symlink)(plan2.target, staged, platform3 === "win32" ? "junction" : "dir");
65243
+ try {
65244
+ if (platform3 === "win32") await removeLink(plan2.path);
65245
+ await (0, import_promises44.rename)(staged, plan2.path);
65246
+ } catch (error61) {
65247
+ await removeLink(staged).catch(() => void 0);
65248
+ throw error61;
65249
+ }
65250
+ return true;
65251
+ }
65252
+ function versionTarget(layout, versionId, platform3) {
65253
+ const absolute = (0, import_node_path45.join)(layout.versionsDir, versionId);
65254
+ return platform3 === "win32" ? absolute : (0, import_node_path45.relative)(layout.pluginSkillsDir, absolute);
65255
+ }
65256
+ async function writeManifest(layout) {
65257
+ const manifest = (0, import_node_path45.join)(layout.pluginDir, ".claude-plugin", "plugin.json");
65258
+ if (await (0, import_promises44.readFile)(manifest, "utf8").catch(() => null) === PLUGIN_MANIFEST) return;
65259
+ await (0, import_promises44.mkdir)((0, import_node_path45.dirname)(manifest), { recursive: true, mode: 448 });
65260
+ const staged = `${manifest}.${(0, import_node_crypto23.randomUUID)()}.tmp`;
65261
+ await (0, import_promises44.writeFile)(staged, PLUGIN_MANIFEST, { mode: 384 });
65262
+ await (0, import_promises44.rename)(staged, manifest);
65263
+ }
65264
+ async function reconcilePluginSkills(layout, installed, platform3) {
65265
+ await (0, import_promises44.mkdir)(layout.pluginSkillsDir, { recursive: true, mode: 448 });
65266
+ const wanted = new Map(installed.map((skill) => [skill.slug, skill]));
65267
+ let linked = 0;
65268
+ for (const skill of installed) {
65269
+ const plan2 = {
65270
+ path: (0, import_node_path45.join)(layout.pluginSkillsDir, skill.slug),
65271
+ target: versionTarget(layout, skill.versionId, platform3)
65272
+ };
65273
+ if (await entryKind2(plan2.path) === "other") {
65274
+ await (0, import_promises44.rm)(plan2.path, { recursive: true, force: true });
65275
+ }
65276
+ if (await placeLink(plan2, platform3)) linked += 1;
65277
+ }
65278
+ let unlinked = 0;
65279
+ for (const name of await (0, import_promises44.readdir)(layout.pluginSkillsDir)) {
65280
+ if (wanted.has(name)) continue;
65281
+ const path4 = (0, import_node_path45.join)(layout.pluginSkillsDir, name);
65282
+ if (await entryKind2(path4) === "link") await removeLink(path4);
65283
+ else await (0, import_promises44.rm)(path4, { recursive: true, force: true });
65284
+ unlinked += 1;
65285
+ }
65286
+ return { linked, unlinked };
65287
+ }
65288
+ async function isOwnCodexLink(layout, path4) {
65289
+ const target = await linkTarget(path4);
65290
+ if (target === null) return false;
65291
+ const absolute = (0, import_node_path45.isAbsolute)(target) ? target : (0, import_node_path45.resolve)((0, import_node_path45.dirname)(path4), target);
65292
+ return isWithinDirectory2(layout.pluginSkillsDir, absolute);
65293
+ }
65294
+ async function isForeignPackage(layout, path4) {
65295
+ const resolved = await (0, import_promises44.realpath)(path4).catch(() => null);
65296
+ if (resolved === null) return false;
65297
+ const root = await (0, import_promises44.realpath)(layout.root).catch(() => layout.root);
65298
+ return !isWithinDirectory2(root, resolved);
65299
+ }
65300
+ async function codexSlot(layout, path4, slug) {
65301
+ const baked = layout.nativeDir !== null && await isForeignPackage(layout, (0, import_node_path45.join)(layout.nativeDir, slug));
65302
+ const kind = await entryKind2(path4);
65303
+ if (kind === "other") return "taken";
65304
+ const ours = kind === "link" && await isOwnCodexLink(layout, path4);
65305
+ if (kind === "link" && !ours) return "taken";
65306
+ if (baked) {
65307
+ if (ours) await removeLink(path4);
65308
+ return "taken";
65309
+ }
65310
+ return ours ? "ours" : "free";
65311
+ }
65312
+ async function unlinkStaleCodexEntries(layout, codexSkillsDir, wanted) {
65313
+ let unlinked = 0;
65314
+ for (const name of await (0, import_promises44.readdir)(codexSkillsDir)) {
65315
+ const path4 = (0, import_node_path45.join)(codexSkillsDir, name);
65316
+ if (wanted.has(name) && !name.endsWith(".tmp")) continue;
65317
+ if (await entryKind2(path4) !== "link" || !await isOwnCodexLink(layout, path4)) continue;
65318
+ await removeLink(path4);
65319
+ unlinked += 1;
65320
+ }
65321
+ return unlinked;
65322
+ }
65323
+ async function reconcileCodexSkills(layout, installed, codexSkillsDir, platform3) {
65324
+ await (0, import_promises44.mkdir)(codexSkillsDir, { recursive: true, mode: 448 });
65325
+ const report2 = { linked: 0, unlinked: 0, skipped: [] };
65326
+ for (const skill of installed) {
65327
+ const path4 = (0, import_node_path45.join)(codexSkillsDir, skill.slug);
65328
+ if (await codexSlot(layout, path4, skill.slug) === "taken") {
65329
+ report2.skipped.push(skill.slug);
65330
+ continue;
65331
+ }
65332
+ const target = (0, import_node_path45.join)(layout.pluginSkillsDir, skill.slug);
65333
+ if (await placeLink({ path: path4, target }, platform3)) report2.linked += 1;
65334
+ }
65335
+ const wanted = new Set(installed.map((skill) => skill.slug));
65336
+ report2.unlinked = await unlinkStaleCodexEntries(layout, codexSkillsDir, wanted);
65337
+ return report2;
65338
+ }
65339
+ async function reconcileNativeIndex(layout, installed, options) {
65340
+ await writeManifest(layout);
65341
+ const plugin = await reconcilePluginSkills(layout, installed, options.platform);
65342
+ if (options.codexSkillsDir === null) return { ...plugin, skipped: [] };
65343
+ const codex = await reconcileCodexSkills(
65344
+ layout,
65345
+ installed,
65346
+ options.codexSkillsDir,
65347
+ options.platform
65348
+ );
65349
+ return {
65350
+ linked: plugin.linked + codex.linked,
65351
+ unlinked: plugin.unlinked + codex.unlinked,
65352
+ skipped: codex.skipped
65353
+ };
65354
+ }
65355
+ function installedSkillFolders(layout) {
65356
+ return (0, import_node_fs16.existsSync)((0, import_node_path45.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
65357
+ }
65358
+
65359
+ // src/capabilities/skills/sync.ts
65360
+ var import_node_crypto24 = require("crypto");
65361
+ var import_promises45 = require("fs/promises");
65362
+ var import_node_path46 = require("path");
65363
+ init_zod();
65170
65364
  var SKILL_PREPARE_WAIT_MS = 15e3;
65171
- async function install(layout, source, skill, download, signal) {
65365
+ var RETIRED_VERSION_RETENTION_MS = 24 * 60 * 60 * 1e3;
65366
+ async function makeFilesReadOnly(directory, platform3) {
65367
+ if (platform3 === "win32") return;
65368
+ for (const entry of await (0, import_promises45.readdir)(directory, { withFileTypes: true })) {
65369
+ const path4 = (0, import_node_path46.join)(directory, entry.name);
65370
+ if (entry.isDirectory()) await makeFilesReadOnly(path4, platform3);
65371
+ else if (entry.isFile()) {
65372
+ const executable = ((await (0, import_promises45.lstat)(path4)).mode & 64) !== 0;
65373
+ await (0, import_promises45.chmod)(path4, executable ? 365 : 292);
65374
+ }
65375
+ }
65376
+ }
65377
+ async function install(env, skill, download, signal) {
65378
+ const { layout, source, platform: platform3 } = env;
65172
65379
  const bytes = await source.download(download.url, signal);
65173
- await (0, import_promises44.mkdir)(layout.tmpDir, { recursive: true, mode: 448 });
65174
- const staging = (0, import_node_path45.join)(layout.tmpDir, (0, import_node_crypto23.randomUUID)());
65380
+ await (0, import_promises45.mkdir)(layout.tmpDir, { recursive: true, mode: 448 });
65381
+ const staging = (0, import_node_path46.join)(layout.tmpDir, (0, import_node_crypto24.randomUUID)());
65175
65382
  await extractSkillBundle(Buffer.from(bytes), staging, {
65176
65383
  expectedArchiveHash: download.archiveHash,
65177
65384
  expectedContentHash: skill.contentHash
65178
65385
  });
65179
65386
  const target = packageDirectory(layout, skill.versionId);
65180
- await (0, import_promises44.mkdir)(layout.versionsDir, { recursive: true, mode: 448 });
65181
- await (0, import_promises44.rm)(target, { recursive: true, force: true });
65182
- await (0, import_promises44.rename)(staging, target);
65183
- }
65184
- async function sweep(layout, keep) {
65387
+ await (0, import_promises45.mkdir)(layout.versionsDir, { recursive: true, mode: 448 });
65388
+ await (0, import_promises45.rm)(target, { recursive: true, force: true });
65389
+ await (0, import_promises45.rename)(staging, target);
65390
+ await makeFilesReadOnly(target, platform3);
65391
+ }
65392
+ var retiredFileSchema = external_exports.record(external_exports.string(), external_exports.number());
65393
+ async function sweep(env, keep) {
65394
+ const { layout } = env;
65185
65395
  const kept = new Set(keep.map((skill) => skill.versionId));
65186
- const stale = (await (0, import_promises44.readdir)(layout.versionsDir).catch(() => [])).filter(
65187
- (name) => !kept.has(name)
65188
- );
65189
- await Promise.all(
65190
- stale.map((name) => (0, import_promises44.rm)((0, import_node_path45.join)(layout.versionsDir, name), { recursive: true, force: true }))
65396
+ const read = await readJsonFile(layout.retiredFile, retiredFileSchema).catch(() => null);
65397
+ const retired = read?.kind === "ok" ? read.value : {};
65398
+ const now = env.now();
65399
+ const stillRetired = {};
65400
+ const expired = [];
65401
+ for (const name of await (0, import_promises45.readdir)(layout.versionsDir).catch(() => [])) {
65402
+ if (kept.has(name)) continue;
65403
+ const since = retired[name] ?? now;
65404
+ if (now - since >= RETIRED_VERSION_RETENTION_MS) expired.push(name);
65405
+ else stillRetired[name] = since;
65406
+ }
65407
+ const results = await Promise.allSettled(
65408
+ expired.map((name) => (0, import_promises45.rm)((0, import_node_path46.join)(layout.versionsDir, name), { recursive: true, force: true }))
65191
65409
  );
65192
- await (0, import_promises44.rm)(layout.tmpDir, { recursive: true, force: true });
65193
- return stale.length;
65410
+ results.forEach((result, index) => {
65411
+ const name = expired[index];
65412
+ if (result.status === "rejected" && name !== void 0) stillRetired[name] = now;
65413
+ });
65414
+ if (JSON.stringify(stillRetired) !== JSON.stringify(retired)) {
65415
+ await writeJsonFileAtomic(layout.retiredFile, stillRetired);
65416
+ }
65417
+ await (0, import_promises45.rm)(layout.tmpDir, { recursive: true, force: true });
65418
+ return results.filter((result) => result.status === "fulfilled").length;
65194
65419
  }
65195
65420
  async function intactSkills(layout) {
65196
65421
  const installed = await readInstalledSkills(layout);
@@ -65216,18 +65441,24 @@ function installedRecorder(layout, present2, onRecorded) {
65216
65441
  present2.map((skill) => [skill.skillId, skill])
65217
65442
  );
65218
65443
  let chain = Promise.resolve();
65444
+ let queued = null;
65219
65445
  return {
65220
65446
  record: (skill) => {
65221
65447
  ready.set(skill.skillId, skill);
65222
- const snapshot2 = [...ready.values()];
65223
- const write = chain.then(() => writeInstalledSkills(layout, snapshot2)).then(onRecorded);
65448
+ if (queued !== null) return queued;
65449
+ const write = chain.then(() => {
65450
+ queued = null;
65451
+ return writeInstalledSkills(layout, [...ready.values()]);
65452
+ }).then(onRecorded);
65453
+ queued = write;
65224
65454
  chain = write.catch(() => void 0);
65225
65455
  return write;
65226
65456
  },
65227
65457
  settled: () => chain
65228
65458
  };
65229
65459
  }
65230
- async function applyDesired(layout, source, log, present2, response, onRecorded, signal) {
65460
+ async function applyDesired(env, present2, response, onRecorded, signal) {
65461
+ const { layout, log } = env;
65231
65462
  const held = new Map(present2.map((skill) => [skill.skillId, skill]));
65232
65463
  const downloads = new Map(
65233
65464
  response.downloads.map((download) => [download.skillId, download])
@@ -65241,21 +65472,34 @@ async function applyDesired(layout, source, log, present2, response, onRecorded,
65241
65472
  return kept ? "kept" : "failed";
65242
65473
  }
65243
65474
  try {
65244
- await install(layout, source, skill, download, signal);
65245
- await recorder.record(skill);
65246
- return "downloaded";
65475
+ await install(env, skill, download, signal);
65247
65476
  } catch (error61) {
65248
65477
  log.warn("skills.install_failed", { skillId: skill.skillId, slug: skill.slug, error: error61 });
65249
65478
  return "failed";
65250
65479
  }
65480
+ await recorder.record(skill).catch((error61) => {
65481
+ log.warn("skills.record_failed", { skillId: skill.skillId, error: error61 });
65482
+ });
65483
+ return "downloaded";
65251
65484
  };
65252
65485
  const outcomes = await mapBounded(response.skills, INSTALL_CONCURRENCY, installOne);
65253
- const installed = response.skills.filter((_, index) => outcomes[index] !== "failed");
65486
+ const installed = response.skills.flatMap((skill, index) => {
65487
+ if (outcomes[index] !== "failed") return [skill];
65488
+ const kept = held.get(skill.skillId);
65489
+ return kept === void 0 ? [] : [kept];
65490
+ });
65254
65491
  const failed = response.skills.filter((_, index) => outcomes[index] === "failed").map((skill) => skill.slug);
65255
65492
  const downloaded = outcomes.filter((outcome2) => outcome2 === "downloaded").length;
65256
65493
  await recorder.settled();
65494
+ if (signal.aborted) return { installed: installed.length, downloaded, removed: 0, failed };
65257
65495
  await writeInstalledSkills(layout, installed);
65258
- const removed = await sweep(layout, installed);
65496
+ await reconcileNativeIndex(layout, installed, {
65497
+ codexSkillsDir: env.codexSkillsDir,
65498
+ platform: env.platform
65499
+ }).catch((error61) => {
65500
+ log.warn("skills.native_index_failed", { error: error61 });
65501
+ });
65502
+ const removed = await sweep(env, installed);
65259
65503
  return { installed: installed.length, downloaded, removed, failed };
65260
65504
  }
65261
65505
  var MAX_EXCHANGES = 4;
@@ -65274,7 +65518,9 @@ async function scanLocal(layout, local) {
65274
65518
  local.scans += 1;
65275
65519
  const sequence = local.scans;
65276
65520
  const context = local.context;
65277
- const scan = await scanLocalSkills(local.options.home, context, local.cache);
65521
+ const scan = await scanLocalSkills(local.options.home, context, local.cache, "incremental", [
65522
+ layout.root
65523
+ ]);
65278
65524
  const scanned = { scan, context, key: reportKey(scan, context) };
65279
65525
  if (local.latest !== null && local.latest.sequence > sequence) return scanned;
65280
65526
  local.latest = { ...scanned, sequence };
@@ -65344,14 +65590,15 @@ async function settleLocal(layout, source, log, local, exchange3, response, sign
65344
65590
  const uploads = await uploadRequested(layout, source, log, local, response.uploads ?? [], signal);
65345
65591
  return serverLost || uploads > 0;
65346
65592
  }
65347
- async function syncOnce(layout, source, log, local, onRecorded, signal) {
65593
+ async function syncOnce(env, local, onRecorded, signal) {
65594
+ const { layout, source, log } = env;
65348
65595
  let report2 = { installed: 0, downloaded: 0, removed: 0, failed: [] };
65349
65596
  if (local !== null) await loadContext(layout, local);
65350
65597
  for (let exchange3 = 0; exchange3 < MAX_EXCHANGES; exchange3 += 1) {
65351
65598
  const present2 = await intactSkills(layout);
65352
65599
  const pending = local === null ? null : localExchange(local);
65353
65600
  const response = await source.sync(syncRequest(present2, pending), signal);
65354
- report2 = await applyDesired(layout, source, log, present2, response, onRecorded, signal);
65601
+ report2 = await applyDesired(env, present2, response, onRecorded, signal);
65355
65602
  if (local === null || pending === null) return report2;
65356
65603
  const again = await settleLocal(layout, source, log, local, pending, response, signal);
65357
65604
  if (!again) return report2;
@@ -65359,14 +65606,22 @@ async function syncOnce(layout, source, log, local, onRecorded, signal) {
65359
65606
  return report2;
65360
65607
  }
65361
65608
  function aborted2(signal) {
65362
- return new Promise((resolve12) => {
65363
- if (signal.aborted) resolve12(null);
65364
- else signal.addEventListener("abort", () => resolve12(null), { once: true });
65609
+ return new Promise((resolve13) => {
65610
+ if (signal.aborted) resolve13(null);
65611
+ else signal.addEventListener("abort", () => resolve13(null), { once: true });
65365
65612
  });
65366
65613
  }
65367
65614
  function openMachineSkills(options) {
65368
65615
  const layout = skillsLayout(options.stateDir, options.local?.home);
65369
65616
  const { source, log } = options;
65617
+ const env = {
65618
+ layout,
65619
+ source,
65620
+ log,
65621
+ codexSkillsDir: options.codexSkillsDir ?? null,
65622
+ platform: options.platform ?? process.platform,
65623
+ now: options.now ?? Date.now
65624
+ };
65370
65625
  const local = options.local === void 0 ? null : {
65371
65626
  options: options.local,
65372
65627
  cache: createLocalSkillScanCache(),
@@ -65401,7 +65656,7 @@ function openMachineSkills(options) {
65401
65656
  return task;
65402
65657
  };
65403
65658
  const run2 = () => {
65404
- const running = syncOnce(layout, source, log, local, recorded, lifetime.signal).then((report2) => {
65659
+ const running = syncOnce(env, local, recorded, lifetime.signal).then((report2) => {
65405
65660
  log.info("skills.synced", { ...report2 });
65406
65661
  return report2;
65407
65662
  }).catch((error61) => {
@@ -65442,11 +65697,11 @@ function openMachineSkills(options) {
65442
65697
  if ((await resolveSkillInvocations(layout, named, "exact")).kind === "resolved") return;
65443
65698
  }
65444
65699
  };
65445
- const recordedUntilResolved = (named, until) => new Promise((resolve12) => {
65700
+ const recordedUntilResolved = (named, until) => new Promise((resolve13) => {
65446
65701
  const done = () => {
65447
65702
  recordWatchers.delete(check3);
65448
65703
  until.removeEventListener("abort", done);
65449
- resolve12();
65704
+ resolve13();
65450
65705
  };
65451
65706
  const check3 = () => {
65452
65707
  void resolveSkillInvocations(layout, named, "exact").then((resolution) => {
@@ -65454,7 +65709,7 @@ function openMachineSkills(options) {
65454
65709
  });
65455
65710
  };
65456
65711
  if (until.aborted) {
65457
- resolve12();
65712
+ resolve13();
65458
65713
  return;
65459
65714
  }
65460
65715
  recordWatchers.add(check3);
@@ -65483,15 +65738,15 @@ function openMachineSkills(options) {
65483
65738
  }
65484
65739
 
65485
65740
  // src/capabilities/workspace/index.ts
65486
- var import_node_path48 = require("path");
65741
+ var import_node_path49 = require("path");
65487
65742
  init_runtime_v2();
65488
65743
 
65489
65744
  // src/capabilities/workspace/approved-paths.ts
65490
- var import_promises45 = require("fs/promises");
65745
+ var import_promises46 = require("fs/promises");
65491
65746
  init_zod();
65492
65747
 
65493
65748
  // src/capabilities/workspace/paths.ts
65494
- var import_node_path46 = require("path");
65749
+ var import_node_path47 = require("path");
65495
65750
  function stripWin32Namespace(path4) {
65496
65751
  if (/^\\\\\?\\UNC\\/i.test(path4)) return `\\\\${path4.slice(8)}`;
65497
65752
  if (path4.startsWith("\\\\?\\")) return path4.slice(4);
@@ -65499,15 +65754,15 @@ function stripWin32Namespace(path4) {
65499
65754
  }
65500
65755
  function comparablePath(path4, platform3) {
65501
65756
  if (platform3 === "win32") {
65502
- const normalized3 = import_node_path46.win32.normalize(stripWin32Namespace(path4).replaceAll("/", "\\"));
65757
+ const normalized3 = import_node_path47.win32.normalize(stripWin32Namespace(path4).replaceAll("/", "\\"));
65503
65758
  const trimmed4 = normalized3.length > 3 || !/^[a-z]:\\$/i.test(normalized3) ? normalized3.replace(/\\+$/, "") : normalized3;
65504
65759
  return trimmed4.toLowerCase();
65505
65760
  }
65506
- const normalized2 = import_node_path46.posix.normalize(path4);
65761
+ const normalized2 = import_node_path47.posix.normalize(path4);
65507
65762
  return normalized2.length > 1 ? normalized2.replace(/\/+$/, "") : normalized2;
65508
65763
  }
65509
65764
  function isAbsoluteFor(path4, platform3) {
65510
- return platform3 === "win32" ? import_node_path46.win32.isAbsolute(path4) : import_node_path46.posix.isAbsolute(path4);
65765
+ return platform3 === "win32" ? import_node_path47.win32.isAbsolute(path4) : import_node_path47.posix.isAbsolute(path4);
65511
65766
  }
65512
65767
  function isWithin(root, candidate, platform3) {
65513
65768
  const separator = platform3 === "win32" ? "\\" : "/";
@@ -65525,7 +65780,7 @@ var storeSchema = external_exports.object({
65525
65780
  });
65526
65781
  async function realpathOrNull(path4) {
65527
65782
  try {
65528
- return await (0, import_promises45.realpath)(path4);
65783
+ return await (0, import_promises46.realpath)(path4);
65529
65784
  } catch (error61) {
65530
65785
  const code = errnoCode(error61);
65531
65786
  if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM") {
@@ -65584,9 +65839,9 @@ async function openApprovedPaths(options) {
65584
65839
  }
65585
65840
 
65586
65841
  // src/capabilities/workspace/locks.ts
65587
- var import_node_crypto24 = require("crypto");
65588
- var import_promises46 = require("fs/promises");
65589
- var import_node_path47 = require("path");
65842
+ var import_node_crypto25 = require("crypto");
65843
+ var import_promises47 = require("fs/promises");
65844
+ var import_node_path48 = require("path");
65590
65845
  init_zod();
65591
65846
  var LOCK_FORMAT = 1;
65592
65847
  var EXCLUSIVE_FILE = "exclusive.json";
@@ -65601,12 +65856,12 @@ var ownerSchema = external_exports.object({
65601
65856
  since: external_exports.number().int().nonnegative()
65602
65857
  });
65603
65858
  function repositoryLockKey(commonDir, platform3) {
65604
- return (0, import_node_crypto24.createHash)("sha256").update(comparablePath(commonDir, platform3)).digest("hex").slice(0, 32);
65859
+ return (0, import_node_crypto25.createHash)("sha256").update(comparablePath(commonDir, platform3)).digest("hex").slice(0, 32);
65605
65860
  }
65606
65861
  async function readOwner2(path4) {
65607
65862
  let text2;
65608
65863
  try {
65609
- text2 = await (0, import_promises46.readFile)(path4, "utf8");
65864
+ text2 = await (0, import_promises47.readFile)(path4, "utf8");
65610
65865
  } catch (error61) {
65611
65866
  if (errnoCode(error61) === "ENOENT") return { kind: "missing" };
65612
65867
  return { kind: "unreadable" };
@@ -65627,7 +65882,7 @@ async function removeIfSame(path4, expected) {
65627
65882
  if (current.kind !== "owner" || current.owner.since !== expected.since) return;
65628
65883
  if (current.owner.pid !== expected.pid || current.owner.holder !== expected.holder) return;
65629
65884
  }
65630
- await (0, import_promises46.unlink)(path4).catch((error61) => {
65885
+ await (0, import_promises47.unlink)(path4).catch((error61) => {
65631
65886
  if (errnoCode(error61) !== "ENOENT") throw error61;
65632
65887
  });
65633
65888
  }
@@ -65652,7 +65907,7 @@ function openRepositoryLocks(options) {
65652
65907
  await removeIfSame(path4, read.owner);
65653
65908
  return null;
65654
65909
  }
65655
- const age = await (0, import_promises46.stat)(path4).then(
65910
+ const age = await (0, import_promises47.stat)(path4).then(
65656
65911
  (info) => clock.now() - info.mtimeMs,
65657
65912
  () => 0
65658
65913
  );
@@ -65666,13 +65921,13 @@ function openRepositoryLocks(options) {
65666
65921
  });
65667
65922
  const folder = async (commonDir) => {
65668
65923
  const key = repositoryLockKey(commonDir, platform3);
65669
- const dir = (0, import_node_path47.join)(options.dir, key);
65670
- await (0, import_promises46.mkdir)(dir, { recursive: true, mode: 448 });
65924
+ const dir = (0, import_node_path48.join)(options.dir, key);
65925
+ await (0, import_promises47.mkdir)(dir, { recursive: true, mode: 448 });
65671
65926
  return { key, dir };
65672
65927
  };
65673
65928
  const createExclusive = async (path4, owner) => {
65674
65929
  try {
65675
- const handle = await (0, import_promises46.open)(path4, "wx", 384);
65930
+ const handle = await (0, import_promises47.open)(path4, "wx", 384);
65676
65931
  try {
65677
65932
  await handle.writeFile(JSON.stringify(owner));
65678
65933
  } finally {
@@ -65685,10 +65940,10 @@ function openRepositoryLocks(options) {
65685
65940
  }
65686
65941
  };
65687
65942
  const liveRun = async (dir) => {
65688
- const entries = await (0, import_promises46.readdir)(dir);
65943
+ const entries = await (0, import_promises47.readdir)(dir);
65689
65944
  for (const entry of entries) {
65690
65945
  if (!entry.startsWith(RUN_FILE_PREFIX)) continue;
65691
- const holder = await heldBy((0, import_node_path47.join)(dir, entry));
65946
+ const holder = await heldBy((0, import_node_path48.join)(dir, entry));
65692
65947
  if (holder !== null) return holder;
65693
65948
  }
65694
65949
  return null;
@@ -65696,7 +65951,7 @@ function openRepositoryLocks(options) {
65696
65951
  return {
65697
65952
  tryExclusive: async (commonDir, operationId) => {
65698
65953
  const { key, dir } = await folder(commonDir);
65699
- const path4 = (0, import_node_path47.join)(dir, EXCLUSIVE_FILE);
65954
+ const path4 = (0, import_node_path48.join)(dir, EXCLUSIVE_FILE);
65700
65955
  const owner = await self(operationId);
65701
65956
  if (!await createExclusive(path4, owner)) {
65702
65957
  const holder = await heldBy(path4);
@@ -65714,11 +65969,11 @@ function openRepositoryLocks(options) {
65714
65969
  },
65715
65970
  tryShared: async (commonDir, runId) => {
65716
65971
  const { key, dir } = await folder(commonDir);
65717
- const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto24.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
65718
- const path4 = (0, import_node_path47.join)(dir, file2);
65972
+ const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto25.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
65973
+ const path4 = (0, import_node_path48.join)(dir, file2);
65719
65974
  const owner = await self(runId);
65720
65975
  await writeJsonFileAtomic(path4, owner);
65721
- const operation = await heldBy((0, import_node_path47.join)(dir, EXCLUSIVE_FILE));
65976
+ const operation = await heldBy((0, import_node_path48.join)(dir, EXCLUSIVE_FILE));
65722
65977
  if (operation !== null) {
65723
65978
  await removeIfSame(path4, owner);
65724
65979
  return { kind: "busy", holder: operation };
@@ -65818,18 +66073,18 @@ async function openWorkspaces(options) {
65818
66073
  const budgetMs = options.budgetMs ?? WORKSPACE_QUERY_BUDGET_MS;
65819
66074
  const lifetime = new AbortController();
65820
66075
  const approved = await openApprovedPaths({
65821
- file: (0, import_node_path48.join)(options.stateDir, "workspaces.json"),
66076
+ file: (0, import_node_path49.join)(options.stateDir, "workspaces.json"),
65822
66077
  log: options.log,
65823
66078
  platform: platform3
65824
66079
  });
65825
66080
  const locks = openRepositoryLocks({
65826
- dir: (0, import_node_path48.join)(options.stateDir, "locks"),
66081
+ dir: (0, import_node_path49.join)(options.stateDir, "locks"),
65827
66082
  clock: options.clock,
65828
66083
  platform: platform3
65829
66084
  });
65830
66085
  const git = createGit({
65831
66086
  env: options.env,
65832
- tmpDir: (0, import_node_path48.join)(options.stateDir, "tmp", "git"),
66087
+ tmpDir: (0, import_node_path49.join)(options.stateDir, "tmp", "git"),
65833
66088
  platform: platform3,
65834
66089
  ...options.gitPath === void 0 ? {} : { gitPath: options.gitPath },
65835
66090
  ...options.localTimeoutMs === void 0 ? {} : { localTimeoutMs: options.localTimeoutMs },
@@ -65950,11 +66205,11 @@ async function openWorkspaces(options) {
65950
66205
 
65951
66206
  // src/cli/config.ts
65952
66207
  var import_node_os11 = require("os");
65953
- var import_node_path66 = require("path");
66208
+ var import_node_path67 = require("path");
65954
66209
  init_zod();
65955
66210
 
65956
66211
  // src/client/contract.ts
65957
- var import_node_path49 = require("path");
66212
+ var import_node_path50 = require("path");
65958
66213
  init_runtime_v2();
65959
66214
  init_zod();
65960
66215
  var LOCAL_API_PROTOCOL = 1;
@@ -66127,7 +66382,7 @@ var nativeHookSignalSchema = external_exports.strictObject({
66127
66382
  provider: external_exports.enum(nativeIngestionProviders),
66128
66383
  event: external_exports.enum(nativeIngestionHookEvents),
66129
66384
  externalSessionId: external_exports.string().trim().min(1).max(200),
66130
- transcriptPath: external_exports.string().min(1).max(4096).refine(import_node_path49.isAbsolute, "transcriptPath must be absolute"),
66385
+ transcriptPath: external_exports.string().min(1).max(4096).refine(import_node_path50.isAbsolute, "transcriptPath must be absolute"),
66131
66386
  cwd: external_exports.string().max(4096).nullable(),
66132
66387
  providerTurnId: external_exports.string().max(200).nullable(),
66133
66388
  assistantFingerprint: assistantFingerprintSchema.nullable(),
@@ -66163,19 +66418,19 @@ var localApiErrorSchema = external_exports.object({
66163
66418
  });
66164
66419
 
66165
66420
  // src/client/locate.ts
66166
- var import_node_path50 = require("path");
66421
+ var import_node_path51 = require("path");
66167
66422
  var RUNTIME_PROFILES = ["production", "staging", "development", "local"];
66168
66423
  function defaultStateDir({ profile, platform: platform3, home, env }) {
66169
66424
  if (platform3 === "win32") {
66170
- return (0, import_node_path50.join)(env.LOCALAPPDATA ?? (0, import_node_path50.join)(home, "AppData", "Local"), "Alan", profile);
66425
+ return (0, import_node_path51.join)(env.LOCALAPPDATA ?? (0, import_node_path51.join)(home, "AppData", "Local"), "Alan", profile);
66171
66426
  }
66172
- return (0, import_node_path50.join)(env.XDG_STATE_HOME ?? (0, import_node_path50.join)(home, ".local", "state"), "alan", profile);
66427
+ return (0, import_node_path51.join)(env.XDG_STATE_HOME ?? (0, import_node_path51.join)(home, ".local", "state"), "alan", profile);
66173
66428
  }
66174
66429
  function defaultInstallDir({ platform: platform3, home, env }) {
66175
66430
  if (platform3 === "win32") {
66176
- return (0, import_node_path50.join)(env.LOCALAPPDATA ?? (0, import_node_path50.join)(home, "AppData", "Local"), "Alan", "runtime");
66431
+ return (0, import_node_path51.join)(env.LOCALAPPDATA ?? (0, import_node_path51.join)(home, "AppData", "Local"), "Alan", "runtime");
66177
66432
  }
66178
- return (0, import_node_path50.join)(env.XDG_DATA_HOME ?? (0, import_node_path50.join)(home, ".local", "share"), "alan", "runtime");
66433
+ return (0, import_node_path51.join)(env.XDG_DATA_HOME ?? (0, import_node_path51.join)(home, ".local", "share"), "alan", "runtime");
66179
66434
  }
66180
66435
 
66181
66436
  // src/client/machine-features-contract.ts
@@ -66234,7 +66489,7 @@ var mcpConfigResultSchema = external_exports.object({
66234
66489
  });
66235
66490
 
66236
66491
  // src/client/runtime-client.ts
66237
- var import_promises47 = require("fs/promises");
66492
+ var import_promises48 = require("fs/promises");
66238
66493
  init_acp();
66239
66494
  init_runtime_v2();
66240
66495
 
@@ -66295,7 +66550,7 @@ var DEFAULT_BACKOFF = { initialMs: 250, maxMs: 3e4 };
66295
66550
  async function readDiscovery(path4) {
66296
66551
  let text2;
66297
66552
  try {
66298
- text2 = await (0, import_promises47.readFile)(path4, "utf8");
66553
+ text2 = await (0, import_promises48.readFile)(path4, "utf8");
66299
66554
  } catch (error61) {
66300
66555
  throw new RuntimeClientError("unavailable", "The runtime is not running", { cause: error61 });
66301
66556
  }
@@ -66368,8 +66623,8 @@ function nextOffsetOf(response) {
66368
66623
  async function pause(ms, signal) {
66369
66624
  const either = AbortSignal.any([signal, AbortSignal.timeout(ms)]);
66370
66625
  if (either.aborted) return;
66371
- await new Promise((resolve12) => {
66372
- either.addEventListener("abort", () => resolve12(), { once: true });
66626
+ await new Promise((resolve13) => {
66627
+ either.addEventListener("abort", () => resolve13(), { once: true });
66373
66628
  });
66374
66629
  }
66375
66630
  function jittered(backoff, failures) {
@@ -66677,14 +66932,14 @@ async function sendNativeHookSignal(discoveryPath, hookSignal, signal) {
66677
66932
  }
66678
66933
 
66679
66934
  // src/sessions/index.ts
66680
- var import_node_crypto30 = require("crypto");
66681
- var import_promises65 = require("fs/promises");
66935
+ var import_node_crypto31 = require("crypto");
66936
+ var import_promises66 = require("fs/promises");
66682
66937
  var import_node_os10 = require("os");
66683
- var import_node_path65 = require("path");
66938
+ var import_node_path66 = require("path");
66684
66939
  init_runtime_v2();
66685
66940
 
66686
66941
  // src/holder/control-client.ts
66687
- var import_node_crypto25 = require("crypto");
66942
+ var import_node_crypto26 = require("crypto");
66688
66943
  var import_node_net2 = require("net");
66689
66944
  init_runtime_v2();
66690
66945
 
@@ -66731,8 +66986,8 @@ function isReply(message2) {
66731
66986
  async function connectHolder(endpoint, token, onEvent) {
66732
66987
  const socket = (0, import_node_net2.connect)(endpoint);
66733
66988
  const pending = /* @__PURE__ */ new Map();
66734
- const closed = new Promise((resolve12) => socket.once("close", () => resolve12()));
66735
- const ready = new Promise((resolve12, reject) => {
66989
+ const closed = new Promise((resolve13) => socket.once("close", () => resolve13()));
66990
+ const ready = new Promise((resolve13, reject) => {
66736
66991
  socket.once("error", reject);
66737
66992
  socket.once(
66738
66993
  "close",
@@ -66740,7 +66995,7 @@ async function connectHolder(endpoint, token, onEvent) {
66740
66995
  );
66741
66996
  readMessages(socket, holderMessageSchema, {
66742
66997
  onMessage: (message2) => {
66743
- if (message2.type === "ready") resolve12(message2.pid);
66998
+ if (message2.type === "ready") resolve13(message2.pid);
66744
66999
  else if (isReply(message2)) {
66745
67000
  const id = message2.id;
66746
67001
  if (id === null) return;
@@ -66754,14 +67009,14 @@ async function connectHolder(endpoint, token, onEvent) {
66754
67009
  });
66755
67010
  const pid = await ready;
66756
67011
  const request2 = (body) => {
66757
- const id = (0, import_node_crypto25.randomUUID)();
66758
- return new Promise((resolve12, reject) => {
67012
+ const id = (0, import_node_crypto26.randomUUID)();
67013
+ return new Promise((resolve13, reject) => {
66759
67014
  const timer = AbortSignal.timeout(REQUEST_TIMEOUT_MS7);
66760
67015
  timer.addEventListener("abort", () => {
66761
67016
  pending.delete(id);
66762
67017
  reject(new RuntimeFault("io_failed", "Holder did not answer"));
66763
67018
  });
66764
- pending.set(id, resolve12);
67019
+ pending.set(id, resolve13);
66765
67020
  writeMessage(socket, { ...body, id });
66766
67021
  });
66767
67022
  };
@@ -66904,7 +67159,7 @@ function createProviderDrivers(options) {
66904
67159
  }
66905
67160
 
66906
67161
  // src/holder/engine-records.ts
66907
- var import_node_path51 = require("path");
67162
+ var import_node_path52 = require("path");
66908
67163
  init_zod();
66909
67164
  var ENGINES_FILE = "engines.json";
66910
67165
  var STOP_GRACE_MS = 2e3;
@@ -66916,7 +67171,7 @@ var engineRecordSchema = external_exports.object({
66916
67171
  });
66917
67172
  var engineRecordsSchema = external_exports.object({ engines: external_exports.array(engineRecordSchema) });
66918
67173
  function engineRecordsPath(sessionDir) {
66919
- return (0, import_node_path51.join)(sessionDir, ENGINES_FILE);
67174
+ return (0, import_node_path52.join)(sessionDir, ENGINES_FILE);
66920
67175
  }
66921
67176
  function recordSpawnedEngines(path4, clock, log) {
66922
67177
  const live = /* @__PURE__ */ new Map();
@@ -66976,12 +67231,12 @@ async function reapLeftoverEngines(path4, options) {
66976
67231
  }
66977
67232
 
66978
67233
  // src/holder/launch-command.ts
66979
- var import_node_fs16 = require("fs");
66980
- var import_node_path52 = require("path");
67234
+ var import_node_fs17 = require("fs");
67235
+ var import_node_path53 = require("path");
66981
67236
  var HOLDER_BUNDLE = "alan-holder.cjs";
66982
- function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs16.existsSync) {
67237
+ function holderArguments(runtimeArgs, nodeFlags, exists6 = import_node_fs17.existsSync) {
66983
67238
  const bundle = runtimeArgs.at(-1);
66984
- const lean = bundle === void 0 ? void 0 : (0, import_node_path52.join)((0, import_node_path52.dirname)(bundle), HOLDER_BUNDLE);
67239
+ const lean = bundle === void 0 ? void 0 : (0, import_node_path53.join)((0, import_node_path53.dirname)(bundle), HOLDER_BUNDLE);
66985
67240
  const script = lean !== void 0 && exists6(lean) ? [...runtimeArgs.slice(0, -1), lean] : runtimeArgs;
66986
67241
  return [...nodeFlags, ...script, "hold"];
66987
67242
  }
@@ -67016,17 +67271,17 @@ function createConversationMcpAuthorization(options) {
67016
67271
  }
67017
67272
 
67018
67273
  // src/holder/mcp-helper-access.ts
67019
- var import_promises54 = require("fs/promises");
67274
+ var import_promises55 = require("fs/promises");
67020
67275
  function createHelperMcpAccess(options) {
67021
67276
  return {
67022
67277
  [Symbol.asyncDispose]: async () => {
67023
- await (0, import_promises54.rm)(options.credentialPath, { force: true });
67278
+ await (0, import_promises55.rm)(options.credentialPath, { force: true });
67024
67279
  },
67025
67280
  url: options.managedMcp.url,
67026
67281
  authorization: async (signal) => {
67027
67282
  const authorization = await options.managedMcp.authorization(signal);
67028
67283
  if (authorization === void 0 || signal.aborted) {
67029
- await (0, import_promises54.rm)(options.credentialPath, { force: true });
67284
+ await (0, import_promises55.rm)(options.credentialPath, { force: true });
67030
67285
  return void 0;
67031
67286
  }
67032
67287
  const credential = {
@@ -67041,8 +67296,8 @@ function createHelperMcpAccess(options) {
67041
67296
  }
67042
67297
 
67043
67298
  // src/holder/run-inputs.ts
67044
- var import_promises55 = require("fs/promises");
67045
- var import_node_path53 = require("path");
67299
+ var import_promises56 = require("fs/promises");
67300
+ var import_node_path54 = require("path");
67046
67301
  var NO_RUN_INPUTS = {
67047
67302
  attachments: [],
67048
67303
  providerEnv: {},
@@ -67055,18 +67310,18 @@ function safeFilename(filename) {
67055
67310
  return safe || "attachment";
67056
67311
  }
67057
67312
  async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
67058
- const dir = (0, import_node_path53.join)(tmpDir, "runs", spec.runId);
67313
+ const dir = (0, import_node_path54.join)(tmpDir, "runs", spec.runId);
67059
67314
  const cleanup = async () => {
67060
- await (0, import_promises55.rm)(dir, { recursive: true, force: true });
67315
+ await (0, import_promises56.rm)(dir, { recursive: true, force: true });
67061
67316
  };
67062
67317
  try {
67063
67318
  const credential = await source.fetchProviderCredential(spec.runId, signal);
67064
67319
  const attachments = [];
67065
- if (spec.attachments?.length) await (0, import_promises55.mkdir)(dir, { recursive: true, mode: 448 });
67320
+ if (spec.attachments?.length) await (0, import_promises56.mkdir)(dir, { recursive: true, mode: 448 });
67066
67321
  for (const [index, attachment] of (spec.attachments ?? []).entries()) {
67067
67322
  const bytes = await source.downloadAttachment(spec.runId, attachment.id, signal);
67068
- const path4 = (0, import_node_path53.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
67069
- await (0, import_promises55.writeFile)(path4, bytes, { mode: 384 });
67323
+ const path4 = (0, import_node_path54.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
67324
+ await (0, import_promises56.writeFile)(path4, bytes, { mode: 384 });
67070
67325
  attachments.push({
67071
67326
  id: attachment.id,
67072
67327
  kind: attachment.kind,
@@ -67093,30 +67348,30 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
67093
67348
  }
67094
67349
 
67095
67350
  // src/holder/serve.ts
67096
- var import_node_crypto29 = require("crypto");
67097
- var import_node_fs21 = require("fs");
67351
+ var import_node_crypto30 = require("crypto");
67352
+ var import_node_fs22 = require("fs");
67098
67353
  var import_node_net3 = require("net");
67099
- var import_node_path64 = require("path");
67354
+ var import_node_path65 = require("path");
67100
67355
  init_runtime_v2();
67101
67356
 
67102
67357
  // src/holder/admission.ts
67103
- var import_node_fs18 = require("fs");
67104
- var import_promises59 = require("fs/promises");
67358
+ var import_node_fs19 = require("fs");
67359
+ var import_promises60 = require("fs/promises");
67105
67360
  var import_node_os9 = require("os");
67106
- var import_node_path58 = require("path");
67361
+ var import_node_path59 = require("path");
67107
67362
  init_constants();
67108
67363
 
67109
67364
  // ../shared/dist/node/local-workspace.js
67110
- var import_node_fs17 = require("fs");
67365
+ var import_node_fs18 = require("fs");
67111
67366
  var import_node_os8 = require("os");
67112
- var import_node_path54 = require("path");
67367
+ var import_node_path55 = require("path");
67113
67368
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os8.homedir)()) {
67114
- return (0, import_node_path54.join)(homeDirectory, ".alan", "workspace");
67369
+ return (0, import_node_path55.join)(homeDirectory, ".alan", "workspace");
67115
67370
  }
67116
67371
 
67117
67372
  // src/holder/admission-relocation.ts
67118
- var import_promises56 = require("fs/promises");
67119
- var import_node_path55 = require("path");
67373
+ var import_promises57 = require("fs/promises");
67374
+ var import_node_path56 = require("path");
67120
67375
  var MAX_RELOCATION_CANDIDATES = 200;
67121
67376
  var RELOCATION_BUDGET_MS = 2e4;
67122
67377
  function repositoryIdentity(url3) {
@@ -67151,8 +67406,8 @@ async function originIdentity(git, path4, signal) {
67151
67406
  }
67152
67407
  async function childDirectories(parent, limit) {
67153
67408
  try {
67154
- const entries = await (0, import_promises56.readdir)(parent, { withFileTypes: true });
67155
- return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path55.join)(parent, entry.name));
67409
+ const entries = await (0, import_promises57.readdir)(parent, { withFileTypes: true });
67410
+ return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path56.join)(parent, entry.name));
67156
67411
  } catch {
67157
67412
  return [];
67158
67413
  }
@@ -67160,7 +67415,7 @@ async function childDirectories(parent, limit) {
67160
67415
  async function candidateFolders(search) {
67161
67416
  const roots = /* @__PURE__ */ new Map();
67162
67417
  for (const path4 of [search.missingPath, ...search.approvedWorkspacePaths]) {
67163
- const parent = (0, import_node_path55.dirname)((0, import_node_path55.resolve)(path4));
67418
+ const parent = (0, import_node_path56.dirname)((0, import_node_path56.resolve)(path4));
67164
67419
  roots.set(comparablePath(parent, search.platform), parent);
67165
67420
  }
67166
67421
  const candidates2 = /* @__PURE__ */ new Map();
@@ -67187,9 +67442,9 @@ async function discoverRelocatedWorkspace(search) {
67187
67442
  }
67188
67443
 
67189
67444
  // src/holder/checkout-refresh.ts
67190
- var import_node_crypto27 = require("crypto");
67191
- var import_promises57 = require("fs/promises");
67192
- var import_node_path56 = require("path");
67445
+ var import_node_crypto28 = require("crypto");
67446
+ var import_promises58 = require("fs/promises");
67447
+ var import_node_path57 = require("path");
67193
67448
  function short(sha) {
67194
67449
  return sha.slice(0, 12);
67195
67450
  }
@@ -67201,8 +67456,8 @@ function staleLine(path4, snapshot2, tip) {
67201
67456
  }
67202
67457
  async function claimOnce(dir, name) {
67203
67458
  try {
67204
- await (0, import_promises57.mkdir)(dir, { recursive: true, mode: 448 });
67205
- await (await (0, import_promises57.open)((0, import_node_path56.join)(dir, name), "wx")).close();
67459
+ await (0, import_promises58.mkdir)(dir, { recursive: true, mode: 448 });
67460
+ await (await (0, import_promises58.open)((0, import_node_path57.join)(dir, name), "wx")).close();
67206
67461
  return true;
67207
67462
  } catch {
67208
67463
  return false;
@@ -67233,8 +67488,8 @@ async function fastForward(freshness, operationId, deps, signal) {
67233
67488
  }
67234
67489
  async function atFirstLease(freshness, spec, deps, signal) {
67235
67490
  const first = await claimOnce(
67236
- (0, import_node_path56.join)(deps.dir, "leased"),
67237
- (0, import_node_crypto27.createHash)("sha256").update(freshness.path).digest("hex")
67491
+ (0, import_node_path57.join)(deps.dir, "leased"),
67492
+ (0, import_node_crypto28.createHash)("sha256").update(freshness.path).digest("hex")
67238
67493
  );
67239
67494
  switch (freshness.state) {
67240
67495
  case "current":
@@ -67264,7 +67519,7 @@ async function checkoutsOf(spec, leaseTargets) {
67264
67519
  function createCheckoutRefresh(deps) {
67265
67520
  return async (spec, leaseTargets, signal) => {
67266
67521
  if (spec.providerSessionId !== void 0) return void 0;
67267
- if (!await claimOnce((0, import_node_path56.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
67522
+ if (!await claimOnce((0, import_node_path57.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
67268
67523
  const lines2 = [];
67269
67524
  for (const target of await checkoutsOf(spec, leaseTargets)) {
67270
67525
  const freshness = await readCheckoutFreshness(deps.dir, target);
@@ -67285,8 +67540,8 @@ function createCheckoutRefresh(deps) {
67285
67540
  }
67286
67541
 
67287
67542
  // src/holder/lease.ts
67288
- var import_promises58 = require("fs/promises");
67289
- var import_node_path57 = require("path");
67543
+ var import_promises59 = require("fs/promises");
67544
+ var import_node_path58 = require("path");
67290
67545
  var LEASE_CHECK_EVERY_MS = 5e3;
67291
67546
  var MAX_TRANSIENT_FAILURES = 3;
67292
67547
  var BACKOFF_BASE_MS = 1e3;
@@ -67300,8 +67555,8 @@ function identityFailure(code, workspacePath) {
67300
67555
  return { code, problemCode: "app.workspace.missing", message: MESSAGES[code], workspacePath };
67301
67556
  }
67302
67557
  async function fileIdentity(path4) {
67303
- const canonical = await (0, import_promises58.realpath)(path4);
67304
- const info = await (0, import_promises58.stat)(canonical, { bigint: true });
67558
+ const canonical = await (0, import_promises59.realpath)(path4);
67559
+ const info = await (0, import_promises59.stat)(canonical, { bigint: true });
67305
67560
  return `${canonical}:${info.dev}:${info.ino}`;
67306
67561
  }
67307
67562
  async function snapshot(git, path4, signal) {
@@ -67320,7 +67575,7 @@ async function snapshot(git, path4, signal) {
67320
67575
  workspace: await fileIdentity(path4),
67321
67576
  repository: await fileIdentity(commonDir),
67322
67577
  worktree: await fileIdentity(gitDir),
67323
- commonDir: await (0, import_promises58.realpath)(commonDir)
67578
+ commonDir: await (0, import_promises59.realpath)(commonDir)
67324
67579
  };
67325
67580
  } catch {
67326
67581
  return null;
@@ -67333,7 +67588,7 @@ async function gitValue(git, path4, args, signal) {
67333
67588
  }
67334
67589
  async function pathExists(path4) {
67335
67590
  try {
67336
- await (0, import_promises58.stat)(path4);
67591
+ await (0, import_promises59.stat)(path4);
67337
67592
  return true;
67338
67593
  } catch (error61) {
67339
67594
  return errnoCode(error61) !== "ENOENT" && errnoCode(error61) !== "ENOTDIR";
@@ -67342,19 +67597,19 @@ async function pathExists(path4) {
67342
67597
  async function hasGitMarker(path4) {
67343
67598
  let directory;
67344
67599
  try {
67345
- directory = await (0, import_promises58.realpath)(path4);
67600
+ directory = await (0, import_promises59.realpath)(path4);
67346
67601
  } catch {
67347
67602
  return true;
67348
67603
  }
67349
67604
  for (; ; ) {
67350
67605
  try {
67351
- await (0, import_promises58.stat)((0, import_node_path57.join)(directory, ".git"));
67606
+ await (0, import_promises59.stat)((0, import_node_path58.join)(directory, ".git"));
67352
67607
  return true;
67353
67608
  } catch (error61) {
67354
67609
  const code = errnoCode(error61);
67355
67610
  if (code !== "ENOENT" && code !== "ENOTDIR") return true;
67356
67611
  }
67357
- const parent = (0, import_node_path57.dirname)(directory);
67612
+ const parent = (0, import_node_path58.dirname)(directory);
67358
67613
  if (parent === directory) return false;
67359
67614
  directory = parent;
67360
67615
  }
@@ -67518,7 +67773,7 @@ function volumeRoot(path4) {
67518
67773
  }
67519
67774
  async function exists4(path4) {
67520
67775
  try {
67521
- await (0, import_promises59.stat)(path4);
67776
+ await (0, import_promises60.stat)(path4);
67522
67777
  return true;
67523
67778
  } catch {
67524
67779
  return false;
@@ -67526,10 +67781,10 @@ async function exists4(path4) {
67526
67781
  }
67527
67782
  async function inspectReadiness(path4) {
67528
67783
  try {
67529
- if (!(await (0, import_promises59.stat)(path4)).isDirectory()) {
67784
+ if (!(await (0, import_promises60.stat)(path4)).isDirectory()) {
67530
67785
  return { ready: false, missing: true, message: MESSAGES2.missing };
67531
67786
  }
67532
- await (0, import_promises59.access)(path4, import_node_fs18.constants.R_OK | import_node_fs18.constants.W_OK | import_node_fs18.constants.X_OK);
67787
+ await (0, import_promises60.access)(path4, import_node_fs19.constants.R_OK | import_node_fs19.constants.W_OK | import_node_fs19.constants.X_OK);
67533
67788
  return { ready: true };
67534
67789
  } catch (error61) {
67535
67790
  const code = errnoCode(error61) ?? "";
@@ -67607,8 +67862,8 @@ async function admitDefaultWorkspace(spec, context, skills) {
67607
67862
  const { env } = context;
67608
67863
  const path4 = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os9.homedir)());
67609
67864
  try {
67610
- await (0, import_promises59.mkdir)(path4, { recursive: true, mode: 448 });
67611
- await (0, import_promises59.access)(path4, import_node_fs18.constants.R_OK | import_node_fs18.constants.W_OK | import_node_fs18.constants.X_OK);
67865
+ await (0, import_promises60.mkdir)(path4, { recursive: true, mode: 448 });
67866
+ await (0, import_promises60.access)(path4, import_node_fs19.constants.R_OK | import_node_fs19.constants.W_OK | import_node_fs19.constants.X_OK);
67612
67867
  return {
67613
67868
  kind: "admitted",
67614
67869
  spec: { ...spec, projectPath: path4 },
@@ -67684,7 +67939,7 @@ var PROBE_TIMEOUT_MS2 = 5e3;
67684
67939
  function createHolderWorkspace(machine, clock, log) {
67685
67940
  const platform3 = machine.platform ?? process.platform;
67686
67941
  const git = createGitRunner({ env: machine.env, platform: platform3, localTimeoutMs: PROBE_TIMEOUT_MS2 });
67687
- const locks = openRepositoryLocks({ dir: (0, import_node_path58.join)(machine.stateDir, "locks"), clock, platform: platform3 });
67942
+ const locks = openRepositoryLocks({ dir: (0, import_node_path59.join)(machine.stateDir, "locks"), clock, platform: platform3 });
67688
67943
  return {
67689
67944
  admission: {
67690
67945
  env: machine.env,
@@ -67696,7 +67951,7 @@ function createHolderWorkspace(machine, clock, log) {
67696
67951
  ),
67697
67952
  approvedRoots: async () => {
67698
67953
  const approved = await openApprovedPaths({
67699
- file: (0, import_node_path58.join)(machine.stateDir, "workspaces.json"),
67954
+ file: (0, import_node_path59.join)(machine.stateDir, "workspaces.json"),
67700
67955
  log,
67701
67956
  platform: platform3
67702
67957
  });
@@ -67709,7 +67964,7 @@ function createHolderWorkspace(machine, clock, log) {
67709
67964
  git,
67710
67965
  locks,
67711
67966
  log,
67712
- dir: (0, import_node_path58.join)(machine.stateDir, "checkout-freshness")
67967
+ dir: (0, import_node_path59.join)(machine.stateDir, "checkout-freshness")
67713
67968
  })
67714
67969
  } : {}
67715
67970
  };
@@ -67737,7 +67992,7 @@ async function respondToTurn(runningRunId, gate, driver, request2) {
67737
67992
  }
67738
67993
 
67739
67994
  // src/holder/session-facts.ts
67740
- var import_promises60 = require("fs/promises");
67995
+ var import_promises61 = require("fs/promises");
67741
67996
  var CLI_RSS_CACHE_MS = 1e4;
67742
67997
  var LOGIN_PROBLEM_PREFIX = "cli.auth.";
67743
67998
  function isLoginFailure(result) {
@@ -67763,8 +68018,8 @@ function createSessionFacts(options) {
67763
68018
  const path4 = await resolveCommandOnPath(command, env, platform3);
67764
68019
  if (path4 === null) return null;
67765
68020
  try {
67766
- const real = await (0, import_promises60.realpath)(path4);
67767
- const info = await (0, import_promises60.stat)(real);
68021
+ const real = await (0, import_promises61.realpath)(path4);
68022
+ const info = await (0, import_promises61.stat)(real);
67768
68023
  return { command, key: `${real}:${info.ino}:${info.size}:${info.mtimeMs}` };
67769
68024
  } catch {
67770
68025
  return null;
@@ -67851,12 +68106,12 @@ function createSessionFacts(options) {
67851
68106
  init_acp2();
67852
68107
 
67853
68108
  // src/run-log/archive.ts
67854
- var import_promises61 = require("fs/promises");
67855
- var import_node_path59 = require("path");
68109
+ var import_promises62 = require("fs/promises");
68110
+ var import_node_path60 = require("path");
67856
68111
  init_runtime_v2();
67857
68112
  async function openRunArchive(runsDir) {
67858
- const path4 = (0, import_node_path59.join)((0, import_node_path59.dirname)(runsDir), "archived-runs.txt");
67859
- const text2 = await (0, import_promises61.readFile)(path4, "utf8").catch((error61) => {
68113
+ const path4 = (0, import_node_path60.join)((0, import_node_path60.dirname)(runsDir), "archived-runs.txt");
68114
+ const text2 = await (0, import_promises62.readFile)(path4, "utf8").catch((error61) => {
67860
68115
  if (errnoCode(error61) === "ENOENT") return "";
67861
68116
  throw error61;
67862
68117
  });
@@ -67870,7 +68125,7 @@ async function openRunArchive(runsDir) {
67870
68125
  add: async (runIds) => {
67871
68126
  const added = runIds.filter((runId) => !archived.has(runId));
67872
68127
  if (added.length === 0) return;
67873
- await (0, import_promises61.appendFile)(path4, `
68128
+ await (0, import_promises62.appendFile)(path4, `
67874
68129
  ${added.join("\n")}
67875
68130
  `, { mode: 384 });
67876
68131
  for (const runId of added) archived.add(runId);
@@ -67879,13 +68134,13 @@ ${added.join("\n")}
67879
68134
  }
67880
68135
 
67881
68136
  // src/run-log/complete.ts
67882
- var import_node_crypto28 = require("crypto");
67883
- var import_node_fs19 = require("fs");
67884
- var import_node_path61 = require("path");
68137
+ var import_node_crypto29 = require("crypto");
68138
+ var import_node_fs20 = require("fs");
68139
+ var import_node_path62 = require("path");
67885
68140
 
67886
68141
  // src/run-log/directory.ts
67887
- var import_promises62 = require("fs/promises");
67888
- var import_node_path60 = require("path");
68142
+ var import_promises63 = require("fs/promises");
68143
+ var import_node_path61 = require("path");
67889
68144
  init_runtime_v2();
67890
68145
  init_zod();
67891
68146
  var runMetaSchema = external_exports.object({
@@ -67911,17 +68166,17 @@ async function readRunMeta(path4) {
67911
68166
  return read.kind === "ok" ? read.value : null;
67912
68167
  }
67913
68168
  function runDirectory(runsDir, runId) {
67914
- const dir = (0, import_node_path60.join)(runsDir, runId);
68169
+ const dir = (0, import_node_path61.join)(runsDir, runId);
67915
68170
  return {
67916
68171
  dir,
67917
- log: (0, import_node_path60.join)(dir, "log.jsonl"),
67918
- upload: (0, import_node_path60.join)(dir, "upload.json"),
67919
- meta: (0, import_node_path60.join)(dir, "run.json")
68172
+ log: (0, import_node_path61.join)(dir, "log.jsonl"),
68173
+ upload: (0, import_node_path61.join)(dir, "upload.json"),
68174
+ meta: (0, import_node_path61.join)(dir, "run.json")
67920
68175
  };
67921
68176
  }
67922
68177
  async function isRunClaimed(runsDir, runId) {
67923
68178
  try {
67924
- return (await (0, import_promises62.stat)(runDirectory(runsDir, runId).log)).size > 0;
68179
+ return (await (0, import_promises63.stat)(runDirectory(runsDir, runId).log)).size > 0;
67925
68180
  } catch (error61) {
67926
68181
  if (errnoCode(error61) === "ENOENT") return false;
67927
68182
  throw error61;
@@ -67930,24 +68185,24 @@ async function isRunClaimed(runsDir, runId) {
67930
68185
 
67931
68186
  // src/run-log/complete.ts
67932
68187
  function writeLogFile(path4, dir, text2) {
67933
- const temp = (0, import_node_path61.join)(dir, `.log.${(0, import_node_crypto28.randomUUID)()}.tmp`);
67934
- const fd = (0, import_node_fs19.openSync)(temp, "wx", 384);
68188
+ const temp = (0, import_node_path62.join)(dir, `.log.${(0, import_node_crypto29.randomUUID)()}.tmp`);
68189
+ const fd = (0, import_node_fs20.openSync)(temp, "wx", 384);
67935
68190
  try {
67936
- (0, import_node_fs19.writeSync)(fd, text2);
67937
- (0, import_node_fs19.fsyncSync)(fd);
68191
+ (0, import_node_fs20.writeSync)(fd, text2);
68192
+ (0, import_node_fs20.fsyncSync)(fd);
67938
68193
  } finally {
67939
- (0, import_node_fs19.closeSync)(fd);
68194
+ (0, import_node_fs20.closeSync)(fd);
67940
68195
  }
67941
68196
  try {
67942
- (0, import_node_fs19.renameSync)(temp, path4);
68197
+ (0, import_node_fs20.renameSync)(temp, path4);
67943
68198
  } finally {
67944
- (0, import_node_fs19.rmSync)(temp, { force: true });
68199
+ (0, import_node_fs20.rmSync)(temp, { force: true });
67945
68200
  }
67946
68201
  }
67947
68202
  async function writeCompleteRunLog(runsDir, meta3, records) {
67948
68203
  const paths = runDirectory(runsDir, meta3.runId);
67949
68204
  if (!await isRunClaimed(runsDir, meta3.runId)) {
67950
- (0, import_node_fs19.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
68205
+ (0, import_node_fs20.mkdirSync)(paths.dir, { recursive: true, mode: 448 });
67951
68206
  const text2 = records.map((record2, index) => {
67952
68207
  const line = { seq: index + 1, at: record2.at, update: record2.update };
67953
68208
  return `${JSON.stringify(line)}
@@ -67959,8 +68214,8 @@ async function writeCompleteRunLog(runsDir, meta3, records) {
67959
68214
  }
67960
68215
 
67961
68216
  // src/run-log/conversation-index.ts
67962
- var import_promises63 = require("fs/promises");
67963
- var import_node_path62 = require("path");
68217
+ var import_promises64 = require("fs/promises");
68218
+ var import_node_path63 = require("path");
67964
68219
  init_runtime_v2();
67965
68220
  init_zod();
67966
68221
  var ORDINALS_PER_SHARD = 1e3;
@@ -67977,13 +68232,13 @@ var coverageSchema = external_exports.object({
67977
68232
  nextExpectedOrdinal: external_exports.number().int().positive()
67978
68233
  });
67979
68234
  function conversationsDirectory(runsDir) {
67980
- return (0, import_node_path62.join)((0, import_node_path62.dirname)(runsDir), "conversations");
68235
+ return (0, import_node_path63.join)((0, import_node_path63.dirname)(runsDir), "conversations");
67981
68236
  }
67982
68237
  function indexDirectory(runsDir, conversationId) {
67983
- return (0, import_node_path62.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
68238
+ return (0, import_node_path63.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
67984
68239
  }
67985
68240
  function shardPath(runsDir, conversationId, ordinal) {
67986
- return (0, import_node_path62.join)(
68241
+ return (0, import_node_path63.join)(
67987
68242
  indexDirectory(runsDir, conversationId),
67988
68243
  `${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
67989
68244
  );
@@ -67992,10 +68247,10 @@ async function indexConversationRun(runsDir, conversationId, ordinal, assistantO
67992
68247
  const nextOrdinal = assistantOrdinal + 1;
67993
68248
  if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
67994
68249
  const path4 = shardPath(runsDir, conversationId, ordinal);
67995
- await (0, import_promises63.mkdir)((0, import_node_path62.dirname)(path4), { recursive: true, mode: 448 });
67996
- await (0, import_promises63.appendFile)(path4, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
68250
+ await (0, import_promises64.mkdir)((0, import_node_path63.dirname)(path4), { recursive: true, mode: 448 });
68251
+ await (0, import_promises64.appendFile)(path4, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
67997
68252
  `, { mode: 384 });
67998
- const coveragePath = (0, import_node_path62.join)((0, import_node_path62.dirname)((0, import_node_path62.dirname)(path4)), "coverage.json");
68253
+ const coveragePath = (0, import_node_path63.join)((0, import_node_path63.dirname)((0, import_node_path63.dirname)(path4)), "coverage.json");
67999
68254
  const coverage = await readJsonFile(coveragePath, coverageSchema);
68000
68255
  const current = coverage.kind === "ok" ? coverage.value : null;
68001
68256
  const next = nextCoverage(current, ordinal, nextOrdinal);
@@ -68010,13 +68265,13 @@ function nextCoverage(current, ordinal, nextOrdinal) {
68010
68265
  return null;
68011
68266
  }
68012
68267
  async function readConversationIndexCoverage(runsDir, conversationId) {
68013
- const path4 = (0, import_node_path62.join)((0, import_node_path62.dirname)(indexDirectory(runsDir, conversationId)), "coverage.json");
68268
+ const path4 = (0, import_node_path63.join)((0, import_node_path63.dirname)(indexDirectory(runsDir, conversationId)), "coverage.json");
68014
68269
  const result = await readJsonFile(path4, coverageSchema);
68015
68270
  return result.kind === "ok" ? result.value : null;
68016
68271
  }
68017
68272
  async function readConversationRunIndex(runsDir, conversationId, before, limit) {
68018
68273
  const directory = indexDirectory(runsDir, conversationId);
68019
- const names = await (0, import_promises63.readdir)(directory).catch((error61) => {
68274
+ const names = await (0, import_promises64.readdir)(directory).catch((error61) => {
68020
68275
  if (error61.code === "ENOENT") return [];
68021
68276
  throw error61;
68022
68277
  });
@@ -68025,7 +68280,7 @@ async function readConversationRunIndex(runsDir, conversationId, before, limit)
68025
68280
  ).sort((left, right) => right - left);
68026
68281
  const selected = [];
68027
68282
  for (const shard of shards) {
68028
- const text2 = await (0, import_promises63.readFile)((0, import_node_path62.join)(directory, `${shard}.jsonl`), "utf8");
68283
+ const text2 = await (0, import_promises64.readFile)((0, import_node_path63.join)(directory, `${shard}.jsonl`), "utf8");
68029
68284
  const records = text2.split("\n").flatMap((line) => {
68030
68285
  if (!line) return [];
68031
68286
  const parsed = indexRecordSchema.parse(JSON.parse(line));
@@ -68050,7 +68305,7 @@ async function readIndexableRun(runsDir, name) {
68050
68305
  return { conversationId: meta3.conversationId, ordinal, assistantOrdinal, runId: runId.data };
68051
68306
  }
68052
68307
  async function readIndexableRuns(runsDir) {
68053
- const names = await (0, import_promises63.readdir)(runsDir).catch(() => []);
68308
+ const names = await (0, import_promises64.readdir)(runsDir).catch(() => []);
68054
68309
  const byConversation = /* @__PURE__ */ new Map();
68055
68310
  let next = 0;
68056
68311
  const worker = async () => {
@@ -68080,21 +68335,21 @@ async function writeConversationIndex(directory, runs) {
68080
68335
  else lines2.push(line);
68081
68336
  coverage = nextCoverage(coverage, run2.ordinal, nextOrdinal) ?? coverage;
68082
68337
  }
68083
- await (0, import_promises63.mkdir)((0, import_node_path62.join)(directory, "turn-index"), { recursive: true, mode: 448 });
68338
+ await (0, import_promises64.mkdir)((0, import_node_path63.join)(directory, "turn-index"), { recursive: true, mode: 448 });
68084
68339
  for (const [shard, lines2] of shards) {
68085
- await (0, import_promises63.writeFile)((0, import_node_path62.join)(directory, "turn-index", `${shard}.jsonl`), `${lines2.join("\n")}
68340
+ await (0, import_promises64.writeFile)((0, import_node_path63.join)(directory, "turn-index", `${shard}.jsonl`), `${lines2.join("\n")}
68086
68341
  `, {
68087
68342
  mode: 384
68088
68343
  });
68089
68344
  }
68090
- await (0, import_promises63.writeFile)((0, import_node_path62.join)(directory, "coverage.json"), `${JSON.stringify(coverage)}
68345
+ await (0, import_promises64.writeFile)((0, import_node_path63.join)(directory, "coverage.json"), `${JSON.stringify(coverage)}
68091
68346
  `, {
68092
68347
  mode: 384
68093
68348
  });
68094
68349
  }
68095
68350
  async function rebuildConversationIndexes(runsDir) {
68096
68351
  const root = conversationsDirectory(runsDir);
68097
- const exists6 = await (0, import_promises63.stat)(root).then(
68352
+ const exists6 = await (0, import_promises64.stat)(root).then(
68098
68353
  () => true,
68099
68354
  (error61) => {
68100
68355
  if (errnoCode(error61) === "ENOENT") return false;
@@ -68103,18 +68358,18 @@ async function rebuildConversationIndexes(runsDir) {
68103
68358
  );
68104
68359
  if (exists6) return 0;
68105
68360
  const building = `${root}.rebuilding`;
68106
- await (0, import_promises63.rm)(building, { recursive: true, force: true });
68107
- await (0, import_promises63.mkdir)(building, { recursive: true, mode: 448 });
68361
+ await (0, import_promises64.rm)(building, { recursive: true, force: true });
68362
+ await (0, import_promises64.mkdir)(building, { recursive: true, mode: 448 });
68108
68363
  const byConversation = await readIndexableRuns(runsDir);
68109
68364
  for (const [conversationId, runs] of byConversation) {
68110
- await writeConversationIndex((0, import_node_path62.join)(building, conversationId), runs);
68365
+ await writeConversationIndex((0, import_node_path63.join)(building, conversationId), runs);
68111
68366
  }
68112
- await (0, import_promises63.rename)(building, root);
68367
+ await (0, import_promises64.rename)(building, root);
68113
68368
  return byConversation.size;
68114
68369
  }
68115
68370
 
68116
68371
  // src/run-log/reader.ts
68117
- var import_promises64 = require("fs/promises");
68372
+ var import_promises65 = require("fs/promises");
68118
68373
  init_runtime_v2();
68119
68374
 
68120
68375
  // src/run-log/tail.ts
@@ -68137,7 +68392,7 @@ function firstRecordLength(bytes) {
68137
68392
  return bytes.indexOf(RUN_LOG_RECORD_SEPARATOR) + 1;
68138
68393
  }
68139
68394
  async function openRunLogReader(path4) {
68140
- const handle = await (0, import_promises64.open)(path4, "r");
68395
+ const handle = await (0, import_promises65.open)(path4, "r");
68141
68396
  const readAt = async (position, length) => {
68142
68397
  const buffer = Buffer.alloc(length);
68143
68398
  const { bytesRead } = await handle.read(buffer, 0, length, position);
@@ -68171,7 +68426,7 @@ async function openRunLogReader(path4) {
68171
68426
  };
68172
68427
  }
68173
68428
  async function readLastRecord(path4) {
68174
- const handle = await (0, import_promises64.open)(path4, "r").catch(() => null);
68429
+ const handle = await (0, import_promises65.open)(path4, "r").catch(() => null);
68175
68430
  if (handle === null) return null;
68176
68431
  try {
68177
68432
  const { size } = await handle.stat();
@@ -68204,13 +68459,13 @@ function runEnded(input2) {
68204
68459
  var decoder = new TextDecoder();
68205
68460
 
68206
68461
  // src/run-log/writer.ts
68207
- var import_node_fs20 = require("fs");
68208
- var import_node_path63 = require("path");
68462
+ var import_node_fs21 = require("fs");
68463
+ var import_node_path64 = require("path");
68209
68464
  init_runtime_v2();
68210
68465
  function lastSeq(fd, size) {
68211
68466
  for (const length of tailWindows(size)) {
68212
68467
  const buffer = Buffer.alloc(length);
68213
- (0, import_node_fs20.readSync)(fd, buffer, 0, length, size - length);
68468
+ (0, import_node_fs21.readSync)(fd, buffer, 0, length, size - length);
68214
68469
  const last = lastLine(buffer.toString("utf8").trimEnd(), length === size);
68215
68470
  if (last === void 0) continue;
68216
68471
  if (last.length === 0) return 0;
@@ -68221,13 +68476,13 @@ function lastSeq(fd, size) {
68221
68476
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
68222
68477
  }
68223
68478
  function openRunLog(path4, clock) {
68224
- (0, import_node_fs20.mkdirSync)((0, import_node_path63.dirname)(path4), { recursive: true, mode: 448 });
68225
- const fd = (0, import_node_fs20.openSync)(path4, "a+", 384);
68226
- let size = (0, import_node_fs20.fstatSync)(fd).size;
68479
+ (0, import_node_fs21.mkdirSync)((0, import_node_path64.dirname)(path4), { recursive: true, mode: 448 });
68480
+ const fd = (0, import_node_fs21.openSync)(path4, "a+", 384);
68481
+ let size = (0, import_node_fs21.fstatSync)(fd).size;
68227
68482
  let seq = lastSeq(fd, size);
68228
68483
  let dirty = false;
68229
68484
  const sync = () => {
68230
- (0, import_node_fs20.fsyncSync)(fd);
68485
+ (0, import_node_fs21.fsyncSync)(fd);
68231
68486
  dirty = false;
68232
68487
  };
68233
68488
  return {
@@ -68241,7 +68496,7 @@ function openRunLog(path4, clock) {
68241
68496
  };
68242
68497
  const line = Buffer.from(`${JSON.stringify(record2)}
68243
68498
  `, "utf8");
68244
- (0, import_node_fs20.writeSync)(fd, line);
68499
+ (0, import_node_fs21.writeSync)(fd, line);
68245
68500
  size += line.length;
68246
68501
  dirty = true;
68247
68502
  if (isRunLifecycleKind(update.sessionUpdate)) sync();
@@ -68253,7 +68508,7 @@ function openRunLog(path4, clock) {
68253
68508
  },
68254
68509
  [Symbol.dispose]: () => {
68255
68510
  if (dirty) sync();
68256
- (0, import_node_fs20.closeSync)(fd);
68511
+ (0, import_node_fs21.closeSync)(fd);
68257
68512
  }
68258
68513
  };
68259
68514
  }
@@ -68538,12 +68793,12 @@ var TASK_UNSUPPORTED = {
68538
68793
  message: "This agent cannot stop one background task."
68539
68794
  };
68540
68795
  function sha2564(value2) {
68541
- return (0, import_node_crypto29.createHash)("sha256").update(value2).digest("hex");
68796
+ return (0, import_node_crypto30.createHash)("sha256").update(value2).digest("hex");
68542
68797
  }
68543
68798
  function tokenMatches(expected, presented) {
68544
68799
  const a = Buffer.from(sha2564(expected), "hex");
68545
68800
  const b = Buffer.from(sha2564(presented), "hex");
68546
- return (0, import_node_crypto29.timingSafeEqual)(a, b);
68801
+ return (0, import_node_crypto30.timingSafeEqual)(a, b);
68547
68802
  }
68548
68803
  async function runHolder({
68549
68804
  launch,
@@ -68557,7 +68812,7 @@ async function runHolder({
68557
68812
  try {
68558
68813
  const identity = await readProcessIdentity(process.pid);
68559
68814
  if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
68560
- const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path64.dirname)(launch.statusPath)), clock, log));
68815
+ const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path65.dirname)(launch.statusPath)), clock, log));
68561
68816
  const holder = {
68562
68817
  state: "idle",
68563
68818
  runId: null,
@@ -68753,17 +69008,17 @@ async function runHolder({
68753
69008
  client.on("error", () => holder.clients.delete(client));
68754
69009
  });
68755
69010
  removeStaleEndpoint(launch.endpoint);
68756
- await new Promise((resolve12, reject) => {
69011
+ await new Promise((resolve13, reject) => {
68757
69012
  server.once("error", reject);
68758
- server.listen(launch.endpoint, () => resolve12());
69013
+ server.listen(launch.endpoint, () => resolve13());
68759
69014
  });
68760
69015
  await writeStatus();
68761
69016
  log.info("holder.ready", { conversationId: launch.conversationId, pid: identity.pid });
68762
- await new Promise((resolve12) => exit.signal.addEventListener("abort", () => resolve12()));
69017
+ await new Promise((resolve13) => exit.signal.addEventListener("abort", () => resolve13()));
68763
69018
  await driver.suspend?.().catch((error61) => log.warn("holder.driver_suspend_failed", { error: error61 }));
68764
69019
  for (const client of holder.clients) client.end();
68765
- await new Promise((resolve12) => server.close(() => resolve12()));
68766
- (0, import_node_fs21.rmSync)(launch.statusPath, { force: true });
69020
+ await new Promise((resolve13) => server.close(() => resolve13()));
69021
+ (0, import_node_fs22.rmSync)(launch.statusPath, { force: true });
68767
69022
  log.info("holder.suspended", { conversationId: launch.conversationId });
68768
69023
  } catch (_) {
68769
69024
  var _error = _, _hasError = true;
@@ -68851,7 +69106,7 @@ var DEFAULT_MAX_ACTIVE_RUNS = 32;
68851
69106
  var HOLDER_BUSY = "busy";
68852
69107
  async function listIds(dir, schema) {
68853
69108
  const ids = [];
68854
- for (const name of await (0, import_promises65.readdir)(dir).catch(() => [])) {
69109
+ for (const name of await (0, import_promises66.readdir)(dir).catch(() => [])) {
68855
69110
  const parsed = schema.safeParse(name);
68856
69111
  if (parsed.success) ids.push(parsed.data);
68857
69112
  }
@@ -68865,14 +69120,14 @@ function holderIdentity(status) {
68865
69120
  return command === void 0 ? { pid, startedAt } : { pid, startedAt, command };
68866
69121
  }
68867
69122
  function sessionFiles(paths, conversationId) {
68868
- const dir = (0, import_node_path65.join)(paths.sessions, conversationId);
68869
- return { dir, launch: (0, import_node_path65.join)(dir, "launch.json"), status: (0, import_node_path65.join)(dir, "holder.json") };
69123
+ const dir = (0, import_node_path66.join)(paths.sessions, conversationId);
69124
+ return { dir, launch: (0, import_node_path66.join)(dir, "launch.json"), status: (0, import_node_path66.join)(dir, "holder.json") };
68870
69125
  }
68871
69126
  async function removeHolderFiles(files) {
68872
69127
  for (const path4 of [files.launch, files.status, engineRecordsPath(files.dir)]) {
68873
- await (0, import_promises65.rm)(path4, { force: true });
69128
+ await (0, import_promises66.rm)(path4, { force: true });
68874
69129
  }
68875
- await (0, import_promises65.rmdir)(files.dir).catch((error61) => {
69130
+ await (0, import_promises66.rmdir)(files.dir).catch((error61) => {
68876
69131
  if (!["ENOENT", "ENOTEMPTY", "EEXIST"].includes(errnoCode(error61) ?? "")) throw error61;
68877
69132
  });
68878
69133
  }
@@ -69035,8 +69290,8 @@ async function openSessions(deps) {
69035
69290
  protocol: HOLDER_PROTOCOL,
69036
69291
  conversationId,
69037
69292
  machineId: deps.machineId,
69038
- endpoint: ipcEndpoint(paths.sockets, (0, import_node_crypto30.randomUUID)().slice(0, 8)),
69039
- token: (0, import_node_crypto30.randomBytes)(32).toString("hex"),
69293
+ endpoint: ipcEndpoint(paths.sockets, (0, import_node_crypto31.randomUUID)().slice(0, 8)),
69294
+ token: (0, import_node_crypto31.randomBytes)(32).toString("hex"),
69040
69295
  runsDir: paths.runs,
69041
69296
  statusPath: files.status
69042
69297
  };
@@ -69062,7 +69317,7 @@ async function openSessions(deps) {
69062
69317
  const meta3 = await readRunMeta(dir.meta);
69063
69318
  const last = await readLastRecord(dir.log);
69064
69319
  if (meta3 === null || last === null) return null;
69065
- const logged = await (0, import_promises65.stat)(dir.log).catch((error61) => {
69320
+ const logged = await (0, import_promises66.stat)(dir.log).catch((error61) => {
69066
69321
  if (errnoCode(error61) === "ENOENT") return null;
69067
69322
  throw error61;
69068
69323
  });
@@ -69287,7 +69542,8 @@ var envSchema = external_exports.object({
69287
69542
  ALAN_RUNTIME_GIT_GATEWAY_URL: external_exports.url().optional(),
69288
69543
  ALAN_RUNTIME_WORKSPACE_ROOT: external_exports.string().min(1).optional(),
69289
69544
  XDG_CONFIG_HOME: external_exports.string().min(1).optional(),
69290
- GH_CONFIG_DIR: external_exports.string().min(1).optional()
69545
+ GH_CONFIG_DIR: external_exports.string().min(1).optional(),
69546
+ CODEX_HOME: external_exports.string().trim().min(1).optional()
69291
69547
  });
69292
69548
  var DEFAULT_API_URLS = {
69293
69549
  production: "https://api.tryalan.ai",
@@ -69340,7 +69596,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
69340
69596
  ALAN_RUNTIME_GIT_GATEWAY_URL,
69341
69597
  ALAN_RUNTIME_WORKSPACE_ROOT,
69342
69598
  XDG_CONFIG_HOME,
69343
- GH_CONFIG_DIR
69599
+ GH_CONFIG_DIR,
69600
+ CODEX_HOME
69344
69601
  } = parsed.data;
69345
69602
  const home = (0, import_node_os11.homedir)();
69346
69603
  const suspendDefaults = defaultSuspendPolicy(totalMemoryBytes);
@@ -69372,7 +69629,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
69372
69629
  providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
69373
69630
  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,
69374
69631
  home,
69375
- configHome: XDG_CONFIG_HOME ?? (0, import_node_path66.join)(home, ".config"),
69632
+ configHome: XDG_CONFIG_HOME ?? (0, import_node_path67.join)(home, ".config"),
69633
+ codexHome: resolveCodexHome(CODEX_HOME, home),
69376
69634
  ...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
69377
69635
  gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
69378
69636
  workspaceRoot: ALAN_RUNTIME_WORKSPACE_ROOT ?? null,
@@ -69380,11 +69638,14 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
69380
69638
  adoptsLegacyInstall: ALAN_RUNTIME_STATE_DIR === void 0
69381
69639
  };
69382
69640
  }
69641
+ function resolveCodexHome(configuredHome, home) {
69642
+ return configuredHome ?? (0, import_node_path67.join)(home, ".codex");
69643
+ }
69383
69644
  function githubProxyConfig(env, home) {
69384
- const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path66.join)(home, ".config");
69645
+ const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path67.join)(home, ".config");
69385
69646
  return {
69386
69647
  githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
69387
- ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path66.join)(configHome, "gh")
69648
+ ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path67.join)(configHome, "gh")
69388
69649
  };
69389
69650
  }
69390
69651
  function serviceEnvironment2(env, profile) {
@@ -69442,9 +69703,9 @@ function takeEnrollmentCodeFromEnv(env = process.env) {
69442
69703
  }
69443
69704
 
69444
69705
  // src/cli/context.ts
69445
- var import_promises66 = require("fs/promises");
69706
+ var import_promises67 = require("fs/promises");
69446
69707
  var import_node_os12 = require("os");
69447
- var import_node_path67 = require("path");
69708
+ var import_node_path68 = require("path");
69448
69709
  var DESKTOP_BUNDLE_IDS = {
69449
69710
  production: ["com.alan-ai.desktop"],
69450
69711
  staging: ["com.alan-ai.desktop.staging"],
@@ -69484,7 +69745,7 @@ function serviceSpec({ config: config2, paths, self }) {
69484
69745
  profile: config2.profile,
69485
69746
  program: serviceCommand(config2.host, self, launcher),
69486
69747
  environment: config2.serviceEnvironment,
69487
- logPath: (0, import_node_path67.join)(paths.logs, "service.log"),
69748
+ logPath: (0, import_node_path68.join)(paths.logs, "service.log"),
69488
69749
  associatedBundleIds: DESKTOP_BUNDLE_IDS[config2.profile]
69489
69750
  };
69490
69751
  }
@@ -69492,7 +69753,7 @@ async function installedServiceSpec(ctx) {
69492
69753
  const spec = serviceSpec(ctx);
69493
69754
  if (ctx.config.host === "app") return spec;
69494
69755
  const layout = installLayout(ctx.config.installDir, ctx.config.profile);
69495
- const installed = await (0, import_promises66.access)(layout.launcher).then(
69756
+ const installed = await (0, import_promises67.access)(layout.launcher).then(
69496
69757
  () => true,
69497
69758
  () => false
69498
69759
  );
@@ -69620,7 +69881,7 @@ var manifestRevisionSchema = external_exports.object({ revision: external_export
69620
69881
  async function manifestRevision(path4) {
69621
69882
  let raw;
69622
69883
  try {
69623
- raw = JSON.parse(await (0, import_promises67.readFile)(path4, "utf8"));
69884
+ raw = JSON.parse(await (0, import_promises68.readFile)(path4, "utf8"));
69624
69885
  } catch (error61) {
69625
69886
  throw new RuntimeFault("invalid_file", `Cannot read the skill manifest at ${path4}`, {
69626
69887
  cause: error61
@@ -69638,7 +69899,7 @@ async function runSkills(argv) {
69638
69899
  case "scan":
69639
69900
  writeJson({
69640
69901
  status: "failed",
69641
- attemptId: (0, import_node_crypto31.randomUUID)(),
69902
+ attemptId: (0, import_node_crypto32.randomUUID)(),
69642
69903
  retainedInventoryRevision: null,
69643
69904
  diagnostics: [
69644
69905
  { code: "RUNTIME_SKILL_SCAN_UNSUPPORTED", message: SKILLS_SYNCED_BY_RUNTIME }
@@ -69654,7 +69915,7 @@ async function runSkills(argv) {
69654
69915
  );
69655
69916
  }
69656
69917
  writeJson({
69657
- attemptId: (0, import_node_crypto31.randomUUID)(),
69918
+ attemptId: (0, import_node_crypto32.randomUUID)(),
69658
69919
  desiredRevision: await manifestRevision(manifest),
69659
69920
  skills: []
69660
69921
  });
@@ -69674,8 +69935,8 @@ async function runSkills(argv) {
69674
69935
  }
69675
69936
 
69676
69937
  // src/cli/commands/doctor.ts
69677
- var import_promises70 = require("fs/promises");
69678
- var import_node_path71 = require("path");
69938
+ var import_promises71 = require("fs/promises");
69939
+ var import_node_path72 = require("path");
69679
69940
  init_runtime_v2();
69680
69941
 
69681
69942
  // src/identity/credential.ts
@@ -69852,24 +70113,24 @@ async function authorizeDevice(input2) {
69852
70113
  }
69853
70114
 
69854
70115
  // src/identity/enroll.ts
69855
- var import_promises68 = require("fs/promises");
70116
+ var import_promises69 = require("fs/promises");
69856
70117
  init_runtime_v2();
69857
70118
 
69858
70119
  // src/identity/installation.ts
69859
- var import_node_crypto32 = require("crypto");
69860
- var import_node_path68 = require("path");
70120
+ var import_node_crypto33 = require("crypto");
70121
+ var import_node_path69 = require("path");
69861
70122
  init_zod();
69862
70123
  var installationFileSchema = external_exports.object({
69863
70124
  installationId: external_exports.uuid()
69864
70125
  });
69865
70126
  function installationPath(paths) {
69866
- return (0, import_node_path68.join)(paths.stateDir, "installation.json");
70127
+ return (0, import_node_path69.join)(paths.stateDir, "installation.json");
69867
70128
  }
69868
70129
  async function ensureInstallationId(paths) {
69869
70130
  const path4 = installationPath(paths);
69870
70131
  const existing = await readJsonFile(path4, installationFileSchema);
69871
70132
  if (existing.kind === "ok") return existing.value.installationId;
69872
- const created = { installationId: (0, import_node_crypto32.randomUUID)() };
70133
+ const created = { installationId: (0, import_node_crypto33.randomUUID)() };
69873
70134
  await writeJsonFileAtomic(path4, created);
69874
70135
  return created.installationId;
69875
70136
  }
@@ -69956,13 +70217,13 @@ async function enrollFromGrantFile(input2) {
69956
70217
  clock: input2.clock,
69957
70218
  access: input2.access
69958
70219
  });
69959
- await (0, import_promises68.rm)(input2.grantPath, { force: true });
70220
+ await (0, import_promises69.rm)(input2.grantPath, { force: true });
69960
70221
  return machine;
69961
70222
  }
69962
70223
 
69963
70224
  // src/identity/migrate-v1.ts
69964
- var import_promises69 = require("fs/promises");
69965
- var import_node_path69 = require("path");
70225
+ var import_promises70 = require("fs/promises");
70226
+ var import_node_path70 = require("path");
69966
70227
  init_runtime_v2();
69967
70228
  init_zod();
69968
70229
  var EXIT_POLL_MS = 200;
@@ -69983,11 +70244,11 @@ var ownerLeaseSchema = external_exports.looseObject({ pid: external_exports.numb
69983
70244
  function legacyConfigPath(home, profile) {
69984
70245
  switch (profile) {
69985
70246
  case "production":
69986
- return (0, import_node_path69.join)(home, ".alan", "agent", "config.json");
70247
+ return (0, import_node_path70.join)(home, ".alan", "agent", "config.json");
69987
70248
  case "staging":
69988
- return (0, import_node_path69.join)(home, ".alan-staging", "agent", "config.json");
70249
+ return (0, import_node_path70.join)(home, ".alan-staging", "agent", "config.json");
69989
70250
  default:
69990
- return (0, import_node_path69.join)(home, ".alan-dev", "agent", "config.json");
70251
+ return (0, import_node_path70.join)(home, ".alan-dev", "agent", "config.json");
69991
70252
  }
69992
70253
  }
69993
70254
  async function findLegacyInstall(home, profile) {
@@ -70012,8 +70273,8 @@ async function scrubLegacyInstall(install2) {
70012
70273
  const scrubbed = { ...install2.config, migratedToRuntimeV2: true };
70013
70274
  for (const key of SCRUBBED_KEYS) delete scrubbed[key];
70014
70275
  await writeJsonFileAtomic(`${install2.configPath}.migrated-v1`, scrubbed);
70015
- await (0, import_promises69.rm)(install2.configPath, { force: true });
70016
- await (0, import_promises69.rm)(install2.ownerLeasePath, { force: true });
70276
+ await (0, import_promises70.rm)(install2.configPath, { force: true });
70277
+ await (0, import_promises70.rm)(install2.ownerLeasePath, { force: true });
70017
70278
  }
70018
70279
  async function exchangeCredential(deps) {
70019
70280
  const { config: config2 } = deps.install;
@@ -70122,7 +70383,7 @@ async function loadIdentity(paths, options = {}) {
70122
70383
  }
70123
70384
 
70124
70385
  // src/cli/commands/status.ts
70125
- var import_node_path70 = require("path");
70386
+ var import_node_path71 = require("path");
70126
70387
  async function serviceStatus(ctx) {
70127
70388
  try {
70128
70389
  return await createServiceManager(ctx.host, ctx.config.profile).status();
@@ -70149,7 +70410,7 @@ async function runtimeState(ctx) {
70149
70410
  const running = await readRunningRuntime(ctx.paths.lock);
70150
70411
  if (running === null) return { state: "offline", pid: null, localApi: null };
70151
70412
  const discovery = await readJsonFile(
70152
- (0, import_node_path70.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE),
70413
+ (0, import_node_path71.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE),
70153
70414
  localApiDiscoverySchema
70154
70415
  );
70155
70416
  const localApi = discovery.kind === "ok" && discovery.value.pid === running.pid ? {
@@ -70370,7 +70631,7 @@ async function runtimeCheck(ctx, status) {
70370
70631
  return check2("runtime", "warn", "No runtime is running for this profile");
70371
70632
  }
70372
70633
  const client = createRuntimeClient({
70373
- discoveryPath: (0, import_node_path71.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE)
70634
+ discoveryPath: (0, import_node_path72.join)(ctx.paths.stateDir, LOCAL_API_DISCOVERY_FILE)
70374
70635
  });
70375
70636
  try {
70376
70637
  const live = await client.status(AbortSignal.timeout(LOCAL_TIMEOUT_MS));
@@ -70397,7 +70658,7 @@ async function runtimeCheck(ctx, status) {
70397
70658
  }
70398
70659
  }
70399
70660
  async function probeHolder(dir, conversationId) {
70400
- const launch = await readJsonFile((0, import_node_path71.join)(dir, "launch.json"), holderLaunchSchema);
70661
+ const launch = await readJsonFile((0, import_node_path72.join)(dir, "launch.json"), holderLaunchSchema);
70401
70662
  if (launch.kind !== "ok") return null;
70402
70663
  try {
70403
70664
  const reply2 = await withTimeout(
@@ -70422,8 +70683,8 @@ async function probeHolder(dir, conversationId) {
70422
70683
  }
70423
70684
  }
70424
70685
  async function holdersCheck(ctx) {
70425
- const names = await (0, import_promises70.readdir)(ctx.paths.sessions).catch(() => []);
70426
- const holders = (await Promise.all(names.map((name) => probeHolder((0, import_node_path71.join)(ctx.paths.sessions, name), name)))).filter((facts) => facts !== null);
70686
+ const names = await (0, import_promises71.readdir)(ctx.paths.sessions).catch(() => []);
70687
+ const holders = (await Promise.all(names.map((name) => probeHolder((0, import_node_path72.join)(ctx.paths.sessions, name), name)))).filter((facts) => facts !== null);
70427
70688
  const dead = holders.filter((holder) => !holder.alive).length;
70428
70689
  return check2(
70429
70690
  "holders",
@@ -70434,10 +70695,10 @@ async function holdersCheck(ctx) {
70434
70695
  }
70435
70696
  async function freeBytesAt(path4) {
70436
70697
  try {
70437
- const stats = await (0, import_promises70.statfs)(path4);
70698
+ const stats = await (0, import_promises71.statfs)(path4);
70438
70699
  return { path: path4, freeBytes: stats.bavail * stats.bsize };
70439
70700
  } catch (error61) {
70440
- const parent = (0, import_node_path71.dirname)(path4);
70701
+ const parent = (0, import_node_path72.dirname)(path4);
70441
70702
  if (parent === path4) throw error61;
70442
70703
  return freeBytesAt(parent);
70443
70704
  }
@@ -70455,9 +70716,9 @@ async function diskCheck(ctx) {
70455
70716
  }
70456
70717
  }
70457
70718
  var resolveFromLoginShell = (own2) => resolveCliEnvironment({ env: own2, platform: process.platform });
70458
- async function cliDiscoveryCheck(resolve12) {
70719
+ async function cliDiscoveryCheck(resolve13) {
70459
70720
  const own2 = readCliEnvironment();
70460
- const env = await resolve12(own2);
70721
+ const env = await resolve13(own2);
70461
70722
  const delimiter = process.platform === "win32" ? ";" : ":";
70462
70723
  const ownDirs = new Set((own2.PATH ?? "").split(delimiter));
70463
70724
  const added = (env.PATH ?? "").split(delimiter).filter((dir) => dir.length > 0 && !ownDirs.has(dir));
@@ -70573,7 +70834,7 @@ async function runDoctor(argv, context = cliContext) {
70573
70834
  }
70574
70835
 
70575
70836
  // src/cli/commands/git-credential.ts
70576
- var import_promises71 = require("fs/promises");
70837
+ var import_promises72 = require("fs/promises");
70577
70838
  var import_node_net4 = require("net");
70578
70839
  var MAX_RESPONSE_BYTES = 64 * 1024;
70579
70840
  async function readAll(stream) {
@@ -70591,7 +70852,7 @@ function processIo() {
70591
70852
  };
70592
70853
  }
70593
70854
  function askGitCredentialSocket(endpoint, request2, signal) {
70594
- return new Promise((resolve12, reject) => {
70855
+ return new Promise((resolve13, reject) => {
70595
70856
  const socket = (0, import_node_net4.createConnection)(endpoint);
70596
70857
  let buffered = "";
70597
70858
  const fail = (error61) => {
@@ -70618,7 +70879,7 @@ function askGitCredentialSocket(endpoint, request2, signal) {
70618
70879
  signal.removeEventListener("abort", onAbort);
70619
70880
  try {
70620
70881
  const line = buffered.split("\n", 1)[0] ?? "";
70621
- resolve12(gitCredentialSocketResponseSchema.parse(JSON.parse(line)));
70882
+ resolve13(gitCredentialSocketResponseSchema.parse(JSON.parse(line)));
70622
70883
  } catch (error61) {
70623
70884
  reject(
70624
70885
  new RuntimeFault("io_failed", "the Alan runtime sent an invalid reply", { cause: error61 })
@@ -70683,7 +70944,7 @@ async function configure(argv) {
70683
70944
  }
70684
70945
  async function configureGitGateway(config2, gatewayUrl, signal) {
70685
70946
  const { launcher } = installLayout(config2.installDir, config2.profile);
70686
- const installed = await (0, import_promises71.access)(launcher).then(
70947
+ const installed = await (0, import_promises72.access)(launcher).then(
70687
70948
  () => true,
70688
70949
  () => false
70689
70950
  );
@@ -70710,7 +70971,7 @@ async function runGitCredential(argv) {
70710
70971
  }
70711
70972
 
70712
70973
  // src/cli/commands/hold.ts
70713
- var import_node_path72 = require("path");
70974
+ var import_node_path73 = require("path");
70714
70975
  init_agent2();
70715
70976
  init_runtime_v2();
70716
70977
  async function machineAccess(paths, log, conversationId, transport) {
@@ -70768,7 +71029,7 @@ async function runHold(argv) {
70768
71029
  const config2 = loadRuntimeConfig();
70769
71030
  const paths = runtimePaths(config2.stateDir);
70770
71031
  const log = __using(_stack, openFileLog(
70771
- (0, import_node_path72.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
71032
+ (0, import_node_path73.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
70772
71033
  config2.logLevel,
70773
71034
  systemClock
70774
71035
  ));
@@ -70779,7 +71040,7 @@ async function runHold(argv) {
70779
71040
  );
70780
71041
  const transport = __using(_stack, createHttpTransport());
70781
71042
  const access7 = await machineAccess(paths, log, launch.value.conversationId, transport);
70782
- const credentialPath = (0, import_node_path72.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
71043
+ const credentialPath = (0, import_node_path73.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
70783
71044
  const managedMcp = __using(_stack, access7.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
70784
71045
  managedMcp: access7.managedMcp,
70785
71046
  conversationId: launch.value.conversationId,
@@ -70798,7 +71059,8 @@ async function runHold(argv) {
70798
71059
  timings: config2.sessionTimings,
70799
71060
  log,
70800
71061
  ...managedMcp === void 0 ? {} : { managedMcp },
70801
- codexCredentials: access7.codexCredentials
71062
+ codexCredentials: access7.codexCredentials,
71063
+ installedSkills: () => installedSkillFolders(skillsLayout(paths.stateDir))
70802
71064
  }),
70803
71065
  clock: systemClock,
70804
71066
  log,
@@ -70819,7 +71081,7 @@ async function runHold(argv) {
70819
71081
  }
70820
71082
 
70821
71083
  // src/cli/commands/hook.ts
70822
- var import_node_path73 = require("path");
71084
+ var import_node_path74 = require("path");
70823
71085
  var RUNTIME_ANSWER_MS = 2e3;
70824
71086
  var DEBUG_VARIABLE = "ALAN_HOOK_DEBUG";
70825
71087
  function flag(argv, name) {
@@ -70851,7 +71113,7 @@ async function forwardHook(argv, io) {
70851
71113
  return "transcript outside provider root";
70852
71114
  }
70853
71115
  const verdict = await io.send(
70854
- (0, import_node_path73.join)(io.stateDir, LOCAL_API_DISCOVERY_FILE),
71116
+ (0, import_node_path74.join)(io.stateDir, LOCAL_API_DISCOVERY_FILE),
70855
71117
  hookSignal,
70856
71118
  AbortSignal.timeout(RUNTIME_ANSWER_MS)
70857
71119
  );
@@ -70887,7 +71149,7 @@ async function runHook(argv, overrides = {}) {
70887
71149
  }
70888
71150
 
70889
71151
  // src/cli/commands/ingestion-hooks.ts
70890
- var import_promises72 = require("fs/promises");
71152
+ var import_promises73 = require("fs/promises");
70891
71153
  var CODEX_TRUST_NOTE = "Codex runs new hooks only after you review them: open /hooks in Codex.";
70892
71154
  function isAction(value2) {
70893
71155
  return value2 === "enable" || value2 === "disable" || value2 === "status";
@@ -70910,7 +71172,7 @@ function errorMessage2(error61) {
70910
71172
  return error61 instanceof Error ? error61.message : String(error61);
70911
71173
  }
70912
71174
  async function exists5(path4) {
70913
- return (0, import_promises72.access)(path4).then(
71175
+ return (0, import_promises73.access)(path4).then(
70914
71176
  () => true,
70915
71177
  () => false
70916
71178
  );
@@ -71013,10 +71275,10 @@ async function runIntegrationsCommand(argv) {
71013
71275
  }
71014
71276
 
71015
71277
  // src/cli/commands/legacy.ts
71016
- var import_node_path75 = require("path");
71278
+ var import_node_path76 = require("path");
71017
71279
 
71018
71280
  // src/cli/commands/setup.ts
71019
- var import_node_path74 = require("path");
71281
+ var import_node_path75 = require("path");
71020
71282
  init_zod();
71021
71283
 
71022
71284
  // src/cli/legacy.ts
@@ -71098,7 +71360,7 @@ async function grantFileCredential(argv, grantPath, ctx, deps) {
71098
71360
  return enrollFromGrantFile({
71099
71361
  paths: ctx.paths,
71100
71362
  storeKind: credentialStoreFlag(argv) ?? ctx.config.credentialStore,
71101
- grantPath: (0, import_node_path74.resolve)(grantPath),
71363
+ grantPath: (0, import_node_path75.resolve)(grantPath),
71102
71364
  clock: deps.clock,
71103
71365
  access: ctx.access
71104
71366
  });
@@ -71174,7 +71436,7 @@ async function runSetup(argv, signal) {
71174
71436
  var _stack = [];
71175
71437
  try {
71176
71438
  const ctx = cliContext();
71177
- const log = __using(_stack, openFileLog((0, import_node_path74.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71439
+ const log = __using(_stack, openFileLog((0, import_node_path75.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71178
71440
  const result = await setupMachine(argv, ctx, {
71179
71441
  enrollment: (apiUrl) => createEnrollmentClient({ apiUrl }),
71180
71442
  isProcessAlive,
@@ -71257,7 +71519,7 @@ async function runToken(argv, signal) {
71257
71519
  );
71258
71520
  }
71259
71521
  const ctx = cliContext();
71260
- const log = __using(_stack, openFileLog((0, import_node_path75.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71522
+ const log = __using(_stack, openFileLog((0, import_node_path76.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71261
71523
  const result = await rotateMachineCredential(ctx, { clock: systemClock, log, signal });
71262
71524
  process.stdout.write(`${rotationMessage(result)}
71263
71525
  `);
@@ -71269,8 +71531,8 @@ async function runToken(argv, signal) {
71269
71531
  }
71270
71532
 
71271
71533
  // src/cli/commands/logout.ts
71272
- var import_promises73 = require("fs/promises");
71273
- var import_node_path76 = require("path");
71534
+ var import_promises74 = require("fs/promises");
71535
+ var import_node_path77 = require("path");
71274
71536
  init_runtime_v2();
71275
71537
  var RUNTIME_EXIT_WAIT_MS = 35e3;
71276
71538
  var TURN_END_WAIT_MS = 3e4;
@@ -71329,9 +71591,9 @@ async function stopHolder(launch, deps, outcome2) {
71329
71591
  }
71330
71592
  async function stopHeldRuns(ctx, deps, outcome2 = "aborted") {
71331
71593
  const stopped = [];
71332
- for (const name of await (0, import_promises73.readdir)(ctx.paths.sessions).catch(() => [])) {
71594
+ for (const name of await (0, import_promises74.readdir)(ctx.paths.sessions).catch(() => [])) {
71333
71595
  const launch = await readJsonFile(
71334
- (0, import_node_path76.join)(ctx.paths.sessions, name, "launch.json"),
71596
+ (0, import_node_path77.join)(ctx.paths.sessions, name, "launch.json"),
71335
71597
  holderLaunchSchema
71336
71598
  );
71337
71599
  if (launch.kind !== "ok") continue;
@@ -71368,13 +71630,13 @@ async function forgetMachineLocally(ctx) {
71368
71630
  const machine = await readMachineFile(ctx.paths);
71369
71631
  if (machine === null) return;
71370
71632
  await credentialStoreFor(ctx.paths, machine.credentialStore, ctx.access).clear();
71371
- await (0, import_promises73.rm)(ctx.paths.machine, { force: true });
71633
+ await (0, import_promises74.rm)(ctx.paths.machine, { force: true });
71372
71634
  }
71373
71635
  async function runLogout(argv, signal) {
71374
71636
  var _stack = [];
71375
71637
  try {
71376
71638
  const ctx = cliContext();
71377
- const log = __using(_stack, openFileLog((0, import_node_path76.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71639
+ const log = __using(_stack, openFileLog((0, import_node_path77.join)(ctx.paths.logs, "cli.jsonl"), ctx.config.logLevel, systemClock));
71378
71640
  const result = await logoutMachine(argv, ctx, {
71379
71641
  api: (apiUrl, accessToken) => createApiClient({ apiUrl, accessToken }),
71380
71642
  stopHeldRuns,
@@ -71391,8 +71653,8 @@ async function runLogout(argv, signal) {
71391
71653
  }
71392
71654
 
71393
71655
  // src/cli/commands/run.ts
71394
- var import_node_fs23 = require("fs");
71395
- var import_node_path80 = require("path");
71656
+ var import_node_fs24 = require("fs");
71657
+ var import_node_path81 = require("path");
71396
71658
 
71397
71659
  // src/local-api/app-attachments.ts
71398
71660
  function createAppAttachments(clock) {
@@ -71432,7 +71694,7 @@ function createRunAppends() {
71432
71694
  const pending = waiters.get(runId);
71433
71695
  if (pending === void 0) return;
71434
71696
  waiters.delete(runId);
71435
- for (const resolve12 of pending) resolve12();
71697
+ for (const resolve13 of pending) resolve13();
71436
71698
  };
71437
71699
  return {
71438
71700
  notify: wake,
@@ -71450,13 +71712,13 @@ function createRunAppends() {
71450
71712
  },
71451
71713
  nextAppend: (runId, signal) => {
71452
71714
  if (signal.aborted) return Promise.resolve();
71453
- return new Promise((resolve12) => {
71715
+ return new Promise((resolve13) => {
71454
71716
  const done = () => {
71455
71717
  signal.removeEventListener("abort", done);
71456
71718
  const pending2 = waiters.get(runId);
71457
71719
  pending2?.delete(done);
71458
71720
  if (pending2?.size === 0) waiters.delete(runId);
71459
- resolve12();
71721
+ resolve13();
71460
71722
  };
71461
71723
  const pending = waiters.get(runId) ?? /* @__PURE__ */ new Set();
71462
71724
  pending.add(done);
@@ -71468,18 +71730,18 @@ function createRunAppends() {
71468
71730
  }
71469
71731
 
71470
71732
  // src/local-api/server.ts
71471
- var import_node_crypto34 = require("crypto");
71472
- var import_promises74 = require("fs/promises");
71733
+ var import_node_crypto35 = require("crypto");
71734
+ var import_promises75 = require("fs/promises");
71473
71735
  var import_node_http4 = require("http");
71474
- var import_node_path77 = require("path");
71736
+ var import_node_path78 = require("path");
71475
71737
 
71476
71738
  // src/local-api/guard.ts
71477
- var import_node_crypto33 = require("crypto");
71739
+ var import_node_crypto34 = require("crypto");
71478
71740
  var ALLOWED = { kind: "allowed" };
71479
71741
  function tokenMatches2(expected, header) {
71480
71742
  if (header === void 0 || !header.startsWith("Bearer ")) return false;
71481
71743
  const presented = Buffer.from(header.slice("Bearer ".length));
71482
- return presented.length === expected.length && (0, import_node_crypto33.timingSafeEqual)(presented, expected);
71744
+ return presented.length === expected.length && (0, import_node_crypto34.timingSafeEqual)(presented, expected);
71483
71745
  }
71484
71746
  function isBrowserReachable(req, allowedHosts) {
71485
71747
  if (req.headers.origin !== void 0 || req.headers.referer !== void 0) return true;
@@ -71548,11 +71810,11 @@ id: ${event.id}
71548
71810
  ${data}
71549
71811
  `);
71550
71812
  if (accepted || res.destroyed) return;
71551
- await new Promise((resolve12) => {
71813
+ await new Promise((resolve13) => {
71552
71814
  const done = () => {
71553
71815
  res.off("drain", done);
71554
71816
  res.off("close", done);
71555
- resolve12();
71817
+ resolve13();
71556
71818
  };
71557
71819
  res.once("drain", done);
71558
71820
  res.once("close", done);
@@ -71780,9 +72042,9 @@ async function readChangedTurn(deps, conversationId, runId, slot) {
71780
72042
  }
71781
72043
  async function nextChangedRuns(bell, signal) {
71782
72044
  if (bell.pending.size === 0) {
71783
- await new Promise((resolve12) => {
71784
- bell.wake = resolve12;
71785
- if (signal.aborted || bell.pending.size > 0) resolve12();
72045
+ await new Promise((resolve13) => {
72046
+ bell.wake = resolve13;
72047
+ if (signal.aborted || bell.pending.size > 0) resolve13();
71786
72048
  });
71787
72049
  bell.wake = void 0;
71788
72050
  }
@@ -71946,7 +72208,7 @@ var machineFeatureRoutes = [
71946
72208
  ];
71947
72209
 
71948
72210
  // src/local-api/run-log-routes.ts
71949
- var import_node_fs22 = require("fs");
72211
+ var import_node_fs23 = require("fs");
71950
72212
  init_runtime_v2();
71951
72213
  var RUN_ENDED = "_alan/run.ended";
71952
72214
  var decoder2 = new TextDecoder();
@@ -71963,7 +72225,7 @@ async function openWhenWritten(deps, runId, res, signal) {
71963
72225
  const path4 = runDirectory(deps.runsDir, runId).log;
71964
72226
  while (!signal.aborted) {
71965
72227
  const appended = deps.appends.nextAppend(runId, signal);
71966
- if ((0, import_node_fs22.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
72228
+ if ((0, import_node_fs23.existsSync)(path4) || !await deps.isHeld(runId, signal)) return openReader(res, path4);
71967
72229
  await appended;
71968
72230
  }
71969
72231
  return null;
@@ -72099,9 +72361,9 @@ var streamStatus = async ({ feed, appAttachments }, { res, signal }) => {
72099
72361
  latest = event;
72100
72362
  writing = writing.then(flush);
72101
72363
  }));
72102
- await new Promise((resolve12) => {
72103
- if (signal.aborted) resolve12();
72104
- signal.addEventListener("abort", () => resolve12(), { once: true });
72364
+ await new Promise((resolve13) => {
72365
+ if (signal.aborted) resolve13();
72366
+ signal.addEventListener("abort", () => resolve13(), { once: true });
72105
72367
  });
72106
72368
  await writing;
72107
72369
  } catch (_) {
@@ -72424,11 +72686,11 @@ function localRequestSignal(path4, closed) {
72424
72686
  ]);
72425
72687
  }
72426
72688
  async function listenOnLoopback(server) {
72427
- await new Promise((resolve12, reject) => {
72689
+ await new Promise((resolve13, reject) => {
72428
72690
  server.once("error", reject);
72429
72691
  server.listen(0, "127.0.0.1", () => {
72430
72692
  server.off("error", reject);
72431
- resolve12();
72693
+ resolve13();
72432
72694
  });
72433
72695
  }).catch((error61) => {
72434
72696
  throw new RuntimeFault("io_failed", "The local API could not listen on loopback", {
@@ -72443,7 +72705,7 @@ async function listenOnLoopback(server) {
72443
72705
  }
72444
72706
  async function closeServer(server) {
72445
72707
  server.closeAllConnections();
72446
- await new Promise((resolve12) => server.close(() => resolve12()));
72708
+ await new Promise((resolve13) => server.close(() => resolve13()));
72447
72709
  }
72448
72710
  async function serveLocalApi(deps) {
72449
72711
  const limits = { ...DEFAULT_LIMITS, ...deps.limits };
@@ -72467,7 +72729,7 @@ async function serveLocalApi(deps) {
72467
72729
  server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MS;
72468
72730
  server.maxConnections = HARD_MAX_CONNECTIONS;
72469
72731
  const port = await listenOnLoopback(server);
72470
- const token = (0, import_node_crypto34.randomBytes)(32).toString("base64url");
72732
+ const token = (0, import_node_crypto35.randomBytes)(32).toString("base64url");
72471
72733
  const guard = createRequestGuard({ token, port, rateLimit: limits.rateLimit, clock });
72472
72734
  const appAttachments = createAppAttachments(clock);
72473
72735
  const routeDeps = {
@@ -72514,7 +72776,7 @@ async function serveLocalApi(deps) {
72514
72776
  startedAtMs,
72515
72777
  runtimeVersion: deps.runtimeVersion
72516
72778
  };
72517
- const discoveryPath = (0, import_node_path77.join)(deps.stateDir, LOCAL_API_DISCOVERY_FILE);
72779
+ const discoveryPath = (0, import_node_path78.join)(deps.stateDir, LOCAL_API_DISCOVERY_FILE);
72518
72780
  await writeJsonFileAtomic(discoveryPath, discovery);
72519
72781
  const followers = startMaintenance({
72520
72782
  everyMs: limits.refreshEveryMs,
@@ -72548,7 +72810,7 @@ async function serveLocalApi(deps) {
72548
72810
  await watchedStatus[Symbol.asyncDispose]();
72549
72811
  const current = await readJsonFile(discoveryPath, localApiDiscoverySchema);
72550
72812
  if (current.kind === "ok" && current.value.token === token) {
72551
- await (0, import_promises74.rm)(discoveryPath, { force: true });
72813
+ await (0, import_promises75.rm)(discoveryPath, { force: true });
72552
72814
  }
72553
72815
  await closeServer(server);
72554
72816
  log.info("local_api.closed", {});
@@ -72633,7 +72895,7 @@ function machineFeatureActions(deps) {
72633
72895
  }
72634
72896
 
72635
72897
  // src/cli/commands/machine-plane.ts
72636
- var import_node_path79 = require("path");
72898
+ var import_node_path80 = require("path");
72637
72899
 
72638
72900
  // src/link/index.ts
72639
72901
  init_runtime_v2();
@@ -75200,9 +75462,9 @@ var Socket2 = class extends Emitter {
75200
75462
  * @return a Promise that will be fulfilled when the server acknowledges the event
75201
75463
  */
75202
75464
  emitWithAck(ev, ...args) {
75203
- return new Promise((resolve12, reject) => {
75465
+ return new Promise((resolve13, reject) => {
75204
75466
  const fn = (arg1, arg2) => {
75205
- return arg1 ? reject(arg1) : resolve12(arg2);
75467
+ return arg1 ? reject(arg1) : resolve13(arg2);
75206
75468
  };
75207
75469
  fn.withError = true;
75208
75470
  args.push(fn);
@@ -76301,7 +76563,7 @@ function refusalFailure(refusal2) {
76301
76563
  }
76302
76564
 
76303
76565
  // src/link/probe.ts
76304
- var import_promises75 = require("dns/promises");
76566
+ var import_promises76 = require("dns/promises");
76305
76567
  var import_node_net5 = require("net");
76306
76568
  var import_node_tls2 = require("tls");
76307
76569
  var PROBE_TIMEOUT_MS4 = 5e3;
@@ -76321,9 +76583,9 @@ async function connectOnce(url3, clock) {
76321
76583
  const timer = new AbortController();
76322
76584
  try {
76323
76585
  return await Promise.race([
76324
- new Promise((resolve12) => {
76325
- socket.once(ready, () => resolve12(null));
76326
- socket.once("error", (error61) => resolve12(classifyTransportFailure(error61)));
76586
+ new Promise((resolve13) => {
76587
+ socket.once(ready, () => resolve13(null));
76588
+ socket.once("error", (error61) => resolve13(classifyTransportFailure(error61)));
76327
76589
  }),
76328
76590
  clock.sleep(PROBE_TIMEOUT_MS4, timer.signal).then(
76329
76591
  () => "connection_timeout",
@@ -76337,7 +76599,7 @@ async function connectOnce(url3, clock) {
76337
76599
  }
76338
76600
  async function probeEndpoint(url3, clock) {
76339
76601
  try {
76340
- await (0, import_promises75.lookup)(url3.hostname);
76602
+ await (0, import_promises76.lookup)(url3.hostname);
76341
76603
  } catch (error61) {
76342
76604
  const reason = classifyTransportFailure(error61);
76343
76605
  return reason === "other" ? "dns" : reason;
@@ -76647,9 +76909,9 @@ function planReconcile(desired, held) {
76647
76909
  }
76648
76910
 
76649
76911
  // src/reconciler/desired-sync.ts
76650
- var import_node_crypto35 = require("crypto");
76912
+ var import_node_crypto36 = require("crypto");
76651
76913
  function fingerprintOf(desired) {
76652
- return (0, import_node_crypto35.createHash)("sha256").update(JSON.stringify(desired)).digest("hex");
76914
+ return (0, import_node_crypto36.createHash)("sha256").update(JSON.stringify(desired)).digest("hex");
76653
76915
  }
76654
76916
  var FAILED_READ_RETRY_MS = 3e4;
76655
76917
  function createDesiredSync(deps) {
@@ -76786,7 +77048,7 @@ function createReconciler(host, lifecycle, log, signal) {
76786
77048
  }
76787
77049
 
76788
77050
  // src/uploader/index.ts
76789
- var import_promises76 = require("fs/promises");
77051
+ var import_promises77 = require("fs/promises");
76790
77052
  init_runtime_v2();
76791
77053
  init_zod();
76792
77054
  var RETRY_DELAYS_MS = [250, 500, 1e3, 2e3, 5e3, 1e4, 3e4];
@@ -76934,7 +77196,7 @@ function startUploader({ api, runsDir, clock, log, archive }) {
76934
77196
  };
76935
77197
  const unsealedRunIds = async () => {
76936
77198
  const runIds = [];
76937
- for (const name of await (0, import_promises76.readdir)(runsDir).catch(() => [])) {
77199
+ for (const name of await (0, import_promises77.readdir)(runsDir).catch(() => [])) {
76938
77200
  const runId = runIdSchema.safeParse(name);
76939
77201
  if (runId.success && !sealed.has(runId.data) && !archive?.has(runId.data))
76940
77202
  runIds.push(runId.data);
@@ -76949,13 +77211,13 @@ function startUploader({ api, runsDir, clock, log, archive }) {
76949
77211
  const dir = runDirectory(runsDir, runId);
76950
77212
  const progress = await readJsonFile(dir.upload, uploadProgressSchema);
76951
77213
  if (progress.kind !== "ok" || !progress.value.sealed) return false;
76952
- const sealedAt = (await (0, import_promises76.stat)(dir.upload)).mtimeMs;
77214
+ const sealedAt = (await (0, import_promises77.stat)(dir.upload)).mtimeMs;
76953
77215
  if (clock.now() - sealedAt < options.sealedForMs) return false;
76954
77216
  return (await readLastRecord(dir.log))?.update.sessionUpdate === "_alan/run.ended";
76955
77217
  };
76956
77218
  const archivable = async (options) => {
76957
77219
  const found = [];
76958
- for (const name of await (0, import_promises76.readdir)(runsDir).catch(() => [])) {
77220
+ for (const name of await (0, import_promises77.readdir)(runsDir).catch(() => [])) {
76959
77221
  const runId = runIdSchema.safeParse(name);
76960
77222
  if (!runId.success || archive?.has(runId.data)) continue;
76961
77223
  try {
@@ -77156,12 +77418,12 @@ async function startMachineNativeIngest(deps) {
77156
77418
  }
77157
77419
 
77158
77420
  // src/cli/commands/run-updates.ts
77159
- var import_node_path78 = require("path");
77421
+ var import_node_path79 = require("path");
77160
77422
  init_runtime_v2();
77161
77423
  var UPDATE_CHECK_EVERY_MS = 6 * 60 * 60 * 1e3;
77162
77424
  var DEFERRED_RETRY_MS = 5 * 60 * 1e3;
77163
77425
  function isInstalledBundle(layout, bundlePath) {
77164
- return (0, import_node_path78.resolve)((0, import_node_path78.dirname)((0, import_node_path78.dirname)(bundlePath))) === (0, import_node_path78.resolve)(layout.versions);
77426
+ return (0, import_node_path79.resolve)((0, import_node_path79.dirname)((0, import_node_path79.dirname)(bundlePath))) === (0, import_node_path79.resolve)(layout.versions);
77165
77427
  }
77166
77428
  async function settleUpgradeOnStart({
77167
77429
  layout,
@@ -77268,7 +77530,7 @@ function startRuntimeUpdates(options) {
77268
77530
  layout,
77269
77531
  release: npmRelease,
77270
77532
  tarball: await options.downloader.download(npmRelease.dist.tarball, signal),
77271
- tmpDir: (0, import_node_path78.join)(layout.root, ".downloads")
77533
+ tmpDir: (0, import_node_path79.join)(layout.root, ".downloads")
77272
77534
  });
77273
77535
  await lifecycle.exclusive("upgrade", async () => {
77274
77536
  await recordPendingUpgrade(layout, currentVersion2, version2, clock.now());
@@ -77499,7 +77761,7 @@ async function startMachinePlane(deps) {
77499
77761
  [ALAN_MANAGED_SESSION_ENV]: "1"
77500
77762
  },
77501
77763
  cwd: paths.stateDir,
77502
- outputPath: (0, import_node_path79.join)(paths.logs, "holders.log")
77764
+ outputPath: (0, import_node_path80.join)(paths.logs, "holders.log")
77503
77765
  },
77504
77766
  deps.holderIsolation
77505
77767
  );
@@ -77535,6 +77797,8 @@ async function startMachinePlane(deps) {
77535
77797
  transport
77536
77798
  }),
77537
77799
  local: { home: config2.home, machineId: identity.machineId },
77800
+ // Only a cloud sandbox's runtime has a git gateway; a person's own ~/.codex is theirs.
77801
+ ...config2.gitGatewayUrl === null ? {} : { codexSkillsDir: (0, import_node_path80.join)(config2.codexHome, "skills") },
77538
77802
  log
77539
77803
  })
77540
77804
  );
@@ -77732,7 +77996,7 @@ async function startMachinePlane(deps) {
77732
77996
  git: createGitRunner({ env: cliEnvironment }),
77733
77997
  clock,
77734
77998
  log,
77735
- dir: (0, import_node_path79.join)(paths.stateDir, "checkout-freshness")
77999
+ dir: (0, import_node_path80.join)(paths.stateDir, "checkout-freshness")
77736
78000
  },
77737
78001
  stopped.signal
77738
78002
  );
@@ -77994,11 +78258,11 @@ function createMachineSlot(deps) {
77994
78258
 
77995
78259
  // src/cli/commands/run-exit.ts
77996
78260
  function firstAborted(signals) {
77997
- return new Promise((resolve12) => {
78261
+ return new Promise((resolve13) => {
77998
78262
  for (const reason of ["stop", "restart"]) {
77999
78263
  const signal = signals[reason];
78000
- if (signal.aborted) resolve12(reason);
78001
- signal.addEventListener("abort", () => resolve12(reason), { once: true });
78264
+ if (signal.aborted) resolve13(reason);
78265
+ signal.addEventListener("abort", () => resolve13(reason), { once: true });
78002
78266
  }
78003
78267
  });
78004
78268
  }
@@ -78026,15 +78290,15 @@ function lockWaitMs(argv) {
78026
78290
  }
78027
78291
  async function openManagedProviders(config2, paths) {
78028
78292
  const providerEnv = readCliEnvironment();
78029
- const bundledNpm = (0, import_node_path80.join)((0, import_node_path80.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
78030
- const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs23.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
78293
+ const bundledNpm = (0, import_node_path81.join)((0, import_node_path81.dirname)(process.execPath), "npm", "bin", "npm-cli.js");
78294
+ const providerToolchain = config2.providerToolchain ?? (process.platform === "win32" && (0, import_node_fs24.existsSync)(bundledNpm) ? { node: process.execPath, npmCli: bundledNpm } : null);
78031
78295
  const npmPath = providerToolchain?.node ?? await resolveCommandOnPath("npm", providerEnv, process.platform);
78032
78296
  const npmOptions = npmPath === null || process.platform === "win32" && providerToolchain === null ? null : {
78033
78297
  command: npmPath,
78034
78298
  ...providerToolchain === null ? {} : { argsBeforeNpm: [providerToolchain.npmCli] },
78035
78299
  env: providerEnv
78036
78300
  };
78037
- const providerNodeDir = providerToolchain?.node === void 0 ? void 0 : (0, import_node_path80.dirname)(providerToolchain.node);
78301
+ const providerNodeDir = providerToolchain?.node === void 0 ? void 0 : (0, import_node_path81.dirname)(providerToolchain.node);
78038
78302
  const probeEnv = providerNodeDir === void 0 ? providerEnv : {
78039
78303
  ...providerEnv,
78040
78304
  PATH: `${providerNodeDir}${pathDelimiter(process.platform)}${envValue(providerEnv, "PATH")}`
@@ -78044,7 +78308,7 @@ async function openManagedProviders(config2, paths) {
78044
78308
  throw new Error("Provider installer is unavailable on this computer");
78045
78309
  };
78046
78310
  const managed = createManagedProviderClis({
78047
- root: (0, import_node_path80.join)(paths.stateDir, "provider-clis"),
78311
+ root: (0, import_node_path81.join)(paths.stateDir, "provider-clis"),
78048
78312
  resolveVersion: npmOptions === null ? unavailable : createNpmVersionResolver(npmOptions),
78049
78313
  installPackage: npmOptions === null ? unavailable : createNpmPackageInstaller(npmOptions),
78050
78314
  probe: (executable, backendKind) => probeManagedProvider(executable, backendKind, canonicalProbeEnv)
@@ -78076,7 +78340,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
78076
78340
  waitMs: lockWaitMs(argv),
78077
78341
  signal: stop
78078
78342
  }));
78079
- const log = __using(_stack, openFileLog((0, import_node_path80.join)(paths.logs, "runtime.jsonl"), config2.logLevel, clock));
78343
+ const log = __using(_stack, openFileLog((0, import_node_path81.join)(paths.logs, "runtime.jsonl"), config2.logLevel, clock));
78080
78344
  const lifecycle = createLifecycleQueue({ clock, log });
78081
78345
  const install2 = installLayout(config2.installDir, config2.profile);
78082
78346
  const bundlePath = process.argv[1] ?? "";
@@ -78110,7 +78374,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
78110
78374
  openCliEnvironment({
78111
78375
  env: readCliEnvironment(),
78112
78376
  platform: process.platform,
78113
- lastKnownGoodFile: (0, import_node_path80.join)(paths.stateDir, "login-path.json"),
78377
+ lastKnownGoodFile: (0, import_node_path81.join)(paths.stateDir, "login-path.json"),
78114
78378
  clock,
78115
78379
  decorate: (env) => withPackagedAlanCodeEngine(env, bundlePath, process.platform)
78116
78380
  })
@@ -78287,17 +78551,17 @@ async function runServiceCommand(argv, ctx = cliContext()) {
78287
78551
  }
78288
78552
 
78289
78553
  // src/cli/commands/upgrade.ts
78290
- var import_promises77 = require("fs/promises");
78291
- var import_node_path81 = require("path");
78554
+ var import_promises78 = require("fs/promises");
78555
+ var import_node_path82 = require("path");
78292
78556
  function isNotNewer(version2, installed) {
78293
78557
  return installed !== null && isReleaseVersion(version2) && isReleaseVersion(installed) && compareVersions(version2, installed) <= 0;
78294
78558
  }
78295
78559
  async function installFromSource(source) {
78296
78560
  const { layout, from, ifNewer } = source;
78297
- const isTarball = (await (0, import_promises77.stat)(from)).isFile();
78298
- const downloads = (0, import_node_path81.join)(layout.root, ".downloads");
78299
- if (isTarball) await (0, import_promises77.mkdir)(downloads, { recursive: true, mode: 448 });
78300
- const scratch = isTarball ? await (0, import_promises77.mkdtemp)((0, import_node_path81.join)(downloads, "upgrade-")) : null;
78561
+ const isTarball = (await (0, import_promises78.stat)(from)).isFile();
78562
+ const downloads = (0, import_node_path82.join)(layout.root, ".downloads");
78563
+ if (isTarball) await (0, import_promises78.mkdir)(downloads, { recursive: true, mode: 448 });
78564
+ const scratch = isTarball ? await (0, import_promises78.mkdtemp)((0, import_node_path82.join)(downloads, "upgrade-")) : null;
78301
78565
  try {
78302
78566
  const sourceDir = scratch === null ? from : await extractPackageTarball(from, scratch);
78303
78567
  const version2 = await readPackageVersion(sourceDir);
@@ -78305,7 +78569,7 @@ async function installFromSource(source) {
78305
78569
  if (ifNewer && isNotNewer(version2, installed)) return { kind: "skipped", version: version2, installed };
78306
78570
  return { kind: "installed", ...await installVersion(layout, sourceDir) };
78307
78571
  } finally {
78308
- if (scratch !== null) await (0, import_promises77.rm)(scratch, { recursive: true, force: true });
78572
+ if (scratch !== null) await (0, import_promises78.rm)(scratch, { recursive: true, force: true });
78309
78573
  }
78310
78574
  }
78311
78575
  async function runUpgrade(argv) {
@@ -78317,7 +78581,7 @@ async function runUpgrade(argv) {
78317
78581
  const layout = installLayout(config2.installDir, config2.profile);
78318
78582
  const outcome2 = await installFromSource({
78319
78583
  layout,
78320
- from: (0, import_node_path81.resolve)(from),
78584
+ from: (0, import_node_path82.resolve)(from),
78321
78585
  ifNewer: hasFlag(argv, "--if-newer")
78322
78586
  });
78323
78587
  if (outcome2.kind === "skipped") {