@alan-ai-hq/agent-manager 0.1.104 → 0.1.106

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 (2) hide show
  1. package/dist/index.cjs +325 -250
  2. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -15504,7 +15504,7 @@ function describeError(error61) {
15504
15504
  }
15505
15505
 
15506
15506
  // src/version.ts
15507
- var AGENT_VERSION = "0.1.104";
15507
+ var AGENT_VERSION = "0.1.106";
15508
15508
 
15509
15509
  // src/daemon-worktree.ts
15510
15510
  var import_node_child_process3 = require("child_process");
@@ -35724,6 +35724,8 @@ var AGENT_CONFIG_KEYS = /* @__PURE__ */ new Map([
35724
35724
  ["teamId", "string"],
35725
35725
  ["runtimeId", "string"],
35726
35726
  ["runtimeToken", "string"],
35727
+ ["runtimeRenewalToken", "string"],
35728
+ ["runtimeTokenExpiresAt", "string"],
35727
35729
  ["localApiPort", "number"],
35728
35730
  ["localApiToken", "string"],
35729
35731
  ["displayName", "string"]
@@ -36556,7 +36558,7 @@ function isBrowserRecordingToolName(toolName) {
36556
36558
  }
36557
36559
 
36558
36560
  // ../shared/dist/agent/mcp-config.js
36559
- var ALAN_AGENT_CREDENTIAL_ENV = "ALAN_AGENT_CREDENTIAL";
36561
+ var ALAN_MCP_AUTHORIZATION_ENV = "ALAN_MCP_AUTHORIZATION";
36560
36562
  var ALAN_RUN_ID_ENV = "ALAN_RUN_ID";
36561
36563
  var MCP_CONFIG_KEY = /^[A-Za-z0-9_-]+$/;
36562
36564
  function isExternalMcpServerName(name) {
@@ -38160,20 +38162,22 @@ var import_util9 = require("util");
38160
38162
  var import_fs6 = require("fs");
38161
38163
  var import_os5 = require("os");
38162
38164
  var import_path6 = require("path");
38165
+ var import_promises = require("fs/promises");
38166
+ var import_path7 = require("path");
38163
38167
  var import_fs7 = require("fs");
38164
38168
  var import_os6 = require("os");
38165
- var import_path7 = require("path");
38169
+ var import_path8 = require("path");
38166
38170
  var import_fs8 = require("fs");
38167
38171
  var import_os7 = require("os");
38168
- var import_path8 = require("path");
38172
+ var import_path9 = require("path");
38169
38173
  var import_fs9 = require("fs");
38170
38174
  var import_os8 = require("os");
38171
- var import_path9 = require("path");
38175
+ var import_path10 = require("path");
38172
38176
  var import_readline2 = require("readline");
38173
38177
  var import_url2 = require("url");
38174
38178
  var import_crypto4 = require("crypto");
38175
38179
  var import_fs10 = require("fs");
38176
- var import_path10 = require("path");
38180
+ var import_path11 = require("path");
38177
38181
  var MAX_PARSED_ATTACHMENTS = 3;
38178
38182
  var MAX_PARSED_ATTACHMENT_CHARS = 12e3;
38179
38183
  var MAX_METADATA_CHARS = 240;
@@ -40806,8 +40810,12 @@ function requiredHeader(registration, name) {
40806
40810
  if (!value2) throw new Error(`Alan MCP ${name} header is missing`);
40807
40811
  return value2;
40808
40812
  }
40809
- function requireManagedAgentCredential(registration) {
40810
- return requiredHeader(registration, "x-alan-agent-credential");
40813
+ function requireManagedAuthorization(registration) {
40814
+ const authorization = requiredHeader(registration, "authorization");
40815
+ if (!authorization.startsWith("Bearer ") || !authorization.slice(7).trim()) {
40816
+ throw new Error("Alan MCP authorization header must contain a bearer token");
40817
+ }
40818
+ return authorization;
40811
40819
  }
40812
40820
  function requireManagedRunId(registration) {
40813
40821
  return requiredHeader(registration, "x-alan-run-id");
@@ -41288,7 +41296,7 @@ function buildClaudeManagedMcpArgs(registration, options = {}) {
41288
41296
  type: "http",
41289
41297
  url: registration.url,
41290
41298
  headers: {
41291
- "x-alan-agent-credential": `\${${ALAN_AGENT_CREDENTIAL_ENV}}`,
41299
+ Authorization: `\${${ALAN_MCP_AUTHORIZATION_ENV}}`,
41292
41300
  "x-alan-run-id": `\${${ALAN_RUN_ID_ENV}}`
41293
41301
  }
41294
41302
  };
@@ -41310,7 +41318,7 @@ function createClaudeCliBackend(command = "claude", defaultArgs = []) {
41310
41318
  env: {
41311
41319
  ...context.env,
41312
41320
  ...externalMcp?.env,
41313
- [ALAN_AGENT_CREDENTIAL_ENV]: requireManagedAgentCredential(managedRegistration),
41321
+ [ALAN_MCP_AUTHORIZATION_ENV]: requireManagedAuthorization(managedRegistration),
41314
41322
  [ALAN_RUN_ID_ENV]: requireManagedRunId(managedRegistration)
41315
41323
  }
41316
41324
  } : context;
@@ -42566,7 +42574,7 @@ function buildCodexManagedMcpArgs(registration, options = {}) {
42566
42574
  "-c",
42567
42575
  `mcp_servers.alan.url=${JSON.stringify(registration.url)}`,
42568
42576
  "-c",
42569
- `mcp_servers.alan.env_http_headers.x-alan-agent-credential=${JSON.stringify(ALAN_AGENT_CREDENTIAL_ENV)}`,
42577
+ `mcp_servers.alan.env_http_headers.Authorization=${JSON.stringify(ALAN_MCP_AUTHORIZATION_ENV)}`,
42570
42578
  "-c",
42571
42579
  `mcp_servers.alan.env_http_headers.x-alan-run-id=${JSON.stringify(ALAN_RUN_ID_ENV)}`,
42572
42580
  "-c",
@@ -42613,7 +42621,7 @@ function createCodexRuntimeBackend(command = "codex", defaultArgs = []) {
42613
42621
  env: {
42614
42622
  ...context.env,
42615
42623
  ...externalMcp?.env,
42616
- [ALAN_AGENT_CREDENTIAL_ENV]: requireManagedAgentCredential(managedRegistration),
42624
+ [ALAN_MCP_AUTHORIZATION_ENV]: requireManagedAuthorization(managedRegistration),
42617
42625
  [ALAN_RUN_ID_ENV]: requireManagedRunId(managedRegistration)
42618
42626
  }
42619
42627
  } : context;
@@ -43000,6 +43008,39 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
43000
43008
  }
43001
43009
  };
43002
43010
  }
43011
+ async function withCursorProjectMcpEntry(cwd, url3, run) {
43012
+ const path2 = (0, import_path7.join)(cwd, ".cursor", "mcp.json");
43013
+ const original = await (0, import_promises.readFile)(path2, "utf8").catch(() => null);
43014
+ const config2 = parseConfig(original);
43015
+ const servers = config2.mcpServers ?? {};
43016
+ config2.mcpServers = servers;
43017
+ servers.alan = {
43018
+ type: "http",
43019
+ url: url3,
43020
+ headers: {
43021
+ Authorization: `\${env:${ALAN_MCP_AUTHORIZATION_ENV}}`,
43022
+ "x-alan-run-id": `\${env:${ALAN_RUN_ID_ENV}}`
43023
+ }
43024
+ };
43025
+ await (0, import_promises.mkdir)((0, import_path7.dirname)(path2), { recursive: true });
43026
+ await (0, import_promises.writeFile)(path2, `${JSON.stringify(config2, null, 2)}
43027
+ `);
43028
+ try {
43029
+ return await run();
43030
+ } finally {
43031
+ if (original === null) await (0, import_promises.rm)(path2, { force: true });
43032
+ else await (0, import_promises.writeFile)(path2, original);
43033
+ }
43034
+ }
43035
+ function parseConfig(raw) {
43036
+ if (!raw) return {};
43037
+ try {
43038
+ const parsed = JSON.parse(raw);
43039
+ return parsed && typeof parsed === "object" ? parsed : {};
43040
+ } catch {
43041
+ return {};
43042
+ }
43043
+ }
43003
43044
  function asRecord4(value2) {
43004
43045
  return typeof value2 === "object" && value2 !== null ? value2 : null;
43005
43046
  }
@@ -43192,10 +43233,10 @@ function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter
43192
43233
  function cursorTranscriptsRoot(context) {
43193
43234
  const projectKey = context.cwd.replace(/^[/\\]+/, "").replace(/[/\\]+/g, "-");
43194
43235
  const home = context.env.HOME || process.env.HOME || (0, import_os6.homedir)();
43195
- return (0, import_path7.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
43236
+ return (0, import_path8.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
43196
43237
  }
43197
43238
  function cursorTranscriptPathForAgent(context, agentId) {
43198
- return (0, import_path7.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
43239
+ return (0, import_path8.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
43199
43240
  }
43200
43241
  function resolveCursorSubagentTranscriptPath(success2, context) {
43201
43242
  const explicit = success2?.transcriptPath ?? success2?.transcript_path;
@@ -43579,88 +43620,90 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
43579
43620
  ...context,
43580
43621
  env: {
43581
43622
  ...context.env,
43582
- [ALAN_AGENT_CREDENTIAL_ENV]: requireManagedAgentCredential(context.config.alanMcp),
43623
+ [ALAN_MCP_AUTHORIZATION_ENV]: requireManagedAuthorization(context.config.alanMcp),
43583
43624
  [ALAN_RUN_ID_ENV]: requireManagedRunId(context.config.alanMcp)
43584
43625
  }
43585
43626
  } : context;
43586
- try {
43587
- return await createGenericCliBackend({
43588
- kind: "cursor_agent_cli",
43589
- supportTier: "structured",
43590
- command,
43591
- args: [],
43592
- buildArgs: (ctx, _prompt) => {
43593
- const args = [
43594
- "--print",
43595
- "--output-format",
43596
- "stream-json",
43597
- "--trust",
43598
- "--workspace",
43599
- ctx.cwd
43600
- ];
43601
- if (approveMcps) {
43602
- args.push("--approve-mcps");
43603
- }
43604
- const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
43605
- if (shouldForceCursorAgent(ctx.config)) args.push("--force");
43606
- if (ctx.config.mode === "plan" || ctx.config.mode === "review") {
43607
- args.push("--mode", "plan");
43608
- } else if (ctx.config.mode === "ask") {
43609
- args.push("--mode", "ask");
43610
- } else if (shouldUseReadOnlyRuntimePermissions(ctx.config)) {
43611
- args.push("--mode", "plan");
43612
- }
43613
- if (resumeId) {
43614
- args.push("--resume", resumeId);
43615
- logResumeObservability("agent_resume_requested", {
43616
- backendKind: "cursor_agent_cli",
43617
- requestedResumeId: resumeId
43618
- });
43619
- }
43620
- const model = ctx.config.selectedModel?.trim();
43621
- if (model && isDispatchableCursorModel(model)) {
43622
- const modelDef = findModelDef("cursor_agent_cli", model) ?? findModelDef("cursor_agent_cli", model.replace(/-fast$/, ""));
43623
- args.push(
43624
- "--model",
43625
- buildCursorAgentModelArg(model, {
43626
- selectedEffortLevel: ctx.config.selectedEffortLevel,
43627
- selectedContextWindow: ctx.config.selectedContextWindow,
43628
- effortLevels: modelDef?.capabilities?.effortLevels,
43629
- contextWindows: modelDef?.capabilities?.contextWindows
43630
- })
43631
- );
43632
- }
43633
- return [...args, ...defaultArgs];
43634
- },
43635
- // Prompt over stdin with immediate EOF (verified live on cursor-agent
43636
- // 2026.07.09): vibe-kanban's mitigation for cursor-agent's documented
43637
- // headless hangs. The result-race/grace-kill stays active via
43638
- // keepStdinOpen; closeStdinAfterPrompt only skips holding stdin open,
43639
- // which cursor never reads after the prompt anyway.
43640
- promptViaStdin: true,
43641
- keepStdinOpen: true,
43642
- closeStdinAfterPrompt: true,
43643
- // cursor-agent headless has a documented failure mode of hanging at startup
43644
- // with zero output; without this watchdog only the 30-min server reaper
43645
- // would end the run.
43646
- startupTimeoutMs: 18e4,
43647
- // Post-startup hang bound: cursor's asks use the non-blocking MCP model and it
43648
- // never populates the idle timer's ask/background fire conditions, so a cursor
43649
- // process that produced output then went silent (no result event) is otherwise
43650
- // bounded only by the ~30-min external reaper. Poll every 5 min; kill after 15
43651
- // min of continuous silence.
43652
- resultIdleTimeoutMs: 5 * 6e4,
43653
- postStartupSilenceTimeoutMs: 15 * 6e4,
43654
- augmentPrompt: (ctx) => {
43655
- const isResume = Boolean(
43656
- ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim()
43627
+ const runBackend = () => createGenericCliBackend({
43628
+ kind: "cursor_agent_cli",
43629
+ supportTier: "structured",
43630
+ command,
43631
+ args: [],
43632
+ buildArgs: (ctx, _prompt) => {
43633
+ const args = [
43634
+ "--print",
43635
+ "--output-format",
43636
+ "stream-json",
43637
+ "--trust",
43638
+ "--workspace",
43639
+ ctx.cwd
43640
+ ];
43641
+ if (approveMcps) {
43642
+ args.push("--approve-mcps");
43643
+ }
43644
+ const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
43645
+ if (shouldForceCursorAgent(ctx.config)) args.push("--force");
43646
+ if (ctx.config.mode === "plan" || ctx.config.mode === "review") {
43647
+ args.push("--mode", "plan");
43648
+ } else if (ctx.config.mode === "ask") {
43649
+ args.push("--mode", "ask");
43650
+ } else if (shouldUseReadOnlyRuntimePermissions(ctx.config)) {
43651
+ args.push("--mode", "plan");
43652
+ }
43653
+ if (resumeId) {
43654
+ args.push("--resume", resumeId);
43655
+ logResumeObservability("agent_resume_requested", {
43656
+ backendKind: "cursor_agent_cli",
43657
+ requestedResumeId: resumeId
43658
+ });
43659
+ }
43660
+ const model = ctx.config.selectedModel?.trim();
43661
+ if (model && isDispatchableCursorModel(model)) {
43662
+ const modelDef = findModelDef("cursor_agent_cli", model) ?? findModelDef("cursor_agent_cli", model.replace(/-fast$/, ""));
43663
+ args.push(
43664
+ "--model",
43665
+ buildCursorAgentModelArg(model, {
43666
+ selectedEffortLevel: ctx.config.selectedEffortLevel,
43667
+ selectedContextWindow: ctx.config.selectedContextWindow,
43668
+ effortLevels: modelDef?.capabilities?.effortLevels,
43669
+ contextWindows: modelDef?.capabilities?.contextWindows
43670
+ })
43657
43671
  );
43658
- const base = buildResumeAwarePrompt(ctx.config, ctx.promptText, { isResume });
43659
- const prompt = ctx.config.mode === "plan" ? buildPlanModePrefix(base) : base;
43660
- return appendImagePathReferences(prompt, imageFiles);
43661
- },
43662
- parseStructuredLine: parseCursorStructuredLine
43663
- }).run(runContext);
43672
+ }
43673
+ return [...args, ...defaultArgs];
43674
+ },
43675
+ // Prompt over stdin with immediate EOF (verified live on cursor-agent
43676
+ // 2026.07.09): vibe-kanban's mitigation for cursor-agent's documented
43677
+ // headless hangs. The result-race/grace-kill stays active via
43678
+ // keepStdinOpen; closeStdinAfterPrompt only skips holding stdin open,
43679
+ // which cursor never reads after the prompt anyway.
43680
+ promptViaStdin: true,
43681
+ keepStdinOpen: true,
43682
+ closeStdinAfterPrompt: true,
43683
+ // cursor-agent headless has a documented failure mode of hanging at startup
43684
+ // with zero output; without this watchdog only the 30-min server reaper
43685
+ // would end the run.
43686
+ startupTimeoutMs: 18e4,
43687
+ // Post-startup hang bound: cursor's asks use the non-blocking MCP model and it
43688
+ // never populates the idle timer's ask/background fire conditions, so a cursor
43689
+ // process that produced output then went silent (no result event) is otherwise
43690
+ // bounded only by the ~30-min external reaper. Poll every 5 min; kill after 15
43691
+ // min of continuous silence.
43692
+ resultIdleTimeoutMs: 5 * 6e4,
43693
+ postStartupSilenceTimeoutMs: 15 * 6e4,
43694
+ augmentPrompt: (ctx) => {
43695
+ const isResume = Boolean(
43696
+ ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim()
43697
+ );
43698
+ const base = buildResumeAwarePrompt(ctx.config, ctx.promptText, { isResume });
43699
+ const prompt = ctx.config.mode === "plan" ? buildPlanModePrefix(base) : base;
43700
+ return appendImagePathReferences(prompt, imageFiles);
43701
+ },
43702
+ parseStructuredLine: parseCursorStructuredLine
43703
+ }).run(runContext);
43704
+ const managed = context.config.alanMcp;
43705
+ try {
43706
+ return await (managed ? withCursorProjectMcpEntry(context.cwd, managed.url, runBackend) : runBackend());
43664
43707
  } finally {
43665
43708
  cleanup();
43666
43709
  }
@@ -44414,9 +44457,9 @@ function buildGrokAgentArgs(config2, defaultArgs = []) {
44414
44457
  return args;
44415
44458
  }
44416
44459
  var DEFAULT_SKILL_ROOTS = [
44417
- (0, import_path9.join)((0, import_os8.homedir)(), ".agents", "skills"),
44418
- (0, import_path9.join)((0, import_os8.homedir)(), ".claude", "skills"),
44419
- (0, import_path9.join)((0, import_os8.homedir)(), ".config", "opencode", "skills")
44460
+ (0, import_path10.join)((0, import_os8.homedir)(), ".agents", "skills"),
44461
+ (0, import_path10.join)((0, import_os8.homedir)(), ".claude", "skills"),
44462
+ (0, import_path10.join)((0, import_os8.homedir)(), ".config", "opencode", "skills")
44420
44463
  ];
44421
44464
  function parseFrontmatter(content) {
44422
44465
  if (!content.startsWith("---\n")) return {};
@@ -44436,7 +44479,7 @@ function listSkillFiles(root) {
44436
44479
  const files = [];
44437
44480
  for (const entry of (0, import_fs9.readdirSync)(root, { withFileTypes: true })) {
44438
44481
  if (!entry.isDirectory()) continue;
44439
- const skillPath = (0, import_path9.join)(root, entry.name, "SKILL.md");
44482
+ const skillPath = (0, import_path10.join)(root, entry.name, "SKILL.md");
44440
44483
  if ((0, import_fs9.existsSync)(skillPath)) files.push(skillPath);
44441
44484
  }
44442
44485
  return files;
@@ -44735,7 +44778,7 @@ function buildKimiMcpConfig(registration, externalServers = {}) {
44735
44778
  mcpServers[managedMcpServerName()] = {
44736
44779
  url: registration.url,
44737
44780
  headers: {
44738
- "x-alan-agent-credential": requireManagedAgentCredential(registration),
44781
+ Authorization: requireManagedAuthorization(registration),
44739
44782
  "x-alan-run-id": requireManagedRunId(registration)
44740
44783
  }
44741
44784
  };
@@ -44747,8 +44790,8 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
44747
44790
  supportTier: "structured",
44748
44791
  async run(context) {
44749
44792
  const registration = context.config.alanMcp;
44750
- const mcpDirectory = registration ? (0, import_fs8.mkdtempSync)((0, import_path8.join)((0, import_os7.tmpdir)(), "alan-kimi-mcp-")) : null;
44751
- const mcpConfigPath = mcpDirectory ? (0, import_path8.join)(mcpDirectory, "mcp.json") : null;
44793
+ const mcpDirectory = registration ? (0, import_fs8.mkdtempSync)((0, import_path9.join)((0, import_os7.tmpdir)(), "alan-kimi-mcp-")) : null;
44794
+ const mcpConfigPath = mcpDirectory ? (0, import_path9.join)(mcpDirectory, "mcp.json") : null;
44752
44795
  if (registration && mcpConfigPath) {
44753
44796
  (0, import_fs8.writeFileSync)(
44754
44797
  mcpConfigPath,
@@ -44827,7 +44870,7 @@ function buildManagedOpenCodeConfigContent(existing, registration) {
44827
44870
  type: "remote",
44828
44871
  url: registration.url,
44829
44872
  headers: {
44830
- "x-alan-agent-credential": `{env:${ALAN_AGENT_CREDENTIAL_ENV}}`,
44873
+ Authorization: `{env:${ALAN_MCP_AUTHORIZATION_ENV}}`,
44831
44874
  "x-alan-run-id": `{env:${ALAN_RUN_ID_ENV}}`
44832
44875
  },
44833
44876
  oauth: false,
@@ -44843,7 +44886,7 @@ function withManagedOpenCodeMcp(context) {
44843
44886
  ...context,
44844
44887
  env: {
44845
44888
  ...context.env,
44846
- [ALAN_AGENT_CREDENTIAL_ENV]: requireManagedAgentCredential(registration),
44889
+ [ALAN_MCP_AUTHORIZATION_ENV]: requireManagedAuthorization(registration),
44847
44890
  [ALAN_RUN_ID_ENV]: requireManagedRunId(registration),
44848
44891
  OPENCODE_CONFIG_CONTENT: buildManagedOpenCodeConfigContent(
44849
44892
  context.env.OPENCODE_CONFIG_CONTENT,
@@ -46706,14 +46749,14 @@ function normalizePath(candidate, cwd) {
46706
46749
  } catch {
46707
46750
  }
46708
46751
  if (path2.startsWith("~/")) return null;
46709
- if ((0, import_path10.isAbsolute)(path2)) return path2;
46710
- return cwd ? (0, import_path10.join)(cwd, path2) : null;
46752
+ if ((0, import_path11.isAbsolute)(path2)) return path2;
46753
+ return cwd ? (0, import_path11.join)(cwd, path2) : null;
46711
46754
  }
46712
46755
  function resolveToolCwd(cwd, toolInput) {
46713
46756
  if (!isRecord(toolInput)) return cwd;
46714
46757
  const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
46715
46758
  if (!raw) return cwd;
46716
- return (0, import_path10.isAbsolute)(raw) || !cwd ? raw : (0, import_path10.join)(cwd, raw);
46759
+ return (0, import_path11.isAbsolute)(raw) || !cwd ? raw : (0, import_path11.join)(cwd, raw);
46717
46760
  }
46718
46761
  function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
46719
46762
  if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
@@ -46758,7 +46801,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
46758
46801
  const path2 = normalizePath(candidate, effectiveCwd);
46759
46802
  if (!path2 || seen.has(path2) || !(0, import_fs10.existsSync)(path2)) continue;
46760
46803
  seen.add(path2);
46761
- const ext = (0, import_path10.extname)(path2).toLowerCase();
46804
+ const ext = (0, import_path11.extname)(path2).toLowerCase();
46762
46805
  const mimeType = IMAGE_MIME_BY_EXT[ext];
46763
46806
  if (!mimeType) continue;
46764
46807
  const stat2 = (0, import_fs10.statSync)(path2);
@@ -46768,7 +46811,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
46768
46811
  images.push({
46769
46812
  type: "generated_image",
46770
46813
  id: (0, import_crypto4.randomUUID)(),
46771
- filename: (0, import_path10.basename)(path2),
46814
+ filename: (0, import_path11.basename)(path2),
46772
46815
  mimeType,
46773
46816
  size: buffer.length,
46774
46817
  width,
@@ -46797,7 +46840,7 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
46797
46840
  const path2 = normalizePath(candidate, effectiveCwd);
46798
46841
  if (!path2 || seen.has(path2) || !(0, import_fs10.existsSync)(path2)) continue;
46799
46842
  seen.add(path2);
46800
- const ext = (0, import_path10.extname)(path2).toLowerCase();
46843
+ const ext = (0, import_path11.extname)(path2).toLowerCase();
46801
46844
  const mimeType = mimeByExt[ext];
46802
46845
  if (!mimeType) continue;
46803
46846
  const stat2 = (0, import_fs10.statSync)(path2);
@@ -46808,7 +46851,7 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
46808
46851
  type: "session_media",
46809
46852
  kind,
46810
46853
  id: (0, import_crypto4.randomUUID)(),
46811
- filename: (0, import_path10.basename)(path2),
46854
+ filename: (0, import_path11.basename)(path2),
46812
46855
  mimeType,
46813
46856
  size: buffer.length,
46814
46857
  width: dimensions?.width,
@@ -55520,7 +55563,7 @@ var CoreAgent = class _CoreAgent extends BaseMachineAgent {
55520
55563
  childProcess = null;
55521
55564
  _aborted = false;
55522
55565
  runId;
55523
- agentCredential;
55566
+ runtimeToken;
55524
55567
  providerApiKey;
55525
55568
  onProviderSpawned;
55526
55569
  cliEnvOverrides;
@@ -55529,7 +55572,7 @@ var CoreAgent = class _CoreAgent extends BaseMachineAgent {
55529
55572
  constructor(presenter, runtime) {
55530
55573
  super(presenter, runtime);
55531
55574
  this.runId = runtime.runId?.trim() || void 0;
55532
- this.agentCredential = runtime.agentCredential?.trim() || void 0;
55575
+ this.runtimeToken = runtime.runtimeToken?.trim() || void 0;
55533
55576
  this.providerApiKey = runtime.providerApiKey;
55534
55577
  this.onProviderSpawned = runtime.onProviderSpawned;
55535
55578
  this.cliEnvOverrides = runtime.cliEnvOverrides ?? {};
@@ -55667,8 +55710,8 @@ var CoreAgent = class _CoreAgent extends BaseMachineAgent {
55667
55710
  augmented.ALAN_MANAGED_RUN = "1";
55668
55711
  if (this.runId) augmented.ALAN_RUN_ID = this.runId;
55669
55712
  else delete augmented.ALAN_RUN_ID;
55670
- if (this.agentCredential) augmented.ALAN_AGENT_CREDENTIAL = this.agentCredential;
55671
- else delete augmented.ALAN_AGENT_CREDENTIAL;
55713
+ if (this.runtimeToken) augmented.ALAN_MCP_AUTHORIZATION = `Bearer ${this.runtimeToken}`;
55714
+ else delete augmented.ALAN_MCP_AUTHORIZATION;
55672
55715
  const backendKind = this.runtime.backendKind ?? "";
55673
55716
  const providerApiKey = this.providerApiKey ?? "";
55674
55717
  if (backendKind === "antigravity_cli" && providerApiKey.trim()) {
@@ -55843,14 +55886,14 @@ ${meta3.description}`);
55843
55886
 
55844
55887
  // src/managed-mcp.ts
55845
55888
  function buildManagedAlanMcp(input2) {
55846
- const agentCredential = input2.agentCredential.trim();
55889
+ const runtimeToken = input2.runtimeToken.trim();
55847
55890
  const runId = input2.runId.trim();
55848
- if (!agentCredential) throw new Error("Alan agent credential is missing");
55891
+ if (!runtimeToken) throw new Error("Alan runtime token is missing");
55849
55892
  if (!runId) throw new Error("Alan run ID is missing");
55850
55893
  return {
55851
55894
  url: new URL("/mcp", input2.apiUrl).toString(),
55852
55895
  headers: {
55853
- "x-alan-agent-credential": agentCredential,
55896
+ Authorization: `Bearer ${runtimeToken}`,
55854
55897
  "x-alan-run-id": runId
55855
55898
  }
55856
55899
  };
@@ -56379,6 +56422,7 @@ async function handleAgentExecute(ctx, payload) {
56379
56422
  runtimeId,
56380
56423
  runtimeSkillManager,
56381
56424
  getRuntimeToken,
56425
+ ensureRuntimeTokenForLaunch,
56382
56426
  eventOutbox,
56383
56427
  daemonSessionId,
56384
56428
  daemonEpoch,
@@ -56396,12 +56440,22 @@ async function handleAgentExecute(ctx, payload) {
56396
56440
  maintenanceReason,
56397
56441
  verifyActiveWorkspaceLease
56398
56442
  } = ctx;
56399
- const runtimeToken = getRuntimeToken();
56400
56443
  const heartbeatSeq = getHeartbeatSeq();
56401
56444
  const disconnectedSinceMs = getDisconnectedSinceMs();
56402
56445
  if (!payload?.runId || !payload.conversationId || typeof payload.content !== "string") {
56403
56446
  return;
56404
56447
  }
56448
+ const tokenReadiness = ensureRuntimeTokenForLaunch();
56449
+ const tokenReady = typeof tokenReadiness === "boolean" ? tokenReadiness : await tokenReadiness;
56450
+ if (!tokenReady) {
56451
+ socket.emit("agent.rejected", {
56452
+ runId: payload.runId,
56453
+ message: "This Computer could not renew its expired Alan credential. Run setup again.",
56454
+ code: "runtime_token_expired"
56455
+ });
56456
+ return;
56457
+ }
56458
+ const runtimeToken = getRuntimeToken();
56405
56459
  const isTaskWorkspacePayload = Boolean(
56406
56460
  payload.worktreeInfo?.worktreePath || payload.worktreeInfo?.allWorktrees?.length
56407
56461
  );
@@ -56641,7 +56695,7 @@ async function handleAgentExecute(ctx, payload) {
56641
56695
  };
56642
56696
  const alanMcp = buildManagedAlanMcp({
56643
56697
  apiUrl,
56644
- agentCredential: runtimeToken,
56698
+ runtimeToken,
56645
56699
  runId: payload.runId
56646
56700
  });
56647
56701
  if (!socket.connected) {
@@ -56811,7 +56865,7 @@ async function handleAgentExecute(ctx, payload) {
56811
56865
  backendKind,
56812
56866
  runtimeCommand,
56813
56867
  runId: payload.runId,
56814
- agentCredential: runtimeToken,
56868
+ runtimeToken,
56815
56869
  providerApiKey: payload.providerApiKey,
56816
56870
  onProviderSpawned: (pid) => {
56817
56871
  const entry = activeAgents.get(payload.runId);
@@ -58201,7 +58255,7 @@ async function exchangeRuntimeSetupGrant(input2, setupSignal) {
58201
58255
  throw new Error(`runtime registration failed: ${response.status} ${responseBody}`);
58202
58256
  }
58203
58257
  const body = await response.json();
58204
- if (typeof body.runtime?.id !== "string" || typeof body.runtime.credentialGeneration !== "number" || typeof body.runtimeToken !== "string" || !body.runtimeToken.startsWith("alan_runtime_") || typeof body.runtimeRenewalToken !== "string" || !body.runtimeRenewalToken.startsWith("alan_runtime_renew_")) {
58258
+ if (typeof body.runtime?.id !== "string" || typeof body.runtime.credentialGeneration !== "number" || typeof body.runtimeToken !== "string" || !body.runtimeToken.startsWith("alan_runtime_") || typeof body.runtimeRenewalToken !== "string" || !body.runtimeRenewalToken.startsWith("alan_runtime_renew_") || body.runtimeTokenExpiresAt !== void 0 && (typeof body.runtimeTokenExpiresAt !== "string" || !Number.isFinite(Date.parse(body.runtimeTokenExpiresAt)))) {
58205
58259
  throw new Error("runtime registration returned an invalid credential bundle");
58206
58260
  }
58207
58261
  return {
@@ -58209,7 +58263,8 @@ async function exchangeRuntimeSetupGrant(input2, setupSignal) {
58209
58263
  displayName: typeof body.runtime.displayName === "string" ? body.runtime.displayName : input2.displayName,
58210
58264
  credentialGeneration: body.runtime.credentialGeneration,
58211
58265
  runtimeToken: body.runtimeToken,
58212
- runtimeRenewalToken: body.runtimeRenewalToken
58266
+ runtimeRenewalToken: body.runtimeRenewalToken,
58267
+ runtimeTokenExpiresAt: typeof body.runtimeTokenExpiresAt === "string" ? body.runtimeTokenExpiresAt : void 0
58213
58268
  };
58214
58269
  }
58215
58270
  async function handoffRuntimeSetupGrant(input2) {
@@ -58236,13 +58291,13 @@ async function handoffRuntimeSetupGrant(input2) {
58236
58291
  // src/skills/local-skill-source.ts
58237
58292
  var import_node_buffer2 = require("buffer");
58238
58293
  var import_node_crypto14 = require("crypto");
58239
- var import_promises2 = require("fs/promises");
58294
+ var import_promises3 = require("fs/promises");
58240
58295
  var import_node_path20 = __toESM(require("path"), 1);
58241
58296
 
58242
58297
  // ../shared/dist/node/skill-package.js
58243
58298
  var import_node_buffer = require("buffer");
58244
58299
  var import_node_crypto13 = require("crypto");
58245
- var import_promises = require("fs/promises");
58300
+ var import_promises2 = require("fs/promises");
58246
58301
  var import_node_path19 = require("path");
58247
58302
  var import_yaml = __toESM(require_dist(), 1);
58248
58303
  var TREE_HASH_PREFIX = import_node_buffer.Buffer.from("alan-skill-tree-v1\0", "utf8");
@@ -58335,11 +58390,11 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
58335
58390
  if (!normalizedPath || normalizedPath !== path2 || normalizedPath.includes("\\") || components.some((component) => !component || component === "." || component === "..")) {
58336
58391
  throw new SkillPackageError("INVALID_PATH", `Invalid Skill package path: ${path2}`, path2);
58337
58392
  }
58338
- const absolutePath = await (0, import_promises.realpath)((0, import_node_path19.resolve)(root, ...components)).catch(() => null);
58393
+ const absolutePath = await (0, import_promises2.realpath)((0, import_node_path19.resolve)(root, ...components)).catch(() => null);
58339
58394
  if (!absolutePath || normalizeRelativePath(root, absolutePath) !== normalizedPath) {
58340
58395
  throw new SkillPackageError("INVALID_PATH", `Skill package file was not found: ${path2}`, path2);
58341
58396
  }
58342
- const entryStat = await (0, import_promises.lstat)(absolutePath);
58397
+ const entryStat = await (0, import_promises2.lstat)(absolutePath);
58343
58398
  if (!entryStat.isFile()) {
58344
58399
  throw new SkillPackageError("SPECIAL_FILE_BLOCKED", `Only regular files are allowed in Skill packages: ${path2}`, path2);
58345
58400
  }
@@ -58356,11 +58411,11 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
58356
58411
  return { file: read.manifest, bytes: read.bytes };
58357
58412
  }
58358
58413
  async function requirePackageRoot(packageRoot) {
58359
- const root = await (0, import_promises.realpath)((0, import_node_path19.resolve)(packageRoot)).catch(() => null);
58414
+ const root = await (0, import_promises2.realpath)((0, import_node_path19.resolve)(packageRoot)).catch(() => null);
58360
58415
  if (!root) {
58361
58416
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package directory does not exist");
58362
58417
  }
58363
- const rootStat = await (0, import_promises.lstat)(root);
58418
+ const rootStat = await (0, import_promises2.lstat)(root);
58364
58419
  if (!rootStat.isDirectory()) {
58365
58420
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package root must be a directory");
58366
58421
  }
@@ -58380,13 +58435,13 @@ async function walkPackage(root, ignoredPaths) {
58380
58435
  }
58381
58436
  return files;
58382
58437
  async function walkDirectory(directory) {
58383
- const entries = await (0, import_promises.readdir)(directory, { withFileTypes: true });
58438
+ const entries = await (0, import_promises2.readdir)(directory, { withFileTypes: true });
58384
58439
  for (const entry of entries) {
58385
58440
  const absolutePath = (0, import_node_path19.resolve)(directory, entry.name);
58386
58441
  const normalizedPath = normalizeRelativePath(root, absolutePath);
58387
58442
  if (isIgnored(normalizedPath, entry.name, entry.isDirectory(), ignored))
58388
58443
  continue;
58389
- const entryStat = await (0, import_promises.lstat)(absolutePath);
58444
+ const entryStat = await (0, import_promises2.lstat)(absolutePath);
58390
58445
  if (entryStat.isSymbolicLink()) {
58391
58446
  throw new SkillPackageError("SYMLINK_BLOCKED", `Nested symbolic links are not allowed in Skill packages: ${normalizedPath}`, normalizedPath);
58392
58447
  }
@@ -58495,7 +58550,7 @@ function isSecretPath(path2) {
58495
58550
  return name.endsWith(".private-key.pem") || name.endsWith(".private-key.key");
58496
58551
  }
58497
58552
  async function readPackageFile(file2) {
58498
- const bytes = await (0, import_promises.readFile)(file2.absolutePath);
58553
+ const bytes = await (0, import_promises2.readFile)(file2.absolutePath);
58499
58554
  return {
58500
58555
  bytes,
58501
58556
  manifest: {
@@ -59622,7 +59677,7 @@ var LocalSkillSource = class {
59622
59677
  async scanRootAsPackage(resolvedRoot, ignoredPaths, mode) {
59623
59678
  const directory = resolvedRoot.directory;
59624
59679
  if (!await pathExists((0, import_node_path20.join)(directory, "SKILL.md"))) return null;
59625
- const canonicalRoot = await (0, import_promises2.realpath)(directory).catch(() => directory);
59680
+ const canonicalRoot = await (0, import_promises3.realpath)(directory).catch(() => directory);
59626
59681
  const name = import_node_path20.default.basename(canonicalRoot);
59627
59682
  try {
59628
59683
  const fingerprint = await fingerprintPackage(canonicalRoot);
@@ -59671,7 +59726,7 @@ var LocalSkillSource = class {
59671
59726
  if (rootPackage) return rootPackage;
59672
59727
  let entries;
59673
59728
  try {
59674
- entries = await (0, import_promises2.readdir)(resolvedRoot.directory, { withFileTypes: true });
59729
+ entries = await (0, import_promises3.readdir)(resolvedRoot.directory, { withFileTypes: true });
59675
59730
  } catch (error61) {
59676
59731
  if (isAbsentDirectory(error61)) return { candidates: [], diagnostics: [], incomplete: false };
59677
59732
  return {
@@ -59688,13 +59743,13 @@ var LocalSkillSource = class {
59688
59743
  }
59689
59744
  const candidates = [];
59690
59745
  const diagnostics = [];
59691
- const canonicalRoot = await (0, import_promises2.realpath)(resolvedRoot.directory).catch(
59746
+ const canonicalRoot = await (0, import_promises3.realpath)(resolvedRoot.directory).catch(
59692
59747
  () => resolvedRoot.directory
59693
59748
  );
59694
59749
  for (const entry of entries) {
59695
59750
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
59696
59751
  const candidatePath = (0, import_node_path20.join)(resolvedRoot.directory, entry.name);
59697
- const canonicalPath = await (0, import_promises2.realpath)(candidatePath).catch(() => null);
59752
+ const canonicalPath = await (0, import_promises3.realpath)(candidatePath).catch(() => null);
59698
59753
  if (!canonicalPath) {
59699
59754
  diagnostics.push({
59700
59755
  code: "SOURCE_UNREADABLE",
@@ -59755,12 +59810,12 @@ async function fingerprintPackage(root) {
59755
59810
  await visit2(root, "");
59756
59811
  return `sha256:${hash2.digest("hex")}`;
59757
59812
  async function visit2(directory, relativeDirectory) {
59758
- const entries = await (0, import_promises2.readdir)(directory, { withFileTypes: true });
59813
+ const entries = await (0, import_promises3.readdir)(directory, { withFileTypes: true });
59759
59814
  entries.sort((left, right) => import_node_buffer2.Buffer.compare(import_node_buffer2.Buffer.from(left.name), import_node_buffer2.Buffer.from(right.name)));
59760
59815
  for (const entry of entries) {
59761
59816
  const path2 = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
59762
59817
  const absolutePath = (0, import_node_path20.join)(directory, entry.name);
59763
- const metadata = await (0, import_promises2.lstat)(absolutePath);
59818
+ const metadata = await (0, import_promises3.lstat)(absolutePath);
59764
59819
  hash2.update(path2.normalize("NFC")).update("\0").update(
59765
59820
  entry.isDirectory() ? "d" : entry.isFile() ? "f" : entry.isSymbolicLink() ? "l" : "o"
59766
59821
  ).update("\0").update(String(metadata.size)).update("\0").update(String(metadata.mtimeMs)).update("\0").update(String(metadata.mode & 511)).update("\0");
@@ -59779,7 +59834,7 @@ function staleCodexDeclaration(relativeDirectory, label, providerKinds) {
59779
59834
  }
59780
59835
  async function canonicalDirectories(directories) {
59781
59836
  const canonical = await Promise.all(
59782
- directories.map((directory) => (0, import_promises2.realpath)(directory).catch(() => directory))
59837
+ directories.map((directory) => (0, import_promises3.realpath)(directory).catch(() => directory))
59783
59838
  );
59784
59839
  return [...new Set(canonical)];
59785
59840
  }
@@ -59790,10 +59845,10 @@ function isWithinDirectory(parent, candidate) {
59790
59845
  async function loadSkillSourceConfig(homeDirectory2) {
59791
59846
  const configDirectory = (0, import_node_path20.join)(homeDirectory2, ".alan");
59792
59847
  const configPath = (0, import_node_path20.join)(configDirectory, "config.toml");
59793
- await (0, import_promises2.mkdir)(configDirectory, { recursive: true, mode: 448 });
59848
+ await (0, import_promises3.mkdir)(configDirectory, { recursive: true, mode: 448 });
59794
59849
  let created = false;
59795
59850
  try {
59796
- await (0, import_promises2.writeFile)(configPath, DEFAULT_SKILL_CONFIG, {
59851
+ await (0, import_promises3.writeFile)(configPath, DEFAULT_SKILL_CONFIG, {
59797
59852
  encoding: "utf8",
59798
59853
  flag: "wx",
59799
59854
  mode: 384
@@ -59802,7 +59857,7 @@ async function loadSkillSourceConfig(homeDirectory2) {
59802
59857
  } catch (error61) {
59803
59858
  if (!isAlreadyPresent(error61)) throw error61;
59804
59859
  }
59805
- const content = await (0, import_promises2.readFile)(configPath, "utf8");
59860
+ const content = await (0, import_promises3.readFile)(configPath, "utf8");
59806
59861
  try {
59807
59862
  return { state: "ready", config: parseSkillSourceConfig(content, homeDirectory2), created };
59808
59863
  } catch (error61) {
@@ -59988,7 +60043,7 @@ function deduplicateCandidatesByContent(candidates) {
59988
60043
  }
59989
60044
  async function pathExists(candidate) {
59990
60045
  try {
59991
- await (0, import_promises2.access)(candidate);
60046
+ await (0, import_promises3.access)(candidate);
59992
60047
  return true;
59993
60048
  } catch {
59994
60049
  return false;
@@ -59996,7 +60051,7 @@ async function pathExists(candidate) {
59996
60051
  }
59997
60052
  async function hasManagedMarker(directory) {
59998
60053
  try {
59999
- await (0, import_promises2.access)((0, import_node_path20.join)(directory, ".alan-managed.json"));
60054
+ await (0, import_promises3.access)((0, import_node_path20.join)(directory, ".alan-managed.json"));
60000
60055
  return true;
60001
60056
  } catch {
60002
60057
  return false;
@@ -60004,7 +60059,7 @@ async function hasManagedMarker(directory) {
60004
60059
  }
60005
60060
  async function isDirectory(path2) {
60006
60061
  try {
60007
- return (await (0, import_promises2.lstat)(path2)).isDirectory();
60062
+ return (await (0, import_promises3.lstat)(path2)).isDirectory();
60008
60063
  } catch {
60009
60064
  return false;
60010
60065
  }
@@ -60175,12 +60230,12 @@ var RuntimeSkillCoordinator = class {
60175
60230
  // src/skills/runtime-skill-manager.ts
60176
60231
  var import_node_buffer5 = require("buffer");
60177
60232
  var import_node_crypto17 = require("crypto");
60178
- var import_promises5 = require("fs/promises");
60233
+ var import_promises6 = require("fs/promises");
60179
60234
  var import_node_path23 = require("path");
60180
60235
 
60181
60236
  // src/skills/managed-skill-store.ts
60182
60237
  var import_node_crypto15 = require("crypto");
60183
- var import_promises3 = require("fs/promises");
60238
+ var import_promises4 = require("fs/promises");
60184
60239
  var import_node_path21 = require("path");
60185
60240
  var EMPTY_STATE = {
60186
60241
  version: 1,
@@ -60198,9 +60253,9 @@ var ManagedSkillStore = class _ManagedSkillStore {
60198
60253
  integrity;
60199
60254
  canRemoveManagedFiles;
60200
60255
  static async open(baseDirectory) {
60201
- await (0, import_promises3.mkdir)(baseDirectory, { recursive: true, mode: 448 });
60256
+ await (0, import_promises4.mkdir)(baseDirectory, { recursive: true, mode: 448 });
60202
60257
  try {
60203
- const parsed = JSON.parse(await (0, import_promises3.readFile)((0, import_node_path21.join)(baseDirectory, "state.json"), "utf8"));
60258
+ const parsed = JSON.parse(await (0, import_promises4.readFile)((0, import_node_path21.join)(baseDirectory, "state.json"), "utf8"));
60204
60259
  return new _ManagedSkillStore(baseDirectory, parseState(parsed), "verified");
60205
60260
  } catch (error61) {
60206
60261
  if (isMissingPath(error61)) {
@@ -60266,15 +60321,15 @@ var ManagedSkillStore = class _ManagedSkillStore {
60266
60321
  `.state.json.pending-${process.pid}-${(0, import_node_crypto15.randomBytes)(6).toString("hex")}`
60267
60322
  );
60268
60323
  try {
60269
- await (0, import_promises3.writeFile)(pendingPath, `${JSON.stringify(this.state, null, 2)}
60324
+ await (0, import_promises4.writeFile)(pendingPath, `${JSON.stringify(this.state, null, 2)}
60270
60325
  `, {
60271
60326
  encoding: "utf8",
60272
60327
  flag: "wx",
60273
60328
  mode: 384
60274
60329
  });
60275
- await (0, import_promises3.rename)(pendingPath, statePath);
60330
+ await (0, import_promises4.rename)(pendingPath, statePath);
60276
60331
  } finally {
60277
- await (0, import_promises3.rm)(pendingPath, { force: true });
60332
+ await (0, import_promises4.rm)(pendingPath, { force: true });
60278
60333
  }
60279
60334
  }
60280
60335
  };
@@ -60332,7 +60387,7 @@ function isMissingPath(error61) {
60332
60387
  // ../shared/dist/node/skill-bundle.js
60333
60388
  var import_node_buffer3 = require("buffer");
60334
60389
  var import_node_crypto16 = require("crypto");
60335
- var import_promises4 = require("fs/promises");
60390
+ var import_promises5 = require("fs/promises");
60336
60391
  var import_node_path22 = require("path");
60337
60392
  var import_node_stream = require("stream");
60338
60393
  var import_node_zlib = require("zlib");
@@ -60342,7 +60397,7 @@ async function createSkillBundle(packageRoot, options = {}) {
60342
60397
  const archive = (0, import_tar_stream.pack)();
60343
60398
  const tarPromise = collectStream(archive);
60344
60399
  for (const file2 of before.files) {
60345
- const bytes2 = await (0, import_promises4.readFile)((0, import_node_path22.join)(packageRoot, ...file2.path.split("/")));
60400
+ const bytes2 = await (0, import_promises5.readFile)((0, import_node_path22.join)(packageRoot, ...file2.path.split("/")));
60346
60401
  await addArchiveEntry(archive, {
60347
60402
  name: file2.path,
60348
60403
  type: "file",
@@ -60374,7 +60429,7 @@ async function extractSkillBundle(archiveBytes, destination, expected) {
60374
60429
  throw new Error("Skill archive hash does not match the expected immutable Version");
60375
60430
  }
60376
60431
  const tarBytes = await decompressBounded(archiveBytes);
60377
- await (0, import_promises4.mkdir)(destination, { recursive: false, mode: 448 });
60432
+ await (0, import_promises5.mkdir)(destination, { recursive: false, mode: 448 });
60378
60433
  try {
60379
60434
  await extractTar(tarBytes, destination);
60380
60435
  const inspected = await inspectSkillPackage(destination, { expectedName: null });
@@ -60382,7 +60437,7 @@ async function extractSkillBundle(archiveBytes, destination, expected) {
60382
60437
  throw new Error("Extracted Skill package hash does not match the expected immutable Version");
60383
60438
  }
60384
60439
  } catch (error61) {
60385
- await (0, import_promises4.rm)(destination, { recursive: true, force: true });
60440
+ await (0, import_promises5.rm)(destination, { recursive: true, force: true });
60386
60441
  throw error61;
60387
60442
  }
60388
60443
  }
@@ -60458,8 +60513,8 @@ async function extractEntry(header, stream, destination, limits) {
60458
60513
  throw new Error(`Skill archive file size is invalid: ${path2}`);
60459
60514
  }
60460
60515
  const outputPath = (0, import_node_path22.join)(destination, ...path2.split("/"));
60461
- await (0, import_promises4.mkdir)((0, import_node_path22.dirname)(outputPath), { recursive: true, mode: 448 });
60462
- await (0, import_promises4.writeFile)(outputPath, bytes, { mode: (header.mode ?? 420) & 73 ? 493 : 420 });
60516
+ await (0, import_promises5.mkdir)((0, import_node_path22.dirname)(outputPath), { recursive: true, mode: 448 });
60517
+ await (0, import_promises5.writeFile)(outputPath, bytes, { mode: (header.mode ?? 420) & 73 ? 493 : 420 });
60463
60518
  }
60464
60519
  function requireSafeArchivePath(value2) {
60465
60520
  const normalized = value2.replaceAll("\\", "/").normalize("NFC");
@@ -60719,12 +60774,12 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60719
60774
  }
60720
60775
  async reconcileUnlocked(manifest) {
60721
60776
  const desired = desiredSkillManifestSchema.parse(manifest);
60722
- await (0, import_promises5.mkdir)(this.managedSkillsDirectory, { recursive: true, mode: 448 });
60723
- await (0, import_promises5.mkdir)((0, import_node_path23.join)(this.skillsStateDirectory, "cache", "sha256"), {
60777
+ await (0, import_promises6.mkdir)(this.managedSkillsDirectory, { recursive: true, mode: 448 });
60778
+ await (0, import_promises6.mkdir)((0, import_node_path23.join)(this.skillsStateDirectory, "cache", "sha256"), {
60724
60779
  recursive: true,
60725
60780
  mode: 448
60726
60781
  });
60727
- await (0, import_promises5.mkdir)((0, import_node_path23.join)(this.skillsStateDirectory, "tmp"), { recursive: true, mode: 448 });
60782
+ await (0, import_promises6.mkdir)((0, import_node_path23.join)(this.skillsStateDirectory, "tmp"), { recursive: true, mode: 448 });
60728
60783
  const results = [];
60729
60784
  const nextProjections = {};
60730
60785
  for (const entry of desired.skills) {
@@ -60847,52 +60902,52 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60847
60902
  let sourceMoved = false;
60848
60903
  let destinationInstalled = false;
60849
60904
  try {
60850
- await (0, import_promises5.rename)(source, backup);
60905
+ await (0, import_promises6.rename)(source, backup);
60851
60906
  sourceMoved = true;
60852
- await (0, import_promises5.cp)(backup, pending, { recursive: true, errorOnExist: true, force: false });
60907
+ await (0, import_promises6.cp)(backup, pending, { recursive: true, errorOnExist: true, force: false });
60853
60908
  const skillMarkdown = (0, import_node_path23.join)(pending, "SKILL.md");
60854
- await (0, import_promises5.writeFile)(
60909
+ await (0, import_promises6.writeFile)(
60855
60910
  skillMarkdown,
60856
- rewriteSkillMarkdownName(await (0, import_promises5.readFile)(skillMarkdown, "utf8"), name),
60911
+ rewriteSkillMarkdownName(await (0, import_promises6.readFile)(skillMarkdown, "utf8"), name),
60857
60912
  {
60858
60913
  encoding: "utf8",
60859
60914
  mode: 420
60860
60915
  }
60861
60916
  );
60862
60917
  await inspectSkillPackage(pending, { expectedName: name });
60863
- await (0, import_promises5.rename)(pending, destination);
60918
+ await (0, import_promises6.rename)(pending, destination);
60864
60919
  destinationInstalled = true;
60865
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60920
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60866
60921
  } catch (error61) {
60867
- if (destinationInstalled) await (0, import_promises5.rm)(destination, { recursive: true, force: true });
60922
+ if (destinationInstalled) await (0, import_promises6.rm)(destination, { recursive: true, force: true });
60868
60923
  if (sourceMoved && await pathExists2(backup) && !await pathExists2(source)) {
60869
- await (0, import_promises5.rename)(backup, source);
60924
+ await (0, import_promises6.rename)(backup, source);
60870
60925
  }
60871
60926
  throw error61;
60872
60927
  } finally {
60873
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
60928
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
60874
60929
  if (!sourceMoved || destinationInstalled) {
60875
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60930
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60876
60931
  }
60877
60932
  }
60878
60933
  }
60879
60934
  async overwriteLocalConflict(input2, entry, conflict, manifest) {
60880
60935
  const source = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
60881
60936
  const backup = `${source}.overwrite-backup-${process.pid}-${(0, import_node_crypto17.randomBytes)(8).toString("hex")}`;
60882
- await (0, import_promises5.rename)(source, backup);
60937
+ await (0, import_promises6.rename)(source, backup);
60883
60938
  try {
60884
60939
  const reconciled = await this.reconcileUnlocked(manifest);
60885
60940
  const result = resolutionFromReconcile(input2, reconciled);
60886
60941
  if (result.state !== "applied") {
60887
60942
  await this.removeResolvedProjection(entry, conflict.kind);
60888
- await (0, import_promises5.rename)(backup, source);
60943
+ await (0, import_promises6.rename)(backup, source);
60889
60944
  return result;
60890
60945
  }
60891
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60946
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60892
60947
  return result;
60893
60948
  } catch (error61) {
60894
60949
  await this.removeResolvedProjection(entry, conflict.kind).catch(() => void 0);
60895
- if (!await pathExists2(source) && await pathExists2(backup)) await (0, import_promises5.rename)(backup, source);
60950
+ if (!await pathExists2(source) && await pathExists2(backup)) await (0, import_promises6.rename)(backup, source);
60896
60951
  throw error61;
60897
60952
  }
60898
60953
  }
@@ -60902,7 +60957,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60902
60957
  if (conflictKind === "managed_destination") {
60903
60958
  const marker = await readMarker(destination);
60904
60959
  if (marker?.skillId === entry.skillId && marker.versionId === entry.versionId && marker.contentHash === entry.contentHash) {
60905
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
60960
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
60906
60961
  }
60907
60962
  return;
60908
60963
  }
@@ -60934,16 +60989,16 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60934
60989
  if (!await legacyFileMatches(source, legacy.hash) || !await packageMatches(source, entry.contentHash)) {
60935
60990
  return;
60936
60991
  }
60937
- await (0, import_promises5.rename)(source, destination);
60992
+ await (0, import_promises6.rename)(source, destination);
60938
60993
  try {
60939
- await (0, import_promises5.writeFile)(
60994
+ await (0, import_promises6.writeFile)(
60940
60995
  (0, import_node_path23.join)(destination, ".alan-managed.json"),
60941
60996
  `${JSON.stringify(markerFor(entry), null, 2)}
60942
60997
  `,
60943
60998
  { encoding: "utf8", flag: "wx", mode: 384 }
60944
60999
  );
60945
61000
  } catch (error61) {
60946
- await (0, import_promises5.rename)(destination, source).catch(() => void 0);
61001
+ await (0, import_promises6.rename)(destination, source).catch(() => void 0);
60947
61002
  throw error61;
60948
61003
  }
60949
61004
  await removeExactLegacySkill((0, import_node_path23.join)(this.compatibilitySkillsDirectory, entry.slug), legacy.hash);
@@ -60956,7 +61011,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60956
61011
  await removeExactLegacySkill((0, import_node_path23.join)(this.managedSkillsDirectory, command), entry.hash);
60957
61012
  await removeExactLegacySkill((0, import_node_path23.join)(this.compatibilitySkillsDirectory, command), entry.hash);
60958
61013
  }
60959
- await (0, import_promises5.rm)(this.legacyManifestPath, { force: true });
61014
+ await (0, import_promises6.rm)(this.legacyManifestPath, { force: true });
60960
61015
  }
60961
61016
  async ensureCached(entry) {
60962
61017
  const cacheDirectory = (0, import_node_path23.join)(
@@ -60966,7 +61021,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60966
61021
  entry.contentHash.slice("sha256:".length)
60967
61022
  );
60968
61023
  if (await packageMatches(cacheDirectory, entry.contentHash)) return cacheDirectory;
60969
- await (0, import_promises5.rm)(cacheDirectory, { recursive: true, force: true });
61024
+ await (0, import_promises6.rm)(cacheDirectory, { recursive: true, force: true });
60970
61025
  const bytes = await this.downloadBundle(entry);
60971
61026
  if (bytes.byteLength !== entry.compressedBytes) {
60972
61027
  throw new Error(
@@ -60984,12 +61039,12 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60984
61039
  expectedContentHash: entry.contentHash
60985
61040
  });
60986
61041
  try {
60987
- await (0, import_promises5.rename)(pendingDirectory, cacheDirectory);
61042
+ await (0, import_promises6.rename)(pendingDirectory, cacheDirectory);
60988
61043
  } catch (error61) {
60989
61044
  if (!await packageMatches(cacheDirectory, entry.contentHash)) throw error61;
60990
61045
  }
60991
61046
  } finally {
60992
- await (0, import_promises5.rm)(pendingDirectory, { recursive: true, force: true });
61047
+ await (0, import_promises6.rm)(pendingDirectory, { recursive: true, force: true });
60993
61048
  }
60994
61049
  return cacheDirectory;
60995
61050
  }
@@ -61007,8 +61062,8 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61007
61062
  let installedPending = false;
61008
61063
  let completed = false;
61009
61064
  try {
61010
- await (0, import_promises5.cp)(cacheDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61011
- await (0, import_promises5.writeFile)(
61065
+ await (0, import_promises6.cp)(cacheDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61066
+ await (0, import_promises6.writeFile)(
61012
61067
  (0, import_node_path23.join)(pending, ".alan-managed.json"),
61013
61068
  `${JSON.stringify(markerFor(entry), null, 2)}
61014
61069
  `,
@@ -61018,14 +61073,14 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61018
61073
  throw new Error("Pending managed Skill projection failed content verification");
61019
61074
  }
61020
61075
  if (await pathExists2(destination)) {
61021
- await (0, import_promises5.rename)(destination, backup);
61076
+ await (0, import_promises6.rename)(destination, backup);
61022
61077
  movedExisting = true;
61023
61078
  }
61024
61079
  try {
61025
- await (0, import_promises5.rename)(pending, destination);
61080
+ await (0, import_promises6.rename)(pending, destination);
61026
61081
  installedPending = true;
61027
61082
  } catch (error61) {
61028
- if (movedExisting) await (0, import_promises5.rename)(backup, destination);
61083
+ if (movedExisting) await (0, import_promises6.rename)(backup, destination);
61029
61084
  throw error61;
61030
61085
  }
61031
61086
  const inspected = await inspectSkillPackage(destination, { expectedName: null });
@@ -61034,18 +61089,18 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61034
61089
  }
61035
61090
  await this.ensureCompatibilityProjection(entry, destination);
61036
61091
  completed = true;
61037
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
61092
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
61038
61093
  return inspected.contentHash;
61039
61094
  } catch (error61) {
61040
61095
  if (!completed && installedPending) {
61041
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61042
- if (movedExisting && await pathExists2(backup)) await (0, import_promises5.rename)(backup, destination);
61096
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
61097
+ if (movedExisting && await pathExists2(backup)) await (0, import_promises6.rename)(backup, destination);
61043
61098
  }
61044
61099
  throw error61;
61045
61100
  } finally {
61046
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
61101
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
61047
61102
  if (completed || !movedExisting) {
61048
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
61103
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
61049
61104
  }
61050
61105
  }
61051
61106
  }
@@ -61086,7 +61141,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61086
61141
  });
61087
61142
  continue;
61088
61143
  }
61089
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61144
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
61090
61145
  } else {
61091
61146
  failures.push({
61092
61147
  skillId: recorded.skillId,
@@ -61101,7 +61156,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61101
61156
  return failures;
61102
61157
  }
61103
61158
  async ensureCompatibilityProjection(entry, canonicalDirectory) {
61104
- await (0, import_promises5.mkdir)(this.compatibilitySkillsDirectory, { recursive: true, mode: 448 });
61159
+ await (0, import_promises6.mkdir)(this.compatibilitySkillsDirectory, { recursive: true, mode: 448 });
61105
61160
  const destination = (0, import_node_path23.join)(
61106
61161
  this.compatibilitySkillsDirectory,
61107
61162
  this.projectionDirectoryName(entry.runtimeDirectory)
@@ -61111,23 +61166,23 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61111
61166
  throw unmanagedCompatibilityConflict(entry.runtimeDirectory);
61112
61167
  }
61113
61168
  try {
61114
- await (0, import_promises5.symlink)(canonicalDirectory, destination, "dir");
61169
+ await (0, import_promises6.symlink)(canonicalDirectory, destination, "dir");
61115
61170
  return;
61116
61171
  } catch (error61) {
61117
61172
  if (!isSymlinkUnsupported(error61)) throw error61;
61118
61173
  }
61119
61174
  const pending = `${destination}.pending-${process.pid}-${(0, import_node_crypto17.randomBytes)(6).toString("hex")}`;
61120
61175
  try {
61121
- await (0, import_promises5.cp)(canonicalDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61122
- await (0, import_promises5.writeFile)(
61176
+ await (0, import_promises6.cp)(canonicalDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61177
+ await (0, import_promises6.writeFile)(
61123
61178
  (0, import_node_path23.join)(pending, ".alan-compatibility.json"),
61124
61179
  `${JSON.stringify({ ...markerFor(entry), canonicalDirectory }, null, 2)}
61125
61180
  `,
61126
61181
  { encoding: "utf8", flag: "wx", mode: 384 }
61127
61182
  );
61128
- await (0, import_promises5.rename)(pending, destination);
61183
+ await (0, import_promises6.rename)(pending, destination);
61129
61184
  } finally {
61130
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
61185
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
61131
61186
  }
61132
61187
  }
61133
61188
  async runExclusively(work) {
@@ -61151,29 +61206,29 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61151
61206
  return this.storageNamespace ? `${runtimeDirectory}--alan-${this.storageNamespace}` : runtimeDirectory;
61152
61207
  }
61153
61208
  async withMachineLock(work) {
61154
- await (0, import_promises5.mkdir)(this.skillsStateDirectory, { recursive: true, mode: 448 });
61209
+ await (0, import_promises6.mkdir)(this.skillsStateDirectory, { recursive: true, mode: 448 });
61155
61210
  const lockDirectory = (0, import_node_path23.join)(this.skillsStateDirectory, "manager.lock");
61156
61211
  const deadline = Date.now() + 3e4;
61157
61212
  while (true) {
61158
61213
  try {
61159
- await (0, import_promises5.mkdir)(lockDirectory, { mode: 448 });
61214
+ await (0, import_promises6.mkdir)(lockDirectory, { mode: 448 });
61160
61215
  try {
61161
- await (0, import_promises5.writeFile)(
61216
+ await (0, import_promises6.writeFile)(
61162
61217
  (0, import_node_path23.join)(lockDirectory, "owner.json"),
61163
61218
  `${JSON.stringify({ pid: process.pid, acquiredAt: (/* @__PURE__ */ new Date()).toISOString() })}
61164
61219
  `,
61165
61220
  { encoding: "utf8", flag: "wx", mode: 384 }
61166
61221
  );
61167
61222
  } catch (error61) {
61168
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61223
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61169
61224
  throw error61;
61170
61225
  }
61171
61226
  break;
61172
61227
  } catch (error61) {
61173
61228
  if (!isAlreadyPresent2(error61)) throw error61;
61174
- const ageMs = await (0, import_promises5.stat)(lockDirectory).then((metadata) => Date.now() - metadata.mtimeMs).catch(() => 0);
61229
+ const ageMs = await (0, import_promises6.stat)(lockDirectory).then((metadata) => Date.now() - metadata.mtimeMs).catch(() => 0);
61175
61230
  if (ageMs > 15 * 6e4) {
61176
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61231
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61177
61232
  continue;
61178
61233
  }
61179
61234
  if (Date.now() >= deadline) {
@@ -61187,7 +61242,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61187
61242
  try {
61188
61243
  return await work();
61189
61244
  } finally {
61190
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61245
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61191
61246
  }
61192
61247
  }
61193
61248
  };
@@ -61209,7 +61264,7 @@ async function packageMatches(directory, expectedHash) {
61209
61264
  async function readMarker(directory) {
61210
61265
  try {
61211
61266
  const value2 = JSON.parse(
61212
- await (0, import_promises5.readFile)((0, import_node_path23.join)(directory, ".alan-managed.json"), "utf8")
61267
+ await (0, import_promises6.readFile)((0, import_node_path23.join)(directory, ".alan-managed.json"), "utf8")
61213
61268
  );
61214
61269
  if (typeof value2 !== "object" || value2 === null || !("protocolVersion" in value2) || value2.protocolVersion !== SKILLS_PROTOCOL_VERSION || !("skillId" in value2) || typeof value2.skillId !== "string" || !("versionId" in value2) || typeof value2.versionId !== "string" || !("contentHash" in value2) || typeof value2.contentHash !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value2.contentHash)) {
61215
61270
  return null;
@@ -61220,9 +61275,9 @@ async function readMarker(directory) {
61220
61275
  }
61221
61276
  }
61222
61277
  async function compatibilityProjectionMatches(destination, canonicalDirectory, entry) {
61223
- const metadata = await (0, import_promises5.lstat)(destination);
61278
+ const metadata = await (0, import_promises6.lstat)(destination);
61224
61279
  if (metadata.isSymbolicLink()) {
61225
- const target = await (0, import_promises5.readlink)(destination);
61280
+ const target = await (0, import_promises6.readlink)(destination);
61226
61281
  return (0, import_node_path23.resolve)((0, import_node_path23.dirname)(destination), target) === (0, import_node_path23.resolve)(canonicalDirectory);
61227
61282
  }
61228
61283
  if (!metadata.isDirectory()) return false;
@@ -61231,22 +61286,22 @@ async function compatibilityProjectionMatches(destination, canonicalDirectory, e
61231
61286
  }
61232
61287
  async function removeCompatibilityProjection(destination, canonicalDirectory, projection) {
61233
61288
  if (!await pathExists2(destination)) return true;
61234
- const metadata = await (0, import_promises5.lstat)(destination);
61289
+ const metadata = await (0, import_promises6.lstat)(destination);
61235
61290
  if (metadata.isSymbolicLink()) {
61236
- const target = await (0, import_promises5.readlink)(destination);
61291
+ const target = await (0, import_promises6.readlink)(destination);
61237
61292
  if ((0, import_node_path23.resolve)((0, import_node_path23.dirname)(destination), target) !== (0, import_node_path23.resolve)(canonicalDirectory)) return false;
61238
- await (0, import_promises5.rm)(destination, { force: true });
61293
+ await (0, import_promises6.rm)(destination, { force: true });
61239
61294
  return true;
61240
61295
  }
61241
61296
  const marker = await readCompatibilityMarker(destination);
61242
61297
  if (!marker || !markerMatchesProjection(marker, projection)) return false;
61243
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61298
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
61244
61299
  return true;
61245
61300
  }
61246
61301
  async function readCompatibilityMarker(directory) {
61247
61302
  try {
61248
61303
  const value2 = JSON.parse(
61249
- await (0, import_promises5.readFile)((0, import_node_path23.join)(directory, ".alan-compatibility.json"), "utf8")
61304
+ await (0, import_promises6.readFile)((0, import_node_path23.join)(directory, ".alan-compatibility.json"), "utf8")
61250
61305
  );
61251
61306
  if (value2.protocolVersion !== SKILLS_PROTOCOL_VERSION || typeof value2.skillId !== "string" || typeof value2.versionId !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value2.contentHash) || typeof value2.canonicalDirectory !== "string") {
61252
61307
  return null;
@@ -61266,7 +61321,7 @@ function markerFor(entry) {
61266
61321
  }
61267
61322
  async function readLegacyManifest(path2) {
61268
61323
  try {
61269
- const value2 = JSON.parse(await (0, import_promises5.readFile)(path2, "utf8"));
61324
+ const value2 = JSON.parse(await (0, import_promises6.readFile)(path2, "utf8"));
61270
61325
  if (!value2 || typeof value2 !== "object" || !("skills" in value2)) return null;
61271
61326
  const skillsValue = value2.skills;
61272
61327
  if (!skillsValue || typeof skillsValue !== "object" || Array.isArray(skillsValue)) return null;
@@ -61284,9 +61339,9 @@ async function readLegacyManifest(path2) {
61284
61339
  }
61285
61340
  async function legacyFileMatches(directory, expectedHash) {
61286
61341
  try {
61287
- const metadata = await (0, import_promises5.lstat)(directory);
61342
+ const metadata = await (0, import_promises6.lstat)(directory);
61288
61343
  if (!metadata.isDirectory() || metadata.isSymbolicLink()) return false;
61289
- const content = await (0, import_promises5.readFile)((0, import_node_path23.join)(directory, "SKILL.md"));
61344
+ const content = await (0, import_promises6.readFile)((0, import_node_path23.join)(directory, "SKILL.md"));
61290
61345
  return (0, import_node_crypto17.createHash)("sha256").update(content).digest("hex").slice(0, 16) === expectedHash;
61291
61346
  } catch {
61292
61347
  return false;
@@ -61294,9 +61349,9 @@ async function legacyFileMatches(directory, expectedHash) {
61294
61349
  }
61295
61350
  async function removeExactLegacySkill(directory, expectedHash) {
61296
61351
  if (!await legacyFileMatches(directory, expectedHash)) return;
61297
- await (0, import_promises5.rm)((0, import_node_path23.join)(directory, "SKILL.md"), { force: true });
61298
- const remaining = await (0, import_promises5.readdir)(directory);
61299
- if (remaining.length === 0) await (0, import_promises5.rm)(directory, { recursive: true, force: true });
61352
+ await (0, import_promises6.rm)((0, import_node_path23.join)(directory, "SKILL.md"), { force: true });
61353
+ const remaining = await (0, import_promises6.readdir)(directory);
61354
+ if (remaining.length === 0) await (0, import_promises6.rm)(directory, { recursive: true, force: true });
61300
61355
  }
61301
61356
  function markerMatchesProjection(marker, projection) {
61302
61357
  return marker.skillId === projection.skillId && marker.versionId === projection.versionId && marker.contentHash === projection.contentHash;
@@ -61389,7 +61444,7 @@ function localTextMediaType(path2) {
61389
61444
  }
61390
61445
  async function pathExists2(path2) {
61391
61446
  try {
61392
- await (0, import_promises5.lstat)(path2);
61447
+ await (0, import_promises6.lstat)(path2);
61393
61448
  return true;
61394
61449
  } catch (error61) {
61395
61450
  if (isMissingPath2(error61)) return false;
@@ -61479,6 +61534,12 @@ var SuspensionDetector = class {
61479
61534
  };
61480
61535
 
61481
61536
  // src/daemon-start.ts
61537
+ var RUNTIME_TOKEN_RENEWAL_WINDOW_MS = 24 * 60 * 60 * 1e3;
61538
+ function runtimeTokenNeedsRenewal(expiresAt, nowMs = Date.now()) {
61539
+ if (!expiresAt) return true;
61540
+ const expiresAtMs = Date.parse(expiresAt);
61541
+ return !Number.isFinite(expiresAtMs) || expiresAtMs <= nowMs + RUNTIME_TOKEN_RENEWAL_WINDOW_MS;
61542
+ }
61482
61543
  async function startDaemon(args) {
61483
61544
  bindConfigPath(args);
61484
61545
  const stored = readConfig();
@@ -61491,6 +61552,7 @@ async function startDaemon(args) {
61491
61552
  const runtimeTokenOverride = argValue(args, "--token") ?? process.env.ALAN_RUNTIME_TOKEN;
61492
61553
  let runtimeToken = runtimeTokenOverride ?? stored.runtimeToken;
61493
61554
  let runtimeRenewalToken = runtimeTokenOverride ? void 0 : stored.runtimeRenewalToken;
61555
+ let runtimeTokenExpiresAt = runtimeTokenOverride ? void 0 : stored.runtimeTokenExpiresAt;
61494
61556
  const wsUrlOverride = argValue(args, "--ws-url") ?? process.env.ALAN_WS_URL;
61495
61557
  const endpointMismatch = wsUrlOverride ? null : checkStoredEndpointConsistency(stored, readEndpointDefaults());
61496
61558
  let wsUrl = wsUrlOverride ?? stored.wsUrl;
@@ -61835,14 +61897,14 @@ async function startDaemon(args) {
61835
61897
  if (runtimeRenewalInFlight) return runtimeRenewalInFlight;
61836
61898
  const attempt = runCredentialOperation(async () => {
61837
61899
  const renewalToken = runtimeRenewalToken;
61838
- if (!stored.apiUrl || !renewalToken) {
61900
+ if (!renewalToken) {
61839
61901
  return false;
61840
61902
  }
61841
61903
  let response = null;
61842
61904
  let transportError = null;
61843
61905
  for (let retry = 1; retry <= 3; retry += 1) {
61844
61906
  try {
61845
- response = await fetch(`${stored.apiUrl}/public/runtimes/${runtimeId}/tokens/renew`, {
61907
+ response = await fetch(`${apiUrl}/public/runtimes/${runtimeId}/tokens/renew`, {
61846
61908
  method: "POST",
61847
61909
  headers: {
61848
61910
  authorization: `Bearer ${renewalToken}`,
@@ -61874,7 +61936,7 @@ async function startDaemon(args) {
61874
61936
  return false;
61875
61937
  }
61876
61938
  const body = await response.json();
61877
- if (typeof body.runtimeToken !== "string" || !body.runtimeToken.startsWith("alan_runtime_")) {
61939
+ if (typeof body.runtimeToken !== "string" || !body.runtimeToken.startsWith("alan_runtime_") || typeof body.runtimeTokenExpiresAt !== "string" || !Number.isFinite(Date.parse(body.runtimeTokenExpiresAt))) {
61878
61940
  rememberConnectErrorCode("runtime_renewal_failed");
61879
61941
  lastConnectError = "Runtime renewal returned an invalid access token";
61880
61942
  pushLog("runtime-renewal-invalid-response");
@@ -61887,8 +61949,13 @@ async function startDaemon(args) {
61887
61949
  pushLog("runtime-renewal-superseded");
61888
61950
  return false;
61889
61951
  }
61952
+ const replacementExpiresAt = body.runtimeTokenExpiresAt;
61890
61953
  try {
61891
- writeConfig({ ...current, runtimeToken: body.runtimeToken });
61954
+ writeConfig({
61955
+ ...current,
61956
+ runtimeToken: body.runtimeToken,
61957
+ runtimeTokenExpiresAt: replacementExpiresAt
61958
+ });
61892
61959
  } catch (error61) {
61893
61960
  rememberConnectErrorCode("config_write_failed");
61894
61961
  lastConnectError = `Runtime renewal could not save its replacement: ${error61.message}`;
@@ -61896,6 +61963,7 @@ async function startDaemon(args) {
61896
61963
  return false;
61897
61964
  }
61898
61965
  runtimeToken = body.runtimeToken;
61966
+ runtimeTokenExpiresAt = replacementExpiresAt;
61899
61967
  socket.auth = { token: body.runtimeToken };
61900
61968
  clearConnectErrors();
61901
61969
  pushLog("runtime-renewal-succeeded");
@@ -61909,6 +61977,14 @@ async function startDaemon(args) {
61909
61977
  });
61910
61978
  return attempt;
61911
61979
  };
61980
+ const ensureRuntimeTokenForLaunch = () => {
61981
+ if (!runtimeRenewalToken || !runtimeTokenNeedsRenewal(runtimeTokenExpiresAt)) return true;
61982
+ return renewRuntimeLease().then((renewed) => {
61983
+ if (renewed) return true;
61984
+ if (!runtimeTokenExpiresAt) return socket.connected;
61985
+ return Date.parse(runtimeTokenExpiresAt) > Date.now();
61986
+ });
61987
+ };
61912
61988
  let queueIdentityRestart = () => {
61913
61989
  };
61914
61990
  let runtimeSetupInFlight = null;
@@ -61935,6 +62011,7 @@ async function startDaemon(args) {
61935
62011
  runtimeId: bundle.runtimeId,
61936
62012
  runtimeToken: bundle.runtimeToken,
61937
62013
  runtimeRenewalToken: bundle.runtimeRenewalToken,
62014
+ runtimeTokenExpiresAt: bundle.runtimeTokenExpiresAt,
61938
62015
  displayName: bundle.displayName
61939
62016
  });
61940
62017
  clearPendingSetupIntent();
@@ -61952,11 +62029,13 @@ async function startDaemon(args) {
61952
62029
  ...current,
61953
62030
  runtimeToken: bundle.runtimeToken,
61954
62031
  runtimeRenewalToken: bundle.runtimeRenewalToken,
62032
+ runtimeTokenExpiresAt: bundle.runtimeTokenExpiresAt,
61955
62033
  displayName: bundle.displayName
61956
62034
  });
61957
62035
  clearPendingSetupIntent();
61958
62036
  runtimeToken = bundle.runtimeToken;
61959
62037
  runtimeRenewalToken = bundle.runtimeRenewalToken;
62038
+ runtimeTokenExpiresAt = bundle.runtimeTokenExpiresAt;
61960
62039
  socket.auth = { token: bundle.runtimeToken };
61961
62040
  clearConnectErrors();
61962
62041
  const ready = new Promise((resolveReady, rejectReady) => {
@@ -62272,6 +62351,7 @@ async function startDaemon(args) {
62272
62351
  runtimeId,
62273
62352
  runtimeSkillManager,
62274
62353
  getRuntimeToken: () => runtimeToken,
62354
+ ensureRuntimeTokenForLaunch,
62275
62355
  eventOutbox,
62276
62356
  daemonSessionId,
62277
62357
  daemonEpoch,
@@ -62725,6 +62805,7 @@ async function setupDaemon(args, options = {}) {
62725
62805
  runtimeId: body.runtimeId,
62726
62806
  runtimeToken: body.runtimeToken,
62727
62807
  runtimeRenewalToken: body.runtimeRenewalToken,
62808
+ runtimeTokenExpiresAt: body.runtimeTokenExpiresAt,
62728
62809
  displayName: body.displayName,
62729
62810
  installationId
62730
62811
  });
@@ -62829,6 +62910,7 @@ async function loginWithDeviceCode(args) {
62829
62910
  runtimeId: body.runtime.id,
62830
62911
  runtimeToken: body.runtimeToken,
62831
62912
  runtimeRenewalToken: body.runtimeRenewalToken,
62913
+ runtimeTokenExpiresAt: body.runtimeTokenExpiresAt,
62832
62914
  displayName: body.runtime.displayName ?? displayName,
62833
62915
  installationId
62834
62916
  });
@@ -63046,7 +63128,8 @@ async function rotateRuntimeToken(args) {
63046
63128
  apiUrl,
63047
63129
  runtimeId,
63048
63130
  runtimeToken: body.runtimeToken,
63049
- runtimeRenewalToken: body.runtimeRenewalToken
63131
+ runtimeRenewalToken: body.runtimeRenewalToken,
63132
+ runtimeTokenExpiresAt: body.runtimeTokenExpiresAt
63050
63133
  });
63051
63134
  console.info("[alan-agent] Runtime token rotated", { runtimeId });
63052
63135
  }
@@ -63174,7 +63257,7 @@ async function printDoctor(args = []) {
63174
63257
  }
63175
63258
 
63176
63259
  // src/install-command.ts
63177
- var import_promises6 = require("timers/promises");
63260
+ var import_promises7 = require("timers/promises");
63178
63261
 
63179
63262
  // src/mcp-config-adapters.ts
63180
63263
  var import_node_crypto20 = require("crypto");
@@ -63347,10 +63430,7 @@ var cursorAdapter = {
63347
63430
  mcpServers[s.name] = {
63348
63431
  type: "http",
63349
63432
  url: s.url,
63350
- headers: s.name === "alan" ? {
63351
- "x-alan-agent-credential": `\${env:ALAN_AGENT_CREDENTIAL}`,
63352
- "x-alan-run-id": `\${env:ALAN_RUN_ID}`
63353
- } : s.headers
63433
+ headers: s.headers
63354
63434
  };
63355
63435
  } else {
63356
63436
  mcpServers[s.name] = {
@@ -63583,7 +63663,6 @@ var ALAN_SESSION_HEADER_NAMES = /* @__PURE__ */ new Set([
63583
63663
  "x-team-id",
63584
63664
  "x-allowed-tools",
63585
63665
  "x-alan-run-reference",
63586
- "x-alan-agent-credential",
63587
63666
  "x-alan-run-id"
63588
63667
  ]);
63589
63668
  function normalizeAlanSessionHeaders(actual, expected) {
@@ -63901,11 +63980,7 @@ function buildAlanMcpServers(apiUrl) {
63901
63980
  return {
63902
63981
  alan: {
63903
63982
  type: "http",
63904
- url: new URL("/mcp", apiUrl).toString(),
63905
- headers: {
63906
- "x-alan-agent-credential": `\${ALAN_AGENT_CREDENTIAL}`,
63907
- "x-alan-run-id": `\${ALAN_RUN_ID}`
63908
- }
63983
+ url: new URL("/mcp", apiUrl).toString()
63909
63984
  }
63910
63985
  };
63911
63986
  }
@@ -65497,7 +65572,7 @@ async function setupWindowsRuntime(commandArgs) {
65497
65572
  throw new Error("Windows runtime setup completed without a local readiness endpoint");
65498
65573
  }
65499
65574
  const probe = () => probeLocalDaemon(localApiPort, localApiToken, Math.min(250, remainingMs()));
65500
- const poll = () => (0, import_promises6.setTimeout)(Math.min(100, remainingMs()), void 0, { signal: controller.signal });
65575
+ const poll = () => (0, import_promises7.setTimeout)(Math.min(100, remainingMs()), void 0, { signal: controller.signal });
65501
65576
  if (runtimeIdentityChanged) {
65502
65577
  while (true) {
65503
65578
  const status = await probe();
@@ -66842,7 +66917,7 @@ function cgroupDirectory(text) {
66842
66917
  }
66843
66918
  async function collectAgentResourceDiagnostics(options = {}) {
66844
66919
  const platform6 = options.platform ?? process.platform;
66845
- const readFile7 = async (path2) => {
66920
+ const readFile8 = async (path2) => {
66846
66921
  try {
66847
66922
  return await (options.readFile ?? readResourceFile)(path2);
66848
66923
  } catch {
@@ -66859,11 +66934,11 @@ async function collectAgentResourceDiagnostics(options = {}) {
66859
66934
  };
66860
66935
  if (platform6 !== "linux") return sample;
66861
66936
  const [meminfo, memoryPsi, cpuPsi, ioPsi, cgroup] = await Promise.all([
66862
- readFile7("/proc/meminfo"),
66863
- readFile7("/proc/pressure/memory"),
66864
- readFile7("/proc/pressure/cpu"),
66865
- readFile7("/proc/pressure/io"),
66866
- readFile7("/proc/self/cgroup")
66937
+ readFile8("/proc/meminfo"),
66938
+ readFile8("/proc/pressure/memory"),
66939
+ readFile8("/proc/pressure/cpu"),
66940
+ readFile8("/proc/pressure/io"),
66941
+ readFile8("/proc/self/cgroup")
66867
66942
  ]);
66868
66943
  sample.memoryAvailableBytes = meminfoBytes(meminfo, "MemAvailable");
66869
66944
  sample.swapTotalBytes = meminfoBytes(meminfo, "SwapTotal");
@@ -66875,9 +66950,9 @@ async function collectAgentResourceDiagnostics(options = {}) {
66875
66950
  const directory = cgroupDirectory(cgroup);
66876
66951
  if (!directory) return sample;
66877
66952
  const [current, limit, events] = await Promise.all([
66878
- readFile7(`${directory}/memory.current`),
66879
- readFile7(`${directory}/memory.max`),
66880
- readFile7(`${directory}/memory.events`)
66953
+ readFile8(`${directory}/memory.current`),
66954
+ readFile8(`${directory}/memory.max`),
66955
+ readFile8(`${directory}/memory.events`)
66881
66956
  ]);
66882
66957
  sample.cgroupMemoryCurrentBytes = counter(current?.trim());
66883
66958
  sample.cgroupMemoryLimitBytes = counter(limit?.trim());
@@ -67661,7 +67736,7 @@ async function runSandbox(config2) {
67661
67736
  const agent = new CoreAgent(presenter, {
67662
67737
  backendKind: activeBackendKind,
67663
67738
  runId: activeRunId,
67664
- agentCredential: config2.sessionToken,
67739
+ runtimeToken: config2.sessionToken,
67665
67740
  providerApiKey: activeProviderApiKey
67666
67741
  });
67667
67742
  currentAgent = agent;
@@ -67710,7 +67785,7 @@ async function runSandbox(config2) {
67710
67785
  }
67711
67786
  const alanMcp = buildManagedAlanMcp({
67712
67787
  apiUrl: config2.apiUrl,
67713
- agentCredential: config2.sessionToken,
67788
+ runtimeToken: config2.sessionToken,
67714
67789
  runId: activeRunId
67715
67790
  });
67716
67791
  const preparedTask = await prepareSkillInvocationTask({
@@ -67886,7 +67961,7 @@ async function runSandbox(config2) {
67886
67961
  }
67887
67962
 
67888
67963
  // src/skills/skill-cli.ts
67889
- var import_promises7 = require("fs/promises");
67964
+ var import_promises8 = require("fs/promises");
67890
67965
  var import_node_os20 = require("os");
67891
67966
  var import_node_path31 = require("path");
67892
67967
  async function runSkillsCommand(args) {
@@ -67933,7 +68008,7 @@ async function defaultScanInput(homeDirectory2) {
67933
68008
  }
67934
68009
  async function readProtectedJson(path2) {
67935
68010
  const absolutePath = (0, import_node_path31.resolve)(path2);
67936
- const stat2 = await (0, import_promises7.lstat)(absolutePath);
68011
+ const stat2 = await (0, import_promises8.lstat)(absolutePath);
67937
68012
  if (!stat2.isFile()) throw new Error(`Skill input is not a regular file: ${absolutePath}`);
67938
68013
  if (process.platform !== "win32" && (stat2.mode & 63) !== 0) {
67939
68014
  throw new Error(`Skill input must not be accessible by group or other users: ${absolutePath}`);
@@ -67942,7 +68017,7 @@ async function readProtectedJson(path2) {
67942
68017
  throw new Error(`Skill input must be owned by the current user: ${absolutePath}`);
67943
68018
  }
67944
68019
  if (stat2.size > 2 * 1024 * 1024) throw new Error("Skill input exceeds 2 MiB");
67945
- return JSON.parse(await (0, import_promises7.readFile)(absolutePath, "utf8"));
68020
+ return JSON.parse(await (0, import_promises8.readFile)(absolutePath, "utf8"));
67946
68021
  }
67947
68022
  function option(args, name) {
67948
68023
  const index = args.indexOf(name);