@alan-ai-hq/agent-manager-linux-arm64 0.1.142 → 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 +908 -639
  2. package/alan-holder.cjs +433 -371
  3. package/package.json +1 -1
package/alan-holder.cjs CHANGED
@@ -21465,37 +21465,15 @@ Platform Documents are the default destination and source of truth for PM work.
21465
21465
 
21466
21466
  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.
21467
21467
 
21468
- ## Platform knowledge lookups
21468
+ ## Evidence and source selection
21469
21469
 
21470
- 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.
21470
+ 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.
21471
21471
 
21472
- **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.
21472
+ 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.
21473
21473
 
21474
- | What you want | Use this | Not this |
21475
- |---|---|---|
21476
- | Requirements, PRDs, specs, notes, any written knowledge | \`list_documents\`, \`find_records\`, \`get_document\` | reading \`docs/\`, \`notes/\`, \`README.md\` |
21477
- | Scope, status, priority, or history of work | \`get_task\`, \`list_subtasks\`, \`list_tasks\` | \`git log\`, commit messages |
21478
- | What was decided and why | \`list_task_decisions\`, \`list_task_events\` | code comments, in-repo ADRs |
21479
- | What an agent did or is doing | \`list_sessions\`, \`get_session_context\` | \`git log\`, diffing the worktree |
21480
- | Prior agent context | \`list_task_events\`, \`get_session_context\` | scratch files |
21481
- | Outputs of completed work | \`list_artifacts\`, \`get_artifact\` | build output, generated files |
21482
- | Where code lives or how it works | \`search_code_context\` first, then \`Read\` the cited files | \`Grep\`/\`Glob\` sweeps |
21474
+ 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.
21483
21475
 
21484
- **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.
21485
-
21486
- 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.
21487
-
21488
- **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.
21489
-
21490
- 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.
21491
-
21492
- **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.
21493
-
21494
- 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:
21495
- - an explicit location \u2014 "in the repo", "in the codebase", "local files", "on disk", "in the worktree"
21496
- - a concrete path or filename \u2014 \`notes/foo.md\`, \`AGENTS.md\`, "the readme"
21497
-
21498
- 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.
21476
+ For team code discovery, follow the shared \`search_code_context\` guidance, verify cited files locally, and use focused local searches when needed.
21499
21477
 
21500
21478
  ## Your primary tools
21501
21479
 
@@ -21949,18 +21927,23 @@ var init_system_prompt = __esm({
21949
21927
  init_agent_definitions();
21950
21928
  ALAN_CONTEXT_SEARCH_PROMPT = `## Memory (non-code context)
21951
21929
 
21952
- 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.
21930
+ 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.
21931
+
21932
+ 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.
21953
21933
 
21954
- 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.
21934
+ 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.`;
21935
+ ALAN_PLATFORM_TOOL_ROUTING_PROMPT = `## Tool choice
21955
21936
 
21956
- 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.
21937
+ Choose tools by the evidence or action the request needs, whether the agent runs locally or in the cloud:
21938
+ - 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.
21939
+ - 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.
21940
+ - 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.
21957
21941
 
21958
- 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.
21942
+ 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.
21959
21943
 
21960
- 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.`;
21961
- ALAN_PLATFORM_TOOL_ROUTING_PROMPT = `## Alan platform and GitHub
21944
+ 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.
21962
21945
 
21963
- 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.`;
21946
+ 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.`;
21964
21947
  ALAN_IDENTITY_PROMPT = `You are Alan, the software factory agent. Alan ships software end to end \u2014 plan, write, review, test, deploy.
21965
21948
 
21966
21949
  ## How Alan is structured
@@ -21984,7 +21967,7 @@ Team
21984
21967
  - Listen first. Don't jump to solutions. One question at a time, not a list.
21985
21968
  - Scan available context (task, subtasks, code, history) before asking questions you can answer yourself.
21986
21969
  - Challenge when off \u2014 never silently implement the wrong thing.
21987
- - Human leads, you propose. Proactive on reversible actions. Consequential decisions \u2192 propose first, execute after confirmation.
21970
+ - 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.
21988
21971
  - Own mistakes. Wrong ID, jumped too fast \u2014 say so and fix it.
21989
21972
  - 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.
21990
21973
  - 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."
@@ -22421,7 +22404,7 @@ function plan(command, args, options) {
22421
22404
  function captureOutput(command, args, options) {
22422
22405
  const launch = plan(command, args, options);
22423
22406
  if (launch === void 0) return Promise.resolve(NEVER_STARTED);
22424
- return new Promise((resolve6) => {
22407
+ return new Promise((resolve7) => {
22425
22408
  (0, import_child_process.execFile)(
22426
22409
  launch.file,
22427
22410
  [...launch.args],
@@ -22435,7 +22418,7 @@ function captureOutput(command, args, options) {
22435
22418
  },
22436
22419
  (error61, stdout, stderr) => {
22437
22420
  const code = error61 && typeof error61.code === "number" ? error61.code : error61 ? void 0 : 0;
22438
- resolve6({ stdout, stderr, exitCode: code });
22421
+ resolve7({ stdout, stderr, exitCode: code });
22439
22422
  }
22440
22423
  );
22441
22424
  });
@@ -22485,10 +22468,10 @@ async function linuxStartTicks(pid) {
22485
22468
  }
22486
22469
  }
22487
22470
  function psStartTime(pid) {
22488
- return new Promise((resolve6) => {
22471
+ return new Promise((resolve7) => {
22489
22472
  (0, import_child_process2.execFile)("ps", ["-o", "lstart=", "-p", String(pid)], { timeout: 2e3 }, (error61, stdout) => {
22490
22473
  const text2 = stdout.trim();
22491
- resolve6(error61 || !text2 ? void 0 : text2);
22474
+ resolve7(error61 || !text2 ? void 0 : text2);
22492
22475
  });
22493
22476
  });
22494
22477
  }
@@ -22517,12 +22500,12 @@ function parseProcessList(text2) {
22517
22500
  }
22518
22501
  function listProcesses(platform = process.platform) {
22519
22502
  if (platform === "win32") return Promise.resolve([]);
22520
- return new Promise((resolve6) => {
22503
+ return new Promise((resolve7) => {
22521
22504
  (0, import_child_process3.execFile)(
22522
22505
  "ps",
22523
22506
  ["-A", "-o", "pid=,ppid=,pgid=,lstart="],
22524
22507
  { timeout: 5e3, maxBuffer: 8 * 1024 * 1024 },
22525
- (error61, stdout) => resolve6(error61 ? [] : parseProcessList(stdout))
22508
+ (error61, stdout) => resolve7(error61 ? [] : parseProcessList(stdout))
22526
22509
  );
22527
22510
  });
22528
22511
  }
@@ -22562,11 +22545,11 @@ async function taskkill(pid, options) {
22562
22545
  stdio: "ignore",
22563
22546
  windowsHide: true
22564
22547
  });
22565
- const exited = new Promise((resolve6) => {
22566
- killer.once("error", (error210) => resolve6(error210));
22548
+ const exited = new Promise((resolve7) => {
22549
+ killer.once("error", (error210) => resolve7(error210));
22567
22550
  killer.once(
22568
22551
  "exit",
22569
- (code, signal) => resolve6(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22552
+ (code, signal) => resolve7(code === 0 ? void 0 : new Error(`taskkill failed: exit ${code}, signal ${signal}`))
22570
22553
  );
22571
22554
  });
22572
22555
  const timedOut = clock.sleep(options.timeoutMs ?? DEFAULT_TASKKILL_TIMEOUT_MS, timeout.signal).then(() => new Error("taskkill timed out")).catch(() => void 0);
@@ -22822,10 +22805,10 @@ function spawnCli(options) {
22822
22805
  function waitForSpawn(child, command) {
22823
22806
  if (isWindowsJob(child)) return waitForWindowsJob(child, command);
22824
22807
  if (child.pid !== void 0) return Promise.resolve();
22825
- return new Promise((resolve6, reject) => {
22808
+ return new Promise((resolve7, reject) => {
22826
22809
  const onSpawn = () => {
22827
22810
  child.off("error", onError);
22828
- resolve6();
22811
+ resolve7();
22829
22812
  };
22830
22813
  const onError = (error61) => {
22831
22814
  child.off("spawn", onSpawn);
@@ -23216,69 +23199,47 @@ var init_models = __esm({
23216
23199
  maxOutputTokens: 16384
23217
23200
  },
23218
23201
  {
23219
- id: "z-ai/glm-4.7-flash",
23220
- name: "GLM 4.7 Flash",
23221
- description: "Fast GLM coding via Alan",
23202
+ id: "z-ai/glm-5.3",
23203
+ name: "GLM 5.3",
23204
+ description: "Z.ai's flagship for coding, agents and long-horizon work",
23222
23205
  enabled: true,
23223
23206
  isDefault: false,
23224
23207
  sortOrder: 30,
23225
- upstreamModelId: "z-ai/glm-4.7-flash",
23226
- contextWindow: 2e5,
23227
- maxOutputTokens: 8192
23228
- },
23229
- {
23230
- id: "z-ai/glm-4.7",
23231
- name: "GLM 4.7",
23232
- description: "GLM coding and multi-step agent work",
23233
- enabled: true,
23234
- isDefault: false,
23235
- sortOrder: 40,
23236
- upstreamModelId: "z-ai/glm-4.7",
23237
- contextWindow: 2e5,
23208
+ upstreamModelId: "z-ai/glm-5.3",
23209
+ contextWindow: 1048576,
23238
23210
  maxOutputTokens: 16384
23239
23211
  },
23240
23212
  {
23241
- id: "qwen/qwen3-coder-flash",
23242
- name: "Qwen3 Coder Flash",
23243
- description: "Fast Qwen coder via Alan",
23244
- enabled: true,
23245
- isDefault: false,
23246
- sortOrder: 50,
23247
- upstreamModelId: "qwen/qwen3-coder-flash",
23248
- contextWindow: 128e3,
23249
- maxOutputTokens: 8192
23250
- },
23251
- {
23252
- id: "qwen/qwen3-coder",
23253
- name: "Qwen3 Coder",
23254
- description: "Open-weight oriented coding",
23213
+ id: "z-ai/glm-5.3-flash",
23214
+ name: "GLM 5.3 Flash",
23215
+ description: "Fast multimodal GLM via Alan",
23255
23216
  enabled: true,
23256
23217
  isDefault: false,
23257
- sortOrder: 60,
23258
- upstreamModelId: "qwen/qwen3-coder",
23259
- contextWindow: 128e3,
23218
+ sortOrder: 40,
23219
+ upstreamModelId: "z-ai/glm-5.3-flash",
23220
+ contextWindow: 1048576,
23260
23221
  maxOutputTokens: 8192
23261
23222
  },
23262
23223
  {
23263
- id: "moonshotai/kimi-k2.6",
23264
- name: "Kimi K2.6",
23265
- description: "Fast Kimi for long-horizon coding",
23224
+ id: "qwen/qwen3.8-27b",
23225
+ name: "Qwen3.8 27B",
23226
+ description: "Qwen3.8 open-weight coding and agentic work",
23266
23227
  enabled: true,
23267
23228
  isDefault: false,
23268
- sortOrder: 70,
23269
- upstreamModelId: "moonshotai/kimi-k2.6",
23270
- contextWindow: 262144,
23229
+ sortOrder: 50,
23230
+ upstreamModelId: "qwen/qwen3.8-27b",
23231
+ contextWindow: 1e6,
23271
23232
  maxOutputTokens: 16384
23272
23233
  },
23273
23234
  {
23274
- id: "moonshotai/kimi-k2.7-code",
23275
- name: "Kimi K2.7 Code",
23276
- description: "Kimi coding specialist",
23235
+ id: "moonshotai/kimi-k3",
23236
+ name: "Kimi K3",
23237
+ description: "Moonshot's 2.8T open-weight flagship",
23277
23238
  enabled: true,
23278
23239
  isDefault: false,
23279
- sortOrder: 80,
23280
- upstreamModelId: "moonshotai/kimi-k2.7-code",
23281
- contextWindow: 262144,
23240
+ sortOrder: 60,
23241
+ upstreamModelId: "moonshotai/kimi-k3",
23242
+ contextWindow: 1048576,
23282
23243
  maxOutputTokens: 16384
23283
23244
  },
23284
23245
  {
@@ -23287,7 +23248,7 @@ var init_models = __esm({
23287
23248
  description: "Fast Nemotron via Alan",
23288
23249
  enabled: true,
23289
23250
  isDefault: false,
23290
- sortOrder: 90,
23251
+ sortOrder: 70,
23291
23252
  upstreamModelId: "nvidia/nemotron-3-nano-30b-a3b",
23292
23253
  contextWindow: 262144,
23293
23254
  maxOutputTokens: 8192
@@ -23298,7 +23259,7 @@ var init_models = __esm({
23298
23259
  description: "Mid-tier Nemotron via Alan",
23299
23260
  enabled: true,
23300
23261
  isDefault: false,
23301
- sortOrder: 100,
23262
+ sortOrder: 80,
23302
23263
  upstreamModelId: "nvidia/nemotron-3-super-120b-a12b",
23303
23264
  contextWindow: 262144,
23304
23265
  maxOutputTokens: 16384
@@ -23309,18 +23270,29 @@ var init_models = __esm({
23309
23270
  description: "Largest Nemotron via Alan",
23310
23271
  enabled: true,
23311
23272
  isDefault: false,
23312
- sortOrder: 110,
23273
+ sortOrder: 90,
23313
23274
  upstreamModelId: "nvidia/nemotron-3-ultra-550b-a55b",
23314
23275
  contextWindow: 262144,
23315
23276
  maxOutputTokens: 16384
23316
23277
  },
23278
+ {
23279
+ id: "nvidia/nemotron-3.5-lightning",
23280
+ name: "Nemotron 3.5 Lightning",
23281
+ description: "Small, fast Nemotron for high-volume work",
23282
+ enabled: true,
23283
+ isDefault: false,
23284
+ sortOrder: 100,
23285
+ upstreamModelId: "nvidia/nemotron-3.5-lightning",
23286
+ contextWindow: 262144,
23287
+ maxOutputTokens: 8192
23288
+ },
23317
23289
  {
23318
23290
  id: "meta/muse-spark-1.3-contributor",
23319
23291
  name: "Muse Spark 1.3 Contributor",
23320
23292
  description: "Cost-efficient Muse Spark (contributor tier)",
23321
23293
  enabled: true,
23322
23294
  isDefault: false,
23323
- sortOrder: 120,
23295
+ sortOrder: 110,
23324
23296
  upstreamModelId: "meta/muse-spark-1.3-contributor",
23325
23297
  contextWindow: 1048576,
23326
23298
  maxOutputTokens: 16384
@@ -23331,7 +23303,7 @@ var init_models = __esm({
23331
23303
  description: "Meta Muse Spark multimodal agentic coding",
23332
23304
  enabled: true,
23333
23305
  isDefault: false,
23334
- sortOrder: 130,
23306
+ sortOrder: 120,
23335
23307
  upstreamModelId: "meta/muse-spark-1.3",
23336
23308
  contextWindow: 1048576,
23337
23309
  maxOutputTokens: 16384
@@ -23342,7 +23314,7 @@ var init_models = __esm({
23342
23314
  description: "Prior Muse Spark contributor tier",
23343
23315
  enabled: true,
23344
23316
  isDefault: false,
23345
- sortOrder: 140,
23317
+ sortOrder: 130,
23346
23318
  upstreamModelId: "meta/muse-spark-1.2-contributor",
23347
23319
  contextWindow: 1048576,
23348
23320
  maxOutputTokens: 16384
@@ -24797,8 +24769,8 @@ function createJsonRpcPeer(writer, handlers) {
24797
24769
  },
24798
24770
  request: (method, params = {}) => {
24799
24771
  const id = counter.next++;
24800
- return new Promise((resolve6, reject) => {
24801
- pending.set(id, { method, resolve: resolve6, reject });
24772
+ return new Promise((resolve7, reject) => {
24773
+ pending.set(id, { method, resolve: resolve7, reject });
24802
24774
  writer.write({ id, method, params }).catch((error61) => {
24803
24775
  pending.delete(id);
24804
24776
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -24911,7 +24883,7 @@ function createNdjsonWriter(stream) {
24911
24883
  get writable() {
24912
24884
  return stream.writable && !stream.destroyed && failure5.error === void 0;
24913
24885
  },
24914
- write: (value) => new Promise((resolve6, reject) => {
24886
+ write: (value) => new Promise((resolve7, reject) => {
24915
24887
  if (failure5.error) {
24916
24888
  reject(failure5.error);
24917
24889
  return;
@@ -24923,7 +24895,7 @@ function createNdjsonWriter(stream) {
24923
24895
  stream.write(`${JSON.stringify(value)}
24924
24896
  `, (error61) => {
24925
24897
  if (error61) reject(error61);
24926
- else resolve6();
24898
+ else resolve7();
24927
24899
  });
24928
24900
  }),
24929
24901
  end: () => {
@@ -24939,11 +24911,11 @@ function hostProcess(child, tree, options, handlers) {
24939
24911
  const stderr = new LineSplitter((line) => handlers.onStderrLine(line));
24940
24912
  child.stderr.on("data", (chunk) => stderr.push(chunk));
24941
24913
  child.stderr.once("end", () => stderr.flush());
24942
- const processExit = new Promise((resolve6) => {
24943
- child.once("exit", (code, signal) => resolve6({ code, signal }));
24914
+ const processExit = new Promise((resolve7) => {
24915
+ child.once("exit", (code, signal) => resolve7({ code, signal }));
24944
24916
  });
24945
- const outputEnded = new Promise((resolve6) => {
24946
- child.stdout.once("close", () => resolve6());
24917
+ const outputEnded = new Promise((resolve7) => {
24918
+ child.stdout.once("close", () => resolve7());
24947
24919
  });
24948
24920
  const watch = async () => {
24949
24921
  const { clock, stdoutDrainMs, log, name } = options;
@@ -25232,13 +25204,13 @@ var init_chunk_VMGVHPBB = __esm({
25232
25204
  const turnId = input2.turnId;
25233
25205
  let finish = () => {
25234
25206
  };
25235
- const done = new Promise((resolve6) => {
25207
+ const done = new Promise((resolve7) => {
25236
25208
  finish = (outcome2) => {
25237
25209
  if (this.#current?.id !== turnId) return;
25238
25210
  this.#current = void 0;
25239
25211
  if (this.#state === "busy") this.#state = "idle";
25240
25212
  this.#emit({ type: "turn_ended", turnId, outcome: outcome2 });
25241
- resolve6({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25213
+ resolve7({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25242
25214
  };
25243
25215
  });
25244
25216
  const pending = {
@@ -25466,7 +25438,7 @@ var init_chunk_J2KTV5FP = __esm({
25466
25438
  }
25467
25439
  });
25468
25440
 
25469
- // ../agent-core/dist/chunk-ITTV3UIM.js
25441
+ // ../agent-core/dist/chunk-VX6QVMKD.js
25470
25442
  function truncate(value, limit) {
25471
25443
  const normalized2 = Array.from(value, (character) => {
25472
25444
  const code = character.charCodeAt(0);
@@ -25555,7 +25527,7 @@ function currentUserSection(user, visibility) {
25555
25527
  if (user.name) lines.push(`- **Name**: ${user.name}`);
25556
25528
  lines.push(`- **Email**: ${user.email}`, `- **User ID**: ${user.id}`, "");
25557
25529
  lines.push(
25558
- 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."
25530
+ 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."
25559
25531
  );
25560
25532
  return lines.join("\n");
25561
25533
  }
@@ -25827,8 +25799,8 @@ ${body}` : body;
25827
25799
  return spec.mode === "plan" ? planModePrefix(prefixed) : prefixed;
25828
25800
  }
25829
25801
  var MAX_PARSED_ATTACHMENTS, MAX_PARSED_ATTACHMENT_CHARS, MAX_METADATA_CHARS, UNAVAILABLE, READ_ONLY_MODES, AGENT_MODES;
25830
- var init_chunk_ITTV3UIM = __esm({
25831
- "../agent-core/dist/chunk-ITTV3UIM.js"() {
25802
+ var init_chunk_VX6QVMKD = __esm({
25803
+ "../agent-core/dist/chunk-VX6QVMKD.js"() {
25832
25804
  "use strict";
25833
25805
  init_agent2();
25834
25806
  MAX_PARSED_ATTACHMENTS = 3;
@@ -25944,6 +25916,7 @@ function buildClaudeArgs(input2) {
25944
25916
  ...capabilities.supportsThinkingDisplay ? ["--thinking-display", "summarized"] : [],
25945
25917
  // Without it the whole answer lands in one frame at turn end.
25946
25918
  ...capabilities.supportsPartialMessages ? ["--include-partial-messages"] : [],
25919
+ ...capabilities.supportsPluginDir ? (input2.pluginDirs ?? []).flatMap((dir) => ["--plugin-dir", dir]) : [],
25947
25920
  ...option("--resume", input2.resumeId),
25948
25921
  "--chrome",
25949
25922
  ...input2.extraArgs ?? []
@@ -25956,18 +25929,21 @@ function createClaudeCapabilityProbe(probe = createFlagProbe()) {
25956
25929
  supportsApproveMcps,
25957
25930
  supportsThinkingDisplay,
25958
25931
  supportsPartialMessages,
25959
- supportsReplayUserMessages
25932
+ supportsReplayUserMessages,
25933
+ supportsPluginDir
25960
25934
  ] = await Promise.all([
25961
25935
  needsApproveMcps ? probe.supportsFlag(command, "--approve-mcps", env) : false,
25962
25936
  probe.supportsHiddenChoiceFlag(command, "--thinking-display", env),
25963
25937
  probe.supportsFlag(command, "--include-partial-messages", env),
25964
- probe.supportsFlag(command, "--replay-user-messages", env)
25938
+ probe.supportsFlag(command, "--replay-user-messages", env),
25939
+ probe.supportsFlag(command, "--plugin-dir", env)
25965
25940
  ]);
25966
25941
  return {
25967
25942
  supportsApproveMcps,
25968
25943
  supportsThinkingDisplay,
25969
25944
  supportsPartialMessages,
25970
- supportsReplayUserMessages
25945
+ supportsReplayUserMessages,
25946
+ supportsPluginDir
25971
25947
  };
25972
25948
  }
25973
25949
  };
@@ -26855,6 +26831,7 @@ function planClaudeSession(run, context) {
26855
26831
  ...run.selectedEffortLevel === void 0 ? {} : { effortLevel: run.selectedEffortLevel },
26856
26832
  ...prompts.systemPrompt === void 0 ? {} : { systemPrompt: prompts.systemPrompt },
26857
26833
  ...prompts.systemPromptAppend === void 0 ? {} : { appendSystemPrompt: prompts.systemPromptAppend },
26834
+ ...context.pluginDirs?.length ? { pluginDirs: context.pluginDirs } : {},
26858
26835
  ...context.managedMcp === void 0 ? {} : {
26859
26836
  mcp: {
26860
26837
  alanMcpUrl: context.managedMcp.url,
@@ -26909,7 +26886,7 @@ var init_claude = __esm({
26909
26886
  init_chunk_54ZRJOQP();
26910
26887
  init_chunk_J2KTV5FP();
26911
26888
  init_chunk_M6YHY2EZ();
26912
- init_chunk_ITTV3UIM();
26889
+ init_chunk_VX6QVMKD();
26913
26890
  init_chunk_YXWJW7I5();
26914
26891
  init_effort();
26915
26892
  import_crypto6 = require("crypto");
@@ -27632,8 +27609,8 @@ var init_claude = __esm({
27632
27609
  }
27633
27610
  async #awaitTaskStop(requestId, taskId) {
27634
27611
  const timer = new AbortController();
27635
- const answered = new Promise((resolve6) => {
27636
- this.#taskStops.set(requestId, resolve6);
27612
+ const answered = new Promise((resolve7) => {
27613
+ this.#taskStops.set(requestId, resolve7);
27637
27614
  });
27638
27615
  const timeoutMs = this.#options.stopTaskTimeoutMs;
27639
27616
  const timedOut = this.#options.clock.sleep(timeoutMs, timer.signal).then(
@@ -27706,17 +27683,17 @@ var init_claude = __esm({
27706
27683
  };
27707
27684
  let markStarted = () => {
27708
27685
  };
27709
- const whenStarted = new Promise((resolve6) => {
27710
- markStarted = resolve6;
27686
+ const whenStarted = new Promise((resolve7) => {
27687
+ markStarted = resolve7;
27711
27688
  });
27712
- const done = new Promise((resolve6) => {
27689
+ const done = new Promise((resolve7) => {
27713
27690
  finish = (outcome2) => {
27714
27691
  if (this.#current?.id !== id) return;
27715
27692
  this.#current = void 0;
27716
27693
  this.#lastTurn = turn;
27717
27694
  if (this.#state === "busy") this.#state = "idle";
27718
27695
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
27719
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27696
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27720
27697
  };
27721
27698
  });
27722
27699
  const active = {
@@ -27834,8 +27811,8 @@ var init_claude = __esm({
27834
27811
  void removeLaunchFiles(this.#launchFiles).catch((error61) => {
27835
27812
  this.#options.log.warn("claude.launch_files_cleanup_failed", { error: error61 });
27836
27813
  });
27837
- for (const resolve6 of this.#taskStops.values()) {
27838
- resolve6({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27814
+ for (const resolve7 of this.#taskStops.values()) {
27815
+ resolve7({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27839
27816
  }
27840
27817
  const active = this.#current;
27841
27818
  if (active) {
@@ -29053,7 +29030,7 @@ var init_codex = __esm({
29053
29030
  init_chunk_54ZRJOQP();
29054
29031
  init_chunk_J2KTV5FP();
29055
29032
  init_chunk_M6YHY2EZ();
29056
- init_chunk_ITTV3UIM();
29033
+ init_chunk_VX6QVMKD();
29057
29034
  init_chunk_YXWJW7I5();
29058
29035
  import_fs6 = require("fs");
29059
29036
  import_path6 = require("path");
@@ -29672,10 +29649,10 @@ var init_codex = __esm({
29672
29649
  };
29673
29650
  let identify = () => {
29674
29651
  };
29675
- const identified = new Promise((resolve6) => {
29676
- identify = resolve6;
29652
+ const identified = new Promise((resolve7) => {
29653
+ identify = resolve7;
29677
29654
  });
29678
- const done = new Promise((resolve6) => {
29655
+ const done = new Promise((resolve7) => {
29679
29656
  finish = (outcome2) => {
29680
29657
  if (this.#current?.id !== id) return;
29681
29658
  this.#current = void 0;
@@ -29683,7 +29660,7 @@ var init_codex = __esm({
29683
29660
  if (this.#state === "busy") this.#state = "idle";
29684
29661
  this.#host.scanDescendants(true);
29685
29662
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
29686
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29663
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29687
29664
  };
29688
29665
  });
29689
29666
  const active = {
@@ -30131,6 +30108,11 @@ function alanCodeConfigContent(existing, input2) {
30131
30108
  return JSON.stringify({
30132
30109
  $schema: "https://opencode.ai/config.json",
30133
30110
  ...config2,
30111
+ // OpenCode writes a whole working-tree diff into every user message summary and re-persists
30112
+ // the message on each update, so a large diff lands in the shared store many times over:
30113
+ // 3.4 GB of a dev machine's engine database was these patches, against 82 sessions. Alan
30114
+ // does not use the engine's undo/revert, so the tracking stays off.
30115
+ snapshot: false,
30134
30116
  model: `${ALAN_CODE_ENGINE_PROVIDER_ID}/${input2.modelId}`,
30135
30117
  enabled_providers: [ALAN_CODE_ENGINE_PROVIDER_ID],
30136
30118
  provider: {
@@ -30156,7 +30138,7 @@ function alanCodeConfigContent(existing, input2) {
30156
30138
  });
30157
30139
  }
30158
30140
  function readBody2(response) {
30159
- return new Promise((resolve6, reject) => {
30141
+ return new Promise((resolve7, reject) => {
30160
30142
  const chunks = [];
30161
30143
  let size = 0;
30162
30144
  response.on("data", (chunk) => {
@@ -30164,7 +30146,7 @@ function readBody2(response) {
30164
30146
  if (size > MAX_CATALOG_BYTES) response.destroy(new Error("catalog too large"));
30165
30147
  else chunks.push(chunk);
30166
30148
  });
30167
- response.on("end", () => resolve6(Buffer.concat(chunks).toString("utf8")));
30149
+ response.on("end", () => resolve7(Buffer.concat(chunks).toString("utf8")));
30168
30150
  response.on("error", reject);
30169
30151
  });
30170
30152
  }
@@ -30180,13 +30162,13 @@ function parseResponseBody(text2, status) {
30180
30162
  }
30181
30163
  function getJson(url2, headers, timeout, signal) {
30182
30164
  const request2 = url2.protocol === "https:" ? import_https.request : import_http3.request;
30183
- return new Promise((resolve6, reject) => {
30165
+ return new Promise((resolve7, reject) => {
30184
30166
  const outgoing = request2(url2, { method: "GET", headers, timeout, signal }, (response) => {
30185
30167
  const status = response.statusCode ?? 0;
30186
30168
  readBody2(response).then((text2) => {
30187
30169
  const body = parseResponseBody(text2, status);
30188
30170
  if (status < 200 || status >= 300) reject(new CatalogResponseError(status, body));
30189
- else resolve6(body);
30171
+ else resolve7(body);
30190
30172
  }).catch(reject);
30191
30173
  });
30192
30174
  outgoing.on("timeout", () => outgoing.destroy(new Error("catalog timed out")));
@@ -37912,7 +37894,7 @@ function within(root, path) {
37912
37894
  }
37913
37895
  async function resolveReal(path) {
37914
37896
  try {
37915
- return await (0, import_promises22.realpath)(path);
37897
+ return await (0, import_promises23.realpath)(path);
37916
37898
  } catch {
37917
37899
  const parent = (0, import_path9.dirname)(path);
37918
37900
  if (parent === path) return path;
@@ -37941,14 +37923,14 @@ function createWorkspaceFs(roots, writable) {
37941
37923
  return {
37942
37924
  read: async (params) => {
37943
37925
  const path = await confined(params);
37944
- const bytes = await (0, import_promises22.readFile)(path);
37926
+ const bytes = await (0, import_promises23.readFile)(path);
37945
37927
  if (bytes.byteLength > MAX_READ_BYTES) throw new FsDenied(`${path} is too large to read`);
37946
37928
  return { content: sliceLines(bytes.toString("utf8"), params) };
37947
37929
  },
37948
37930
  write: async (params) => {
37949
37931
  if (!writable) throw new FsDenied("This session is read-only");
37950
37932
  const path = await confined(params);
37951
- await (0, import_promises22.writeFile)(path, asString(params.content));
37933
+ await (0, import_promises23.writeFile)(path, asString(params.content));
37952
37934
  return {};
37953
37935
  }
37954
37936
  };
@@ -38551,7 +38533,7 @@ async function acpTurnInput(run, context) {
38551
38533
  const encoded = await Promise.all(
38552
38534
  images.map(async (image) => ({
38553
38535
  mimeType: image.mimeType,
38554
- data: (await (0, import_promises23.readFile)(image.path)).toString("base64")
38536
+ data: (await (0, import_promises24.readFile)(image.path)).toString("base64")
38555
38537
  }))
38556
38538
  );
38557
38539
  return {
@@ -38560,7 +38542,7 @@ async function acpTurnInput(run, context) {
38560
38542
  ...encoded.length ? { images: encoded, imagePaths: images.map((image) => image.path) } : {}
38561
38543
  };
38562
38544
  }
38563
- var import_promises22, import_path9, import_crypto12, import_promises23, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES, 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;
38545
+ var import_promises23, import_path9, import_crypto12, import_promises24, CURSOR_ASK_QUESTION, copilotAcpProfile, cursorAcpProfile, MODEL_REJECTED, MAX_READ_BYTES, FsDenied, ENV_REFERENCE, AcpBackgroundTasks, CURSOR_CREATE_PLAN, STATUSES, 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;
38564
38546
  var init_acp3 = __esm({
38565
38547
  "../agent-core/dist/providers/acp.js"() {
38566
38548
  "use strict";
@@ -38569,14 +38551,14 @@ var init_acp3 = __esm({
38569
38551
  init_chunk_54ZRJOQP();
38570
38552
  init_chunk_J2KTV5FP();
38571
38553
  init_chunk_M6YHY2EZ();
38572
- init_chunk_ITTV3UIM();
38554
+ init_chunk_VX6QVMKD();
38573
38555
  init_chunk_YXWJW7I5();
38574
- import_promises22 = require("fs/promises");
38556
+ import_promises23 = require("fs/promises");
38575
38557
  import_path9 = require("path");
38576
38558
  init_effort();
38577
38559
  init_acp();
38578
38560
  import_crypto12 = require("crypto");
38579
- import_promises23 = require("fs/promises");
38561
+ import_promises24 = require("fs/promises");
38580
38562
  init_agent2();
38581
38563
  CURSOR_ASK_QUESTION = "cursor/ask_question";
38582
38564
  copilotAcpProfile = {
@@ -39092,7 +39074,7 @@ var init_acp3 = __esm({
39092
39074
  const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile);
39093
39075
  let finish = () => {
39094
39076
  };
39095
- const done = new Promise((resolve6) => {
39077
+ const done = new Promise((resolve7) => {
39096
39078
  finish = (outcome2) => {
39097
39079
  if (this.#current?.id !== id) return;
39098
39080
  this.#current = void 0;
@@ -39100,7 +39082,7 @@ var init_acp3 = __esm({
39100
39082
  if (this.#state === "busy") this.#state = "idle";
39101
39083
  this.#host.scanDescendants(true);
39102
39084
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
39103
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39085
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39104
39086
  };
39105
39087
  });
39106
39088
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -39796,10 +39778,14 @@ function openCodeConfigContent(input2) {
39796
39778
  enabled: true
39797
39779
  };
39798
39780
  }
39781
+ const skills = asRecord(config2.skills) ?? {};
39782
+ const ownPaths = Array.isArray(skills.paths) ? skills.paths : [];
39783
+ const skillPaths = input2.skillPaths ?? [];
39799
39784
  return JSON.stringify({
39800
39785
  ...config2,
39801
39786
  ...input2.readOnly ? {} : { permission: "allow" },
39802
- ...Object.keys(mcp).length ? { mcp } : {}
39787
+ ...Object.keys(mcp).length ? { mcp } : {},
39788
+ ...skillPaths.length ? { skills: { ...skills, paths: [...ownPaths, ...skillPaths] } } : {}
39803
39789
  });
39804
39790
  }
39805
39791
  function storedParts(message) {
@@ -40094,7 +40080,7 @@ async function sameDirectory(left, right) {
40094
40080
  }
40095
40081
  async function canonicalDirectory(directory) {
40096
40082
  try {
40097
- return await (0, import_promises24.realpath)(directory);
40083
+ return await (0, import_promises25.realpath)(directory);
40098
40084
  } catch {
40099
40085
  return (0, import_path10.resolve)(directory);
40100
40086
  }
@@ -40119,6 +40105,57 @@ async function openSession(session, client, spec, log) {
40119
40105
  const id = await client.createSession({ title: spec.title, permission: NON_INTERACTIVE_RULES });
40120
40106
  return { id, resumed: false };
40121
40107
  }
40108
+ function isOpenTimeout(error61) {
40109
+ return error61 instanceof CoreFault && error61.code === "protocol_violation";
40110
+ }
40111
+ async function openOnce(spec, password, options) {
40112
+ const attempt = { abandoned: false };
40113
+ const { session, url: url2 } = await withDeadline3(
40114
+ startServer(spec, password, options, attempt),
40115
+ options.clock,
40116
+ options.openTimeoutMs,
40117
+ "report a listening URL"
40118
+ ).catch(async (error61) => {
40119
+ attempt.abandoned = true;
40120
+ await attempt.current?.suspend().catch(() => void 0);
40121
+ throw error61;
40122
+ });
40123
+ try {
40124
+ const client = new OpenCodeClient(url2, password, options.engine.label);
40125
+ const opened = await withDeadline3(
40126
+ openSession(session, client, spec, options.log),
40127
+ options.clock,
40128
+ options.openTimeoutMs,
40129
+ "open a session"
40130
+ );
40131
+ session.attach(
40132
+ opened.id,
40133
+ spec.prompt,
40134
+ expiredSignInNotices(spec.env, options.clock.now()),
40135
+ opened.resumed
40136
+ );
40137
+ } catch (error61) {
40138
+ await session.suspend().catch(() => void 0);
40139
+ throw error61;
40140
+ }
40141
+ options.log.info("opencode.opened", {
40142
+ pid: session.pid,
40143
+ sessionId: session.providerSessionId,
40144
+ resumeFailed: session.resumeFailed
40145
+ });
40146
+ return session;
40147
+ }
40148
+ async function openWithRetries(spec, password, options) {
40149
+ for (let tries = 1; ; tries += 1) {
40150
+ try {
40151
+ return await openOnce(spec, password, options);
40152
+ } catch (error61) {
40153
+ if (!isOpenTimeout(error61) || tries >= options.openAttempts) throw error61;
40154
+ options.log.warn("opencode.open_retry", { tries });
40155
+ await options.clock.sleep(options.reconnectDelayMs);
40156
+ }
40157
+ }
40158
+ }
40122
40159
  function createOpenCodeDriver(options = {}) {
40123
40160
  const resolved = {
40124
40161
  clock: options.clock ?? systemClock2,
@@ -40128,6 +40165,7 @@ function createOpenCodeDriver(options = {}) {
40128
40165
  stdoutDrainMs: options.stdoutDrainMs ?? DEFAULTS4.stdoutDrainMs,
40129
40166
  descendantScanMs: options.descendantScanMs ?? DEFAULTS4.descendantScanMs,
40130
40167
  openTimeoutMs: options.openTimeoutMs ?? DEFAULTS4.openTimeoutMs,
40168
+ openAttempts: options.openAttempts ?? DEFAULTS4.openAttempts,
40131
40169
  startAttempts: options.startAttempts ?? DEFAULTS4.startAttempts,
40132
40170
  reconnectAttempts: options.reconnectAttempts ?? DEFAULTS4.reconnectAttempts,
40133
40171
  reconnectDelayMs: options.reconnectDelayMs ?? DEFAULTS4.reconnectDelayMs,
@@ -40143,45 +40181,16 @@ function createOpenCodeDriver(options = {}) {
40143
40181
  };
40144
40182
  const spec = { ...planned, env: launchEnv(planned, authorization) };
40145
40183
  const password = options.password?.() ?? (0, import_crypto13.randomBytes)(24).toString("base64url");
40146
- const attempt = { abandoned: false };
40147
- const { session, url: url2 } = await withDeadline3(
40148
- startServer(spec, password, resolved, attempt),
40149
- resolved.clock,
40150
- resolved.openTimeoutMs,
40151
- "report a listening URL"
40152
- ).catch(async (error61) => {
40153
- attempt.abandoned = true;
40154
- await attempt.current?.suspend().catch(() => void 0);
40155
- await removeAuthorization();
40156
- throw error61;
40157
- });
40158
- void session.exited.then(removeAuthorization).catch((error61) => {
40159
- resolved.log.warn("opencode.authorization_cleanup_failed", { error: error61 });
40160
- });
40161
40184
  try {
40162
- const client = new OpenCodeClient(url2, password, resolved.engine.label);
40163
- const opened = await withDeadline3(
40164
- openSession(session, client, spec, resolved.log),
40165
- resolved.clock,
40166
- resolved.openTimeoutMs,
40167
- "open a session"
40168
- );
40169
- session.attach(
40170
- opened.id,
40171
- spec.prompt,
40172
- expiredSignInNotices(spec.env, resolved.clock.now()),
40173
- opened.resumed
40174
- );
40185
+ const session = await openWithRetries(spec, password, resolved);
40186
+ void session.exited.then(removeAuthorization).catch((error61) => {
40187
+ resolved.log.warn("opencode.authorization_cleanup_failed", { error: error61 });
40188
+ });
40189
+ return session;
40175
40190
  } catch (error61) {
40176
- await session.suspend().catch(() => void 0);
40191
+ await removeAuthorization();
40177
40192
  throw error61;
40178
40193
  }
40179
- resolved.log.info("opencode.opened", {
40180
- pid: session.pid,
40181
- sessionId: session.providerSessionId,
40182
- resumeFailed: session.resumeFailed
40183
- });
40184
- return session;
40185
40194
  }
40186
40195
  };
40187
40196
  }
@@ -40214,6 +40223,7 @@ function planOpenCodeSession(run, context) {
40214
40223
  const config2 = {
40215
40224
  existing: baseEnv[OPENCODE_CONFIG_ENV],
40216
40225
  readOnly,
40226
+ ...context.skillPaths?.length ? { skillPaths: context.skillPaths } : {},
40217
40227
  mcp: {
40218
40228
  conversationId: run.conversationId,
40219
40229
  externalServers: mcp.servers,
@@ -40266,7 +40276,7 @@ function openCodeTurnInput(run, context) {
40266
40276
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
40267
40277
  };
40268
40278
  }
40269
- var import_http4, import_crypto13, import_promises24, import_path10, import_path11, import_url2, import_crypto14, IDLE_SOCKET_MS2, 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_OPERATIONS, 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;
40279
+ var import_http4, import_crypto13, import_promises25, import_path10, import_path11, import_url2, import_crypto14, IDLE_SOCKET_MS2, 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_OPERATIONS, 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;
40270
40280
  var init_opencode = __esm({
40271
40281
  "../agent-core/dist/providers/opencode.js"() {
40272
40282
  "use strict";
@@ -40275,12 +40285,12 @@ var init_opencode = __esm({
40275
40285
  init_chunk_54ZRJOQP();
40276
40286
  init_chunk_J2KTV5FP();
40277
40287
  init_chunk_M6YHY2EZ();
40278
- init_chunk_ITTV3UIM();
40288
+ init_chunk_VX6QVMKD();
40279
40289
  init_chunk_YXWJW7I5();
40280
40290
  import_http4 = require("http");
40281
40291
  init_runtime_v2();
40282
40292
  import_crypto13 = require("crypto");
40283
- import_promises24 = require("fs/promises");
40293
+ import_promises25 = require("fs/promises");
40284
40294
  import_path10 = require("path");
40285
40295
  init_agent2();
40286
40296
  import_path11 = require("path");
@@ -41366,6 +41376,7 @@ var init_opencode = __esm({
41366
41376
  stdoutDrainMs: 2e3,
41367
41377
  descendantScanMs: 5e3,
41368
41378
  openTimeoutMs: 6e4,
41379
+ openAttempts: 2,
41369
41380
  startAttempts: 3,
41370
41381
  reconnectAttempts: 3,
41371
41382
  reconnectDelayMs: 500,
@@ -41444,6 +41455,7 @@ function createAlanCodeHolderDriver(options) {
41444
41455
  engineRoot,
41445
41456
  requestedModel: spec.model
41446
41457
  };
41458
+ const skills = options.installedSkills?.() ?? null;
41447
41459
  const planned = planOpenCodeSession(spec, {
41448
41460
  command: engine.command,
41449
41461
  cwd: spec.projectPath ?? options.defaultCwd,
@@ -41453,7 +41465,8 @@ function createAlanCodeHolderDriver(options) {
41453
41465
  },
41454
41466
  providerEnv: inputs.providerEnv,
41455
41467
  ...managedMcp === void 0 ? {} : { managedMcp },
41456
- ...resumeId === void 0 ? {} : { resumeSessionId: resumeId }
41468
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
41469
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
41457
41470
  });
41458
41471
  return {
41459
41472
  spec: { opencode: planned.spec, profile },
@@ -41504,14 +41517,18 @@ function createClaudeHolderDriver(options) {
41504
41517
  {
41505
41518
  harness: "claude_cli",
41506
41519
  displayName: "Claude CLI",
41507
- plan: (spec, inputs, resumeId, managedMcp) => planClaudeSession(spec, {
41508
- command: options.command ?? "claude",
41509
- cwd: spec.projectPath ?? options.defaultCwd,
41510
- cliEnv: options.cliEnvironment,
41511
- providerEnv: inputs.providerEnv,
41512
- ...managedMcp === void 0 ? {} : { managedMcp },
41513
- ...resumeId === void 0 ? {} : { resumeId }
41514
- }),
41520
+ plan: (spec, inputs, resumeId, managedMcp) => {
41521
+ const skills = options.installedSkills?.() ?? null;
41522
+ return planClaudeSession(spec, {
41523
+ command: options.command ?? "claude",
41524
+ cwd: spec.projectPath ?? options.defaultCwd,
41525
+ cliEnv: options.cliEnvironment,
41526
+ providerEnv: inputs.providerEnv,
41527
+ ...managedMcp === void 0 ? {} : { managedMcp },
41528
+ ...resumeId === void 0 ? {} : { resumeId },
41529
+ ...skills === null ? {} : { pluginDirs: [skills.pluginDir] }
41530
+ });
41531
+ },
41515
41532
  canResume: (planned, resumeId) => claudeSessionLogExists({
41516
41533
  sessionId: resumeId,
41517
41534
  cwd: planned.spec.cwd,
@@ -41548,7 +41565,7 @@ __export(codex_exports, {
41548
41565
  createCodexHolderDriver: () => createCodexHolderDriver
41549
41566
  });
41550
41567
  function sha2562(value) {
41551
- return (0, import_node_crypto12.createHash)("sha256").update(value).digest("hex");
41568
+ return (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex");
41552
41569
  }
41553
41570
  function createCodexLogin(broker) {
41554
41571
  const state = {};
@@ -41623,11 +41640,11 @@ function createCodexHolderDriver(options) {
41623
41640
  }
41624
41641
  );
41625
41642
  }
41626
- var import_node_crypto12;
41643
+ var import_node_crypto13;
41627
41644
  var init_codex2 = __esm({
41628
41645
  "src/holder/drivers/codex.ts"() {
41629
41646
  "use strict";
41630
- import_node_crypto12 = require("crypto");
41647
+ import_node_crypto13 = require("crypto");
41631
41648
  init_dist();
41632
41649
  init_codex();
41633
41650
  init_persistent();
@@ -41734,8 +41751,8 @@ function createDroidPeer(writer, handlers) {
41734
41751
  },
41735
41752
  request: (method, params = {}) => {
41736
41753
  const id = `alan-${counter.next++}`;
41737
- return new Promise((resolve6, reject) => {
41738
- pending.set(id, { method, resolve: resolve6, reject });
41754
+ return new Promise((resolve7, reject) => {
41755
+ pending.set(id, { method, resolve: resolve7, reject });
41739
41756
  writer.write(envelope("request", { id, method, params })).catch((error61) => {
41740
41757
  pending.delete(id);
41741
41758
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -42070,12 +42087,12 @@ async function droidTurnInput(run, context) {
42070
42087
  const encoded = await Promise.all(
42071
42088
  images.map(async (image) => ({
42072
42089
  mimeType: image.mimeType,
42073
- data: (await (0, import_promises25.readFile)(image.path)).toString("base64")
42090
+ data: (await (0, import_promises26.readFile)(image.path)).toString("base64")
42074
42091
  }))
42075
42092
  );
42076
42093
  return { turnId: run.runId, text: text2, ...encoded.length ? { images: encoded } : {} };
42077
42094
  }
42078
- var import_crypto15, import_promises25, 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;
42095
+ var import_crypto15, import_promises26, 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;
42079
42096
  var init_droid = __esm({
42080
42097
  "../agent-core/dist/providers/droid.js"() {
42081
42098
  "use strict";
@@ -42084,11 +42101,11 @@ var init_droid = __esm({
42084
42101
  init_chunk_54ZRJOQP();
42085
42102
  init_chunk_J2KTV5FP();
42086
42103
  init_chunk_M6YHY2EZ();
42087
- init_chunk_ITTV3UIM();
42104
+ init_chunk_VX6QVMKD();
42088
42105
  init_chunk_YXWJW7I5();
42089
42106
  init_runtime_v2();
42090
42107
  import_crypto15 = require("crypto");
42091
- import_promises25 = require("fs/promises");
42108
+ import_promises26 = require("fs/promises");
42092
42109
  init_agent2();
42093
42110
  FACTORY_API_VERSION = "1.0.0";
42094
42111
  FACTORY_PROTOCOL_VERSION = "1.187.0";
@@ -42360,14 +42377,14 @@ var init_droid = __esm({
42360
42377
  const turn = new DroidTurn(sessionId, this.#memory);
42361
42378
  let finish = () => {
42362
42379
  };
42363
- const done = new Promise((resolve6) => {
42380
+ const done = new Promise((resolve7) => {
42364
42381
  finish = (outcome2) => {
42365
42382
  if (this.#current?.id !== id) return;
42366
42383
  this.#current = void 0;
42367
42384
  if (this.#state === "busy") this.#state = "idle";
42368
42385
  this.#host.scanDescendants(true);
42369
42386
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
42370
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42387
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42371
42388
  };
42372
42389
  });
42373
42390
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -42515,14 +42532,18 @@ function createOpenCodeHolderDriver(options) {
42515
42532
  {
42516
42533
  harness: "opencode_serve",
42517
42534
  displayName: "OpenCode server",
42518
- plan: (spec, inputs, resumeId, managedMcp) => planOpenCodeSession(spec, {
42519
- command: options.command ?? "opencode",
42520
- cwd: spec.projectPath ?? options.defaultCwd,
42521
- cliEnv: options.cliEnvironment,
42522
- providerEnv: inputs.providerEnv,
42523
- ...managedMcp === void 0 ? {} : { managedMcp },
42524
- ...resumeId === void 0 ? {} : { resumeSessionId: resumeId }
42525
- }),
42535
+ plan: (spec, inputs, resumeId, managedMcp) => {
42536
+ const skills = options.installedSkills?.() ?? null;
42537
+ return planOpenCodeSession(spec, {
42538
+ command: options.command ?? "opencode",
42539
+ cwd: spec.projectPath ?? options.defaultCwd,
42540
+ cliEnv: options.cliEnvironment,
42541
+ providerEnv: inputs.providerEnv,
42542
+ ...managedMcp === void 0 ? {} : { managedMcp },
42543
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
42544
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
42545
+ });
42546
+ },
42526
42547
  canResume: () => true,
42527
42548
  open: async (spec) => {
42528
42549
  const session = await sessions.open(spec);
@@ -42559,7 +42580,7 @@ function settingsPath(env) {
42559
42580
  async function readSettings(path) {
42560
42581
  let raw;
42561
42582
  try {
42562
- raw = (await (0, import_promises26.readFile)(path, "utf8")).trim();
42583
+ raw = (await (0, import_promises27.readFile)(path, "utf8")).trim();
42563
42584
  } catch {
42564
42585
  return {};
42565
42586
  }
@@ -42577,8 +42598,8 @@ async function selectAntigravityApiKeyMode(env) {
42577
42598
  const settings2 = await readSettings(path);
42578
42599
  if (settings2 === "malformed") return "malformed";
42579
42600
  if (settings2.modelProvider === "gemini") return "already_selected";
42580
- await (0, import_promises26.mkdir)((0, import_path12.dirname)(path), { recursive: true });
42581
- await (0, import_promises26.writeFile)(path, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
42601
+ await (0, import_promises27.mkdir)((0, import_path12.dirname)(path), { recursive: true });
42602
+ await (0, import_promises27.writeFile)(path, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
42582
42603
  return "selected";
42583
42604
  }
42584
42605
  function readAntigravityCapabilities(version2, help) {
@@ -43177,7 +43198,7 @@ function antigravityTurnInput(run, context) {
43177
43198
  });
43178
43199
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43179
43200
  }
43180
- var import_promises26, 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;
43201
+ var import_promises27, 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;
43181
43202
  var init_antigravity = __esm({
43182
43203
  "../agent-core/dist/providers/antigravity.js"() {
43183
43204
  "use strict";
@@ -43186,9 +43207,9 @@ var init_antigravity = __esm({
43186
43207
  init_chunk_XC5676SG();
43187
43208
  init_chunk_54ZRJOQP();
43188
43209
  init_chunk_M6YHY2EZ();
43189
- init_chunk_ITTV3UIM();
43210
+ init_chunk_VX6QVMKD();
43190
43211
  init_chunk_YXWJW7I5();
43191
- import_promises26 = require("fs/promises");
43212
+ import_promises27 = require("fs/promises");
43192
43213
  import_path12 = require("path");
43193
43214
  init_type_guards();
43194
43215
  import_fs8 = require("fs");
@@ -43688,7 +43709,7 @@ function parseConfig(raw) {
43688
43709
  }
43689
43710
  async function writeCommandCodeProjectMcp(cwd, mcp) {
43690
43711
  const path = (0, import_path15.join)(cwd, ".mcp.json");
43691
- const original = await (0, import_promises27.readFile)(path, "utf8").catch(() => null);
43712
+ const original = await (0, import_promises28.readFile)(path, "utf8").catch(() => null);
43692
43713
  const config2 = parseConfig(original);
43693
43714
  const next = {
43694
43715
  ...config2,
@@ -43705,12 +43726,12 @@ async function writeCommandCodeProjectMcp(cwd, mcp) {
43705
43726
  }
43706
43727
  }
43707
43728
  };
43708
- await (0, import_promises27.mkdir)(cwd, { recursive: true });
43709
- await (0, import_promises27.writeFile)(path, `${JSON.stringify(next, null, 2)}
43729
+ await (0, import_promises28.mkdir)(cwd, { recursive: true });
43730
+ await (0, import_promises28.writeFile)(path, `${JSON.stringify(next, null, 2)}
43710
43731
  `);
43711
43732
  return async () => {
43712
- if (original === null) await (0, import_promises27.rm)(path, { force: true });
43713
- else await (0, import_promises27.writeFile)(path, original);
43733
+ if (original === null) await (0, import_promises28.rm)(path, { force: true });
43734
+ else await (0, import_promises28.writeFile)(path, original);
43714
43735
  };
43715
43736
  }
43716
43737
  function commandCodeString(value) {
@@ -43882,7 +43903,7 @@ function commandCodeTurnInput(run, context) {
43882
43903
  });
43883
43904
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43884
43905
  }
43885
- var import_promises27, 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;
43906
+ var import_promises28, 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;
43886
43907
  var init_command_code = __esm({
43887
43908
  "../agent-core/dist/providers/command-code.js"() {
43888
43909
  "use strict";
@@ -43891,9 +43912,9 @@ var init_command_code = __esm({
43891
43912
  init_chunk_54ZRJOQP();
43892
43913
  init_chunk_J2KTV5FP();
43893
43914
  init_chunk_M6YHY2EZ();
43894
- init_chunk_ITTV3UIM();
43915
+ init_chunk_VX6QVMKD();
43895
43916
  init_chunk_YXWJW7I5();
43896
- import_promises27 = require("fs/promises");
43917
+ import_promises28 = require("fs/promises");
43897
43918
  import_path15 = require("path");
43898
43919
  init_agent2();
43899
43920
  init_runtime_v2();
@@ -44755,7 +44776,7 @@ function transportFailure(request2, error61) {
44755
44776
  });
44756
44777
  }
44757
44778
  function readBody(incoming, url2, maxBytes) {
44758
- return new Promise((resolve6, reject) => {
44779
+ return new Promise((resolve7, reject) => {
44759
44780
  const declared = Number(incoming.headers["content-length"] ?? "0");
44760
44781
  if (maxBytes !== void 0 && declared > maxBytes) {
44761
44782
  incoming.destroy();
@@ -44774,7 +44795,7 @@ function readBody(incoming, url2, maxBytes) {
44774
44795
  chunks.push(chunk);
44775
44796
  });
44776
44797
  incoming.on("error", reject);
44777
- incoming.on("end", () => resolve6(Buffer.concat(chunks)));
44798
+ incoming.on("end", () => resolve7(Buffer.concat(chunks)));
44778
44799
  });
44779
44800
  }
44780
44801
  function isConnectionReset(error61) {
@@ -44782,7 +44803,7 @@ function isConnectionReset(error61) {
44782
44803
  }
44783
44804
  function exchange(request2, agents, attempt = 0) {
44784
44805
  const { signal, url: url2 } = request2;
44785
- return new Promise((resolve6, reject) => {
44806
+ return new Promise((resolve7, reject) => {
44786
44807
  if (signal.aborted) {
44787
44808
  reject(signal.reason);
44788
44809
  return;
@@ -44809,7 +44830,7 @@ function exchange(request2, agents, attempt = 0) {
44809
44830
  const stale = outgoing.reusedSocket && !responded && isConnectionReset(error61);
44810
44831
  if (stale && attempt < STALE_SOCKET_RETRIES && !signal.aborted) {
44811
44832
  settle();
44812
- resolve6(exchange(request2, agents, attempt + 1));
44833
+ resolve7(exchange(request2, agents, attempt + 1));
44813
44834
  return;
44814
44835
  }
44815
44836
  fail(error61);
@@ -44822,7 +44843,7 @@ function exchange(request2, agents, attempt = 0) {
44822
44843
  readBody(incoming, url2, isRedirect(status) ? void 0 : request2.maxBodyBytes).then(
44823
44844
  (body) => {
44824
44845
  settle();
44825
- resolve6({ status, headers: incoming.headers, body });
44846
+ resolve7({ status, headers: incoming.headers, body });
44826
44847
  },
44827
44848
  fail
44828
44849
  );
@@ -45111,7 +45132,7 @@ function createGitRunner(options) {
45111
45132
  }
45112
45133
  await killProcessTree(child.pid, { signal: "SIGKILL", child, platform });
45113
45134
  };
45114
- return new Promise((resolve6, reject) => {
45135
+ return new Promise((resolve7, reject) => {
45115
45136
  let ending = null;
45116
45137
  const stop = (next) => {
45117
45138
  if (ending !== null) return;
@@ -45136,7 +45157,7 @@ function createGitRunner(options) {
45136
45157
  signal.removeEventListener("abort", onAbort);
45137
45158
  const final = ending ?? last;
45138
45159
  if (final.kind === "exited") {
45139
- resolve6({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45160
+ resolve7({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45140
45161
  } else {
45141
45162
  reject(faultFor(final, command));
45142
45163
  }
@@ -45636,7 +45657,7 @@ function statusOf(error61) {
45636
45657
  }
45637
45658
  return 1;
45638
45659
  }
45639
- var systemExec = (request2) => new Promise((resolve6) => {
45660
+ var systemExec = (request2) => new Promise((resolve7) => {
45640
45661
  const child = (0, import_node_child_process5.execFile)(
45641
45662
  request2.command,
45642
45663
  [...request2.args],
@@ -45647,7 +45668,7 @@ var systemExec = (request2) => new Promise((resolve6) => {
45647
45668
  windowsHide: true
45648
45669
  },
45649
45670
  (error61, stdout, stderr) => {
45650
- resolve6({ status: statusOf(error61), stdout, stderr });
45671
+ resolve7({ status: statusOf(error61), stdout, stderr });
45651
45672
  }
45652
45673
  );
45653
45674
  child.stdin?.on("error", () => {
@@ -45925,10 +45946,10 @@ function createIgnoreMatcher(path) {
45925
45946
  const expression = globToRegExp(pattern);
45926
45947
  return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
45927
45948
  }
45928
- function isIgnored(normalizedPath, basename6, isDirectory2, configured) {
45929
- if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename6))
45949
+ function isIgnored(normalizedPath, basename7, isDirectory2, configured) {
45950
+ if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename7))
45930
45951
  return true;
45931
- if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename6))
45952
+ if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename7))
45932
45953
  return true;
45933
45954
  return configured.some((matches) => matches(normalizedPath));
45934
45955
  }
@@ -46187,6 +46208,9 @@ function uuidV5(name, namespace) {
46187
46208
  function alanSkillId(slug) {
46188
46209
  return uuidV5(`alan:${slug}`, ALAN_SKILL_NAMESPACE);
46189
46210
  }
46211
+ function alanSkillVersionId(slug, contentHash) {
46212
+ return uuidV5(`alan:${slug}:${contentHash}`, ALAN_SKILL_NAMESPACE);
46213
+ }
46190
46214
 
46191
46215
  // src/capabilities/skills/store.ts
46192
46216
  init_runtime_v2();
@@ -46196,9 +46220,12 @@ function skillsLayout(stateDir, home) {
46196
46220
  return {
46197
46221
  root,
46198
46222
  installedFile: (0, import_node_path11.join)(root, "installed.json"),
46223
+ retiredFile: (0, import_node_path11.join)(root, "retired.json"),
46199
46224
  localFile: (0, import_node_path11.join)(root, "local.json"),
46200
46225
  versionsDir: (0, import_node_path11.join)(root, "versions"),
46201
46226
  tmpDir: (0, import_node_path11.join)(root, "tmp"),
46227
+ pluginDir: (0, import_node_path11.join)(root, "alan-plugin"),
46228
+ pluginSkillsDir: (0, import_node_path11.join)(root, "alan-plugin", "skills"),
46202
46229
  nativeDir: home === void 0 || home === "" ? null : (0, import_node_path11.join)(home, ".agents", "skills")
46203
46230
  };
46204
46231
  }
@@ -46260,18 +46287,20 @@ async function isIntact(layout, skill) {
46260
46287
  return false;
46261
46288
  }
46262
46289
  }
46263
- async function resolveNativeBuiltIn(layout, invocation) {
46290
+ async function resolveNativeBuiltIn(layout, invocation, baked) {
46264
46291
  const slug = invocation.displayName;
46265
46292
  if (layout.nativeDir === null || invocation.skillId !== alanSkillId(slug)) return null;
46266
46293
  const directory = (0, import_node_path11.join)(layout.nativeDir, slug);
46267
46294
  try {
46268
- await inspectSkillPackage(directory, { expectedName: slug });
46295
+ const inspected = await inspectSkillPackage(directory, { expectedName: slug });
46296
+ if (baked === "exact" && alanSkillVersionId(slug, inspected.contentHash) !== invocation.versionId)
46297
+ return null;
46269
46298
  return { packageDirectory: directory };
46270
46299
  } catch {
46271
46300
  return null;
46272
46301
  }
46273
46302
  }
46274
- async function resolveSkillInvocations(layout, invocations) {
46303
+ async function resolveSkillInvocations(layout, invocations, baked = "any") {
46275
46304
  if (invocations.length === 0) return { kind: "resolved", skills: [] };
46276
46305
  const installed = await readInstalledSkills(layout);
46277
46306
  const local = invocations.some((invocation) => invocation.kind === "local_skill") ? await readLocalSkills(layout) : null;
@@ -46291,7 +46320,7 @@ async function resolveSkillInvocations(layout, invocations) {
46291
46320
  resolved.push({ packageDirectory: packageDirectory(layout, skill.versionId) });
46292
46321
  continue;
46293
46322
  }
46294
- const native = await resolveNativeBuiltIn(layout, invocation);
46323
+ const native = await resolveNativeBuiltIn(layout, invocation, baked);
46295
46324
  if (native === null) missing.push(invocation.displayName);
46296
46325
  else resolved.push(native);
46297
46326
  }
@@ -46313,12 +46342,19 @@ async function availableSkillIndex(layout) {
46313
46342
  candidates2.push({ directory: (0, import_node_path11.join)(layout.nativeDir, entry.name) });
46314
46343
  }
46315
46344
  }
46316
- for (const candidate of candidates2.slice(0, 2e3)) {
46317
- const skill = await inspectIndexedSkill(candidate.directory, candidate.contentHash);
46318
- if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
46345
+ const bounded = candidates2.slice(0, 2e3);
46346
+ for (let start = 0; start < bounded.length; start += INDEX_CONCURRENCY) {
46347
+ const batch = bounded.slice(start, start + INDEX_CONCURRENCY);
46348
+ const inspected = await Promise.all(
46349
+ batch.map((candidate) => inspectIndexedSkill(candidate.directory, candidate.contentHash))
46350
+ );
46351
+ for (const skill of inspected) {
46352
+ if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
46353
+ }
46319
46354
  }
46320
46355
  return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
46321
46356
  }
46357
+ var INDEX_CONCURRENCY = 8;
46322
46358
  async function inspectIndexedSkill(directory, contentHash) {
46323
46359
  try {
46324
46360
  const inspected = await inspectSkillPackage(directory, { expectedName: null });
@@ -46330,15 +46366,34 @@ async function inspectIndexedSkill(directory, contentHash) {
46330
46366
  }
46331
46367
  }
46332
46368
 
46369
+ // src/capabilities/skills/native-index.ts
46370
+ var import_node_crypto10 = require("crypto");
46371
+ var import_node_fs7 = require("fs");
46372
+ var import_promises20 = require("fs/promises");
46373
+ var import_node_path12 = require("path");
46374
+ var ALAN_SKILLS_PLUGIN_NAME = "alan";
46375
+ var PLUGIN_MANIFEST = `${JSON.stringify(
46376
+ {
46377
+ name: ALAN_SKILLS_PLUGIN_NAME,
46378
+ description: "Skills Alan installed on this machine for you and your team."
46379
+ },
46380
+ null,
46381
+ 2
46382
+ )}
46383
+ `;
46384
+ function installedSkillFolders(layout) {
46385
+ return (0, import_node_fs7.existsSync)((0, import_node_path12.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
46386
+ }
46387
+
46333
46388
  // src/capabilities/workspace/index.ts
46334
- var import_node_path14 = require("path");
46389
+ var import_node_path15 = require("path");
46335
46390
 
46336
46391
  // src/capabilities/workspace/approved-paths.ts
46337
- var import_promises20 = require("fs/promises");
46392
+ var import_promises21 = require("fs/promises");
46338
46393
  init_zod();
46339
46394
 
46340
46395
  // src/capabilities/workspace/paths.ts
46341
- var import_node_path12 = require("path");
46396
+ var import_node_path13 = require("path");
46342
46397
  function stripWin32Namespace(path) {
46343
46398
  if (/^\\\\\?\\UNC\\/i.test(path)) return `\\\\${path.slice(8)}`;
46344
46399
  if (path.startsWith("\\\\?\\")) return path.slice(4);
@@ -46346,15 +46401,15 @@ function stripWin32Namespace(path) {
46346
46401
  }
46347
46402
  function comparablePath(path, platform) {
46348
46403
  if (platform === "win32") {
46349
- const normalized3 = import_node_path12.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46404
+ const normalized3 = import_node_path13.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46350
46405
  const trimmed4 = normalized3.length > 3 || !/^[a-z]:\\$/i.test(normalized3) ? normalized3.replace(/\\+$/, "") : normalized3;
46351
46406
  return trimmed4.toLowerCase();
46352
46407
  }
46353
- const normalized2 = import_node_path12.posix.normalize(path);
46408
+ const normalized2 = import_node_path13.posix.normalize(path);
46354
46409
  return normalized2.length > 1 ? normalized2.replace(/\/+$/, "") : normalized2;
46355
46410
  }
46356
46411
  function isAbsoluteFor(path, platform) {
46357
- return platform === "win32" ? import_node_path12.win32.isAbsolute(path) : import_node_path12.posix.isAbsolute(path);
46412
+ return platform === "win32" ? import_node_path13.win32.isAbsolute(path) : import_node_path13.posix.isAbsolute(path);
46358
46413
  }
46359
46414
  function isWithin(root, candidate, platform) {
46360
46415
  const separator = platform === "win32" ? "\\" : "/";
@@ -46372,7 +46427,7 @@ var storeSchema = external_exports.object({
46372
46427
  });
46373
46428
  async function realpathOrNull(path) {
46374
46429
  try {
46375
- return await (0, import_promises20.realpath)(path);
46430
+ return await (0, import_promises21.realpath)(path);
46376
46431
  } catch (error61) {
46377
46432
  const code = errnoCode(error61);
46378
46433
  if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM") {
@@ -46431,9 +46486,9 @@ async function openApprovedPaths(options) {
46431
46486
  }
46432
46487
 
46433
46488
  // src/capabilities/workspace/locks.ts
46434
- var import_node_crypto10 = require("crypto");
46435
- var import_promises21 = require("fs/promises");
46436
- var import_node_path13 = require("path");
46489
+ var import_node_crypto11 = require("crypto");
46490
+ var import_promises22 = require("fs/promises");
46491
+ var import_node_path14 = require("path");
46437
46492
  init_zod();
46438
46493
  var LOCK_FORMAT = 1;
46439
46494
  var EXCLUSIVE_FILE = "exclusive.json";
@@ -46448,12 +46503,12 @@ var ownerSchema = external_exports.object({
46448
46503
  since: external_exports.number().int().nonnegative()
46449
46504
  });
46450
46505
  function repositoryLockKey(commonDir, platform) {
46451
- return (0, import_node_crypto10.createHash)("sha256").update(comparablePath(commonDir, platform)).digest("hex").slice(0, 32);
46506
+ return (0, import_node_crypto11.createHash)("sha256").update(comparablePath(commonDir, platform)).digest("hex").slice(0, 32);
46452
46507
  }
46453
46508
  async function readOwner(path) {
46454
46509
  let text2;
46455
46510
  try {
46456
- text2 = await (0, import_promises21.readFile)(path, "utf8");
46511
+ text2 = await (0, import_promises22.readFile)(path, "utf8");
46457
46512
  } catch (error61) {
46458
46513
  if (errnoCode(error61) === "ENOENT") return { kind: "missing" };
46459
46514
  return { kind: "unreadable" };
@@ -46474,7 +46529,7 @@ async function removeIfSame(path, expected) {
46474
46529
  if (current.kind !== "owner" || current.owner.since !== expected.since) return;
46475
46530
  if (current.owner.pid !== expected.pid || current.owner.holder !== expected.holder) return;
46476
46531
  }
46477
- await (0, import_promises21.unlink)(path).catch((error61) => {
46532
+ await (0, import_promises22.unlink)(path).catch((error61) => {
46478
46533
  if (errnoCode(error61) !== "ENOENT") throw error61;
46479
46534
  });
46480
46535
  }
@@ -46499,7 +46554,7 @@ function openRepositoryLocks(options) {
46499
46554
  await removeIfSame(path, read.owner);
46500
46555
  return null;
46501
46556
  }
46502
- const age = await (0, import_promises21.stat)(path).then(
46557
+ const age = await (0, import_promises22.stat)(path).then(
46503
46558
  (info) => clock.now() - info.mtimeMs,
46504
46559
  () => 0
46505
46560
  );
@@ -46513,13 +46568,13 @@ function openRepositoryLocks(options) {
46513
46568
  });
46514
46569
  const folder = async (commonDir) => {
46515
46570
  const key = repositoryLockKey(commonDir, platform);
46516
- const dir = (0, import_node_path13.join)(options.dir, key);
46517
- await (0, import_promises21.mkdir)(dir, { recursive: true, mode: 448 });
46571
+ const dir = (0, import_node_path14.join)(options.dir, key);
46572
+ await (0, import_promises22.mkdir)(dir, { recursive: true, mode: 448 });
46518
46573
  return { key, dir };
46519
46574
  };
46520
46575
  const createExclusive = async (path, owner) => {
46521
46576
  try {
46522
- const handle = await (0, import_promises21.open)(path, "wx", 384);
46577
+ const handle = await (0, import_promises22.open)(path, "wx", 384);
46523
46578
  try {
46524
46579
  await handle.writeFile(JSON.stringify(owner));
46525
46580
  } finally {
@@ -46532,10 +46587,10 @@ function openRepositoryLocks(options) {
46532
46587
  }
46533
46588
  };
46534
46589
  const liveRun = async (dir) => {
46535
- const entries = await (0, import_promises21.readdir)(dir);
46590
+ const entries = await (0, import_promises22.readdir)(dir);
46536
46591
  for (const entry of entries) {
46537
46592
  if (!entry.startsWith(RUN_FILE_PREFIX)) continue;
46538
- const holder = await heldBy((0, import_node_path13.join)(dir, entry));
46593
+ const holder = await heldBy((0, import_node_path14.join)(dir, entry));
46539
46594
  if (holder !== null) return holder;
46540
46595
  }
46541
46596
  return null;
@@ -46543,7 +46598,7 @@ function openRepositoryLocks(options) {
46543
46598
  return {
46544
46599
  tryExclusive: async (commonDir, operationId) => {
46545
46600
  const { key, dir } = await folder(commonDir);
46546
- const path = (0, import_node_path13.join)(dir, EXCLUSIVE_FILE);
46601
+ const path = (0, import_node_path14.join)(dir, EXCLUSIVE_FILE);
46547
46602
  const owner = await self(operationId);
46548
46603
  if (!await createExclusive(path, owner)) {
46549
46604
  const holder = await heldBy(path);
@@ -46561,11 +46616,11 @@ function openRepositoryLocks(options) {
46561
46616
  },
46562
46617
  tryShared: async (commonDir, runId) => {
46563
46618
  const { key, dir } = await folder(commonDir);
46564
- const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto10.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
46565
- const path = (0, import_node_path13.join)(dir, file2);
46619
+ const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto11.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
46620
+ const path = (0, import_node_path14.join)(dir, file2);
46566
46621
  const owner = await self(runId);
46567
46622
  await writeJsonFileAtomic(path, owner);
46568
- const operation = await heldBy((0, import_node_path13.join)(dir, EXCLUSIVE_FILE));
46623
+ const operation = await heldBy((0, import_node_path14.join)(dir, EXCLUSIVE_FILE));
46569
46624
  if (operation !== null) {
46570
46625
  await removeIfSame(path, owner);
46571
46626
  return { kind: "busy", holder: operation };
@@ -46577,33 +46632,33 @@ function openRepositoryLocks(options) {
46577
46632
 
46578
46633
  // src/cli/config.ts
46579
46634
  var import_node_os7 = require("os");
46580
- var import_node_path28 = require("path");
46635
+ var import_node_path29 = require("path");
46581
46636
  init_zod();
46582
46637
 
46583
46638
  // src/client/locate.ts
46584
- var import_node_path15 = require("path");
46639
+ var import_node_path16 = require("path");
46585
46640
  var RUNTIME_PROFILES = ["production", "staging", "development", "local"];
46586
46641
  function defaultStateDir({ profile, platform, home, env }) {
46587
46642
  if (platform === "win32") {
46588
- return (0, import_node_path15.join)(env.LOCALAPPDATA ?? (0, import_node_path15.join)(home, "AppData", "Local"), "Alan", profile);
46643
+ return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", profile);
46589
46644
  }
46590
- return (0, import_node_path15.join)(env.XDG_STATE_HOME ?? (0, import_node_path15.join)(home, ".local", "state"), "alan", profile);
46645
+ return (0, import_node_path16.join)(env.XDG_STATE_HOME ?? (0, import_node_path16.join)(home, ".local", "state"), "alan", profile);
46591
46646
  }
46592
46647
  function defaultInstallDir({ platform, home, env }) {
46593
46648
  if (platform === "win32") {
46594
- return (0, import_node_path15.join)(env.LOCALAPPDATA ?? (0, import_node_path15.join)(home, "AppData", "Local"), "Alan", "runtime");
46649
+ return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", "runtime");
46595
46650
  }
46596
- return (0, import_node_path15.join)(env.XDG_DATA_HOME ?? (0, import_node_path15.join)(home, ".local", "share"), "alan", "runtime");
46651
+ return (0, import_node_path16.join)(env.XDG_DATA_HOME ?? (0, import_node_path16.join)(home, ".local", "share"), "alan", "runtime");
46597
46652
  }
46598
46653
 
46599
46654
  // src/sessions/index.ts
46600
- var import_node_crypto15 = require("crypto");
46601
- var import_promises37 = require("fs/promises");
46655
+ var import_node_crypto16 = require("crypto");
46656
+ var import_promises38 = require("fs/promises");
46602
46657
  var import_node_os6 = require("os");
46603
- var import_node_path27 = require("path");
46658
+ var import_node_path28 = require("path");
46604
46659
 
46605
46660
  // src/holder/control-client.ts
46606
- var import_node_crypto11 = require("crypto");
46661
+ var import_node_crypto12 = require("crypto");
46607
46662
  var import_node_net = require("net");
46608
46663
 
46609
46664
  // src/holder/ndjson.ts
@@ -46767,7 +46822,7 @@ function createProviderDrivers(options) {
46767
46822
  }
46768
46823
 
46769
46824
  // src/holder/engine-records.ts
46770
- var import_node_path16 = require("path");
46825
+ var import_node_path17 = require("path");
46771
46826
  init_zod();
46772
46827
  var ENGINES_FILE = "engines.json";
46773
46828
  var engineRecordSchema = external_exports.object({
@@ -46777,7 +46832,7 @@ var engineRecordSchema = external_exports.object({
46777
46832
  });
46778
46833
  var engineRecordsSchema = external_exports.object({ engines: external_exports.array(engineRecordSchema) });
46779
46834
  function engineRecordsPath(sessionDir) {
46780
- return (0, import_node_path16.join)(sessionDir, ENGINES_FILE);
46835
+ return (0, import_node_path17.join)(sessionDir, ENGINES_FILE);
46781
46836
  }
46782
46837
  function recordSpawnedEngines(path, clock, log) {
46783
46838
  const live = /* @__PURE__ */ new Map();
@@ -46832,17 +46887,17 @@ function createConversationMcpAuthorization(options) {
46832
46887
  }
46833
46888
 
46834
46889
  // src/holder/mcp-helper-access.ts
46835
- var import_promises28 = require("fs/promises");
46890
+ var import_promises29 = require("fs/promises");
46836
46891
  function createHelperMcpAccess(options) {
46837
46892
  return {
46838
46893
  [Symbol.asyncDispose]: async () => {
46839
- await (0, import_promises28.rm)(options.credentialPath, { force: true });
46894
+ await (0, import_promises29.rm)(options.credentialPath, { force: true });
46840
46895
  },
46841
46896
  url: options.managedMcp.url,
46842
46897
  authorization: async (signal) => {
46843
46898
  const authorization = await options.managedMcp.authorization(signal);
46844
46899
  if (authorization === void 0 || signal.aborted) {
46845
- await (0, import_promises28.rm)(options.credentialPath, { force: true });
46900
+ await (0, import_promises29.rm)(options.credentialPath, { force: true });
46846
46901
  return void 0;
46847
46902
  }
46848
46903
  const credential = {
@@ -46857,8 +46912,8 @@ function createHelperMcpAccess(options) {
46857
46912
  }
46858
46913
 
46859
46914
  // src/holder/run-inputs.ts
46860
- var import_promises29 = require("fs/promises");
46861
- var import_node_path17 = require("path");
46915
+ var import_promises30 = require("fs/promises");
46916
+ var import_node_path18 = require("path");
46862
46917
  var NO_RUN_INPUTS = {
46863
46918
  attachments: [],
46864
46919
  providerEnv: {},
@@ -46871,18 +46926,18 @@ function safeFilename(filename) {
46871
46926
  return safe || "attachment";
46872
46927
  }
46873
46928
  async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46874
- const dir = (0, import_node_path17.join)(tmpDir, "runs", spec.runId);
46929
+ const dir = (0, import_node_path18.join)(tmpDir, "runs", spec.runId);
46875
46930
  const cleanup = async () => {
46876
- await (0, import_promises29.rm)(dir, { recursive: true, force: true });
46931
+ await (0, import_promises30.rm)(dir, { recursive: true, force: true });
46877
46932
  };
46878
46933
  try {
46879
46934
  const credential = await source.fetchProviderCredential(spec.runId, signal);
46880
46935
  const attachments = [];
46881
- if (spec.attachments?.length) await (0, import_promises29.mkdir)(dir, { recursive: true, mode: 448 });
46936
+ if (spec.attachments?.length) await (0, import_promises30.mkdir)(dir, { recursive: true, mode: 448 });
46882
46937
  for (const [index, attachment] of (spec.attachments ?? []).entries()) {
46883
46938
  const bytes = await source.downloadAttachment(spec.runId, attachment.id, signal);
46884
- const path = (0, import_node_path17.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
46885
- await (0, import_promises29.writeFile)(path, bytes, { mode: 384 });
46939
+ const path = (0, import_node_path18.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
46940
+ await (0, import_promises30.writeFile)(path, bytes, { mode: 384 });
46886
46941
  attachments.push({
46887
46942
  id: attachment.id,
46888
46943
  kind: attachment.kind,
@@ -46909,30 +46964,30 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46909
46964
  }
46910
46965
 
46911
46966
  // src/holder/serve.ts
46912
- var import_node_crypto14 = require("crypto");
46913
- var import_node_fs10 = require("fs");
46967
+ var import_node_crypto15 = require("crypto");
46968
+ var import_node_fs11 = require("fs");
46914
46969
  var import_node_net2 = require("net");
46915
- var import_node_path26 = require("path");
46970
+ var import_node_path27 = require("path");
46916
46971
  init_runtime_v2();
46917
46972
 
46918
46973
  // src/holder/admission.ts
46919
- var import_node_fs8 = require("fs");
46920
- var import_promises33 = require("fs/promises");
46974
+ var import_node_fs9 = require("fs");
46975
+ var import_promises34 = require("fs/promises");
46921
46976
  var import_node_os5 = require("os");
46922
- var import_node_path22 = require("path");
46977
+ var import_node_path23 = require("path");
46923
46978
  init_constants();
46924
46979
 
46925
46980
  // ../shared/dist/node/local-workspace.js
46926
- var import_node_fs7 = require("fs");
46981
+ var import_node_fs8 = require("fs");
46927
46982
  var import_node_os4 = require("os");
46928
- var import_node_path18 = require("path");
46983
+ var import_node_path19 = require("path");
46929
46984
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os4.homedir)()) {
46930
- return (0, import_node_path18.join)(homeDirectory, ".alan", "workspace");
46985
+ return (0, import_node_path19.join)(homeDirectory, ".alan", "workspace");
46931
46986
  }
46932
46987
 
46933
46988
  // src/holder/admission-relocation.ts
46934
- var import_promises30 = require("fs/promises");
46935
- var import_node_path19 = require("path");
46989
+ var import_promises31 = require("fs/promises");
46990
+ var import_node_path20 = require("path");
46936
46991
  var MAX_RELOCATION_CANDIDATES = 200;
46937
46992
  var RELOCATION_BUDGET_MS = 2e4;
46938
46993
  function repositoryIdentity(url2) {
@@ -46967,8 +47022,8 @@ async function originIdentity(git, path, signal) {
46967
47022
  }
46968
47023
  async function childDirectories(parent, limit) {
46969
47024
  try {
46970
- const entries = await (0, import_promises30.readdir)(parent, { withFileTypes: true });
46971
- return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path19.join)(parent, entry.name));
47025
+ const entries = await (0, import_promises31.readdir)(parent, { withFileTypes: true });
47026
+ return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path20.join)(parent, entry.name));
46972
47027
  } catch {
46973
47028
  return [];
46974
47029
  }
@@ -46976,7 +47031,7 @@ async function childDirectories(parent, limit) {
46976
47031
  async function candidateFolders(search) {
46977
47032
  const roots = /* @__PURE__ */ new Map();
46978
47033
  for (const path of [search.missingPath, ...search.approvedWorkspacePaths]) {
46979
- const parent = (0, import_node_path19.dirname)((0, import_node_path19.resolve)(path));
47034
+ const parent = (0, import_node_path20.dirname)((0, import_node_path20.resolve)(path));
46980
47035
  roots.set(comparablePath(parent, search.platform), parent);
46981
47036
  }
46982
47037
  const candidates2 = /* @__PURE__ */ new Map();
@@ -47003,9 +47058,9 @@ async function discoverRelocatedWorkspace(search) {
47003
47058
  }
47004
47059
 
47005
47060
  // src/holder/checkout-refresh.ts
47006
- var import_node_crypto13 = require("crypto");
47007
- var import_promises31 = require("fs/promises");
47008
- var import_node_path20 = require("path");
47061
+ var import_node_crypto14 = require("crypto");
47062
+ var import_promises32 = require("fs/promises");
47063
+ var import_node_path21 = require("path");
47009
47064
  function short(sha) {
47010
47065
  return sha.slice(0, 12);
47011
47066
  }
@@ -47017,8 +47072,8 @@ function staleLine(path, snapshot2, tip) {
47017
47072
  }
47018
47073
  async function claimOnce(dir, name) {
47019
47074
  try {
47020
- await (0, import_promises31.mkdir)(dir, { recursive: true, mode: 448 });
47021
- await (await (0, import_promises31.open)((0, import_node_path20.join)(dir, name), "wx")).close();
47075
+ await (0, import_promises32.mkdir)(dir, { recursive: true, mode: 448 });
47076
+ await (await (0, import_promises32.open)((0, import_node_path21.join)(dir, name), "wx")).close();
47022
47077
  return true;
47023
47078
  } catch {
47024
47079
  return false;
@@ -47049,8 +47104,8 @@ async function fastForward(freshness, operationId, deps, signal) {
47049
47104
  }
47050
47105
  async function atFirstLease(freshness, spec, deps, signal) {
47051
47106
  const first = await claimOnce(
47052
- (0, import_node_path20.join)(deps.dir, "leased"),
47053
- (0, import_node_crypto13.createHash)("sha256").update(freshness.path).digest("hex")
47107
+ (0, import_node_path21.join)(deps.dir, "leased"),
47108
+ (0, import_node_crypto14.createHash)("sha256").update(freshness.path).digest("hex")
47054
47109
  );
47055
47110
  switch (freshness.state) {
47056
47111
  case "current":
@@ -47080,7 +47135,7 @@ async function checkoutsOf(spec, leaseTargets) {
47080
47135
  function createCheckoutRefresh(deps) {
47081
47136
  return async (spec, leaseTargets, signal) => {
47082
47137
  if (spec.providerSessionId !== void 0) return void 0;
47083
- if (!await claimOnce((0, import_node_path20.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47138
+ if (!await claimOnce((0, import_node_path21.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47084
47139
  const lines = [];
47085
47140
  for (const target of await checkoutsOf(spec, leaseTargets)) {
47086
47141
  const freshness = await readCheckoutFreshness(deps.dir, target);
@@ -47101,8 +47156,8 @@ function createCheckoutRefresh(deps) {
47101
47156
  }
47102
47157
 
47103
47158
  // src/holder/lease.ts
47104
- var import_promises32 = require("fs/promises");
47105
- var import_node_path21 = require("path");
47159
+ var import_promises33 = require("fs/promises");
47160
+ var import_node_path22 = require("path");
47106
47161
  var LEASE_CHECK_EVERY_MS = 5e3;
47107
47162
  var MAX_TRANSIENT_FAILURES = 3;
47108
47163
  var BACKOFF_BASE_MS = 1e3;
@@ -47116,8 +47171,8 @@ function identityFailure(code, workspacePath) {
47116
47171
  return { code, problemCode: "app.workspace.missing", message: MESSAGES[code], workspacePath };
47117
47172
  }
47118
47173
  async function fileIdentity(path) {
47119
- const canonical = await (0, import_promises32.realpath)(path);
47120
- const info = await (0, import_promises32.stat)(canonical, { bigint: true });
47174
+ const canonical = await (0, import_promises33.realpath)(path);
47175
+ const info = await (0, import_promises33.stat)(canonical, { bigint: true });
47121
47176
  return `${canonical}:${info.dev}:${info.ino}`;
47122
47177
  }
47123
47178
  async function snapshot(git, path, signal) {
@@ -47136,7 +47191,7 @@ async function snapshot(git, path, signal) {
47136
47191
  workspace: await fileIdentity(path),
47137
47192
  repository: await fileIdentity(commonDir),
47138
47193
  worktree: await fileIdentity(gitDir),
47139
- commonDir: await (0, import_promises32.realpath)(commonDir)
47194
+ commonDir: await (0, import_promises33.realpath)(commonDir)
47140
47195
  };
47141
47196
  } catch {
47142
47197
  return null;
@@ -47149,7 +47204,7 @@ async function gitValue(git, path, args, signal) {
47149
47204
  }
47150
47205
  async function pathExists(path) {
47151
47206
  try {
47152
- await (0, import_promises32.stat)(path);
47207
+ await (0, import_promises33.stat)(path);
47153
47208
  return true;
47154
47209
  } catch (error61) {
47155
47210
  return errnoCode(error61) !== "ENOENT" && errnoCode(error61) !== "ENOTDIR";
@@ -47158,19 +47213,19 @@ async function pathExists(path) {
47158
47213
  async function hasGitMarker(path) {
47159
47214
  let directory;
47160
47215
  try {
47161
- directory = await (0, import_promises32.realpath)(path);
47216
+ directory = await (0, import_promises33.realpath)(path);
47162
47217
  } catch {
47163
47218
  return true;
47164
47219
  }
47165
47220
  for (; ; ) {
47166
47221
  try {
47167
- await (0, import_promises32.stat)((0, import_node_path21.join)(directory, ".git"));
47222
+ await (0, import_promises33.stat)((0, import_node_path22.join)(directory, ".git"));
47168
47223
  return true;
47169
47224
  } catch (error61) {
47170
47225
  const code = errnoCode(error61);
47171
47226
  if (code !== "ENOENT" && code !== "ENOTDIR") return true;
47172
47227
  }
47173
- const parent = (0, import_node_path21.dirname)(directory);
47228
+ const parent = (0, import_node_path22.dirname)(directory);
47174
47229
  if (parent === directory) return false;
47175
47230
  directory = parent;
47176
47231
  }
@@ -47334,7 +47389,7 @@ function volumeRoot(path) {
47334
47389
  }
47335
47390
  async function exists(path) {
47336
47391
  try {
47337
- await (0, import_promises33.stat)(path);
47392
+ await (0, import_promises34.stat)(path);
47338
47393
  return true;
47339
47394
  } catch {
47340
47395
  return false;
@@ -47342,10 +47397,10 @@ async function exists(path) {
47342
47397
  }
47343
47398
  async function inspectReadiness(path) {
47344
47399
  try {
47345
- if (!(await (0, import_promises33.stat)(path)).isDirectory()) {
47400
+ if (!(await (0, import_promises34.stat)(path)).isDirectory()) {
47346
47401
  return { ready: false, missing: true, message: MESSAGES2.missing };
47347
47402
  }
47348
- await (0, import_promises33.access)(path, import_node_fs8.constants.R_OK | import_node_fs8.constants.W_OK | import_node_fs8.constants.X_OK);
47403
+ await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47349
47404
  return { ready: true };
47350
47405
  } catch (error61) {
47351
47406
  const code = errnoCode(error61) ?? "";
@@ -47423,8 +47478,8 @@ async function admitDefaultWorkspace(spec, context, skills) {
47423
47478
  const { env } = context;
47424
47479
  const path = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)());
47425
47480
  try {
47426
- await (0, import_promises33.mkdir)(path, { recursive: true, mode: 448 });
47427
- await (0, import_promises33.access)(path, import_node_fs8.constants.R_OK | import_node_fs8.constants.W_OK | import_node_fs8.constants.X_OK);
47481
+ await (0, import_promises34.mkdir)(path, { recursive: true, mode: 448 });
47482
+ await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47428
47483
  return {
47429
47484
  kind: "admitted",
47430
47485
  spec: { ...spec, projectPath: path },
@@ -47500,7 +47555,7 @@ var PROBE_TIMEOUT_MS2 = 5e3;
47500
47555
  function createHolderWorkspace(machine, clock, log) {
47501
47556
  const platform = machine.platform ?? process.platform;
47502
47557
  const git = createGitRunner({ env: machine.env, platform, localTimeoutMs: PROBE_TIMEOUT_MS2 });
47503
- const locks = openRepositoryLocks({ dir: (0, import_node_path22.join)(machine.stateDir, "locks"), clock, platform });
47558
+ const locks = openRepositoryLocks({ dir: (0, import_node_path23.join)(machine.stateDir, "locks"), clock, platform });
47504
47559
  return {
47505
47560
  admission: {
47506
47561
  env: machine.env,
@@ -47512,7 +47567,7 @@ function createHolderWorkspace(machine, clock, log) {
47512
47567
  ),
47513
47568
  approvedRoots: async () => {
47514
47569
  const approved = await openApprovedPaths({
47515
- file: (0, import_node_path22.join)(machine.stateDir, "workspaces.json"),
47570
+ file: (0, import_node_path23.join)(machine.stateDir, "workspaces.json"),
47516
47571
  log,
47517
47572
  platform
47518
47573
  });
@@ -47525,7 +47580,7 @@ function createHolderWorkspace(machine, clock, log) {
47525
47580
  git,
47526
47581
  locks,
47527
47582
  log,
47528
- dir: (0, import_node_path22.join)(machine.stateDir, "checkout-freshness")
47583
+ dir: (0, import_node_path23.join)(machine.stateDir, "checkout-freshness")
47529
47584
  })
47530
47585
  } : {}
47531
47586
  };
@@ -47553,7 +47608,7 @@ async function respondToTurn(runningRunId, gate, driver, request2) {
47553
47608
  }
47554
47609
 
47555
47610
  // src/holder/session-facts.ts
47556
- var import_promises34 = require("fs/promises");
47611
+ var import_promises35 = require("fs/promises");
47557
47612
  var CLI_RSS_CACHE_MS = 1e4;
47558
47613
  var LOGIN_PROBLEM_PREFIX = "cli.auth.";
47559
47614
  function isLoginFailure(result) {
@@ -47579,8 +47634,8 @@ function createSessionFacts(options) {
47579
47634
  const path = await resolveCommandOnPath(command, env, platform);
47580
47635
  if (path === null) return null;
47581
47636
  try {
47582
- const real = await (0, import_promises34.realpath)(path);
47583
- const info = await (0, import_promises34.stat)(real);
47637
+ const real = await (0, import_promises35.realpath)(path);
47638
+ const info = await (0, import_promises35.stat)(real);
47584
47639
  return { command, key: `${real}:${info.ino}:${info.size}:${info.mtimeMs}` };
47585
47640
  } catch {
47586
47641
  return null;
@@ -47667,8 +47722,8 @@ function createSessionFacts(options) {
47667
47722
  init_acp2();
47668
47723
 
47669
47724
  // src/run-log/directory.ts
47670
- var import_promises35 = require("fs/promises");
47671
- var import_node_path23 = require("path");
47725
+ var import_promises36 = require("fs/promises");
47726
+ var import_node_path24 = require("path");
47672
47727
  init_runtime_v2();
47673
47728
  init_zod();
47674
47729
  var runMetaSchema = external_exports.object({
@@ -47690,17 +47745,17 @@ var runMetaSchema = external_exports.object({
47690
47745
  }).optional()
47691
47746
  });
47692
47747
  function runDirectory(runsDir, runId) {
47693
- const dir = (0, import_node_path23.join)(runsDir, runId);
47748
+ const dir = (0, import_node_path24.join)(runsDir, runId);
47694
47749
  return {
47695
47750
  dir,
47696
- log: (0, import_node_path23.join)(dir, "log.jsonl"),
47697
- upload: (0, import_node_path23.join)(dir, "upload.json"),
47698
- meta: (0, import_node_path23.join)(dir, "run.json")
47751
+ log: (0, import_node_path24.join)(dir, "log.jsonl"),
47752
+ upload: (0, import_node_path24.join)(dir, "upload.json"),
47753
+ meta: (0, import_node_path24.join)(dir, "run.json")
47699
47754
  };
47700
47755
  }
47701
47756
  async function isRunClaimed(runsDir, runId) {
47702
47757
  try {
47703
- return (await (0, import_promises35.stat)(runDirectory(runsDir, runId).log)).size > 0;
47758
+ return (await (0, import_promises36.stat)(runDirectory(runsDir, runId).log)).size > 0;
47704
47759
  } catch (error61) {
47705
47760
  if (errnoCode(error61) === "ENOENT") return false;
47706
47761
  throw error61;
@@ -47708,8 +47763,8 @@ async function isRunClaimed(runsDir, runId) {
47708
47763
  }
47709
47764
 
47710
47765
  // src/run-log/conversation-index.ts
47711
- var import_promises36 = require("fs/promises");
47712
- var import_node_path24 = require("path");
47766
+ var import_promises37 = require("fs/promises");
47767
+ var import_node_path25 = require("path");
47713
47768
  init_runtime_v2();
47714
47769
  init_zod();
47715
47770
  var ORDINALS_PER_SHARD = 1e3;
@@ -47725,13 +47780,13 @@ var coverageSchema = external_exports.object({
47725
47780
  nextExpectedOrdinal: external_exports.number().int().positive()
47726
47781
  });
47727
47782
  function conversationsDirectory(runsDir) {
47728
- return (0, import_node_path24.join)((0, import_node_path24.dirname)(runsDir), "conversations");
47783
+ return (0, import_node_path25.join)((0, import_node_path25.dirname)(runsDir), "conversations");
47729
47784
  }
47730
47785
  function indexDirectory(runsDir, conversationId) {
47731
- return (0, import_node_path24.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
47786
+ return (0, import_node_path25.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
47732
47787
  }
47733
47788
  function shardPath(runsDir, conversationId, ordinal) {
47734
- return (0, import_node_path24.join)(
47789
+ return (0, import_node_path25.join)(
47735
47790
  indexDirectory(runsDir, conversationId),
47736
47791
  `${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
47737
47792
  );
@@ -47740,10 +47795,10 @@ async function indexConversationRun(runsDir, conversationId, ordinal, assistantO
47740
47795
  const nextOrdinal = assistantOrdinal + 1;
47741
47796
  if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
47742
47797
  const path = shardPath(runsDir, conversationId, ordinal);
47743
- await (0, import_promises36.mkdir)((0, import_node_path24.dirname)(path), { recursive: true, mode: 448 });
47744
- await (0, import_promises36.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
47798
+ await (0, import_promises37.mkdir)((0, import_node_path25.dirname)(path), { recursive: true, mode: 448 });
47799
+ await (0, import_promises37.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
47745
47800
  `, { mode: 384 });
47746
- const coveragePath = (0, import_node_path24.join)((0, import_node_path24.dirname)((0, import_node_path24.dirname)(path)), "coverage.json");
47801
+ const coveragePath = (0, import_node_path25.join)((0, import_node_path25.dirname)((0, import_node_path25.dirname)(path)), "coverage.json");
47747
47802
  const coverage = await readJsonFile(coveragePath, coverageSchema);
47748
47803
  const current = coverage.kind === "ok" ? coverage.value : null;
47749
47804
  const next = nextCoverage(current, ordinal, nextOrdinal);
@@ -47786,13 +47841,13 @@ function runEnded(input2) {
47786
47841
  var decoder = new TextDecoder();
47787
47842
 
47788
47843
  // src/run-log/writer.ts
47789
- var import_node_fs9 = require("fs");
47790
- var import_node_path25 = require("path");
47844
+ var import_node_fs10 = require("fs");
47845
+ var import_node_path26 = require("path");
47791
47846
  init_runtime_v2();
47792
47847
  function lastSeq(fd, size) {
47793
47848
  for (const length of tailWindows(size)) {
47794
47849
  const buffer = Buffer.alloc(length);
47795
- (0, import_node_fs9.readSync)(fd, buffer, 0, length, size - length);
47850
+ (0, import_node_fs10.readSync)(fd, buffer, 0, length, size - length);
47796
47851
  const last = lastLine(buffer.toString("utf8").trimEnd(), length === size);
47797
47852
  if (last === void 0) continue;
47798
47853
  if (last.length === 0) return 0;
@@ -47803,13 +47858,13 @@ function lastSeq(fd, size) {
47803
47858
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
47804
47859
  }
47805
47860
  function openRunLog(path, clock) {
47806
- (0, import_node_fs9.mkdirSync)((0, import_node_path25.dirname)(path), { recursive: true, mode: 448 });
47807
- const fd = (0, import_node_fs9.openSync)(path, "a+", 384);
47808
- let size = (0, import_node_fs9.fstatSync)(fd).size;
47861
+ (0, import_node_fs10.mkdirSync)((0, import_node_path26.dirname)(path), { recursive: true, mode: 448 });
47862
+ const fd = (0, import_node_fs10.openSync)(path, "a+", 384);
47863
+ let size = (0, import_node_fs10.fstatSync)(fd).size;
47809
47864
  let seq = lastSeq(fd, size);
47810
47865
  let dirty = false;
47811
47866
  const sync = () => {
47812
- (0, import_node_fs9.fsyncSync)(fd);
47867
+ (0, import_node_fs10.fsyncSync)(fd);
47813
47868
  dirty = false;
47814
47869
  };
47815
47870
  return {
@@ -47823,7 +47878,7 @@ function openRunLog(path, clock) {
47823
47878
  };
47824
47879
  const line = Buffer.from(`${JSON.stringify(record2)}
47825
47880
  `, "utf8");
47826
- (0, import_node_fs9.writeSync)(fd, line);
47881
+ (0, import_node_fs10.writeSync)(fd, line);
47827
47882
  size += line.length;
47828
47883
  dirty = true;
47829
47884
  if (isRunLifecycleKind(update.sessionUpdate)) sync();
@@ -47835,7 +47890,7 @@ function openRunLog(path, clock) {
47835
47890
  },
47836
47891
  [Symbol.dispose]: () => {
47837
47892
  if (dirty) sync();
47838
- (0, import_node_fs9.closeSync)(fd);
47893
+ (0, import_node_fs10.closeSync)(fd);
47839
47894
  }
47840
47895
  };
47841
47896
  }
@@ -48120,12 +48175,12 @@ var TASK_UNSUPPORTED = {
48120
48175
  message: "This agent cannot stop one background task."
48121
48176
  };
48122
48177
  function sha2563(value) {
48123
- return (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex");
48178
+ return (0, import_node_crypto15.createHash)("sha256").update(value).digest("hex");
48124
48179
  }
48125
48180
  function tokenMatches(expected, presented) {
48126
48181
  const a = Buffer.from(sha2563(expected), "hex");
48127
48182
  const b = Buffer.from(sha2563(presented), "hex");
48128
- return (0, import_node_crypto14.timingSafeEqual)(a, b);
48183
+ return (0, import_node_crypto15.timingSafeEqual)(a, b);
48129
48184
  }
48130
48185
  async function runHolder({
48131
48186
  launch,
@@ -48139,7 +48194,7 @@ async function runHolder({
48139
48194
  try {
48140
48195
  const identity = await readProcessIdentity(process.pid);
48141
48196
  if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
48142
- const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path26.dirname)(launch.statusPath)), clock, log));
48197
+ const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path27.dirname)(launch.statusPath)), clock, log));
48143
48198
  const holder = {
48144
48199
  state: "idle",
48145
48200
  runId: null,
@@ -48335,17 +48390,17 @@ async function runHolder({
48335
48390
  client.on("error", () => holder.clients.delete(client));
48336
48391
  });
48337
48392
  removeStaleEndpoint(launch.endpoint);
48338
- await new Promise((resolve6, reject) => {
48393
+ await new Promise((resolve7, reject) => {
48339
48394
  server.once("error", reject);
48340
- server.listen(launch.endpoint, () => resolve6());
48395
+ server.listen(launch.endpoint, () => resolve7());
48341
48396
  });
48342
48397
  await writeStatus();
48343
48398
  log.info("holder.ready", { conversationId: launch.conversationId, pid: identity.pid });
48344
- await new Promise((resolve6) => exit.signal.addEventListener("abort", () => resolve6()));
48399
+ await new Promise((resolve7) => exit.signal.addEventListener("abort", () => resolve7()));
48345
48400
  await driver.suspend?.().catch((error61) => log.warn("holder.driver_suspend_failed", { error: error61 }));
48346
48401
  for (const client of holder.clients) client.end();
48347
- await new Promise((resolve6) => server.close(() => resolve6()));
48348
- (0, import_node_fs10.rmSync)(launch.statusPath, { force: true });
48402
+ await new Promise((resolve7) => server.close(() => resolve7()));
48403
+ (0, import_node_fs11.rmSync)(launch.statusPath, { force: true });
48349
48404
  log.info("holder.suspended", { conversationId: launch.conversationId });
48350
48405
  } catch (_) {
48351
48406
  var _error = _, _hasError = true;
@@ -48397,7 +48452,8 @@ var envSchema = external_exports.object({
48397
48452
  ALAN_RUNTIME_GIT_GATEWAY_URL: external_exports.url().optional(),
48398
48453
  ALAN_RUNTIME_WORKSPACE_ROOT: external_exports.string().min(1).optional(),
48399
48454
  XDG_CONFIG_HOME: external_exports.string().min(1).optional(),
48400
- GH_CONFIG_DIR: external_exports.string().min(1).optional()
48455
+ GH_CONFIG_DIR: external_exports.string().min(1).optional(),
48456
+ CODEX_HOME: external_exports.string().trim().min(1).optional()
48401
48457
  });
48402
48458
  var DEFAULT_API_URLS = {
48403
48459
  production: "https://api.tryalan.ai",
@@ -48450,7 +48506,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48450
48506
  ALAN_RUNTIME_GIT_GATEWAY_URL,
48451
48507
  ALAN_RUNTIME_WORKSPACE_ROOT,
48452
48508
  XDG_CONFIG_HOME,
48453
- GH_CONFIG_DIR
48509
+ GH_CONFIG_DIR,
48510
+ CODEX_HOME
48454
48511
  } = parsed.data;
48455
48512
  const home = (0, import_node_os7.homedir)();
48456
48513
  const suspendDefaults = defaultSuspendPolicy(totalMemoryBytes);
@@ -48482,7 +48539,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48482
48539
  providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
48483
48540
  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,
48484
48541
  home,
48485
- configHome: XDG_CONFIG_HOME ?? (0, import_node_path28.join)(home, ".config"),
48542
+ configHome: XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config"),
48543
+ codexHome: resolveCodexHome(CODEX_HOME, home),
48486
48544
  ...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
48487
48545
  gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
48488
48546
  workspaceRoot: ALAN_RUNTIME_WORKSPACE_ROOT ?? null,
@@ -48490,11 +48548,14 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48490
48548
  adoptsLegacyInstall: ALAN_RUNTIME_STATE_DIR === void 0
48491
48549
  };
48492
48550
  }
48551
+ function resolveCodexHome(configuredHome, home) {
48552
+ return configuredHome ?? (0, import_node_path29.join)(home, ".codex");
48553
+ }
48493
48554
  function githubProxyConfig(env, home) {
48494
- const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path28.join)(home, ".config");
48555
+ const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config");
48495
48556
  return {
48496
48557
  githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
48497
- ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path28.join)(configHome, "gh")
48558
+ ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path29.join)(configHome, "gh")
48498
48559
  };
48499
48560
  }
48500
48561
  function serviceEnvironment(env, profile) {
@@ -48593,7 +48654,7 @@ async function loadStoredAccess(paths, access3 = { exec: systemExec }) {
48593
48654
  }
48594
48655
 
48595
48656
  // src/cli/commands/hold.ts
48596
- var import_node_path29 = require("path");
48657
+ var import_node_path30 = require("path");
48597
48658
  init_agent2();
48598
48659
  init_runtime_v2();
48599
48660
  async function machineAccess(paths, log, conversationId, transport) {
@@ -48651,7 +48712,7 @@ async function runHold(argv) {
48651
48712
  const config2 = loadRuntimeConfig();
48652
48713
  const paths = runtimePaths(config2.stateDir);
48653
48714
  const log = __using(_stack, openFileLog(
48654
- (0, import_node_path29.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
48715
+ (0, import_node_path30.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
48655
48716
  config2.logLevel,
48656
48717
  systemClock
48657
48718
  ));
@@ -48662,7 +48723,7 @@ async function runHold(argv) {
48662
48723
  );
48663
48724
  const transport = __using(_stack, createHttpTransport());
48664
48725
  const access3 = await machineAccess(paths, log, launch.value.conversationId, transport);
48665
- const credentialPath = (0, import_node_path29.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
48726
+ const credentialPath = (0, import_node_path30.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
48666
48727
  const managedMcp = __using(_stack, access3.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
48667
48728
  managedMcp: access3.managedMcp,
48668
48729
  conversationId: launch.value.conversationId,
@@ -48681,7 +48742,8 @@ async function runHold(argv) {
48681
48742
  timings: config2.sessionTimings,
48682
48743
  log,
48683
48744
  ...managedMcp === void 0 ? {} : { managedMcp },
48684
- codexCredentials: access3.codexCredentials
48745
+ codexCredentials: access3.codexCredentials,
48746
+ installedSkills: () => installedSkillFolders(skillsLayout(paths.stateDir))
48685
48747
  }),
48686
48748
  clock: systemClock,
48687
48749
  log,