@alan-ai-hq/agent-manager-linux-arm64 0.1.143 → 0.1.145

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 +1509 -1067
  2. package/alan-holder.cjs +466 -384
  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",
23213
+ id: "z-ai/glm-5.3-flash",
23214
+ name: "GLM 5.3 Flash",
23215
+ description: "Fast multimodal GLM via Alan",
23244
23216
  enabled: true,
23245
23217
  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",
23255
- enabled: true,
23256
- 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
@@ -23691,6 +23663,13 @@ var init_notice_visibility = __esm({
23691
23663
  }
23692
23664
  });
23693
23665
 
23666
+ // ../shared/dist/agent/acp/presentation/turn-artifacts.js
23667
+ var init_turn_artifacts = __esm({
23668
+ "../shared/dist/agent/acp/presentation/turn-artifacts.js"() {
23669
+ "use strict";
23670
+ }
23671
+ });
23672
+
23694
23673
  // ../shared/dist/agent/acp/presentation/prepare-conversation-turns.js
23695
23674
  var init_prepare_conversation_turns = __esm({
23696
23675
  "../shared/dist/agent/acp/presentation/prepare-conversation-turns.js"() {
@@ -23781,6 +23760,7 @@ var init_acp = __esm({
23781
23760
  init_notice_visibility();
23782
23761
  init_prepare_conversation_turns();
23783
23762
  init_terminal_events();
23763
+ init_turn_artifacts();
23784
23764
  init_types3();
23785
23765
  init_read();
23786
23766
  init_reduce();
@@ -24629,7 +24609,21 @@ var init_chunk_54ZRJOQP = __esm({
24629
24609
  }
24630
24610
  });
24631
24611
 
24632
- // ../agent-core/dist/chunk-VMGVHPBB.js
24612
+ // ../agent-core/dist/chunk-72NSEYHK.js
24613
+ function detectImageMimeType(buffer) {
24614
+ if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
24615
+ if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
24616
+ return "image/jpeg";
24617
+ }
24618
+ if (buffer.length >= 6) {
24619
+ const signature = buffer.subarray(0, 6).toString("ascii");
24620
+ if (signature === "GIF87a" || signature === "GIF89a") return "image/gif";
24621
+ }
24622
+ if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") {
24623
+ return "image/webp";
24624
+ }
24625
+ return null;
24626
+ }
24633
24627
  function collectStrings(value, out) {
24634
24628
  if (typeof value === "string") out.push(value);
24635
24629
  else if (Array.isArray(value)) for (const item of value) collectStrings(item, out);
@@ -24797,8 +24791,8 @@ function createJsonRpcPeer(writer, handlers) {
24797
24791
  },
24798
24792
  request: (method, params = {}) => {
24799
24793
  const id = counter.next++;
24800
- return new Promise((resolve6, reject) => {
24801
- pending.set(id, { method, resolve: resolve6, reject });
24794
+ return new Promise((resolve7, reject) => {
24795
+ pending.set(id, { method, resolve: resolve7, reject });
24802
24796
  writer.write({ id, method, params }).catch((error61) => {
24803
24797
  pending.delete(id);
24804
24798
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -24911,7 +24905,7 @@ function createNdjsonWriter(stream) {
24911
24905
  get writable() {
24912
24906
  return stream.writable && !stream.destroyed && failure5.error === void 0;
24913
24907
  },
24914
- write: (value) => new Promise((resolve6, reject) => {
24908
+ write: (value) => new Promise((resolve7, reject) => {
24915
24909
  if (failure5.error) {
24916
24910
  reject(failure5.error);
24917
24911
  return;
@@ -24923,7 +24917,7 @@ function createNdjsonWriter(stream) {
24923
24917
  stream.write(`${JSON.stringify(value)}
24924
24918
  `, (error61) => {
24925
24919
  if (error61) reject(error61);
24926
- else resolve6();
24920
+ else resolve7();
24927
24921
  });
24928
24922
  }),
24929
24923
  end: () => {
@@ -24939,11 +24933,11 @@ function hostProcess(child, tree, options, handlers) {
24939
24933
  const stderr = new LineSplitter((line) => handlers.onStderrLine(line));
24940
24934
  child.stderr.on("data", (chunk) => stderr.push(chunk));
24941
24935
  child.stderr.once("end", () => stderr.flush());
24942
- const processExit = new Promise((resolve6) => {
24943
- child.once("exit", (code, signal) => resolve6({ code, signal }));
24936
+ const processExit = new Promise((resolve7) => {
24937
+ child.once("exit", (code, signal) => resolve7({ code, signal }));
24944
24938
  });
24945
- const outputEnded = new Promise((resolve6) => {
24946
- child.stdout.once("close", () => resolve6());
24939
+ const outputEnded = new Promise((resolve7) => {
24940
+ child.stdout.once("close", () => resolve7());
24947
24941
  });
24948
24942
  const watch = async () => {
24949
24943
  const { clock, stdoutDrainMs, log, name } = options;
@@ -24998,9 +24992,9 @@ function silentStartError(name, timeoutMs) {
24998
24992
  message: `${name} printed nothing for ${seconds}s after it started and was stopped. Send your message again.`
24999
24993
  };
25000
24994
  }
25001
- var import_crypto3, import_fs4, import_path3, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
25002
- var init_chunk_VMGVHPBB = __esm({
25003
- "../agent-core/dist/chunk-VMGVHPBB.js"() {
24995
+ var import_crypto3, import_fs4, import_path3, PNG_SIGNATURE, IMAGE_MIME_BY_EXT, VIDEO_MIME_BY_EXT, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, AGENT_BROWSER_MENTION, LocalMediaReader, SessionOpenRefusal, JsonRpcError, ACP_PROTOCOL_VERSION, ACP_ERROR, STDERR_TAIL_LINES, RESULT_EXIT_GRACE_MS, PerTurnSession;
24996
+ var init_chunk_72NSEYHK = __esm({
24997
+ "../agent-core/dist/chunk-72NSEYHK.js"() {
25004
24998
  "use strict";
25005
24999
  init_chunk_XC5676SG();
25006
25000
  init_chunk_54ZRJOQP();
@@ -25011,6 +25005,7 @@ var init_chunk_VMGVHPBB = __esm({
25011
25005
  import_path3 = require("path");
25012
25006
  init_agent2();
25013
25007
  init_acp();
25008
+ PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
25014
25009
  IMAGE_MIME_BY_EXT = {
25015
25010
  ".gif": "image/gif",
25016
25011
  ".jpeg": "image/jpeg",
@@ -25232,13 +25227,13 @@ var init_chunk_VMGVHPBB = __esm({
25232
25227
  const turnId = input2.turnId;
25233
25228
  let finish = () => {
25234
25229
  };
25235
- const done = new Promise((resolve6) => {
25230
+ const done = new Promise((resolve7) => {
25236
25231
  finish = (outcome2) => {
25237
25232
  if (this.#current?.id !== turnId) return;
25238
25233
  this.#current = void 0;
25239
25234
  if (this.#state === "busy") this.#state = "idle";
25240
25235
  this.#emit({ type: "turn_ended", turnId, outcome: outcome2 });
25241
- resolve6({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25236
+ resolve7({ turnId, outcome: outcome2, providerSessionId: this.#sessionId });
25242
25237
  };
25243
25238
  });
25244
25239
  const pending = {
@@ -25466,7 +25461,7 @@ var init_chunk_J2KTV5FP = __esm({
25466
25461
  }
25467
25462
  });
25468
25463
 
25469
- // ../agent-core/dist/chunk-ITTV3UIM.js
25464
+ // ../agent-core/dist/chunk-FPGAN4XO.js
25470
25465
  function truncate(value, limit) {
25471
25466
  const normalized2 = Array.from(value, (character) => {
25472
25467
  const code = character.charCodeAt(0);
@@ -25555,7 +25550,7 @@ function currentUserSection(user, visibility) {
25555
25550
  if (user.name) lines.push(`- **Name**: ${user.name}`);
25556
25551
  lines.push(`- **Email**: ${user.email}`, `- **User ID**: ${user.id}`, "");
25557
25552
  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."
25553
+ 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
25554
  );
25560
25555
  return lines.join("\n");
25561
25556
  }
@@ -25729,7 +25724,7 @@ function cloudExecutionSection(spec) {
25729
25724
  );
25730
25725
  if (!isReadOnlyMode(spec.mode) && !isReadOnlyAgent(spec.agentId)) {
25731
25726
  lines.push(
25732
- "Own the authorized work end to end: inspect context, make reasonable assumptions, implement, test, review and create or update the pull request for code changes when the repository workflow calls for one. Do not stop at a plan or ask for routine implementation choices or permission already granted. Ask only for a missing secret, an essential decision you cannot derive, or an action requiring explicit approval. Respect the user's scope, repository rules and tool authorization; report a blocked capability and continue independent work."
25727
+ "Own the authorized work end to end: inspect context, make reasonable assumptions, implement, test, review and create or update the pull request for code changes when the repository workflow calls for one. Do not stop at a plan or ask for routine implementation choices or permission already granted. For application changes, check the repository's setup instructions and configured start commands, start the app if needed, and verify it is reachable before testing. For user-facing flows, use alan-test-feature when installed to test the running app, capture a video, and create a test report. Ask only for a missing secret, an essential decision you cannot derive, or an action requiring explicit approval. Respect the user's scope, repository rules and tool authorization; report blocked capabilities and validation gaps while continuing independent work."
25733
25728
  );
25734
25729
  }
25735
25730
  const skills = spec.promptContext?.availableSkills ?? [];
@@ -25827,8 +25822,8 @@ ${body}` : body;
25827
25822
  return spec.mode === "plan" ? planModePrefix(prefixed) : prefixed;
25828
25823
  }
25829
25824
  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"() {
25825
+ var init_chunk_FPGAN4XO = __esm({
25826
+ "../agent-core/dist/chunk-FPGAN4XO.js"() {
25832
25827
  "use strict";
25833
25828
  init_agent2();
25834
25829
  MAX_PARSED_ATTACHMENTS = 3;
@@ -25944,6 +25939,7 @@ function buildClaudeArgs(input2) {
25944
25939
  ...capabilities.supportsThinkingDisplay ? ["--thinking-display", "summarized"] : [],
25945
25940
  // Without it the whole answer lands in one frame at turn end.
25946
25941
  ...capabilities.supportsPartialMessages ? ["--include-partial-messages"] : [],
25942
+ ...capabilities.supportsPluginDir ? (input2.pluginDirs ?? []).flatMap((dir) => ["--plugin-dir", dir]) : [],
25947
25943
  ...option("--resume", input2.resumeId),
25948
25944
  "--chrome",
25949
25945
  ...input2.extraArgs ?? []
@@ -25956,18 +25952,21 @@ function createClaudeCapabilityProbe(probe = createFlagProbe()) {
25956
25952
  supportsApproveMcps,
25957
25953
  supportsThinkingDisplay,
25958
25954
  supportsPartialMessages,
25959
- supportsReplayUserMessages
25955
+ supportsReplayUserMessages,
25956
+ supportsPluginDir
25960
25957
  ] = await Promise.all([
25961
25958
  needsApproveMcps ? probe.supportsFlag(command, "--approve-mcps", env) : false,
25962
25959
  probe.supportsHiddenChoiceFlag(command, "--thinking-display", env),
25963
25960
  probe.supportsFlag(command, "--include-partial-messages", env),
25964
- probe.supportsFlag(command, "--replay-user-messages", env)
25961
+ probe.supportsFlag(command, "--replay-user-messages", env),
25962
+ probe.supportsFlag(command, "--plugin-dir", env)
25965
25963
  ]);
25966
25964
  return {
25967
25965
  supportsApproveMcps,
25968
25966
  supportsThinkingDisplay,
25969
25967
  supportsPartialMessages,
25970
- supportsReplayUserMessages
25968
+ supportsReplayUserMessages,
25969
+ supportsPluginDir
25971
25970
  };
25972
25971
  }
25973
25972
  };
@@ -26855,6 +26854,7 @@ function planClaudeSession(run, context) {
26855
26854
  ...run.selectedEffortLevel === void 0 ? {} : { effortLevel: run.selectedEffortLevel },
26856
26855
  ...prompts.systemPrompt === void 0 ? {} : { systemPrompt: prompts.systemPrompt },
26857
26856
  ...prompts.systemPromptAppend === void 0 ? {} : { appendSystemPrompt: prompts.systemPromptAppend },
26857
+ ...context.pluginDirs?.length ? { pluginDirs: context.pluginDirs } : {},
26858
26858
  ...context.managedMcp === void 0 ? {} : {
26859
26859
  mcp: {
26860
26860
  alanMcpUrl: context.managedMcp.url,
@@ -26904,12 +26904,12 @@ var init_claude = __esm({
26904
26904
  "../agent-core/dist/providers/claude.js"() {
26905
26905
  "use strict";
26906
26906
  init_chunk_SBT5W7L4();
26907
- init_chunk_VMGVHPBB();
26907
+ init_chunk_72NSEYHK();
26908
26908
  init_chunk_XC5676SG();
26909
26909
  init_chunk_54ZRJOQP();
26910
26910
  init_chunk_J2KTV5FP();
26911
26911
  init_chunk_M6YHY2EZ();
26912
- init_chunk_ITTV3UIM();
26912
+ init_chunk_FPGAN4XO();
26913
26913
  init_chunk_YXWJW7I5();
26914
26914
  init_effort();
26915
26915
  import_crypto6 = require("crypto");
@@ -27632,8 +27632,8 @@ var init_claude = __esm({
27632
27632
  }
27633
27633
  async #awaitTaskStop(requestId, taskId) {
27634
27634
  const timer = new AbortController();
27635
- const answered = new Promise((resolve6) => {
27636
- this.#taskStops.set(requestId, resolve6);
27635
+ const answered = new Promise((resolve7) => {
27636
+ this.#taskStops.set(requestId, resolve7);
27637
27637
  });
27638
27638
  const timeoutMs = this.#options.stopTaskTimeoutMs;
27639
27639
  const timedOut = this.#options.clock.sleep(timeoutMs, timer.signal).then(
@@ -27706,17 +27706,17 @@ var init_claude = __esm({
27706
27706
  };
27707
27707
  let markStarted = () => {
27708
27708
  };
27709
- const whenStarted = new Promise((resolve6) => {
27710
- markStarted = resolve6;
27709
+ const whenStarted = new Promise((resolve7) => {
27710
+ markStarted = resolve7;
27711
27711
  });
27712
- const done = new Promise((resolve6) => {
27712
+ const done = new Promise((resolve7) => {
27713
27713
  finish = (outcome2) => {
27714
27714
  if (this.#current?.id !== id) return;
27715
27715
  this.#current = void 0;
27716
27716
  this.#lastTurn = turn;
27717
27717
  if (this.#state === "busy") this.#state = "idle";
27718
27718
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
27719
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27719
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#providerSessionId });
27720
27720
  };
27721
27721
  });
27722
27722
  const active = {
@@ -27834,8 +27834,8 @@ var init_claude = __esm({
27834
27834
  void removeLaunchFiles(this.#launchFiles).catch((error61) => {
27835
27835
  this.#options.log.warn("claude.launch_files_cleanup_failed", { error: error61 });
27836
27836
  });
27837
- for (const resolve6 of this.#taskStops.values()) {
27838
- resolve6({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27837
+ for (const resolve7 of this.#taskStops.values()) {
27838
+ resolve7({ ok: false, reason: "runtime_unavailable", message: "Claude Code exited." });
27839
27839
  }
27840
27840
  const active = this.#current;
27841
27841
  if (active) {
@@ -28089,7 +28089,7 @@ function elicitationAnswer(elicitation, answer) {
28089
28089
  return { action: "accept", content };
28090
28090
  }
28091
28091
  function inferImageMimeType(buffer) {
28092
- if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE)) return "image/png";
28092
+ if (buffer.length >= 8 && buffer.subarray(0, 8).equals(PNG_SIGNATURE2)) return "image/png";
28093
28093
  if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
28094
28094
  return "image/jpeg";
28095
28095
  }
@@ -29043,17 +29043,17 @@ function codexTurnInput(run, context) {
29043
29043
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
29044
29044
  };
29045
29045
  }
29046
- var import_fs6, import_path6, import_crypto8, import_crypto9, import_crypto10, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession;
29046
+ var import_fs6, import_path6, import_crypto8, import_crypto9, import_crypto10, TokenRefresher, MCP_STARTUP_TIMEOUT_SEC, FIELD_TYPES, YES_NO, ACCEPT_DECLINE, MAX_INLINE_GENERATED_IMAGE_BYTES, PNG_SIGNATURE2, JPEG_NON_FRAME_MARKERS, IMAGE_GEN_CALL, PROMPT_LITERAL, RELOCATE_EVERY_MS, CodexImageGenerationFold, CodexRolloutImages, USER_INPUT_METHOD, PERMISSIONS_METHOD, ELICITATION_METHOD, COMMAND_OR_FILE, LEGACY, DECISIONS, COORDINATION_TOOLS, SETTLED_AGENT, STATUS, CHANGE_OPERATIONS, SILENT_ON_START, IGNORED_ITEMS, PLAN_STATUS, WORKER_LIFECYCLE, INFO_KINDS, SILENT, CodexTurn, STDERR_TAIL_LINES3, MAX_BETWEEN_UPDATES, UNSUPPORTED_REQUEST, DECLINED_ELICITATION, IMAGE_CATCH_UP_MS, IMAGE_POLL_MS, CodexSession, CODEX_MIN_VERSION, CODEX_REQUIREMENT, CODEX_TESTED_LINE, DEFAULTS2, CLIENT_INFO, STATUS2, EXITED_WITHOUT_RESPONSE, CodexExecTurn, DEFAULTS22, CodexExecSession;
29047
29047
  var init_codex = __esm({
29048
29048
  "../agent-core/dist/providers/codex.js"() {
29049
29049
  "use strict";
29050
29050
  init_chunk_SBT5W7L4();
29051
- init_chunk_VMGVHPBB();
29051
+ init_chunk_72NSEYHK();
29052
29052
  init_chunk_XC5676SG();
29053
29053
  init_chunk_54ZRJOQP();
29054
29054
  init_chunk_J2KTV5FP();
29055
29055
  init_chunk_M6YHY2EZ();
29056
- init_chunk_ITTV3UIM();
29056
+ init_chunk_FPGAN4XO();
29057
29057
  init_chunk_YXWJW7I5();
29058
29058
  import_fs6 = require("fs");
29059
29059
  import_path6 = require("path");
@@ -29103,7 +29103,7 @@ var init_codex = __esm({
29103
29103
  ];
29104
29104
  ACCEPT_DECLINE = [{ label: "Accept" }, { label: "Decline" }];
29105
29105
  MAX_INLINE_GENERATED_IMAGE_BYTES = 20 * 1024 * 1024;
29106
- PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
29106
+ PNG_SIGNATURE2 = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
29107
29107
  JPEG_NON_FRAME_MARKERS = /* @__PURE__ */ new Set([196, 200, 204]);
29108
29108
  IMAGE_GEN_CALL = /\bimage_gen\w*\s*\(/;
29109
29109
  PROMPT_LITERAL = /\bprompt\s*:\s*("(?:[^"\\]|\\.)*")/;
@@ -29672,10 +29672,10 @@ var init_codex = __esm({
29672
29672
  };
29673
29673
  let identify = () => {
29674
29674
  };
29675
- const identified = new Promise((resolve6) => {
29676
- identify = resolve6;
29675
+ const identified = new Promise((resolve7) => {
29676
+ identify = resolve7;
29677
29677
  });
29678
- const done = new Promise((resolve6) => {
29678
+ const done = new Promise((resolve7) => {
29679
29679
  finish = (outcome2) => {
29680
29680
  if (this.#current?.id !== id) return;
29681
29681
  this.#current = void 0;
@@ -29683,7 +29683,7 @@ var init_codex = __esm({
29683
29683
  if (this.#state === "busy") this.#state = "idle";
29684
29684
  this.#host.scanDescendants(true);
29685
29685
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
29686
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29686
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#threadId });
29687
29687
  };
29688
29688
  });
29689
29689
  const active = {
@@ -30131,6 +30131,11 @@ function alanCodeConfigContent(existing, input2) {
30131
30131
  return JSON.stringify({
30132
30132
  $schema: "https://opencode.ai/config.json",
30133
30133
  ...config2,
30134
+ // OpenCode writes a whole working-tree diff into every user message summary and re-persists
30135
+ // the message on each update, so a large diff lands in the shared store many times over:
30136
+ // 3.4 GB of a dev machine's engine database was these patches, against 82 sessions. Alan
30137
+ // does not use the engine's undo/revert, so the tracking stays off.
30138
+ snapshot: false,
30134
30139
  model: `${ALAN_CODE_ENGINE_PROVIDER_ID}/${input2.modelId}`,
30135
30140
  enabled_providers: [ALAN_CODE_ENGINE_PROVIDER_ID],
30136
30141
  provider: {
@@ -30156,7 +30161,7 @@ function alanCodeConfigContent(existing, input2) {
30156
30161
  });
30157
30162
  }
30158
30163
  function readBody2(response) {
30159
- return new Promise((resolve6, reject) => {
30164
+ return new Promise((resolve7, reject) => {
30160
30165
  const chunks = [];
30161
30166
  let size = 0;
30162
30167
  response.on("data", (chunk) => {
@@ -30164,7 +30169,7 @@ function readBody2(response) {
30164
30169
  if (size > MAX_CATALOG_BYTES) response.destroy(new Error("catalog too large"));
30165
30170
  else chunks.push(chunk);
30166
30171
  });
30167
- response.on("end", () => resolve6(Buffer.concat(chunks).toString("utf8")));
30172
+ response.on("end", () => resolve7(Buffer.concat(chunks).toString("utf8")));
30168
30173
  response.on("error", reject);
30169
30174
  });
30170
30175
  }
@@ -30180,13 +30185,13 @@ function parseResponseBody(text2, status) {
30180
30185
  }
30181
30186
  function getJson(url2, headers, timeout, signal) {
30182
30187
  const request2 = url2.protocol === "https:" ? import_https.request : import_http3.request;
30183
- return new Promise((resolve6, reject) => {
30188
+ return new Promise((resolve7, reject) => {
30184
30189
  const outgoing = request2(url2, { method: "GET", headers, timeout, signal }, (response) => {
30185
30190
  const status = response.statusCode ?? 0;
30186
30191
  readBody2(response).then((text2) => {
30187
30192
  const body = parseResponseBody(text2, status);
30188
30193
  if (status < 200 || status >= 300) reject(new CatalogResponseError(status, body));
30189
- else resolve6(body);
30194
+ else resolve7(body);
30190
30195
  }).catch(reject);
30191
30196
  });
30192
30197
  outgoing.on("timeout", () => outgoing.destroy(new Error("catalog timed out")));
@@ -37817,7 +37822,7 @@ var require_dist = __commonJS({
37817
37822
  var init_dist = __esm({
37818
37823
  "../agent-core/dist/index.js"() {
37819
37824
  "use strict";
37820
- init_chunk_VMGVHPBB();
37825
+ init_chunk_72NSEYHK();
37821
37826
  init_chunk_XC5676SG();
37822
37827
  init_chunk_54ZRJOQP();
37823
37828
  init_chunk_M6YHY2EZ();
@@ -37912,7 +37917,7 @@ function within(root, path) {
37912
37917
  }
37913
37918
  async function resolveReal(path) {
37914
37919
  try {
37915
- return await (0, import_promises22.realpath)(path);
37920
+ return await (0, import_promises23.realpath)(path);
37916
37921
  } catch {
37917
37922
  const parent = (0, import_path9.dirname)(path);
37918
37923
  if (parent === path) return path;
@@ -37941,14 +37946,14 @@ function createWorkspaceFs(roots, writable) {
37941
37946
  return {
37942
37947
  read: async (params) => {
37943
37948
  const path = await confined(params);
37944
- const bytes = await (0, import_promises22.readFile)(path);
37949
+ const bytes = await (0, import_promises23.readFile)(path);
37945
37950
  if (bytes.byteLength > MAX_READ_BYTES) throw new FsDenied(`${path} is too large to read`);
37946
37951
  return { content: sliceLines(bytes.toString("utf8"), params) };
37947
37952
  },
37948
37953
  write: async (params) => {
37949
37954
  if (!writable) throw new FsDenied("This session is read-only");
37950
37955
  const path = await confined(params);
37951
- await (0, import_promises22.writeFile)(path, asString(params.content));
37956
+ await (0, import_promises23.writeFile)(path, asString(params.content));
37952
37957
  return {};
37953
37958
  }
37954
37959
  };
@@ -38551,7 +38556,7 @@ async function acpTurnInput(run, context) {
38551
38556
  const encoded = await Promise.all(
38552
38557
  images.map(async (image) => ({
38553
38558
  mimeType: image.mimeType,
38554
- data: (await (0, import_promises23.readFile)(image.path)).toString("base64")
38559
+ data: (await (0, import_promises24.readFile)(image.path)).toString("base64")
38555
38560
  }))
38556
38561
  );
38557
38562
  return {
@@ -38560,23 +38565,23 @@ async function acpTurnInput(run, context) {
38560
38565
  ...encoded.length ? { images: encoded, imagePaths: images.map((image) => image.path) } : {}
38561
38566
  };
38562
38567
  }
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;
38568
+ 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
38569
  var init_acp3 = __esm({
38565
38570
  "../agent-core/dist/providers/acp.js"() {
38566
38571
  "use strict";
38567
- init_chunk_VMGVHPBB();
38572
+ init_chunk_72NSEYHK();
38568
38573
  init_chunk_XC5676SG();
38569
38574
  init_chunk_54ZRJOQP();
38570
38575
  init_chunk_J2KTV5FP();
38571
38576
  init_chunk_M6YHY2EZ();
38572
- init_chunk_ITTV3UIM();
38577
+ init_chunk_FPGAN4XO();
38573
38578
  init_chunk_YXWJW7I5();
38574
- import_promises22 = require("fs/promises");
38579
+ import_promises23 = require("fs/promises");
38575
38580
  import_path9 = require("path");
38576
38581
  init_effort();
38577
38582
  init_acp();
38578
38583
  import_crypto12 = require("crypto");
38579
- import_promises23 = require("fs/promises");
38584
+ import_promises24 = require("fs/promises");
38580
38585
  init_agent2();
38581
38586
  CURSOR_ASK_QUESTION = "cursor/ask_question";
38582
38587
  copilotAcpProfile = {
@@ -39092,7 +39097,7 @@ var init_acp3 = __esm({
39092
39097
  const turn = new AcpTurn(`acp-${this.#turns}-${id}`, this.#profile);
39093
39098
  let finish = () => {
39094
39099
  };
39095
- const done = new Promise((resolve6) => {
39100
+ const done = new Promise((resolve7) => {
39096
39101
  finish = (outcome2) => {
39097
39102
  if (this.#current?.id !== id) return;
39098
39103
  this.#current = void 0;
@@ -39100,7 +39105,7 @@ var init_acp3 = __esm({
39100
39105
  if (this.#state === "busy") this.#state = "idle";
39101
39106
  this.#host.scanDescendants(true);
39102
39107
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
39103
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39108
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
39104
39109
  };
39105
39110
  });
39106
39111
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -39796,10 +39801,14 @@ function openCodeConfigContent(input2) {
39796
39801
  enabled: true
39797
39802
  };
39798
39803
  }
39804
+ const skills = asRecord(config2.skills) ?? {};
39805
+ const ownPaths = Array.isArray(skills.paths) ? skills.paths : [];
39806
+ const skillPaths = input2.skillPaths ?? [];
39799
39807
  return JSON.stringify({
39800
39808
  ...config2,
39801
39809
  ...input2.readOnly ? {} : { permission: "allow" },
39802
- ...Object.keys(mcp).length ? { mcp } : {}
39810
+ ...Object.keys(mcp).length ? { mcp } : {},
39811
+ ...skillPaths.length ? { skills: { ...skills, paths: [...ownPaths, ...skillPaths] } } : {}
39803
39812
  });
39804
39813
  }
39805
39814
  function storedParts(message) {
@@ -40094,7 +40103,7 @@ async function sameDirectory(left, right) {
40094
40103
  }
40095
40104
  async function canonicalDirectory(directory) {
40096
40105
  try {
40097
- return await (0, import_promises24.realpath)(directory);
40106
+ return await (0, import_promises25.realpath)(directory);
40098
40107
  } catch {
40099
40108
  return (0, import_path10.resolve)(directory);
40100
40109
  }
@@ -40119,6 +40128,57 @@ async function openSession(session, client, spec, log) {
40119
40128
  const id = await client.createSession({ title: spec.title, permission: NON_INTERACTIVE_RULES });
40120
40129
  return { id, resumed: false };
40121
40130
  }
40131
+ function isOpenTimeout(error61) {
40132
+ return error61 instanceof CoreFault && error61.code === "protocol_violation";
40133
+ }
40134
+ async function openOnce(spec, password, options) {
40135
+ const attempt = { abandoned: false };
40136
+ const { session, url: url2 } = await withDeadline3(
40137
+ startServer(spec, password, options, attempt),
40138
+ options.clock,
40139
+ options.openTimeoutMs,
40140
+ "report a listening URL"
40141
+ ).catch(async (error61) => {
40142
+ attempt.abandoned = true;
40143
+ await attempt.current?.suspend().catch(() => void 0);
40144
+ throw error61;
40145
+ });
40146
+ try {
40147
+ const client = new OpenCodeClient(url2, password, options.engine.label);
40148
+ const opened = await withDeadline3(
40149
+ openSession(session, client, spec, options.log),
40150
+ options.clock,
40151
+ options.openTimeoutMs,
40152
+ "open a session"
40153
+ );
40154
+ session.attach(
40155
+ opened.id,
40156
+ spec.prompt,
40157
+ expiredSignInNotices(spec.env, options.clock.now()),
40158
+ opened.resumed
40159
+ );
40160
+ } catch (error61) {
40161
+ await session.suspend().catch(() => void 0);
40162
+ throw error61;
40163
+ }
40164
+ options.log.info("opencode.opened", {
40165
+ pid: session.pid,
40166
+ sessionId: session.providerSessionId,
40167
+ resumeFailed: session.resumeFailed
40168
+ });
40169
+ return session;
40170
+ }
40171
+ async function openWithRetries(spec, password, options) {
40172
+ for (let tries = 1; ; tries += 1) {
40173
+ try {
40174
+ return await openOnce(spec, password, options);
40175
+ } catch (error61) {
40176
+ if (!isOpenTimeout(error61) || tries >= options.openAttempts) throw error61;
40177
+ options.log.warn("opencode.open_retry", { tries });
40178
+ await options.clock.sleep(options.reconnectDelayMs);
40179
+ }
40180
+ }
40181
+ }
40122
40182
  function createOpenCodeDriver(options = {}) {
40123
40183
  const resolved = {
40124
40184
  clock: options.clock ?? systemClock2,
@@ -40128,6 +40188,7 @@ function createOpenCodeDriver(options = {}) {
40128
40188
  stdoutDrainMs: options.stdoutDrainMs ?? DEFAULTS4.stdoutDrainMs,
40129
40189
  descendantScanMs: options.descendantScanMs ?? DEFAULTS4.descendantScanMs,
40130
40190
  openTimeoutMs: options.openTimeoutMs ?? DEFAULTS4.openTimeoutMs,
40191
+ openAttempts: options.openAttempts ?? DEFAULTS4.openAttempts,
40131
40192
  startAttempts: options.startAttempts ?? DEFAULTS4.startAttempts,
40132
40193
  reconnectAttempts: options.reconnectAttempts ?? DEFAULTS4.reconnectAttempts,
40133
40194
  reconnectDelayMs: options.reconnectDelayMs ?? DEFAULTS4.reconnectDelayMs,
@@ -40143,45 +40204,16 @@ function createOpenCodeDriver(options = {}) {
40143
40204
  };
40144
40205
  const spec = { ...planned, env: launchEnv(planned, authorization) };
40145
40206
  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
40207
  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
- );
40208
+ const session = await openWithRetries(spec, password, resolved);
40209
+ void session.exited.then(removeAuthorization).catch((error61) => {
40210
+ resolved.log.warn("opencode.authorization_cleanup_failed", { error: error61 });
40211
+ });
40212
+ return session;
40175
40213
  } catch (error61) {
40176
- await session.suspend().catch(() => void 0);
40214
+ await removeAuthorization();
40177
40215
  throw error61;
40178
40216
  }
40179
- resolved.log.info("opencode.opened", {
40180
- pid: session.pid,
40181
- sessionId: session.providerSessionId,
40182
- resumeFailed: session.resumeFailed
40183
- });
40184
- return session;
40185
40217
  }
40186
40218
  };
40187
40219
  }
@@ -40214,6 +40246,7 @@ function planOpenCodeSession(run, context) {
40214
40246
  const config2 = {
40215
40247
  existing: baseEnv[OPENCODE_CONFIG_ENV],
40216
40248
  readOnly,
40249
+ ...context.skillPaths?.length ? { skillPaths: context.skillPaths } : {},
40217
40250
  mcp: {
40218
40251
  conversationId: run.conversationId,
40219
40252
  externalServers: mcp.servers,
@@ -40266,21 +40299,21 @@ function openCodeTurnInput(run, context) {
40266
40299
  ...images.length ? { imagePaths: images.map((image) => image.path) } : {}
40267
40300
  };
40268
40301
  }
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;
40302
+ 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
40303
  var init_opencode = __esm({
40271
40304
  "../agent-core/dist/providers/opencode.js"() {
40272
40305
  "use strict";
40273
- init_chunk_VMGVHPBB();
40306
+ init_chunk_72NSEYHK();
40274
40307
  init_chunk_XC5676SG();
40275
40308
  init_chunk_54ZRJOQP();
40276
40309
  init_chunk_J2KTV5FP();
40277
40310
  init_chunk_M6YHY2EZ();
40278
- init_chunk_ITTV3UIM();
40311
+ init_chunk_FPGAN4XO();
40279
40312
  init_chunk_YXWJW7I5();
40280
40313
  import_http4 = require("http");
40281
40314
  init_runtime_v2();
40282
40315
  import_crypto13 = require("crypto");
40283
- import_promises24 = require("fs/promises");
40316
+ import_promises25 = require("fs/promises");
40284
40317
  import_path10 = require("path");
40285
40318
  init_agent2();
40286
40319
  import_path11 = require("path");
@@ -41366,6 +41399,7 @@ var init_opencode = __esm({
41366
41399
  stdoutDrainMs: 2e3,
41367
41400
  descendantScanMs: 5e3,
41368
41401
  openTimeoutMs: 6e4,
41402
+ openAttempts: 2,
41369
41403
  startAttempts: 3,
41370
41404
  reconnectAttempts: 3,
41371
41405
  reconnectDelayMs: 500,
@@ -41444,6 +41478,7 @@ function createAlanCodeHolderDriver(options) {
41444
41478
  engineRoot,
41445
41479
  requestedModel: spec.model
41446
41480
  };
41481
+ const skills = options.installedSkills?.() ?? null;
41447
41482
  const planned = planOpenCodeSession(spec, {
41448
41483
  command: engine.command,
41449
41484
  cwd: spec.projectPath ?? options.defaultCwd,
@@ -41453,7 +41488,8 @@ function createAlanCodeHolderDriver(options) {
41453
41488
  },
41454
41489
  providerEnv: inputs.providerEnv,
41455
41490
  ...managedMcp === void 0 ? {} : { managedMcp },
41456
- ...resumeId === void 0 ? {} : { resumeSessionId: resumeId }
41491
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
41492
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
41457
41493
  });
41458
41494
  return {
41459
41495
  spec: { opencode: planned.spec, profile },
@@ -41504,14 +41540,18 @@ function createClaudeHolderDriver(options) {
41504
41540
  {
41505
41541
  harness: "claude_cli",
41506
41542
  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
- }),
41543
+ plan: (spec, inputs, resumeId, managedMcp) => {
41544
+ const skills = options.installedSkills?.() ?? null;
41545
+ return planClaudeSession(spec, {
41546
+ command: options.command ?? "claude",
41547
+ cwd: spec.projectPath ?? options.defaultCwd,
41548
+ cliEnv: options.cliEnvironment,
41549
+ providerEnv: inputs.providerEnv,
41550
+ ...managedMcp === void 0 ? {} : { managedMcp },
41551
+ ...resumeId === void 0 ? {} : { resumeId },
41552
+ ...skills === null ? {} : { pluginDirs: [skills.pluginDir] }
41553
+ });
41554
+ },
41515
41555
  canResume: (planned, resumeId) => claudeSessionLogExists({
41516
41556
  sessionId: resumeId,
41517
41557
  cwd: planned.spec.cwd,
@@ -41548,7 +41588,7 @@ __export(codex_exports, {
41548
41588
  createCodexHolderDriver: () => createCodexHolderDriver
41549
41589
  });
41550
41590
  function sha2562(value) {
41551
- return (0, import_node_crypto12.createHash)("sha256").update(value).digest("hex");
41591
+ return (0, import_node_crypto13.createHash)("sha256").update(value).digest("hex");
41552
41592
  }
41553
41593
  function createCodexLogin(broker) {
41554
41594
  const state = {};
@@ -41623,11 +41663,11 @@ function createCodexHolderDriver(options) {
41623
41663
  }
41624
41664
  );
41625
41665
  }
41626
- var import_node_crypto12;
41666
+ var import_node_crypto13;
41627
41667
  var init_codex2 = __esm({
41628
41668
  "src/holder/drivers/codex.ts"() {
41629
41669
  "use strict";
41630
- import_node_crypto12 = require("crypto");
41670
+ import_node_crypto13 = require("crypto");
41631
41671
  init_dist();
41632
41672
  init_codex();
41633
41673
  init_persistent();
@@ -41734,8 +41774,8 @@ function createDroidPeer(writer, handlers) {
41734
41774
  },
41735
41775
  request: (method, params = {}) => {
41736
41776
  const id = `alan-${counter.next++}`;
41737
- return new Promise((resolve6, reject) => {
41738
- pending.set(id, { method, resolve: resolve6, reject });
41777
+ return new Promise((resolve7, reject) => {
41778
+ pending.set(id, { method, resolve: resolve7, reject });
41739
41779
  writer.write(envelope("request", { id, method, params })).catch((error61) => {
41740
41780
  pending.delete(id);
41741
41781
  reject(error61 instanceof Error ? error61 : new Error(String(error61)));
@@ -42070,25 +42110,25 @@ async function droidTurnInput(run, context) {
42070
42110
  const encoded = await Promise.all(
42071
42111
  images.map(async (image) => ({
42072
42112
  mimeType: image.mimeType,
42073
- data: (await (0, import_promises25.readFile)(image.path)).toString("base64")
42113
+ data: (await (0, import_promises26.readFile)(image.path)).toString("base64")
42074
42114
  }))
42075
42115
  );
42076
42116
  return { turnId: run.runId, text: text2, ...encoded.length ? { images: encoded } : {} };
42077
42117
  }
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;
42118
+ 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
42119
  var init_droid = __esm({
42080
42120
  "../agent-core/dist/providers/droid.js"() {
42081
42121
  "use strict";
42082
- init_chunk_VMGVHPBB();
42122
+ init_chunk_72NSEYHK();
42083
42123
  init_chunk_XC5676SG();
42084
42124
  init_chunk_54ZRJOQP();
42085
42125
  init_chunk_J2KTV5FP();
42086
42126
  init_chunk_M6YHY2EZ();
42087
- init_chunk_ITTV3UIM();
42127
+ init_chunk_FPGAN4XO();
42088
42128
  init_chunk_YXWJW7I5();
42089
42129
  init_runtime_v2();
42090
42130
  import_crypto15 = require("crypto");
42091
- import_promises25 = require("fs/promises");
42131
+ import_promises26 = require("fs/promises");
42092
42132
  init_agent2();
42093
42133
  FACTORY_API_VERSION = "1.0.0";
42094
42134
  FACTORY_PROTOCOL_VERSION = "1.187.0";
@@ -42360,14 +42400,14 @@ var init_droid = __esm({
42360
42400
  const turn = new DroidTurn(sessionId, this.#memory);
42361
42401
  let finish = () => {
42362
42402
  };
42363
- const done = new Promise((resolve6) => {
42403
+ const done = new Promise((resolve7) => {
42364
42404
  finish = (outcome2) => {
42365
42405
  if (this.#current?.id !== id) return;
42366
42406
  this.#current = void 0;
42367
42407
  if (this.#state === "busy") this.#state = "idle";
42368
42408
  this.#host.scanDescendants(true);
42369
42409
  this.#emit({ type: "turn_ended", turnId: id, outcome: outcome2 });
42370
- resolve6({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42410
+ resolve7({ turnId: id, outcome: outcome2, providerSessionId: this.#sessionId });
42371
42411
  };
42372
42412
  });
42373
42413
  const active = { id, turn, done, finish, cancelRequested: false };
@@ -42515,14 +42555,18 @@ function createOpenCodeHolderDriver(options) {
42515
42555
  {
42516
42556
  harness: "opencode_serve",
42517
42557
  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
- }),
42558
+ plan: (spec, inputs, resumeId, managedMcp) => {
42559
+ const skills = options.installedSkills?.() ?? null;
42560
+ return planOpenCodeSession(spec, {
42561
+ command: options.command ?? "opencode",
42562
+ cwd: spec.projectPath ?? options.defaultCwd,
42563
+ cliEnv: options.cliEnvironment,
42564
+ providerEnv: inputs.providerEnv,
42565
+ ...managedMcp === void 0 ? {} : { managedMcp },
42566
+ ...resumeId === void 0 ? {} : { resumeSessionId: resumeId },
42567
+ ...skills === null ? {} : { skillPaths: [skills.skillsDir] }
42568
+ });
42569
+ },
42526
42570
  canResume: () => true,
42527
42571
  open: async (spec) => {
42528
42572
  const session = await sessions.open(spec);
@@ -42559,7 +42603,7 @@ function settingsPath(env) {
42559
42603
  async function readSettings(path) {
42560
42604
  let raw;
42561
42605
  try {
42562
- raw = (await (0, import_promises26.readFile)(path, "utf8")).trim();
42606
+ raw = (await (0, import_promises27.readFile)(path, "utf8")).trim();
42563
42607
  } catch {
42564
42608
  return {};
42565
42609
  }
@@ -42577,8 +42621,8 @@ async function selectAntigravityApiKeyMode(env) {
42577
42621
  const settings2 = await readSettings(path);
42578
42622
  if (settings2 === "malformed") return "malformed";
42579
42623
  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 });
42624
+ await (0, import_promises27.mkdir)((0, import_path12.dirname)(path), { recursive: true });
42625
+ await (0, import_promises27.writeFile)(path, JSON.stringify({ ...settings2, modelProvider: "gemini" }), { mode: 384 });
42582
42626
  return "selected";
42583
42627
  }
42584
42628
  function readAntigravityCapabilities(version2, help) {
@@ -43177,18 +43221,18 @@ function antigravityTurnInput(run, context) {
43177
43221
  });
43178
43222
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43179
43223
  }
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;
43224
+ 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
43225
  var init_antigravity = __esm({
43182
43226
  "../agent-core/dist/providers/antigravity.js"() {
43183
43227
  "use strict";
43184
43228
  init_chunk_SBT5W7L4();
43185
- init_chunk_VMGVHPBB();
43229
+ init_chunk_72NSEYHK();
43186
43230
  init_chunk_XC5676SG();
43187
43231
  init_chunk_54ZRJOQP();
43188
43232
  init_chunk_M6YHY2EZ();
43189
- init_chunk_ITTV3UIM();
43233
+ init_chunk_FPGAN4XO();
43190
43234
  init_chunk_YXWJW7I5();
43191
- import_promises26 = require("fs/promises");
43235
+ import_promises27 = require("fs/promises");
43192
43236
  import_path12 = require("path");
43193
43237
  init_type_guards();
43194
43238
  import_fs8 = require("fs");
@@ -43688,7 +43732,7 @@ function parseConfig(raw) {
43688
43732
  }
43689
43733
  async function writeCommandCodeProjectMcp(cwd, mcp) {
43690
43734
  const path = (0, import_path15.join)(cwd, ".mcp.json");
43691
- const original = await (0, import_promises27.readFile)(path, "utf8").catch(() => null);
43735
+ const original = await (0, import_promises28.readFile)(path, "utf8").catch(() => null);
43692
43736
  const config2 = parseConfig(original);
43693
43737
  const next = {
43694
43738
  ...config2,
@@ -43705,12 +43749,12 @@ async function writeCommandCodeProjectMcp(cwd, mcp) {
43705
43749
  }
43706
43750
  }
43707
43751
  };
43708
- await (0, import_promises27.mkdir)(cwd, { recursive: true });
43709
- await (0, import_promises27.writeFile)(path, `${JSON.stringify(next, null, 2)}
43752
+ await (0, import_promises28.mkdir)(cwd, { recursive: true });
43753
+ await (0, import_promises28.writeFile)(path, `${JSON.stringify(next, null, 2)}
43710
43754
  `);
43711
43755
  return async () => {
43712
- if (original === null) await (0, import_promises27.rm)(path, { force: true });
43713
- else await (0, import_promises27.writeFile)(path, original);
43756
+ if (original === null) await (0, import_promises28.rm)(path, { force: true });
43757
+ else await (0, import_promises28.writeFile)(path, original);
43714
43758
  };
43715
43759
  }
43716
43760
  function commandCodeString(value) {
@@ -43882,18 +43926,18 @@ function commandCodeTurnInput(run, context) {
43882
43926
  });
43883
43927
  return { turnId: run.runId, text: appendImagePathReferences(text2, images) };
43884
43928
  }
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;
43929
+ 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
43930
  var init_command_code = __esm({
43887
43931
  "../agent-core/dist/providers/command-code.js"() {
43888
43932
  "use strict";
43889
- init_chunk_VMGVHPBB();
43933
+ init_chunk_72NSEYHK();
43890
43934
  init_chunk_XC5676SG();
43891
43935
  init_chunk_54ZRJOQP();
43892
43936
  init_chunk_J2KTV5FP();
43893
43937
  init_chunk_M6YHY2EZ();
43894
- init_chunk_ITTV3UIM();
43938
+ init_chunk_FPGAN4XO();
43895
43939
  init_chunk_YXWJW7I5();
43896
- import_promises27 = require("fs/promises");
43940
+ import_promises28 = require("fs/promises");
43897
43941
  import_path15 = require("path");
43898
43942
  init_agent2();
43899
43943
  init_runtime_v2();
@@ -44755,7 +44799,7 @@ function transportFailure(request2, error61) {
44755
44799
  });
44756
44800
  }
44757
44801
  function readBody(incoming, url2, maxBytes) {
44758
- return new Promise((resolve6, reject) => {
44802
+ return new Promise((resolve7, reject) => {
44759
44803
  const declared = Number(incoming.headers["content-length"] ?? "0");
44760
44804
  if (maxBytes !== void 0 && declared > maxBytes) {
44761
44805
  incoming.destroy();
@@ -44774,7 +44818,7 @@ function readBody(incoming, url2, maxBytes) {
44774
44818
  chunks.push(chunk);
44775
44819
  });
44776
44820
  incoming.on("error", reject);
44777
- incoming.on("end", () => resolve6(Buffer.concat(chunks)));
44821
+ incoming.on("end", () => resolve7(Buffer.concat(chunks)));
44778
44822
  });
44779
44823
  }
44780
44824
  function isConnectionReset(error61) {
@@ -44782,7 +44826,7 @@ function isConnectionReset(error61) {
44782
44826
  }
44783
44827
  function exchange(request2, agents, attempt = 0) {
44784
44828
  const { signal, url: url2 } = request2;
44785
- return new Promise((resolve6, reject) => {
44829
+ return new Promise((resolve7, reject) => {
44786
44830
  if (signal.aborted) {
44787
44831
  reject(signal.reason);
44788
44832
  return;
@@ -44809,7 +44853,7 @@ function exchange(request2, agents, attempt = 0) {
44809
44853
  const stale = outgoing.reusedSocket && !responded && isConnectionReset(error61);
44810
44854
  if (stale && attempt < STALE_SOCKET_RETRIES && !signal.aborted) {
44811
44855
  settle();
44812
- resolve6(exchange(request2, agents, attempt + 1));
44856
+ resolve7(exchange(request2, agents, attempt + 1));
44813
44857
  return;
44814
44858
  }
44815
44859
  fail(error61);
@@ -44822,7 +44866,7 @@ function exchange(request2, agents, attempt = 0) {
44822
44866
  readBody(incoming, url2, isRedirect(status) ? void 0 : request2.maxBodyBytes).then(
44823
44867
  (body) => {
44824
44868
  settle();
44825
- resolve6({ status, headers: incoming.headers, body });
44869
+ resolve7({ status, headers: incoming.headers, body });
44826
44870
  },
44827
44871
  fail
44828
44872
  );
@@ -45111,7 +45155,7 @@ function createGitRunner(options) {
45111
45155
  }
45112
45156
  await killProcessTree(child.pid, { signal: "SIGKILL", child, platform });
45113
45157
  };
45114
- return new Promise((resolve6, reject) => {
45158
+ return new Promise((resolve7, reject) => {
45115
45159
  let ending = null;
45116
45160
  const stop = (next) => {
45117
45161
  if (ending !== null) return;
@@ -45136,7 +45180,7 @@ function createGitRunner(options) {
45136
45180
  signal.removeEventListener("abort", onAbort);
45137
45181
  const final = ending ?? last;
45138
45182
  if (final.kind === "exited") {
45139
- resolve6({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45183
+ resolve7({ exitCode: final.exitCode, stdout: stdout.text(), stderr: stderr.text() });
45140
45184
  } else {
45141
45185
  reject(faultFor(final, command));
45142
45186
  }
@@ -45636,7 +45680,7 @@ function statusOf(error61) {
45636
45680
  }
45637
45681
  return 1;
45638
45682
  }
45639
- var systemExec = (request2) => new Promise((resolve6) => {
45683
+ var systemExec = (request2) => new Promise((resolve7) => {
45640
45684
  const child = (0, import_node_child_process5.execFile)(
45641
45685
  request2.command,
45642
45686
  [...request2.args],
@@ -45647,7 +45691,7 @@ var systemExec = (request2) => new Promise((resolve6) => {
45647
45691
  windowsHide: true
45648
45692
  },
45649
45693
  (error61, stdout, stderr) => {
45650
- resolve6({ status: statusOf(error61), stdout, stderr });
45694
+ resolve7({ status: statusOf(error61), stdout, stderr });
45651
45695
  }
45652
45696
  );
45653
45697
  child.stdin?.on("error", () => {
@@ -45925,10 +45969,10 @@ function createIgnoreMatcher(path) {
45925
45969
  const expression = globToRegExp(pattern);
45926
45970
  return (candidate) => expression.test(candidate) || expression.test(`${candidate}/`);
45927
45971
  }
45928
- function isIgnored(normalizedPath, basename6, isDirectory2, configured) {
45929
- if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename6))
45972
+ function isIgnored(normalizedPath, basename7, isDirectory2, configured) {
45973
+ if (isDirectory2 && ALWAYS_IGNORED_DIRECTORIES.has(basename7))
45930
45974
  return true;
45931
- if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename6))
45975
+ if (!isDirectory2 && ALWAYS_IGNORED_FILES.has(basename7))
45932
45976
  return true;
45933
45977
  return configured.some((matches) => matches(normalizedPath));
45934
45978
  }
@@ -46199,9 +46243,12 @@ function skillsLayout(stateDir, home) {
46199
46243
  return {
46200
46244
  root,
46201
46245
  installedFile: (0, import_node_path11.join)(root, "installed.json"),
46246
+ retiredFile: (0, import_node_path11.join)(root, "retired.json"),
46202
46247
  localFile: (0, import_node_path11.join)(root, "local.json"),
46203
46248
  versionsDir: (0, import_node_path11.join)(root, "versions"),
46204
46249
  tmpDir: (0, import_node_path11.join)(root, "tmp"),
46250
+ pluginDir: (0, import_node_path11.join)(root, "alan-plugin"),
46251
+ pluginSkillsDir: (0, import_node_path11.join)(root, "alan-plugin", "skills"),
46205
46252
  nativeDir: home === void 0 || home === "" ? null : (0, import_node_path11.join)(home, ".agents", "skills")
46206
46253
  };
46207
46254
  }
@@ -46318,12 +46365,19 @@ async function availableSkillIndex(layout) {
46318
46365
  candidates2.push({ directory: (0, import_node_path11.join)(layout.nativeDir, entry.name) });
46319
46366
  }
46320
46367
  }
46321
- for (const candidate of candidates2.slice(0, 2e3)) {
46322
- const skill = await inspectIndexedSkill(candidate.directory, candidate.contentHash);
46323
- if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
46368
+ const bounded = candidates2.slice(0, 2e3);
46369
+ for (let start = 0; start < bounded.length; start += INDEX_CONCURRENCY) {
46370
+ const batch = bounded.slice(start, start + INDEX_CONCURRENCY);
46371
+ const inspected = await Promise.all(
46372
+ batch.map((candidate) => inspectIndexedSkill(candidate.directory, candidate.contentHash))
46373
+ );
46374
+ for (const skill of inspected) {
46375
+ if (skill !== null && !found.has(skill.name)) found.set(skill.name, skill);
46376
+ }
46324
46377
  }
46325
46378
  return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
46326
46379
  }
46380
+ var INDEX_CONCURRENCY = 8;
46327
46381
  async function inspectIndexedSkill(directory, contentHash) {
46328
46382
  try {
46329
46383
  const inspected = await inspectSkillPackage(directory, { expectedName: null });
@@ -46335,15 +46389,34 @@ async function inspectIndexedSkill(directory, contentHash) {
46335
46389
  }
46336
46390
  }
46337
46391
 
46392
+ // src/capabilities/skills/native-index.ts
46393
+ var import_node_crypto10 = require("crypto");
46394
+ var import_node_fs7 = require("fs");
46395
+ var import_promises20 = require("fs/promises");
46396
+ var import_node_path12 = require("path");
46397
+ var ALAN_SKILLS_PLUGIN_NAME = "alan";
46398
+ var PLUGIN_MANIFEST = `${JSON.stringify(
46399
+ {
46400
+ name: ALAN_SKILLS_PLUGIN_NAME,
46401
+ description: "Skills Alan installed on this machine for you and your team."
46402
+ },
46403
+ null,
46404
+ 2
46405
+ )}
46406
+ `;
46407
+ function installedSkillFolders(layout) {
46408
+ return (0, import_node_fs7.existsSync)((0, import_node_path12.join)(layout.pluginDir, ".claude-plugin", "plugin.json")) ? { pluginDir: layout.pluginDir, skillsDir: layout.pluginSkillsDir } : null;
46409
+ }
46410
+
46338
46411
  // src/capabilities/workspace/index.ts
46339
- var import_node_path14 = require("path");
46412
+ var import_node_path15 = require("path");
46340
46413
 
46341
46414
  // src/capabilities/workspace/approved-paths.ts
46342
- var import_promises20 = require("fs/promises");
46415
+ var import_promises21 = require("fs/promises");
46343
46416
  init_zod();
46344
46417
 
46345
46418
  // src/capabilities/workspace/paths.ts
46346
- var import_node_path12 = require("path");
46419
+ var import_node_path13 = require("path");
46347
46420
  function stripWin32Namespace(path) {
46348
46421
  if (/^\\\\\?\\UNC\\/i.test(path)) return `\\\\${path.slice(8)}`;
46349
46422
  if (path.startsWith("\\\\?\\")) return path.slice(4);
@@ -46351,15 +46424,15 @@ function stripWin32Namespace(path) {
46351
46424
  }
46352
46425
  function comparablePath(path, platform) {
46353
46426
  if (platform === "win32") {
46354
- const normalized3 = import_node_path12.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46427
+ const normalized3 = import_node_path13.win32.normalize(stripWin32Namespace(path).replaceAll("/", "\\"));
46355
46428
  const trimmed4 = normalized3.length > 3 || !/^[a-z]:\\$/i.test(normalized3) ? normalized3.replace(/\\+$/, "") : normalized3;
46356
46429
  return trimmed4.toLowerCase();
46357
46430
  }
46358
- const normalized2 = import_node_path12.posix.normalize(path);
46431
+ const normalized2 = import_node_path13.posix.normalize(path);
46359
46432
  return normalized2.length > 1 ? normalized2.replace(/\/+$/, "") : normalized2;
46360
46433
  }
46361
46434
  function isAbsoluteFor(path, platform) {
46362
- return platform === "win32" ? import_node_path12.win32.isAbsolute(path) : import_node_path12.posix.isAbsolute(path);
46435
+ return platform === "win32" ? import_node_path13.win32.isAbsolute(path) : import_node_path13.posix.isAbsolute(path);
46363
46436
  }
46364
46437
  function isWithin(root, candidate, platform) {
46365
46438
  const separator = platform === "win32" ? "\\" : "/";
@@ -46377,7 +46450,7 @@ var storeSchema = external_exports.object({
46377
46450
  });
46378
46451
  async function realpathOrNull(path) {
46379
46452
  try {
46380
- return await (0, import_promises20.realpath)(path);
46453
+ return await (0, import_promises21.realpath)(path);
46381
46454
  } catch (error61) {
46382
46455
  const code = errnoCode(error61);
46383
46456
  if (code === "ENOENT" || code === "ENOTDIR" || code === "EACCES" || code === "EPERM") {
@@ -46436,9 +46509,9 @@ async function openApprovedPaths(options) {
46436
46509
  }
46437
46510
 
46438
46511
  // src/capabilities/workspace/locks.ts
46439
- var import_node_crypto10 = require("crypto");
46440
- var import_promises21 = require("fs/promises");
46441
- var import_node_path13 = require("path");
46512
+ var import_node_crypto11 = require("crypto");
46513
+ var import_promises22 = require("fs/promises");
46514
+ var import_node_path14 = require("path");
46442
46515
  init_zod();
46443
46516
  var LOCK_FORMAT = 1;
46444
46517
  var EXCLUSIVE_FILE = "exclusive.json";
@@ -46453,12 +46526,12 @@ var ownerSchema = external_exports.object({
46453
46526
  since: external_exports.number().int().nonnegative()
46454
46527
  });
46455
46528
  function repositoryLockKey(commonDir, platform) {
46456
- return (0, import_node_crypto10.createHash)("sha256").update(comparablePath(commonDir, platform)).digest("hex").slice(0, 32);
46529
+ return (0, import_node_crypto11.createHash)("sha256").update(comparablePath(commonDir, platform)).digest("hex").slice(0, 32);
46457
46530
  }
46458
46531
  async function readOwner(path) {
46459
46532
  let text2;
46460
46533
  try {
46461
- text2 = await (0, import_promises21.readFile)(path, "utf8");
46534
+ text2 = await (0, import_promises22.readFile)(path, "utf8");
46462
46535
  } catch (error61) {
46463
46536
  if (errnoCode(error61) === "ENOENT") return { kind: "missing" };
46464
46537
  return { kind: "unreadable" };
@@ -46479,7 +46552,7 @@ async function removeIfSame(path, expected) {
46479
46552
  if (current.kind !== "owner" || current.owner.since !== expected.since) return;
46480
46553
  if (current.owner.pid !== expected.pid || current.owner.holder !== expected.holder) return;
46481
46554
  }
46482
- await (0, import_promises21.unlink)(path).catch((error61) => {
46555
+ await (0, import_promises22.unlink)(path).catch((error61) => {
46483
46556
  if (errnoCode(error61) !== "ENOENT") throw error61;
46484
46557
  });
46485
46558
  }
@@ -46504,7 +46577,7 @@ function openRepositoryLocks(options) {
46504
46577
  await removeIfSame(path, read.owner);
46505
46578
  return null;
46506
46579
  }
46507
- const age = await (0, import_promises21.stat)(path).then(
46580
+ const age = await (0, import_promises22.stat)(path).then(
46508
46581
  (info) => clock.now() - info.mtimeMs,
46509
46582
  () => 0
46510
46583
  );
@@ -46518,13 +46591,13 @@ function openRepositoryLocks(options) {
46518
46591
  });
46519
46592
  const folder = async (commonDir) => {
46520
46593
  const key = repositoryLockKey(commonDir, platform);
46521
- const dir = (0, import_node_path13.join)(options.dir, key);
46522
- await (0, import_promises21.mkdir)(dir, { recursive: true, mode: 448 });
46594
+ const dir = (0, import_node_path14.join)(options.dir, key);
46595
+ await (0, import_promises22.mkdir)(dir, { recursive: true, mode: 448 });
46523
46596
  return { key, dir };
46524
46597
  };
46525
46598
  const createExclusive = async (path, owner) => {
46526
46599
  try {
46527
- const handle = await (0, import_promises21.open)(path, "wx", 384);
46600
+ const handle = await (0, import_promises22.open)(path, "wx", 384);
46528
46601
  try {
46529
46602
  await handle.writeFile(JSON.stringify(owner));
46530
46603
  } finally {
@@ -46537,10 +46610,10 @@ function openRepositoryLocks(options) {
46537
46610
  }
46538
46611
  };
46539
46612
  const liveRun = async (dir) => {
46540
- const entries = await (0, import_promises21.readdir)(dir);
46613
+ const entries = await (0, import_promises22.readdir)(dir);
46541
46614
  for (const entry of entries) {
46542
46615
  if (!entry.startsWith(RUN_FILE_PREFIX)) continue;
46543
- const holder = await heldBy((0, import_node_path13.join)(dir, entry));
46616
+ const holder = await heldBy((0, import_node_path14.join)(dir, entry));
46544
46617
  if (holder !== null) return holder;
46545
46618
  }
46546
46619
  return null;
@@ -46548,7 +46621,7 @@ function openRepositoryLocks(options) {
46548
46621
  return {
46549
46622
  tryExclusive: async (commonDir, operationId) => {
46550
46623
  const { key, dir } = await folder(commonDir);
46551
- const path = (0, import_node_path13.join)(dir, EXCLUSIVE_FILE);
46624
+ const path = (0, import_node_path14.join)(dir, EXCLUSIVE_FILE);
46552
46625
  const owner = await self(operationId);
46553
46626
  if (!await createExclusive(path, owner)) {
46554
46627
  const holder = await heldBy(path);
@@ -46566,11 +46639,11 @@ function openRepositoryLocks(options) {
46566
46639
  },
46567
46640
  tryShared: async (commonDir, runId) => {
46568
46641
  const { key, dir } = await folder(commonDir);
46569
- const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto10.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
46570
- const path = (0, import_node_path13.join)(dir, file2);
46642
+ const file2 = `${RUN_FILE_PREFIX}${(0, import_node_crypto11.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}.json`;
46643
+ const path = (0, import_node_path14.join)(dir, file2);
46571
46644
  const owner = await self(runId);
46572
46645
  await writeJsonFileAtomic(path, owner);
46573
- const operation = await heldBy((0, import_node_path13.join)(dir, EXCLUSIVE_FILE));
46646
+ const operation = await heldBy((0, import_node_path14.join)(dir, EXCLUSIVE_FILE));
46574
46647
  if (operation !== null) {
46575
46648
  await removeIfSame(path, owner);
46576
46649
  return { kind: "busy", holder: operation };
@@ -46582,33 +46655,33 @@ function openRepositoryLocks(options) {
46582
46655
 
46583
46656
  // src/cli/config.ts
46584
46657
  var import_node_os7 = require("os");
46585
- var import_node_path28 = require("path");
46658
+ var import_node_path29 = require("path");
46586
46659
  init_zod();
46587
46660
 
46588
46661
  // src/client/locate.ts
46589
- var import_node_path15 = require("path");
46662
+ var import_node_path16 = require("path");
46590
46663
  var RUNTIME_PROFILES = ["production", "staging", "development", "local"];
46591
46664
  function defaultStateDir({ profile, platform, home, env }) {
46592
46665
  if (platform === "win32") {
46593
- return (0, import_node_path15.join)(env.LOCALAPPDATA ?? (0, import_node_path15.join)(home, "AppData", "Local"), "Alan", profile);
46666
+ return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", profile);
46594
46667
  }
46595
- return (0, import_node_path15.join)(env.XDG_STATE_HOME ?? (0, import_node_path15.join)(home, ".local", "state"), "alan", profile);
46668
+ return (0, import_node_path16.join)(env.XDG_STATE_HOME ?? (0, import_node_path16.join)(home, ".local", "state"), "alan", profile);
46596
46669
  }
46597
46670
  function defaultInstallDir({ platform, home, env }) {
46598
46671
  if (platform === "win32") {
46599
- return (0, import_node_path15.join)(env.LOCALAPPDATA ?? (0, import_node_path15.join)(home, "AppData", "Local"), "Alan", "runtime");
46672
+ return (0, import_node_path16.join)(env.LOCALAPPDATA ?? (0, import_node_path16.join)(home, "AppData", "Local"), "Alan", "runtime");
46600
46673
  }
46601
- return (0, import_node_path15.join)(env.XDG_DATA_HOME ?? (0, import_node_path15.join)(home, ".local", "share"), "alan", "runtime");
46674
+ return (0, import_node_path16.join)(env.XDG_DATA_HOME ?? (0, import_node_path16.join)(home, ".local", "share"), "alan", "runtime");
46602
46675
  }
46603
46676
 
46604
46677
  // src/sessions/index.ts
46605
- var import_node_crypto15 = require("crypto");
46606
- var import_promises37 = require("fs/promises");
46678
+ var import_node_crypto16 = require("crypto");
46679
+ var import_promises38 = require("fs/promises");
46607
46680
  var import_node_os6 = require("os");
46608
- var import_node_path27 = require("path");
46681
+ var import_node_path28 = require("path");
46609
46682
 
46610
46683
  // src/holder/control-client.ts
46611
- var import_node_crypto11 = require("crypto");
46684
+ var import_node_crypto12 = require("crypto");
46612
46685
  var import_node_net = require("net");
46613
46686
 
46614
46687
  // src/holder/ndjson.ts
@@ -46772,7 +46845,7 @@ function createProviderDrivers(options) {
46772
46845
  }
46773
46846
 
46774
46847
  // src/holder/engine-records.ts
46775
- var import_node_path16 = require("path");
46848
+ var import_node_path17 = require("path");
46776
46849
  init_zod();
46777
46850
  var ENGINES_FILE = "engines.json";
46778
46851
  var engineRecordSchema = external_exports.object({
@@ -46782,7 +46855,7 @@ var engineRecordSchema = external_exports.object({
46782
46855
  });
46783
46856
  var engineRecordsSchema = external_exports.object({ engines: external_exports.array(engineRecordSchema) });
46784
46857
  function engineRecordsPath(sessionDir) {
46785
- return (0, import_node_path16.join)(sessionDir, ENGINES_FILE);
46858
+ return (0, import_node_path17.join)(sessionDir, ENGINES_FILE);
46786
46859
  }
46787
46860
  function recordSpawnedEngines(path, clock, log) {
46788
46861
  const live = /* @__PURE__ */ new Map();
@@ -46837,17 +46910,17 @@ function createConversationMcpAuthorization(options) {
46837
46910
  }
46838
46911
 
46839
46912
  // src/holder/mcp-helper-access.ts
46840
- var import_promises28 = require("fs/promises");
46913
+ var import_promises29 = require("fs/promises");
46841
46914
  function createHelperMcpAccess(options) {
46842
46915
  return {
46843
46916
  [Symbol.asyncDispose]: async () => {
46844
- await (0, import_promises28.rm)(options.credentialPath, { force: true });
46917
+ await (0, import_promises29.rm)(options.credentialPath, { force: true });
46845
46918
  },
46846
46919
  url: options.managedMcp.url,
46847
46920
  authorization: async (signal) => {
46848
46921
  const authorization = await options.managedMcp.authorization(signal);
46849
46922
  if (authorization === void 0 || signal.aborted) {
46850
- await (0, import_promises28.rm)(options.credentialPath, { force: true });
46923
+ await (0, import_promises29.rm)(options.credentialPath, { force: true });
46851
46924
  return void 0;
46852
46925
  }
46853
46926
  const credential = {
@@ -46862,8 +46935,9 @@ function createHelperMcpAccess(options) {
46862
46935
  }
46863
46936
 
46864
46937
  // src/holder/run-inputs.ts
46865
- var import_promises29 = require("fs/promises");
46866
- var import_node_path17 = require("path");
46938
+ var import_promises30 = require("fs/promises");
46939
+ var import_node_path18 = require("path");
46940
+ init_dist();
46867
46941
  var NO_RUN_INPUTS = {
46868
46942
  attachments: [],
46869
46943
  providerEnv: {},
@@ -46876,23 +46950,24 @@ function safeFilename(filename) {
46876
46950
  return safe || "attachment";
46877
46951
  }
46878
46952
  async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46879
- const dir = (0, import_node_path17.join)(tmpDir, "runs", spec.runId);
46953
+ const dir = (0, import_node_path18.join)(tmpDir, "runs", spec.runId);
46880
46954
  const cleanup = async () => {
46881
- await (0, import_promises29.rm)(dir, { recursive: true, force: true });
46955
+ await (0, import_promises30.rm)(dir, { recursive: true, force: true });
46882
46956
  };
46883
46957
  try {
46884
46958
  const credential = await source.fetchProviderCredential(spec.runId, signal);
46885
46959
  const attachments = [];
46886
- if (spec.attachments?.length) await (0, import_promises29.mkdir)(dir, { recursive: true, mode: 448 });
46960
+ if (spec.attachments?.length) await (0, import_promises30.mkdir)(dir, { recursive: true, mode: 448 });
46887
46961
  for (const [index, attachment] of (spec.attachments ?? []).entries()) {
46888
46962
  const bytes = await source.downloadAttachment(spec.runId, attachment.id, signal);
46889
- const path = (0, import_node_path17.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
46890
- await (0, import_promises29.writeFile)(path, bytes, { mode: 384 });
46963
+ const path = (0, import_node_path18.join)(dir, `${index}-${safeFilename(attachment.filename)}`);
46964
+ await (0, import_promises30.writeFile)(path, bytes, { mode: 384 });
46965
+ const imageMimeType = attachment.kind === "image" ? detectImageMimeType(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength)) : null;
46891
46966
  attachments.push({
46892
46967
  id: attachment.id,
46893
46968
  kind: attachment.kind,
46894
46969
  filename: attachment.filename,
46895
- mimeType: attachment.mimeType,
46970
+ mimeType: imageMimeType ?? attachment.mimeType,
46896
46971
  size: bytes.byteLength,
46897
46972
  path,
46898
46973
  ...attachment.label === void 0 ? {} : { label: attachment.label },
@@ -46914,30 +46989,30 @@ async function prepareRunInputs(spec, { source, tmpDir, signal, skills = [] }) {
46914
46989
  }
46915
46990
 
46916
46991
  // src/holder/serve.ts
46917
- var import_node_crypto14 = require("crypto");
46918
- var import_node_fs10 = require("fs");
46992
+ var import_node_crypto15 = require("crypto");
46993
+ var import_node_fs11 = require("fs");
46919
46994
  var import_node_net2 = require("net");
46920
- var import_node_path26 = require("path");
46995
+ var import_node_path27 = require("path");
46921
46996
  init_runtime_v2();
46922
46997
 
46923
46998
  // src/holder/admission.ts
46924
- var import_node_fs8 = require("fs");
46925
- var import_promises33 = require("fs/promises");
46999
+ var import_node_fs9 = require("fs");
47000
+ var import_promises34 = require("fs/promises");
46926
47001
  var import_node_os5 = require("os");
46927
- var import_node_path22 = require("path");
47002
+ var import_node_path23 = require("path");
46928
47003
  init_constants();
46929
47004
 
46930
47005
  // ../shared/dist/node/local-workspace.js
46931
- var import_node_fs7 = require("fs");
47006
+ var import_node_fs8 = require("fs");
46932
47007
  var import_node_os4 = require("os");
46933
- var import_node_path18 = require("path");
47008
+ var import_node_path19 = require("path");
46934
47009
  function resolveAlanDefaultWorkspacePath(homeDirectory = (0, import_node_os4.homedir)()) {
46935
- return (0, import_node_path18.join)(homeDirectory, ".alan", "workspace");
47010
+ return (0, import_node_path19.join)(homeDirectory, ".alan", "workspace");
46936
47011
  }
46937
47012
 
46938
47013
  // src/holder/admission-relocation.ts
46939
- var import_promises30 = require("fs/promises");
46940
- var import_node_path19 = require("path");
47014
+ var import_promises31 = require("fs/promises");
47015
+ var import_node_path20 = require("path");
46941
47016
  var MAX_RELOCATION_CANDIDATES = 200;
46942
47017
  var RELOCATION_BUDGET_MS = 2e4;
46943
47018
  function repositoryIdentity(url2) {
@@ -46972,8 +47047,8 @@ async function originIdentity(git, path, signal) {
46972
47047
  }
46973
47048
  async function childDirectories(parent, limit) {
46974
47049
  try {
46975
- const entries = await (0, import_promises30.readdir)(parent, { withFileTypes: true });
46976
- return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path19.join)(parent, entry.name));
47050
+ const entries = await (0, import_promises31.readdir)(parent, { withFileTypes: true });
47051
+ return entries.filter((entry) => entry.isDirectory()).slice(0, limit).map((entry) => (0, import_node_path20.join)(parent, entry.name));
46977
47052
  } catch {
46978
47053
  return [];
46979
47054
  }
@@ -46981,7 +47056,7 @@ async function childDirectories(parent, limit) {
46981
47056
  async function candidateFolders(search) {
46982
47057
  const roots = /* @__PURE__ */ new Map();
46983
47058
  for (const path of [search.missingPath, ...search.approvedWorkspacePaths]) {
46984
- const parent = (0, import_node_path19.dirname)((0, import_node_path19.resolve)(path));
47059
+ const parent = (0, import_node_path20.dirname)((0, import_node_path20.resolve)(path));
46985
47060
  roots.set(comparablePath(parent, search.platform), parent);
46986
47061
  }
46987
47062
  const candidates2 = /* @__PURE__ */ new Map();
@@ -47008,9 +47083,9 @@ async function discoverRelocatedWorkspace(search) {
47008
47083
  }
47009
47084
 
47010
47085
  // src/holder/checkout-refresh.ts
47011
- var import_node_crypto13 = require("crypto");
47012
- var import_promises31 = require("fs/promises");
47013
- var import_node_path20 = require("path");
47086
+ var import_node_crypto14 = require("crypto");
47087
+ var import_promises32 = require("fs/promises");
47088
+ var import_node_path21 = require("path");
47014
47089
  function short(sha) {
47015
47090
  return sha.slice(0, 12);
47016
47091
  }
@@ -47022,8 +47097,8 @@ function staleLine(path, snapshot2, tip) {
47022
47097
  }
47023
47098
  async function claimOnce(dir, name) {
47024
47099
  try {
47025
- await (0, import_promises31.mkdir)(dir, { recursive: true, mode: 448 });
47026
- await (await (0, import_promises31.open)((0, import_node_path20.join)(dir, name), "wx")).close();
47100
+ await (0, import_promises32.mkdir)(dir, { recursive: true, mode: 448 });
47101
+ await (await (0, import_promises32.open)((0, import_node_path21.join)(dir, name), "wx")).close();
47027
47102
  return true;
47028
47103
  } catch {
47029
47104
  return false;
@@ -47054,8 +47129,8 @@ async function fastForward(freshness, operationId, deps, signal) {
47054
47129
  }
47055
47130
  async function atFirstLease(freshness, spec, deps, signal) {
47056
47131
  const first = await claimOnce(
47057
- (0, import_node_path20.join)(deps.dir, "leased"),
47058
- (0, import_node_crypto13.createHash)("sha256").update(freshness.path).digest("hex")
47132
+ (0, import_node_path21.join)(deps.dir, "leased"),
47133
+ (0, import_node_crypto14.createHash)("sha256").update(freshness.path).digest("hex")
47059
47134
  );
47060
47135
  switch (freshness.state) {
47061
47136
  case "current":
@@ -47085,7 +47160,7 @@ async function checkoutsOf(spec, leaseTargets) {
47085
47160
  function createCheckoutRefresh(deps) {
47086
47161
  return async (spec, leaseTargets, signal) => {
47087
47162
  if (spec.providerSessionId !== void 0) return void 0;
47088
- if (!await claimOnce((0, import_node_path20.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47163
+ if (!await claimOnce((0, import_node_path21.join)(deps.dir, "conversations"), spec.conversationId)) return void 0;
47089
47164
  const lines = [];
47090
47165
  for (const target of await checkoutsOf(spec, leaseTargets)) {
47091
47166
  const freshness = await readCheckoutFreshness(deps.dir, target);
@@ -47106,8 +47181,8 @@ function createCheckoutRefresh(deps) {
47106
47181
  }
47107
47182
 
47108
47183
  // src/holder/lease.ts
47109
- var import_promises32 = require("fs/promises");
47110
- var import_node_path21 = require("path");
47184
+ var import_promises33 = require("fs/promises");
47185
+ var import_node_path22 = require("path");
47111
47186
  var LEASE_CHECK_EVERY_MS = 5e3;
47112
47187
  var MAX_TRANSIENT_FAILURES = 3;
47113
47188
  var BACKOFF_BASE_MS = 1e3;
@@ -47121,8 +47196,8 @@ function identityFailure(code, workspacePath) {
47121
47196
  return { code, problemCode: "app.workspace.missing", message: MESSAGES[code], workspacePath };
47122
47197
  }
47123
47198
  async function fileIdentity(path) {
47124
- const canonical = await (0, import_promises32.realpath)(path);
47125
- const info = await (0, import_promises32.stat)(canonical, { bigint: true });
47199
+ const canonical = await (0, import_promises33.realpath)(path);
47200
+ const info = await (0, import_promises33.stat)(canonical, { bigint: true });
47126
47201
  return `${canonical}:${info.dev}:${info.ino}`;
47127
47202
  }
47128
47203
  async function snapshot(git, path, signal) {
@@ -47141,7 +47216,7 @@ async function snapshot(git, path, signal) {
47141
47216
  workspace: await fileIdentity(path),
47142
47217
  repository: await fileIdentity(commonDir),
47143
47218
  worktree: await fileIdentity(gitDir),
47144
- commonDir: await (0, import_promises32.realpath)(commonDir)
47219
+ commonDir: await (0, import_promises33.realpath)(commonDir)
47145
47220
  };
47146
47221
  } catch {
47147
47222
  return null;
@@ -47154,7 +47229,7 @@ async function gitValue(git, path, args, signal) {
47154
47229
  }
47155
47230
  async function pathExists(path) {
47156
47231
  try {
47157
- await (0, import_promises32.stat)(path);
47232
+ await (0, import_promises33.stat)(path);
47158
47233
  return true;
47159
47234
  } catch (error61) {
47160
47235
  return errnoCode(error61) !== "ENOENT" && errnoCode(error61) !== "ENOTDIR";
@@ -47163,19 +47238,19 @@ async function pathExists(path) {
47163
47238
  async function hasGitMarker(path) {
47164
47239
  let directory;
47165
47240
  try {
47166
- directory = await (0, import_promises32.realpath)(path);
47241
+ directory = await (0, import_promises33.realpath)(path);
47167
47242
  } catch {
47168
47243
  return true;
47169
47244
  }
47170
47245
  for (; ; ) {
47171
47246
  try {
47172
- await (0, import_promises32.stat)((0, import_node_path21.join)(directory, ".git"));
47247
+ await (0, import_promises33.stat)((0, import_node_path22.join)(directory, ".git"));
47173
47248
  return true;
47174
47249
  } catch (error61) {
47175
47250
  const code = errnoCode(error61);
47176
47251
  if (code !== "ENOENT" && code !== "ENOTDIR") return true;
47177
47252
  }
47178
- const parent = (0, import_node_path21.dirname)(directory);
47253
+ const parent = (0, import_node_path22.dirname)(directory);
47179
47254
  if (parent === directory) return false;
47180
47255
  directory = parent;
47181
47256
  }
@@ -47339,7 +47414,7 @@ function volumeRoot(path) {
47339
47414
  }
47340
47415
  async function exists(path) {
47341
47416
  try {
47342
- await (0, import_promises33.stat)(path);
47417
+ await (0, import_promises34.stat)(path);
47343
47418
  return true;
47344
47419
  } catch {
47345
47420
  return false;
@@ -47347,10 +47422,10 @@ async function exists(path) {
47347
47422
  }
47348
47423
  async function inspectReadiness(path) {
47349
47424
  try {
47350
- if (!(await (0, import_promises33.stat)(path)).isDirectory()) {
47425
+ if (!(await (0, import_promises34.stat)(path)).isDirectory()) {
47351
47426
  return { ready: false, missing: true, message: MESSAGES2.missing };
47352
47427
  }
47353
- await (0, import_promises33.access)(path, import_node_fs8.constants.R_OK | import_node_fs8.constants.W_OK | import_node_fs8.constants.X_OK);
47428
+ await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47354
47429
  return { ready: true };
47355
47430
  } catch (error61) {
47356
47431
  const code = errnoCode(error61) ?? "";
@@ -47428,8 +47503,8 @@ async function admitDefaultWorkspace(spec, context, skills) {
47428
47503
  const { env } = context;
47429
47504
  const path = resolveAlanDefaultWorkspacePath(env.HOME || env.USERPROFILE || (0, import_node_os5.homedir)());
47430
47505
  try {
47431
- await (0, import_promises33.mkdir)(path, { recursive: true, mode: 448 });
47432
- await (0, import_promises33.access)(path, import_node_fs8.constants.R_OK | import_node_fs8.constants.W_OK | import_node_fs8.constants.X_OK);
47506
+ await (0, import_promises34.mkdir)(path, { recursive: true, mode: 448 });
47507
+ await (0, import_promises34.access)(path, import_node_fs9.constants.R_OK | import_node_fs9.constants.W_OK | import_node_fs9.constants.X_OK);
47433
47508
  return {
47434
47509
  kind: "admitted",
47435
47510
  spec: { ...spec, projectPath: path },
@@ -47505,7 +47580,7 @@ var PROBE_TIMEOUT_MS2 = 5e3;
47505
47580
  function createHolderWorkspace(machine, clock, log) {
47506
47581
  const platform = machine.platform ?? process.platform;
47507
47582
  const git = createGitRunner({ env: machine.env, platform, localTimeoutMs: PROBE_TIMEOUT_MS2 });
47508
- const locks = openRepositoryLocks({ dir: (0, import_node_path22.join)(machine.stateDir, "locks"), clock, platform });
47583
+ const locks = openRepositoryLocks({ dir: (0, import_node_path23.join)(machine.stateDir, "locks"), clock, platform });
47509
47584
  return {
47510
47585
  admission: {
47511
47586
  env: machine.env,
@@ -47517,7 +47592,7 @@ function createHolderWorkspace(machine, clock, log) {
47517
47592
  ),
47518
47593
  approvedRoots: async () => {
47519
47594
  const approved = await openApprovedPaths({
47520
- file: (0, import_node_path22.join)(machine.stateDir, "workspaces.json"),
47595
+ file: (0, import_node_path23.join)(machine.stateDir, "workspaces.json"),
47521
47596
  log,
47522
47597
  platform
47523
47598
  });
@@ -47530,7 +47605,7 @@ function createHolderWorkspace(machine, clock, log) {
47530
47605
  git,
47531
47606
  locks,
47532
47607
  log,
47533
- dir: (0, import_node_path22.join)(machine.stateDir, "checkout-freshness")
47608
+ dir: (0, import_node_path23.join)(machine.stateDir, "checkout-freshness")
47534
47609
  })
47535
47610
  } : {}
47536
47611
  };
@@ -47558,7 +47633,7 @@ async function respondToTurn(runningRunId, gate, driver, request2) {
47558
47633
  }
47559
47634
 
47560
47635
  // src/holder/session-facts.ts
47561
- var import_promises34 = require("fs/promises");
47636
+ var import_promises35 = require("fs/promises");
47562
47637
  var CLI_RSS_CACHE_MS = 1e4;
47563
47638
  var LOGIN_PROBLEM_PREFIX = "cli.auth.";
47564
47639
  function isLoginFailure(result) {
@@ -47584,8 +47659,8 @@ function createSessionFacts(options) {
47584
47659
  const path = await resolveCommandOnPath(command, env, platform);
47585
47660
  if (path === null) return null;
47586
47661
  try {
47587
- const real = await (0, import_promises34.realpath)(path);
47588
- const info = await (0, import_promises34.stat)(real);
47662
+ const real = await (0, import_promises35.realpath)(path);
47663
+ const info = await (0, import_promises35.stat)(real);
47589
47664
  return { command, key: `${real}:${info.ino}:${info.size}:${info.mtimeMs}` };
47590
47665
  } catch {
47591
47666
  return null;
@@ -47672,8 +47747,8 @@ function createSessionFacts(options) {
47672
47747
  init_acp2();
47673
47748
 
47674
47749
  // src/run-log/directory.ts
47675
- var import_promises35 = require("fs/promises");
47676
- var import_node_path23 = require("path");
47750
+ var import_promises36 = require("fs/promises");
47751
+ var import_node_path24 = require("path");
47677
47752
  init_runtime_v2();
47678
47753
  init_zod();
47679
47754
  var runMetaSchema = external_exports.object({
@@ -47695,17 +47770,17 @@ var runMetaSchema = external_exports.object({
47695
47770
  }).optional()
47696
47771
  });
47697
47772
  function runDirectory(runsDir, runId) {
47698
- const dir = (0, import_node_path23.join)(runsDir, runId);
47773
+ const dir = (0, import_node_path24.join)(runsDir, runId);
47699
47774
  return {
47700
47775
  dir,
47701
- log: (0, import_node_path23.join)(dir, "log.jsonl"),
47702
- upload: (0, import_node_path23.join)(dir, "upload.json"),
47703
- meta: (0, import_node_path23.join)(dir, "run.json")
47776
+ log: (0, import_node_path24.join)(dir, "log.jsonl"),
47777
+ upload: (0, import_node_path24.join)(dir, "upload.json"),
47778
+ meta: (0, import_node_path24.join)(dir, "run.json")
47704
47779
  };
47705
47780
  }
47706
47781
  async function isRunClaimed(runsDir, runId) {
47707
47782
  try {
47708
- return (await (0, import_promises35.stat)(runDirectory(runsDir, runId).log)).size > 0;
47783
+ return (await (0, import_promises36.stat)(runDirectory(runsDir, runId).log)).size > 0;
47709
47784
  } catch (error61) {
47710
47785
  if (errnoCode(error61) === "ENOENT") return false;
47711
47786
  throw error61;
@@ -47713,8 +47788,8 @@ async function isRunClaimed(runsDir, runId) {
47713
47788
  }
47714
47789
 
47715
47790
  // src/run-log/conversation-index.ts
47716
- var import_promises36 = require("fs/promises");
47717
- var import_node_path24 = require("path");
47791
+ var import_promises37 = require("fs/promises");
47792
+ var import_node_path25 = require("path");
47718
47793
  init_runtime_v2();
47719
47794
  init_zod();
47720
47795
  var ORDINALS_PER_SHARD = 1e3;
@@ -47730,13 +47805,13 @@ var coverageSchema = external_exports.object({
47730
47805
  nextExpectedOrdinal: external_exports.number().int().positive()
47731
47806
  });
47732
47807
  function conversationsDirectory(runsDir) {
47733
- return (0, import_node_path24.join)((0, import_node_path24.dirname)(runsDir), "conversations");
47808
+ return (0, import_node_path25.join)((0, import_node_path25.dirname)(runsDir), "conversations");
47734
47809
  }
47735
47810
  function indexDirectory(runsDir, conversationId) {
47736
- return (0, import_node_path24.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
47811
+ return (0, import_node_path25.join)(conversationsDirectory(runsDir), conversationId, "turn-index");
47737
47812
  }
47738
47813
  function shardPath(runsDir, conversationId, ordinal) {
47739
- return (0, import_node_path24.join)(
47814
+ return (0, import_node_path25.join)(
47740
47815
  indexDirectory(runsDir, conversationId),
47741
47816
  `${Math.floor(ordinal / ORDINALS_PER_SHARD)}.jsonl`
47742
47817
  );
@@ -47745,10 +47820,10 @@ async function indexConversationRun(runsDir, conversationId, ordinal, assistantO
47745
47820
  const nextOrdinal = assistantOrdinal + 1;
47746
47821
  if (nextOrdinal <= ordinal) throw new Error("Assistant order must follow the prompt");
47747
47822
  const path = shardPath(runsDir, conversationId, ordinal);
47748
- await (0, import_promises36.mkdir)((0, import_node_path24.dirname)(path), { recursive: true, mode: 448 });
47749
- await (0, import_promises36.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
47823
+ await (0, import_promises37.mkdir)((0, import_node_path25.dirname)(path), { recursive: true, mode: 448 });
47824
+ await (0, import_promises37.appendFile)(path, `${JSON.stringify({ ordinal, nextOrdinal, runId })}
47750
47825
  `, { mode: 384 });
47751
- const coveragePath = (0, import_node_path24.join)((0, import_node_path24.dirname)((0, import_node_path24.dirname)(path)), "coverage.json");
47826
+ const coveragePath = (0, import_node_path25.join)((0, import_node_path25.dirname)((0, import_node_path25.dirname)(path)), "coverage.json");
47752
47827
  const coverage = await readJsonFile(coveragePath, coverageSchema);
47753
47828
  const current = coverage.kind === "ok" ? coverage.value : null;
47754
47829
  const next = nextCoverage(current, ordinal, nextOrdinal);
@@ -47791,13 +47866,13 @@ function runEnded(input2) {
47791
47866
  var decoder = new TextDecoder();
47792
47867
 
47793
47868
  // src/run-log/writer.ts
47794
- var import_node_fs9 = require("fs");
47795
- var import_node_path25 = require("path");
47869
+ var import_node_fs10 = require("fs");
47870
+ var import_node_path26 = require("path");
47796
47871
  init_runtime_v2();
47797
47872
  function lastSeq(fd, size) {
47798
47873
  for (const length of tailWindows(size)) {
47799
47874
  const buffer = Buffer.alloc(length);
47800
- (0, import_node_fs9.readSync)(fd, buffer, 0, length, size - length);
47875
+ (0, import_node_fs10.readSync)(fd, buffer, 0, length, size - length);
47801
47876
  const last = lastLine(buffer.toString("utf8").trimEnd(), length === size);
47802
47877
  if (last === void 0) continue;
47803
47878
  if (last.length === 0) return 0;
@@ -47808,13 +47883,13 @@ function lastSeq(fd, size) {
47808
47883
  throw new RuntimeFault("record_too_large", "Run log tail record is larger than any record");
47809
47884
  }
47810
47885
  function openRunLog(path, clock) {
47811
- (0, import_node_fs9.mkdirSync)((0, import_node_path25.dirname)(path), { recursive: true, mode: 448 });
47812
- const fd = (0, import_node_fs9.openSync)(path, "a+", 384);
47813
- let size = (0, import_node_fs9.fstatSync)(fd).size;
47886
+ (0, import_node_fs10.mkdirSync)((0, import_node_path26.dirname)(path), { recursive: true, mode: 448 });
47887
+ const fd = (0, import_node_fs10.openSync)(path, "a+", 384);
47888
+ let size = (0, import_node_fs10.fstatSync)(fd).size;
47814
47889
  let seq = lastSeq(fd, size);
47815
47890
  let dirty = false;
47816
47891
  const sync = () => {
47817
- (0, import_node_fs9.fsyncSync)(fd);
47892
+ (0, import_node_fs10.fsyncSync)(fd);
47818
47893
  dirty = false;
47819
47894
  };
47820
47895
  return {
@@ -47828,7 +47903,7 @@ function openRunLog(path, clock) {
47828
47903
  };
47829
47904
  const line = Buffer.from(`${JSON.stringify(record2)}
47830
47905
  `, "utf8");
47831
- (0, import_node_fs9.writeSync)(fd, line);
47906
+ (0, import_node_fs10.writeSync)(fd, line);
47832
47907
  size += line.length;
47833
47908
  dirty = true;
47834
47909
  if (isRunLifecycleKind(update.sessionUpdate)) sync();
@@ -47840,7 +47915,7 @@ function openRunLog(path, clock) {
47840
47915
  },
47841
47916
  [Symbol.dispose]: () => {
47842
47917
  if (dirty) sync();
47843
- (0, import_node_fs9.closeSync)(fd);
47918
+ (0, import_node_fs10.closeSync)(fd);
47844
47919
  }
47845
47920
  };
47846
47921
  }
@@ -48125,12 +48200,12 @@ var TASK_UNSUPPORTED = {
48125
48200
  message: "This agent cannot stop one background task."
48126
48201
  };
48127
48202
  function sha2563(value) {
48128
- return (0, import_node_crypto14.createHash)("sha256").update(value).digest("hex");
48203
+ return (0, import_node_crypto15.createHash)("sha256").update(value).digest("hex");
48129
48204
  }
48130
48205
  function tokenMatches(expected, presented) {
48131
48206
  const a = Buffer.from(sha2563(expected), "hex");
48132
48207
  const b = Buffer.from(sha2563(presented), "hex");
48133
- return (0, import_node_crypto14.timingSafeEqual)(a, b);
48208
+ return (0, import_node_crypto15.timingSafeEqual)(a, b);
48134
48209
  }
48135
48210
  async function runHolder({
48136
48211
  launch,
@@ -48144,7 +48219,7 @@ async function runHolder({
48144
48219
  try {
48145
48220
  const identity = await readProcessIdentity(process.pid);
48146
48221
  if (identity === null) throw new RuntimeFault("internal", "Cannot read own process identity");
48147
- const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path26.dirname)(launch.statusPath)), clock, log));
48222
+ const _engines = __using(_stack, recordSpawnedEngines(engineRecordsPath((0, import_node_path27.dirname)(launch.statusPath)), clock, log));
48148
48223
  const holder = {
48149
48224
  state: "idle",
48150
48225
  runId: null,
@@ -48340,17 +48415,17 @@ async function runHolder({
48340
48415
  client.on("error", () => holder.clients.delete(client));
48341
48416
  });
48342
48417
  removeStaleEndpoint(launch.endpoint);
48343
- await new Promise((resolve6, reject) => {
48418
+ await new Promise((resolve7, reject) => {
48344
48419
  server.once("error", reject);
48345
- server.listen(launch.endpoint, () => resolve6());
48420
+ server.listen(launch.endpoint, () => resolve7());
48346
48421
  });
48347
48422
  await writeStatus();
48348
48423
  log.info("holder.ready", { conversationId: launch.conversationId, pid: identity.pid });
48349
- await new Promise((resolve6) => exit.signal.addEventListener("abort", () => resolve6()));
48424
+ await new Promise((resolve7) => exit.signal.addEventListener("abort", () => resolve7()));
48350
48425
  await driver.suspend?.().catch((error61) => log.warn("holder.driver_suspend_failed", { error: error61 }));
48351
48426
  for (const client of holder.clients) client.end();
48352
- await new Promise((resolve6) => server.close(() => resolve6()));
48353
- (0, import_node_fs10.rmSync)(launch.statusPath, { force: true });
48427
+ await new Promise((resolve7) => server.close(() => resolve7()));
48428
+ (0, import_node_fs11.rmSync)(launch.statusPath, { force: true });
48354
48429
  log.info("holder.suspended", { conversationId: launch.conversationId });
48355
48430
  } catch (_) {
48356
48431
  var _error = _, _hasError = true;
@@ -48402,7 +48477,8 @@ var envSchema = external_exports.object({
48402
48477
  ALAN_RUNTIME_GIT_GATEWAY_URL: external_exports.url().optional(),
48403
48478
  ALAN_RUNTIME_WORKSPACE_ROOT: external_exports.string().min(1).optional(),
48404
48479
  XDG_CONFIG_HOME: external_exports.string().min(1).optional(),
48405
- GH_CONFIG_DIR: external_exports.string().min(1).optional()
48480
+ GH_CONFIG_DIR: external_exports.string().min(1).optional(),
48481
+ CODEX_HOME: external_exports.string().trim().min(1).optional()
48406
48482
  });
48407
48483
  var DEFAULT_API_URLS = {
48408
48484
  production: "https://api.tryalan.ai",
@@ -48455,7 +48531,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48455
48531
  ALAN_RUNTIME_GIT_GATEWAY_URL,
48456
48532
  ALAN_RUNTIME_WORKSPACE_ROOT,
48457
48533
  XDG_CONFIG_HOME,
48458
- GH_CONFIG_DIR
48534
+ GH_CONFIG_DIR,
48535
+ CODEX_HOME
48459
48536
  } = parsed.data;
48460
48537
  const home = (0, import_node_os7.homedir)();
48461
48538
  const suspendDefaults = defaultSuspendPolicy(totalMemoryBytes);
@@ -48487,7 +48564,8 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48487
48564
  providerProbes: ALAN_RUNTIME_PROVIDER_PROBES === "on",
48488
48565
  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,
48489
48566
  home,
48490
- configHome: XDG_CONFIG_HOME ?? (0, import_node_path28.join)(home, ".config"),
48567
+ configHome: XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config"),
48568
+ codexHome: resolveCodexHome(CODEX_HOME, home),
48491
48569
  ...githubProxyConfig({ ALAN_RUNTIME_GITHUB_PROXY, XDG_CONFIG_HOME, GH_CONFIG_DIR }, home),
48492
48570
  gitGatewayUrl: ALAN_RUNTIME_GIT_GATEWAY_URL ?? null,
48493
48571
  workspaceRoot: ALAN_RUNTIME_WORKSPACE_ROOT ?? null,
@@ -48495,11 +48573,14 @@ function loadRuntimeConfig(env = process.env, totalMemoryBytes = (0, import_node
48495
48573
  adoptsLegacyInstall: ALAN_RUNTIME_STATE_DIR === void 0
48496
48574
  };
48497
48575
  }
48576
+ function resolveCodexHome(configuredHome, home) {
48577
+ return configuredHome ?? (0, import_node_path29.join)(home, ".codex");
48578
+ }
48498
48579
  function githubProxyConfig(env, home) {
48499
- const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path28.join)(home, ".config");
48580
+ const configHome = env.XDG_CONFIG_HOME ?? (0, import_node_path29.join)(home, ".config");
48500
48581
  return {
48501
48582
  githubProxy: env.ALAN_RUNTIME_GITHUB_PROXY === "on",
48502
- ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path28.join)(configHome, "gh")
48583
+ ghConfigDir: env.GH_CONFIG_DIR ?? (0, import_node_path29.join)(configHome, "gh")
48503
48584
  };
48504
48585
  }
48505
48586
  function serviceEnvironment(env, profile) {
@@ -48598,7 +48679,7 @@ async function loadStoredAccess(paths, access3 = { exec: systemExec }) {
48598
48679
  }
48599
48680
 
48600
48681
  // src/cli/commands/hold.ts
48601
- var import_node_path29 = require("path");
48682
+ var import_node_path30 = require("path");
48602
48683
  init_agent2();
48603
48684
  init_runtime_v2();
48604
48685
  async function machineAccess(paths, log, conversationId, transport) {
@@ -48656,7 +48737,7 @@ async function runHold(argv) {
48656
48737
  const config2 = loadRuntimeConfig();
48657
48738
  const paths = runtimePaths(config2.stateDir);
48658
48739
  const log = __using(_stack, openFileLog(
48659
- (0, import_node_path29.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
48740
+ (0, import_node_path30.join)(paths.logs, `holder-${launch.value.conversationId}.jsonl`),
48660
48741
  config2.logLevel,
48661
48742
  systemClock
48662
48743
  ));
@@ -48667,7 +48748,7 @@ async function runHold(argv) {
48667
48748
  );
48668
48749
  const transport = __using(_stack, createHttpTransport());
48669
48750
  const access3 = await machineAccess(paths, log, launch.value.conversationId, transport);
48670
- const credentialPath = (0, import_node_path29.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
48751
+ const credentialPath = (0, import_node_path30.join)(paths.tmp, "mcp", `${launch.value.conversationId}.json`);
48671
48752
  const managedMcp = __using(_stack, access3.managedMcp === void 0 ? void 0 : createHelperMcpAccess({
48672
48753
  managedMcp: access3.managedMcp,
48673
48754
  conversationId: launch.value.conversationId,
@@ -48686,7 +48767,8 @@ async function runHold(argv) {
48686
48767
  timings: config2.sessionTimings,
48687
48768
  log,
48688
48769
  ...managedMcp === void 0 ? {} : { managedMcp },
48689
- codexCredentials: access3.codexCredentials
48770
+ codexCredentials: access3.codexCredentials,
48771
+ installedSkills: () => installedSkillFolders(skillsLayout(paths.stateDir))
48690
48772
  }),
48691
48773
  clock: systemClock,
48692
48774
  log,