@alan-ai-hq/agent-manager 0.1.105 → 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 +249 -219
  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.105";
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");
@@ -38162,20 +38162,22 @@ var import_util9 = require("util");
38162
38162
  var import_fs6 = require("fs");
38163
38163
  var import_os5 = require("os");
38164
38164
  var import_path6 = require("path");
38165
+ var import_promises = require("fs/promises");
38166
+ var import_path7 = require("path");
38165
38167
  var import_fs7 = require("fs");
38166
38168
  var import_os6 = require("os");
38167
- var import_path7 = require("path");
38169
+ var import_path8 = require("path");
38168
38170
  var import_fs8 = require("fs");
38169
38171
  var import_os7 = require("os");
38170
- var import_path8 = require("path");
38172
+ var import_path9 = require("path");
38171
38173
  var import_fs9 = require("fs");
38172
38174
  var import_os8 = require("os");
38173
- var import_path9 = require("path");
38175
+ var import_path10 = require("path");
38174
38176
  var import_readline2 = require("readline");
38175
38177
  var import_url2 = require("url");
38176
38178
  var import_crypto4 = require("crypto");
38177
38179
  var import_fs10 = require("fs");
38178
- var import_path10 = require("path");
38180
+ var import_path11 = require("path");
38179
38181
  var MAX_PARSED_ATTACHMENTS = 3;
38180
38182
  var MAX_PARSED_ATTACHMENT_CHARS = 12e3;
38181
38183
  var MAX_METADATA_CHARS = 240;
@@ -43006,6 +43008,39 @@ function createCopilotCliBackend(command = "copilot", defaultArgs = []) {
43006
43008
  }
43007
43009
  };
43008
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
+ }
43009
43044
  function asRecord4(value2) {
43010
43045
  return typeof value2 === "object" && value2 !== null ? value2 : null;
43011
43046
  }
@@ -43198,10 +43233,10 @@ function emitCursorSubagentTranscript(transcriptPath, parentToolUseId, presenter
43198
43233
  function cursorTranscriptsRoot(context) {
43199
43234
  const projectKey = context.cwd.replace(/^[/\\]+/, "").replace(/[/\\]+/g, "-");
43200
43235
  const home = context.env.HOME || process.env.HOME || (0, import_os6.homedir)();
43201
- return (0, import_path7.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
43236
+ return (0, import_path8.join)(home, ".cursor", "projects", projectKey, "agent-transcripts");
43202
43237
  }
43203
43238
  function cursorTranscriptPathForAgent(context, agentId) {
43204
- return (0, import_path7.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
43239
+ return (0, import_path8.join)(cursorTranscriptsRoot(context), agentId, `${agentId}.jsonl`);
43205
43240
  }
43206
43241
  function resolveCursorSubagentTranscriptPath(success2, context) {
43207
43242
  const explicit = success2?.transcriptPath ?? success2?.transcript_path;
@@ -43589,84 +43624,86 @@ function createCursorAgentCliBackend(command = "cursor-agent", defaultArgs = [])
43589
43624
  [ALAN_RUN_ID_ENV]: requireManagedRunId(context.config.alanMcp)
43590
43625
  }
43591
43626
  } : context;
43592
- try {
43593
- return await createGenericCliBackend({
43594
- kind: "cursor_agent_cli",
43595
- supportTier: "structured",
43596
- command,
43597
- args: [],
43598
- buildArgs: (ctx, _prompt) => {
43599
- const args = [
43600
- "--print",
43601
- "--output-format",
43602
- "stream-json",
43603
- "--trust",
43604
- "--workspace",
43605
- ctx.cwd
43606
- ];
43607
- if (approveMcps) {
43608
- args.push("--approve-mcps");
43609
- }
43610
- const resumeId = ctx.config.runtimeSessionId?.trim() || ctx.config.providerSessionId?.trim();
43611
- if (shouldForceCursorAgent(ctx.config)) args.push("--force");
43612
- if (ctx.config.mode === "plan" || ctx.config.mode === "review") {
43613
- args.push("--mode", "plan");
43614
- } else if (ctx.config.mode === "ask") {
43615
- args.push("--mode", "ask");
43616
- } else if (shouldUseReadOnlyRuntimePermissions(ctx.config)) {
43617
- args.push("--mode", "plan");
43618
- }
43619
- if (resumeId) {
43620
- args.push("--resume", resumeId);
43621
- logResumeObservability("agent_resume_requested", {
43622
- backendKind: "cursor_agent_cli",
43623
- requestedResumeId: resumeId
43624
- });
43625
- }
43626
- const model = ctx.config.selectedModel?.trim();
43627
- if (model && isDispatchableCursorModel(model)) {
43628
- const modelDef = findModelDef("cursor_agent_cli", model) ?? findModelDef("cursor_agent_cli", model.replace(/-fast$/, ""));
43629
- args.push(
43630
- "--model",
43631
- buildCursorAgentModelArg(model, {
43632
- selectedEffortLevel: ctx.config.selectedEffortLevel,
43633
- selectedContextWindow: ctx.config.selectedContextWindow,
43634
- effortLevels: modelDef?.capabilities?.effortLevels,
43635
- contextWindows: modelDef?.capabilities?.contextWindows
43636
- })
43637
- );
43638
- }
43639
- return [...args, ...defaultArgs];
43640
- },
43641
- // Prompt over stdin with immediate EOF (verified live on cursor-agent
43642
- // 2026.07.09): vibe-kanban's mitigation for cursor-agent's documented
43643
- // headless hangs. The result-race/grace-kill stays active via
43644
- // keepStdinOpen; closeStdinAfterPrompt only skips holding stdin open,
43645
- // which cursor never reads after the prompt anyway.
43646
- promptViaStdin: true,
43647
- keepStdinOpen: true,
43648
- closeStdinAfterPrompt: true,
43649
- // cursor-agent headless has a documented failure mode of hanging at startup
43650
- // with zero output; without this watchdog only the 30-min server reaper
43651
- // would end the run.
43652
- startupTimeoutMs: 18e4,
43653
- // Post-startup hang bound: cursor's asks use the non-blocking MCP model and it
43654
- // never populates the idle timer's ask/background fire conditions, so a cursor
43655
- // process that produced output then went silent (no result event) is otherwise
43656
- // bounded only by the ~30-min external reaper. Poll every 5 min; kill after 15
43657
- // min of continuous silence.
43658
- resultIdleTimeoutMs: 5 * 6e4,
43659
- postStartupSilenceTimeoutMs: 15 * 6e4,
43660
- augmentPrompt: (ctx) => {
43661
- const isResume = Boolean(
43662
- 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
+ })
43663
43671
  );
43664
- const base = buildResumeAwarePrompt(ctx.config, ctx.promptText, { isResume });
43665
- const prompt = ctx.config.mode === "plan" ? buildPlanModePrefix(base) : base;
43666
- return appendImagePathReferences(prompt, imageFiles);
43667
- },
43668
- parseStructuredLine: parseCursorStructuredLine
43669
- }).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());
43670
43707
  } finally {
43671
43708
  cleanup();
43672
43709
  }
@@ -44420,9 +44457,9 @@ function buildGrokAgentArgs(config2, defaultArgs = []) {
44420
44457
  return args;
44421
44458
  }
44422
44459
  var DEFAULT_SKILL_ROOTS = [
44423
- (0, import_path9.join)((0, import_os8.homedir)(), ".agents", "skills"),
44424
- (0, import_path9.join)((0, import_os8.homedir)(), ".claude", "skills"),
44425
- (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")
44426
44463
  ];
44427
44464
  function parseFrontmatter(content) {
44428
44465
  if (!content.startsWith("---\n")) return {};
@@ -44442,7 +44479,7 @@ function listSkillFiles(root) {
44442
44479
  const files = [];
44443
44480
  for (const entry of (0, import_fs9.readdirSync)(root, { withFileTypes: true })) {
44444
44481
  if (!entry.isDirectory()) continue;
44445
- const skillPath = (0, import_path9.join)(root, entry.name, "SKILL.md");
44482
+ const skillPath = (0, import_path10.join)(root, entry.name, "SKILL.md");
44446
44483
  if ((0, import_fs9.existsSync)(skillPath)) files.push(skillPath);
44447
44484
  }
44448
44485
  return files;
@@ -44753,8 +44790,8 @@ function createKimiCliBackend(command = "kimi-cli", defaultArgs = []) {
44753
44790
  supportTier: "structured",
44754
44791
  async run(context) {
44755
44792
  const registration = context.config.alanMcp;
44756
- const mcpDirectory = registration ? (0, import_fs8.mkdtempSync)((0, import_path8.join)((0, import_os7.tmpdir)(), "alan-kimi-mcp-")) : null;
44757
- 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;
44758
44795
  if (registration && mcpConfigPath) {
44759
44796
  (0, import_fs8.writeFileSync)(
44760
44797
  mcpConfigPath,
@@ -46712,14 +46749,14 @@ function normalizePath(candidate, cwd) {
46712
46749
  } catch {
46713
46750
  }
46714
46751
  if (path2.startsWith("~/")) return null;
46715
- if ((0, import_path10.isAbsolute)(path2)) return path2;
46716
- 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;
46717
46754
  }
46718
46755
  function resolveToolCwd(cwd, toolInput) {
46719
46756
  if (!isRecord(toolInput)) return cwd;
46720
46757
  const raw = typeof toolInput.cwd === "string" ? toolInput.cwd : typeof toolInput.workdir === "string" ? toolInput.workdir : typeof toolInput.workingDirectory === "string" ? toolInput.workingDirectory : null;
46721
46758
  if (!raw) return cwd;
46722
- 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);
46723
46760
  }
46724
46761
  function extractBrowserMediaPathHints(content, cwd, toolName, options = {}, kind = "video") {
46725
46762
  if (!isAgentBrowserMediaInvocation(toolName, content, options.toolInput, kind)) return [];
@@ -46764,7 +46801,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
46764
46801
  const path2 = normalizePath(candidate, effectiveCwd);
46765
46802
  if (!path2 || seen.has(path2) || !(0, import_fs10.existsSync)(path2)) continue;
46766
46803
  seen.add(path2);
46767
- const ext = (0, import_path10.extname)(path2).toLowerCase();
46804
+ const ext = (0, import_path11.extname)(path2).toLowerCase();
46768
46805
  const mimeType = IMAGE_MIME_BY_EXT[ext];
46769
46806
  if (!mimeType) continue;
46770
46807
  const stat2 = (0, import_fs10.statSync)(path2);
@@ -46774,7 +46811,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName, op
46774
46811
  images.push({
46775
46812
  type: "generated_image",
46776
46813
  id: (0, import_crypto4.randomUUID)(),
46777
- filename: (0, import_path10.basename)(path2),
46814
+ filename: (0, import_path11.basename)(path2),
46778
46815
  mimeType,
46779
46816
  size: buffer.length,
46780
46817
  width,
@@ -46803,7 +46840,7 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
46803
46840
  const path2 = normalizePath(candidate, effectiveCwd);
46804
46841
  if (!path2 || seen.has(path2) || !(0, import_fs10.existsSync)(path2)) continue;
46805
46842
  seen.add(path2);
46806
- const ext = (0, import_path10.extname)(path2).toLowerCase();
46843
+ const ext = (0, import_path11.extname)(path2).toLowerCase();
46807
46844
  const mimeType = mimeByExt[ext];
46808
46845
  if (!mimeType) continue;
46809
46846
  const stat2 = (0, import_fs10.statSync)(path2);
@@ -46814,7 +46851,7 @@ function extractSessionMediaFromToolResult(toolId, content, cwd, toolName, optio
46814
46851
  type: "session_media",
46815
46852
  kind,
46816
46853
  id: (0, import_crypto4.randomUUID)(),
46817
- filename: (0, import_path10.basename)(path2),
46854
+ filename: (0, import_path11.basename)(path2),
46818
46855
  mimeType,
46819
46856
  size: buffer.length,
46820
46857
  width: dimensions?.width,
@@ -58254,13 +58291,13 @@ async function handoffRuntimeSetupGrant(input2) {
58254
58291
  // src/skills/local-skill-source.ts
58255
58292
  var import_node_buffer2 = require("buffer");
58256
58293
  var import_node_crypto14 = require("crypto");
58257
- var import_promises2 = require("fs/promises");
58294
+ var import_promises3 = require("fs/promises");
58258
58295
  var import_node_path20 = __toESM(require("path"), 1);
58259
58296
 
58260
58297
  // ../shared/dist/node/skill-package.js
58261
58298
  var import_node_buffer = require("buffer");
58262
58299
  var import_node_crypto13 = require("crypto");
58263
- var import_promises = require("fs/promises");
58300
+ var import_promises2 = require("fs/promises");
58264
58301
  var import_node_path19 = require("path");
58265
58302
  var import_yaml = __toESM(require_dist(), 1);
58266
58303
  var TREE_HASH_PREFIX = import_node_buffer.Buffer.from("alan-skill-tree-v1\0", "utf8");
@@ -58353,11 +58390,11 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
58353
58390
  if (!normalizedPath || normalizedPath !== path2 || normalizedPath.includes("\\") || components.some((component) => !component || component === "." || component === "..")) {
58354
58391
  throw new SkillPackageError("INVALID_PATH", `Invalid Skill package path: ${path2}`, path2);
58355
58392
  }
58356
- 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);
58357
58394
  if (!absolutePath || normalizeRelativePath(root, absolutePath) !== normalizedPath) {
58358
58395
  throw new SkillPackageError("INVALID_PATH", `Skill package file was not found: ${path2}`, path2);
58359
58396
  }
58360
- const entryStat = await (0, import_promises.lstat)(absolutePath);
58397
+ const entryStat = await (0, import_promises2.lstat)(absolutePath);
58361
58398
  if (!entryStat.isFile()) {
58362
58399
  throw new SkillPackageError("SPECIAL_FILE_BLOCKED", `Only regular files are allowed in Skill packages: ${path2}`, path2);
58363
58400
  }
@@ -58374,11 +58411,11 @@ async function readSkillPackageFile(packageRoot, path2, expectedSha256) {
58374
58411
  return { file: read.manifest, bytes: read.bytes };
58375
58412
  }
58376
58413
  async function requirePackageRoot(packageRoot) {
58377
- 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);
58378
58415
  if (!root) {
58379
58416
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package directory does not exist");
58380
58417
  }
58381
- const rootStat = await (0, import_promises.lstat)(root);
58418
+ const rootStat = await (0, import_promises2.lstat)(root);
58382
58419
  if (!rootStat.isDirectory()) {
58383
58420
  throw new SkillPackageError("INVALID_PACKAGE_ROOT", "Skill package root must be a directory");
58384
58421
  }
@@ -58398,13 +58435,13 @@ async function walkPackage(root, ignoredPaths) {
58398
58435
  }
58399
58436
  return files;
58400
58437
  async function walkDirectory(directory) {
58401
- const entries = await (0, import_promises.readdir)(directory, { withFileTypes: true });
58438
+ const entries = await (0, import_promises2.readdir)(directory, { withFileTypes: true });
58402
58439
  for (const entry of entries) {
58403
58440
  const absolutePath = (0, import_node_path19.resolve)(directory, entry.name);
58404
58441
  const normalizedPath = normalizeRelativePath(root, absolutePath);
58405
58442
  if (isIgnored(normalizedPath, entry.name, entry.isDirectory(), ignored))
58406
58443
  continue;
58407
- const entryStat = await (0, import_promises.lstat)(absolutePath);
58444
+ const entryStat = await (0, import_promises2.lstat)(absolutePath);
58408
58445
  if (entryStat.isSymbolicLink()) {
58409
58446
  throw new SkillPackageError("SYMLINK_BLOCKED", `Nested symbolic links are not allowed in Skill packages: ${normalizedPath}`, normalizedPath);
58410
58447
  }
@@ -58513,7 +58550,7 @@ function isSecretPath(path2) {
58513
58550
  return name.endsWith(".private-key.pem") || name.endsWith(".private-key.key");
58514
58551
  }
58515
58552
  async function readPackageFile(file2) {
58516
- const bytes = await (0, import_promises.readFile)(file2.absolutePath);
58553
+ const bytes = await (0, import_promises2.readFile)(file2.absolutePath);
58517
58554
  return {
58518
58555
  bytes,
58519
58556
  manifest: {
@@ -59640,7 +59677,7 @@ var LocalSkillSource = class {
59640
59677
  async scanRootAsPackage(resolvedRoot, ignoredPaths, mode) {
59641
59678
  const directory = resolvedRoot.directory;
59642
59679
  if (!await pathExists((0, import_node_path20.join)(directory, "SKILL.md"))) return null;
59643
- const canonicalRoot = await (0, import_promises2.realpath)(directory).catch(() => directory);
59680
+ const canonicalRoot = await (0, import_promises3.realpath)(directory).catch(() => directory);
59644
59681
  const name = import_node_path20.default.basename(canonicalRoot);
59645
59682
  try {
59646
59683
  const fingerprint = await fingerprintPackage(canonicalRoot);
@@ -59689,7 +59726,7 @@ var LocalSkillSource = class {
59689
59726
  if (rootPackage) return rootPackage;
59690
59727
  let entries;
59691
59728
  try {
59692
- entries = await (0, import_promises2.readdir)(resolvedRoot.directory, { withFileTypes: true });
59729
+ entries = await (0, import_promises3.readdir)(resolvedRoot.directory, { withFileTypes: true });
59693
59730
  } catch (error61) {
59694
59731
  if (isAbsentDirectory(error61)) return { candidates: [], diagnostics: [], incomplete: false };
59695
59732
  return {
@@ -59706,13 +59743,13 @@ var LocalSkillSource = class {
59706
59743
  }
59707
59744
  const candidates = [];
59708
59745
  const diagnostics = [];
59709
- const canonicalRoot = await (0, import_promises2.realpath)(resolvedRoot.directory).catch(
59746
+ const canonicalRoot = await (0, import_promises3.realpath)(resolvedRoot.directory).catch(
59710
59747
  () => resolvedRoot.directory
59711
59748
  );
59712
59749
  for (const entry of entries) {
59713
59750
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
59714
59751
  const candidatePath = (0, import_node_path20.join)(resolvedRoot.directory, entry.name);
59715
- const canonicalPath = await (0, import_promises2.realpath)(candidatePath).catch(() => null);
59752
+ const canonicalPath = await (0, import_promises3.realpath)(candidatePath).catch(() => null);
59716
59753
  if (!canonicalPath) {
59717
59754
  diagnostics.push({
59718
59755
  code: "SOURCE_UNREADABLE",
@@ -59773,12 +59810,12 @@ async function fingerprintPackage(root) {
59773
59810
  await visit2(root, "");
59774
59811
  return `sha256:${hash2.digest("hex")}`;
59775
59812
  async function visit2(directory, relativeDirectory) {
59776
- const entries = await (0, import_promises2.readdir)(directory, { withFileTypes: true });
59813
+ const entries = await (0, import_promises3.readdir)(directory, { withFileTypes: true });
59777
59814
  entries.sort((left, right) => import_node_buffer2.Buffer.compare(import_node_buffer2.Buffer.from(left.name), import_node_buffer2.Buffer.from(right.name)));
59778
59815
  for (const entry of entries) {
59779
59816
  const path2 = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
59780
59817
  const absolutePath = (0, import_node_path20.join)(directory, entry.name);
59781
- const metadata = await (0, import_promises2.lstat)(absolutePath);
59818
+ const metadata = await (0, import_promises3.lstat)(absolutePath);
59782
59819
  hash2.update(path2.normalize("NFC")).update("\0").update(
59783
59820
  entry.isDirectory() ? "d" : entry.isFile() ? "f" : entry.isSymbolicLink() ? "l" : "o"
59784
59821
  ).update("\0").update(String(metadata.size)).update("\0").update(String(metadata.mtimeMs)).update("\0").update(String(metadata.mode & 511)).update("\0");
@@ -59797,7 +59834,7 @@ function staleCodexDeclaration(relativeDirectory, label, providerKinds) {
59797
59834
  }
59798
59835
  async function canonicalDirectories(directories) {
59799
59836
  const canonical = await Promise.all(
59800
- directories.map((directory) => (0, import_promises2.realpath)(directory).catch(() => directory))
59837
+ directories.map((directory) => (0, import_promises3.realpath)(directory).catch(() => directory))
59801
59838
  );
59802
59839
  return [...new Set(canonical)];
59803
59840
  }
@@ -59808,10 +59845,10 @@ function isWithinDirectory(parent, candidate) {
59808
59845
  async function loadSkillSourceConfig(homeDirectory2) {
59809
59846
  const configDirectory = (0, import_node_path20.join)(homeDirectory2, ".alan");
59810
59847
  const configPath = (0, import_node_path20.join)(configDirectory, "config.toml");
59811
- await (0, import_promises2.mkdir)(configDirectory, { recursive: true, mode: 448 });
59848
+ await (0, import_promises3.mkdir)(configDirectory, { recursive: true, mode: 448 });
59812
59849
  let created = false;
59813
59850
  try {
59814
- await (0, import_promises2.writeFile)(configPath, DEFAULT_SKILL_CONFIG, {
59851
+ await (0, import_promises3.writeFile)(configPath, DEFAULT_SKILL_CONFIG, {
59815
59852
  encoding: "utf8",
59816
59853
  flag: "wx",
59817
59854
  mode: 384
@@ -59820,7 +59857,7 @@ async function loadSkillSourceConfig(homeDirectory2) {
59820
59857
  } catch (error61) {
59821
59858
  if (!isAlreadyPresent(error61)) throw error61;
59822
59859
  }
59823
- const content = await (0, import_promises2.readFile)(configPath, "utf8");
59860
+ const content = await (0, import_promises3.readFile)(configPath, "utf8");
59824
59861
  try {
59825
59862
  return { state: "ready", config: parseSkillSourceConfig(content, homeDirectory2), created };
59826
59863
  } catch (error61) {
@@ -60006,7 +60043,7 @@ function deduplicateCandidatesByContent(candidates) {
60006
60043
  }
60007
60044
  async function pathExists(candidate) {
60008
60045
  try {
60009
- await (0, import_promises2.access)(candidate);
60046
+ await (0, import_promises3.access)(candidate);
60010
60047
  return true;
60011
60048
  } catch {
60012
60049
  return false;
@@ -60014,7 +60051,7 @@ async function pathExists(candidate) {
60014
60051
  }
60015
60052
  async function hasManagedMarker(directory) {
60016
60053
  try {
60017
- 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"));
60018
60055
  return true;
60019
60056
  } catch {
60020
60057
  return false;
@@ -60022,7 +60059,7 @@ async function hasManagedMarker(directory) {
60022
60059
  }
60023
60060
  async function isDirectory(path2) {
60024
60061
  try {
60025
- return (await (0, import_promises2.lstat)(path2)).isDirectory();
60062
+ return (await (0, import_promises3.lstat)(path2)).isDirectory();
60026
60063
  } catch {
60027
60064
  return false;
60028
60065
  }
@@ -60193,12 +60230,12 @@ var RuntimeSkillCoordinator = class {
60193
60230
  // src/skills/runtime-skill-manager.ts
60194
60231
  var import_node_buffer5 = require("buffer");
60195
60232
  var import_node_crypto17 = require("crypto");
60196
- var import_promises5 = require("fs/promises");
60233
+ var import_promises6 = require("fs/promises");
60197
60234
  var import_node_path23 = require("path");
60198
60235
 
60199
60236
  // src/skills/managed-skill-store.ts
60200
60237
  var import_node_crypto15 = require("crypto");
60201
- var import_promises3 = require("fs/promises");
60238
+ var import_promises4 = require("fs/promises");
60202
60239
  var import_node_path21 = require("path");
60203
60240
  var EMPTY_STATE = {
60204
60241
  version: 1,
@@ -60216,9 +60253,9 @@ var ManagedSkillStore = class _ManagedSkillStore {
60216
60253
  integrity;
60217
60254
  canRemoveManagedFiles;
60218
60255
  static async open(baseDirectory) {
60219
- await (0, import_promises3.mkdir)(baseDirectory, { recursive: true, mode: 448 });
60256
+ await (0, import_promises4.mkdir)(baseDirectory, { recursive: true, mode: 448 });
60220
60257
  try {
60221
- 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"));
60222
60259
  return new _ManagedSkillStore(baseDirectory, parseState(parsed), "verified");
60223
60260
  } catch (error61) {
60224
60261
  if (isMissingPath(error61)) {
@@ -60284,15 +60321,15 @@ var ManagedSkillStore = class _ManagedSkillStore {
60284
60321
  `.state.json.pending-${process.pid}-${(0, import_node_crypto15.randomBytes)(6).toString("hex")}`
60285
60322
  );
60286
60323
  try {
60287
- 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)}
60288
60325
  `, {
60289
60326
  encoding: "utf8",
60290
60327
  flag: "wx",
60291
60328
  mode: 384
60292
60329
  });
60293
- await (0, import_promises3.rename)(pendingPath, statePath);
60330
+ await (0, import_promises4.rename)(pendingPath, statePath);
60294
60331
  } finally {
60295
- await (0, import_promises3.rm)(pendingPath, { force: true });
60332
+ await (0, import_promises4.rm)(pendingPath, { force: true });
60296
60333
  }
60297
60334
  }
60298
60335
  };
@@ -60350,7 +60387,7 @@ function isMissingPath(error61) {
60350
60387
  // ../shared/dist/node/skill-bundle.js
60351
60388
  var import_node_buffer3 = require("buffer");
60352
60389
  var import_node_crypto16 = require("crypto");
60353
- var import_promises4 = require("fs/promises");
60390
+ var import_promises5 = require("fs/promises");
60354
60391
  var import_node_path22 = require("path");
60355
60392
  var import_node_stream = require("stream");
60356
60393
  var import_node_zlib = require("zlib");
@@ -60360,7 +60397,7 @@ async function createSkillBundle(packageRoot, options = {}) {
60360
60397
  const archive = (0, import_tar_stream.pack)();
60361
60398
  const tarPromise = collectStream(archive);
60362
60399
  for (const file2 of before.files) {
60363
- 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("/")));
60364
60401
  await addArchiveEntry(archive, {
60365
60402
  name: file2.path,
60366
60403
  type: "file",
@@ -60392,7 +60429,7 @@ async function extractSkillBundle(archiveBytes, destination, expected) {
60392
60429
  throw new Error("Skill archive hash does not match the expected immutable Version");
60393
60430
  }
60394
60431
  const tarBytes = await decompressBounded(archiveBytes);
60395
- await (0, import_promises4.mkdir)(destination, { recursive: false, mode: 448 });
60432
+ await (0, import_promises5.mkdir)(destination, { recursive: false, mode: 448 });
60396
60433
  try {
60397
60434
  await extractTar(tarBytes, destination);
60398
60435
  const inspected = await inspectSkillPackage(destination, { expectedName: null });
@@ -60400,7 +60437,7 @@ async function extractSkillBundle(archiveBytes, destination, expected) {
60400
60437
  throw new Error("Extracted Skill package hash does not match the expected immutable Version");
60401
60438
  }
60402
60439
  } catch (error61) {
60403
- await (0, import_promises4.rm)(destination, { recursive: true, force: true });
60440
+ await (0, import_promises5.rm)(destination, { recursive: true, force: true });
60404
60441
  throw error61;
60405
60442
  }
60406
60443
  }
@@ -60476,8 +60513,8 @@ async function extractEntry(header, stream, destination, limits) {
60476
60513
  throw new Error(`Skill archive file size is invalid: ${path2}`);
60477
60514
  }
60478
60515
  const outputPath = (0, import_node_path22.join)(destination, ...path2.split("/"));
60479
- await (0, import_promises4.mkdir)((0, import_node_path22.dirname)(outputPath), { recursive: true, mode: 448 });
60480
- 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 });
60481
60518
  }
60482
60519
  function requireSafeArchivePath(value2) {
60483
60520
  const normalized = value2.replaceAll("\\", "/").normalize("NFC");
@@ -60737,12 +60774,12 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60737
60774
  }
60738
60775
  async reconcileUnlocked(manifest) {
60739
60776
  const desired = desiredSkillManifestSchema.parse(manifest);
60740
- await (0, import_promises5.mkdir)(this.managedSkillsDirectory, { recursive: true, mode: 448 });
60741
- 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"), {
60742
60779
  recursive: true,
60743
60780
  mode: 448
60744
60781
  });
60745
- 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 });
60746
60783
  const results = [];
60747
60784
  const nextProjections = {};
60748
60785
  for (const entry of desired.skills) {
@@ -60865,52 +60902,52 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60865
60902
  let sourceMoved = false;
60866
60903
  let destinationInstalled = false;
60867
60904
  try {
60868
- await (0, import_promises5.rename)(source, backup);
60905
+ await (0, import_promises6.rename)(source, backup);
60869
60906
  sourceMoved = true;
60870
- 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 });
60871
60908
  const skillMarkdown = (0, import_node_path23.join)(pending, "SKILL.md");
60872
- await (0, import_promises5.writeFile)(
60909
+ await (0, import_promises6.writeFile)(
60873
60910
  skillMarkdown,
60874
- rewriteSkillMarkdownName(await (0, import_promises5.readFile)(skillMarkdown, "utf8"), name),
60911
+ rewriteSkillMarkdownName(await (0, import_promises6.readFile)(skillMarkdown, "utf8"), name),
60875
60912
  {
60876
60913
  encoding: "utf8",
60877
60914
  mode: 420
60878
60915
  }
60879
60916
  );
60880
60917
  await inspectSkillPackage(pending, { expectedName: name });
60881
- await (0, import_promises5.rename)(pending, destination);
60918
+ await (0, import_promises6.rename)(pending, destination);
60882
60919
  destinationInstalled = true;
60883
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60920
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60884
60921
  } catch (error61) {
60885
- 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 });
60886
60923
  if (sourceMoved && await pathExists2(backup) && !await pathExists2(source)) {
60887
- await (0, import_promises5.rename)(backup, source);
60924
+ await (0, import_promises6.rename)(backup, source);
60888
60925
  }
60889
60926
  throw error61;
60890
60927
  } finally {
60891
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
60928
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
60892
60929
  if (!sourceMoved || destinationInstalled) {
60893
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60930
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60894
60931
  }
60895
60932
  }
60896
60933
  }
60897
60934
  async overwriteLocalConflict(input2, entry, conflict, manifest) {
60898
60935
  const source = this.conflictDirectory(entry.runtimeDirectory, conflict.kind);
60899
60936
  const backup = `${source}.overwrite-backup-${process.pid}-${(0, import_node_crypto17.randomBytes)(8).toString("hex")}`;
60900
- await (0, import_promises5.rename)(source, backup);
60937
+ await (0, import_promises6.rename)(source, backup);
60901
60938
  try {
60902
60939
  const reconciled = await this.reconcileUnlocked(manifest);
60903
60940
  const result = resolutionFromReconcile(input2, reconciled);
60904
60941
  if (result.state !== "applied") {
60905
60942
  await this.removeResolvedProjection(entry, conflict.kind);
60906
- await (0, import_promises5.rename)(backup, source);
60943
+ await (0, import_promises6.rename)(backup, source);
60907
60944
  return result;
60908
60945
  }
60909
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
60946
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
60910
60947
  return result;
60911
60948
  } catch (error61) {
60912
60949
  await this.removeResolvedProjection(entry, conflict.kind).catch(() => void 0);
60913
- 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);
60914
60951
  throw error61;
60915
60952
  }
60916
60953
  }
@@ -60920,7 +60957,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60920
60957
  if (conflictKind === "managed_destination") {
60921
60958
  const marker = await readMarker(destination);
60922
60959
  if (marker?.skillId === entry.skillId && marker.versionId === entry.versionId && marker.contentHash === entry.contentHash) {
60923
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
60960
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
60924
60961
  }
60925
60962
  return;
60926
60963
  }
@@ -60952,16 +60989,16 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60952
60989
  if (!await legacyFileMatches(source, legacy.hash) || !await packageMatches(source, entry.contentHash)) {
60953
60990
  return;
60954
60991
  }
60955
- await (0, import_promises5.rename)(source, destination);
60992
+ await (0, import_promises6.rename)(source, destination);
60956
60993
  try {
60957
- await (0, import_promises5.writeFile)(
60994
+ await (0, import_promises6.writeFile)(
60958
60995
  (0, import_node_path23.join)(destination, ".alan-managed.json"),
60959
60996
  `${JSON.stringify(markerFor(entry), null, 2)}
60960
60997
  `,
60961
60998
  { encoding: "utf8", flag: "wx", mode: 384 }
60962
60999
  );
60963
61000
  } catch (error61) {
60964
- await (0, import_promises5.rename)(destination, source).catch(() => void 0);
61001
+ await (0, import_promises6.rename)(destination, source).catch(() => void 0);
60965
61002
  throw error61;
60966
61003
  }
60967
61004
  await removeExactLegacySkill((0, import_node_path23.join)(this.compatibilitySkillsDirectory, entry.slug), legacy.hash);
@@ -60974,7 +61011,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60974
61011
  await removeExactLegacySkill((0, import_node_path23.join)(this.managedSkillsDirectory, command), entry.hash);
60975
61012
  await removeExactLegacySkill((0, import_node_path23.join)(this.compatibilitySkillsDirectory, command), entry.hash);
60976
61013
  }
60977
- await (0, import_promises5.rm)(this.legacyManifestPath, { force: true });
61014
+ await (0, import_promises6.rm)(this.legacyManifestPath, { force: true });
60978
61015
  }
60979
61016
  async ensureCached(entry) {
60980
61017
  const cacheDirectory = (0, import_node_path23.join)(
@@ -60984,7 +61021,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
60984
61021
  entry.contentHash.slice("sha256:".length)
60985
61022
  );
60986
61023
  if (await packageMatches(cacheDirectory, entry.contentHash)) return cacheDirectory;
60987
- await (0, import_promises5.rm)(cacheDirectory, { recursive: true, force: true });
61024
+ await (0, import_promises6.rm)(cacheDirectory, { recursive: true, force: true });
60988
61025
  const bytes = await this.downloadBundle(entry);
60989
61026
  if (bytes.byteLength !== entry.compressedBytes) {
60990
61027
  throw new Error(
@@ -61002,12 +61039,12 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61002
61039
  expectedContentHash: entry.contentHash
61003
61040
  });
61004
61041
  try {
61005
- await (0, import_promises5.rename)(pendingDirectory, cacheDirectory);
61042
+ await (0, import_promises6.rename)(pendingDirectory, cacheDirectory);
61006
61043
  } catch (error61) {
61007
61044
  if (!await packageMatches(cacheDirectory, entry.contentHash)) throw error61;
61008
61045
  }
61009
61046
  } finally {
61010
- await (0, import_promises5.rm)(pendingDirectory, { recursive: true, force: true });
61047
+ await (0, import_promises6.rm)(pendingDirectory, { recursive: true, force: true });
61011
61048
  }
61012
61049
  return cacheDirectory;
61013
61050
  }
@@ -61025,8 +61062,8 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61025
61062
  let installedPending = false;
61026
61063
  let completed = false;
61027
61064
  try {
61028
- await (0, import_promises5.cp)(cacheDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61029
- 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)(
61030
61067
  (0, import_node_path23.join)(pending, ".alan-managed.json"),
61031
61068
  `${JSON.stringify(markerFor(entry), null, 2)}
61032
61069
  `,
@@ -61036,14 +61073,14 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61036
61073
  throw new Error("Pending managed Skill projection failed content verification");
61037
61074
  }
61038
61075
  if (await pathExists2(destination)) {
61039
- await (0, import_promises5.rename)(destination, backup);
61076
+ await (0, import_promises6.rename)(destination, backup);
61040
61077
  movedExisting = true;
61041
61078
  }
61042
61079
  try {
61043
- await (0, import_promises5.rename)(pending, destination);
61080
+ await (0, import_promises6.rename)(pending, destination);
61044
61081
  installedPending = true;
61045
61082
  } catch (error61) {
61046
- if (movedExisting) await (0, import_promises5.rename)(backup, destination);
61083
+ if (movedExisting) await (0, import_promises6.rename)(backup, destination);
61047
61084
  throw error61;
61048
61085
  }
61049
61086
  const inspected = await inspectSkillPackage(destination, { expectedName: null });
@@ -61052,18 +61089,18 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61052
61089
  }
61053
61090
  await this.ensureCompatibilityProjection(entry, destination);
61054
61091
  completed = true;
61055
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
61092
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
61056
61093
  return inspected.contentHash;
61057
61094
  } catch (error61) {
61058
61095
  if (!completed && installedPending) {
61059
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61060
- 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);
61061
61098
  }
61062
61099
  throw error61;
61063
61100
  } finally {
61064
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
61101
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
61065
61102
  if (completed || !movedExisting) {
61066
- await (0, import_promises5.rm)(backup, { recursive: true, force: true });
61103
+ await (0, import_promises6.rm)(backup, { recursive: true, force: true });
61067
61104
  }
61068
61105
  }
61069
61106
  }
@@ -61104,7 +61141,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61104
61141
  });
61105
61142
  continue;
61106
61143
  }
61107
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61144
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
61108
61145
  } else {
61109
61146
  failures.push({
61110
61147
  skillId: recorded.skillId,
@@ -61119,7 +61156,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61119
61156
  return failures;
61120
61157
  }
61121
61158
  async ensureCompatibilityProjection(entry, canonicalDirectory) {
61122
- await (0, import_promises5.mkdir)(this.compatibilitySkillsDirectory, { recursive: true, mode: 448 });
61159
+ await (0, import_promises6.mkdir)(this.compatibilitySkillsDirectory, { recursive: true, mode: 448 });
61123
61160
  const destination = (0, import_node_path23.join)(
61124
61161
  this.compatibilitySkillsDirectory,
61125
61162
  this.projectionDirectoryName(entry.runtimeDirectory)
@@ -61129,23 +61166,23 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61129
61166
  throw unmanagedCompatibilityConflict(entry.runtimeDirectory);
61130
61167
  }
61131
61168
  try {
61132
- await (0, import_promises5.symlink)(canonicalDirectory, destination, "dir");
61169
+ await (0, import_promises6.symlink)(canonicalDirectory, destination, "dir");
61133
61170
  return;
61134
61171
  } catch (error61) {
61135
61172
  if (!isSymlinkUnsupported(error61)) throw error61;
61136
61173
  }
61137
61174
  const pending = `${destination}.pending-${process.pid}-${(0, import_node_crypto17.randomBytes)(6).toString("hex")}`;
61138
61175
  try {
61139
- await (0, import_promises5.cp)(canonicalDirectory, pending, { recursive: true, errorOnExist: true, force: false });
61140
- 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)(
61141
61178
  (0, import_node_path23.join)(pending, ".alan-compatibility.json"),
61142
61179
  `${JSON.stringify({ ...markerFor(entry), canonicalDirectory }, null, 2)}
61143
61180
  `,
61144
61181
  { encoding: "utf8", flag: "wx", mode: 384 }
61145
61182
  );
61146
- await (0, import_promises5.rename)(pending, destination);
61183
+ await (0, import_promises6.rename)(pending, destination);
61147
61184
  } finally {
61148
- await (0, import_promises5.rm)(pending, { recursive: true, force: true });
61185
+ await (0, import_promises6.rm)(pending, { recursive: true, force: true });
61149
61186
  }
61150
61187
  }
61151
61188
  async runExclusively(work) {
@@ -61169,29 +61206,29 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61169
61206
  return this.storageNamespace ? `${runtimeDirectory}--alan-${this.storageNamespace}` : runtimeDirectory;
61170
61207
  }
61171
61208
  async withMachineLock(work) {
61172
- await (0, import_promises5.mkdir)(this.skillsStateDirectory, { recursive: true, mode: 448 });
61209
+ await (0, import_promises6.mkdir)(this.skillsStateDirectory, { recursive: true, mode: 448 });
61173
61210
  const lockDirectory = (0, import_node_path23.join)(this.skillsStateDirectory, "manager.lock");
61174
61211
  const deadline = Date.now() + 3e4;
61175
61212
  while (true) {
61176
61213
  try {
61177
- await (0, import_promises5.mkdir)(lockDirectory, { mode: 448 });
61214
+ await (0, import_promises6.mkdir)(lockDirectory, { mode: 448 });
61178
61215
  try {
61179
- await (0, import_promises5.writeFile)(
61216
+ await (0, import_promises6.writeFile)(
61180
61217
  (0, import_node_path23.join)(lockDirectory, "owner.json"),
61181
61218
  `${JSON.stringify({ pid: process.pid, acquiredAt: (/* @__PURE__ */ new Date()).toISOString() })}
61182
61219
  `,
61183
61220
  { encoding: "utf8", flag: "wx", mode: 384 }
61184
61221
  );
61185
61222
  } catch (error61) {
61186
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61223
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61187
61224
  throw error61;
61188
61225
  }
61189
61226
  break;
61190
61227
  } catch (error61) {
61191
61228
  if (!isAlreadyPresent2(error61)) throw error61;
61192
- 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);
61193
61230
  if (ageMs > 15 * 6e4) {
61194
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61231
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61195
61232
  continue;
61196
61233
  }
61197
61234
  if (Date.now() >= deadline) {
@@ -61205,7 +61242,7 @@ var RuntimeSkillManager = class _RuntimeSkillManager {
61205
61242
  try {
61206
61243
  return await work();
61207
61244
  } finally {
61208
- await (0, import_promises5.rm)(lockDirectory, { recursive: true, force: true });
61245
+ await (0, import_promises6.rm)(lockDirectory, { recursive: true, force: true });
61209
61246
  }
61210
61247
  }
61211
61248
  };
@@ -61227,7 +61264,7 @@ async function packageMatches(directory, expectedHash) {
61227
61264
  async function readMarker(directory) {
61228
61265
  try {
61229
61266
  const value2 = JSON.parse(
61230
- 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")
61231
61268
  );
61232
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)) {
61233
61270
  return null;
@@ -61238,9 +61275,9 @@ async function readMarker(directory) {
61238
61275
  }
61239
61276
  }
61240
61277
  async function compatibilityProjectionMatches(destination, canonicalDirectory, entry) {
61241
- const metadata = await (0, import_promises5.lstat)(destination);
61278
+ const metadata = await (0, import_promises6.lstat)(destination);
61242
61279
  if (metadata.isSymbolicLink()) {
61243
- const target = await (0, import_promises5.readlink)(destination);
61280
+ const target = await (0, import_promises6.readlink)(destination);
61244
61281
  return (0, import_node_path23.resolve)((0, import_node_path23.dirname)(destination), target) === (0, import_node_path23.resolve)(canonicalDirectory);
61245
61282
  }
61246
61283
  if (!metadata.isDirectory()) return false;
@@ -61249,22 +61286,22 @@ async function compatibilityProjectionMatches(destination, canonicalDirectory, e
61249
61286
  }
61250
61287
  async function removeCompatibilityProjection(destination, canonicalDirectory, projection) {
61251
61288
  if (!await pathExists2(destination)) return true;
61252
- const metadata = await (0, import_promises5.lstat)(destination);
61289
+ const metadata = await (0, import_promises6.lstat)(destination);
61253
61290
  if (metadata.isSymbolicLink()) {
61254
- const target = await (0, import_promises5.readlink)(destination);
61291
+ const target = await (0, import_promises6.readlink)(destination);
61255
61292
  if ((0, import_node_path23.resolve)((0, import_node_path23.dirname)(destination), target) !== (0, import_node_path23.resolve)(canonicalDirectory)) return false;
61256
- await (0, import_promises5.rm)(destination, { force: true });
61293
+ await (0, import_promises6.rm)(destination, { force: true });
61257
61294
  return true;
61258
61295
  }
61259
61296
  const marker = await readCompatibilityMarker(destination);
61260
61297
  if (!marker || !markerMatchesProjection(marker, projection)) return false;
61261
- await (0, import_promises5.rm)(destination, { recursive: true, force: true });
61298
+ await (0, import_promises6.rm)(destination, { recursive: true, force: true });
61262
61299
  return true;
61263
61300
  }
61264
61301
  async function readCompatibilityMarker(directory) {
61265
61302
  try {
61266
61303
  const value2 = JSON.parse(
61267
- 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")
61268
61305
  );
61269
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") {
61270
61307
  return null;
@@ -61284,7 +61321,7 @@ function markerFor(entry) {
61284
61321
  }
61285
61322
  async function readLegacyManifest(path2) {
61286
61323
  try {
61287
- const value2 = JSON.parse(await (0, import_promises5.readFile)(path2, "utf8"));
61324
+ const value2 = JSON.parse(await (0, import_promises6.readFile)(path2, "utf8"));
61288
61325
  if (!value2 || typeof value2 !== "object" || !("skills" in value2)) return null;
61289
61326
  const skillsValue = value2.skills;
61290
61327
  if (!skillsValue || typeof skillsValue !== "object" || Array.isArray(skillsValue)) return null;
@@ -61302,9 +61339,9 @@ async function readLegacyManifest(path2) {
61302
61339
  }
61303
61340
  async function legacyFileMatches(directory, expectedHash) {
61304
61341
  try {
61305
- const metadata = await (0, import_promises5.lstat)(directory);
61342
+ const metadata = await (0, import_promises6.lstat)(directory);
61306
61343
  if (!metadata.isDirectory() || metadata.isSymbolicLink()) return false;
61307
- 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"));
61308
61345
  return (0, import_node_crypto17.createHash)("sha256").update(content).digest("hex").slice(0, 16) === expectedHash;
61309
61346
  } catch {
61310
61347
  return false;
@@ -61312,9 +61349,9 @@ async function legacyFileMatches(directory, expectedHash) {
61312
61349
  }
61313
61350
  async function removeExactLegacySkill(directory, expectedHash) {
61314
61351
  if (!await legacyFileMatches(directory, expectedHash)) return;
61315
- await (0, import_promises5.rm)((0, import_node_path23.join)(directory, "SKILL.md"), { force: true });
61316
- const remaining = await (0, import_promises5.readdir)(directory);
61317
- 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 });
61318
61355
  }
61319
61356
  function markerMatchesProjection(marker, projection) {
61320
61357
  return marker.skillId === projection.skillId && marker.versionId === projection.versionId && marker.contentHash === projection.contentHash;
@@ -61407,7 +61444,7 @@ function localTextMediaType(path2) {
61407
61444
  }
61408
61445
  async function pathExists2(path2) {
61409
61446
  try {
61410
- await (0, import_promises5.lstat)(path2);
61447
+ await (0, import_promises6.lstat)(path2);
61411
61448
  return true;
61412
61449
  } catch (error61) {
61413
61450
  if (isMissingPath2(error61)) return false;
@@ -63220,7 +63257,7 @@ async function printDoctor(args = []) {
63220
63257
  }
63221
63258
 
63222
63259
  // src/install-command.ts
63223
- var import_promises6 = require("timers/promises");
63260
+ var import_promises7 = require("timers/promises");
63224
63261
 
63225
63262
  // src/mcp-config-adapters.ts
63226
63263
  var import_node_crypto20 = require("crypto");
@@ -63393,10 +63430,7 @@ var cursorAdapter = {
63393
63430
  mcpServers[s.name] = {
63394
63431
  type: "http",
63395
63432
  url: s.url,
63396
- headers: s.name === "alan" ? {
63397
- Authorization: `\${env:ALAN_MCP_AUTHORIZATION}`,
63398
- "x-alan-run-id": `\${env:ALAN_RUN_ID}`
63399
- } : s.headers
63433
+ headers: s.headers
63400
63434
  };
63401
63435
  } else {
63402
63436
  mcpServers[s.name] = {
@@ -63946,11 +63980,7 @@ function buildAlanMcpServers(apiUrl) {
63946
63980
  return {
63947
63981
  alan: {
63948
63982
  type: "http",
63949
- url: new URL("/mcp", apiUrl).toString(),
63950
- headers: {
63951
- Authorization: `\${ALAN_MCP_AUTHORIZATION}`,
63952
- "x-alan-run-id": `\${ALAN_RUN_ID}`
63953
- }
63983
+ url: new URL("/mcp", apiUrl).toString()
63954
63984
  }
63955
63985
  };
63956
63986
  }
@@ -65542,7 +65572,7 @@ async function setupWindowsRuntime(commandArgs) {
65542
65572
  throw new Error("Windows runtime setup completed without a local readiness endpoint");
65543
65573
  }
65544
65574
  const probe = () => probeLocalDaemon(localApiPort, localApiToken, Math.min(250, remainingMs()));
65545
- 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 });
65546
65576
  if (runtimeIdentityChanged) {
65547
65577
  while (true) {
65548
65578
  const status = await probe();
@@ -66887,7 +66917,7 @@ function cgroupDirectory(text) {
66887
66917
  }
66888
66918
  async function collectAgentResourceDiagnostics(options = {}) {
66889
66919
  const platform6 = options.platform ?? process.platform;
66890
- const readFile7 = async (path2) => {
66920
+ const readFile8 = async (path2) => {
66891
66921
  try {
66892
66922
  return await (options.readFile ?? readResourceFile)(path2);
66893
66923
  } catch {
@@ -66904,11 +66934,11 @@ async function collectAgentResourceDiagnostics(options = {}) {
66904
66934
  };
66905
66935
  if (platform6 !== "linux") return sample;
66906
66936
  const [meminfo, memoryPsi, cpuPsi, ioPsi, cgroup] = await Promise.all([
66907
- readFile7("/proc/meminfo"),
66908
- readFile7("/proc/pressure/memory"),
66909
- readFile7("/proc/pressure/cpu"),
66910
- readFile7("/proc/pressure/io"),
66911
- 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")
66912
66942
  ]);
66913
66943
  sample.memoryAvailableBytes = meminfoBytes(meminfo, "MemAvailable");
66914
66944
  sample.swapTotalBytes = meminfoBytes(meminfo, "SwapTotal");
@@ -66920,9 +66950,9 @@ async function collectAgentResourceDiagnostics(options = {}) {
66920
66950
  const directory = cgroupDirectory(cgroup);
66921
66951
  if (!directory) return sample;
66922
66952
  const [current, limit, events] = await Promise.all([
66923
- readFile7(`${directory}/memory.current`),
66924
- readFile7(`${directory}/memory.max`),
66925
- readFile7(`${directory}/memory.events`)
66953
+ readFile8(`${directory}/memory.current`),
66954
+ readFile8(`${directory}/memory.max`),
66955
+ readFile8(`${directory}/memory.events`)
66926
66956
  ]);
66927
66957
  sample.cgroupMemoryCurrentBytes = counter(current?.trim());
66928
66958
  sample.cgroupMemoryLimitBytes = counter(limit?.trim());
@@ -67931,7 +67961,7 @@ async function runSandbox(config2) {
67931
67961
  }
67932
67962
 
67933
67963
  // src/skills/skill-cli.ts
67934
- var import_promises7 = require("fs/promises");
67964
+ var import_promises8 = require("fs/promises");
67935
67965
  var import_node_os20 = require("os");
67936
67966
  var import_node_path31 = require("path");
67937
67967
  async function runSkillsCommand(args) {
@@ -67978,7 +68008,7 @@ async function defaultScanInput(homeDirectory2) {
67978
68008
  }
67979
68009
  async function readProtectedJson(path2) {
67980
68010
  const absolutePath = (0, import_node_path31.resolve)(path2);
67981
- const stat2 = await (0, import_promises7.lstat)(absolutePath);
68011
+ const stat2 = await (0, import_promises8.lstat)(absolutePath);
67982
68012
  if (!stat2.isFile()) throw new Error(`Skill input is not a regular file: ${absolutePath}`);
67983
68013
  if (process.platform !== "win32" && (stat2.mode & 63) !== 0) {
67984
68014
  throw new Error(`Skill input must not be accessible by group or other users: ${absolutePath}`);
@@ -67987,7 +68017,7 @@ async function readProtectedJson(path2) {
67987
68017
  throw new Error(`Skill input must be owned by the current user: ${absolutePath}`);
67988
68018
  }
67989
68019
  if (stat2.size > 2 * 1024 * 1024) throw new Error("Skill input exceeds 2 MiB");
67990
- return JSON.parse(await (0, import_promises7.readFile)(absolutePath, "utf8"));
68020
+ return JSON.parse(await (0, import_promises8.readFile)(absolutePath, "utf8"));
67991
68021
  }
67992
68022
  function option(args, name) {
67993
68023
  const index = args.indexOf(name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alan-ai-hq/agent-manager",
3
- "version": "0.1.105",
3
+ "version": "0.1.106",
4
4
  "type": "module",
5
5
  "description": "Alan agent runtime — cloud sandbox and local daemon (alan-agent CLI)",
6
6
  "bin": {
@@ -24,9 +24,9 @@
24
24
  "tsup": "^8.5.1",
25
25
  "tsx": "^4.19.0",
26
26
  "typescript": "~5.9.3",
27
- "@alan-ai/sandbox-runtime-spec": "0.1.0",
28
27
  "@alan-ai/agent-core": "0.1.0",
29
- "@alan-ai/shared": "0.1.0"
28
+ "@alan-ai/shared": "0.1.0",
29
+ "@alan-ai/sandbox-runtime-spec": "0.1.0"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup",