@alan-ai-hq/agent-manager-linux-x64 0.1.128 → 0.1.129

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.
package/alan-agent.cjs CHANGED
@@ -26351,14 +26351,8 @@ function hookResponse(event) {
26351
26351
  if (outcome2 === "success" && exitCode === 0) return [];
26352
26352
  const name = asString(event.hook_name) || "hook";
26353
26353
  const detail = asString(event.stderr) || asString(event.output) || asString(event.stdout);
26354
- return [
26355
- noticeUpdate(
26356
- "warning",
26357
- "hook_failed",
26358
- `Hook ${name} failed${exitCode ? ` (exit ${exitCode})` : ""}${outcome2 ? `: ${outcome2}` : ""}.`,
26359
- detail || void 0
26360
- )
26361
- ];
26354
+ const summary = `Hook ${name} failed${exitCode ? ` (exit ${exitCode})` : ""}${outcome2 ? `: ${outcome2}` : ""}.`;
26355
+ return [logUpdate("claude_cli/hook", detail ? `${summary} ${detail}` : summary)];
26362
26356
  }
26363
26357
  function apiRetryNotice(event) {
26364
26358
  const attempt2 = asFiniteNumber(event.attempt) ?? 0;
@@ -29038,6 +29032,10 @@ function isAuthStatus(error61) {
29038
29032
  const status = httpStatusOf(info);
29039
29033
  return info === "unauthorized" || status === 401 || status === 403;
29040
29034
  }
29035
+ function cliLog(method, params) {
29036
+ const text2 = [asString(params.message) || asString(params.summary), asString(params.details)].filter((part) => part.length > 0).join(" ");
29037
+ return logUpdate(`codex/${method}`, text2);
29038
+ }
29041
29039
  function pendingAnswer(pending, answer) {
29042
29040
  switch (pending.kind) {
29043
29041
  case "approval":
@@ -29287,7 +29285,6 @@ function promptFor(spec, turn, resumeId) {
29287
29285
  return [system?.trim(), turn.text.trim()].filter(Boolean).join("\n\n");
29288
29286
  }
29289
29287
  function provider(spec, clock) {
29290
- const memory = { shownWarnings: /* @__PURE__ */ new Set() };
29291
29288
  return {
29292
29289
  name: "codex-exec",
29293
29290
  launch: async (turn, resumeId) => ({
@@ -29304,7 +29301,7 @@ function provider(spec, clock) {
29304
29301
  }),
29305
29302
  stdin: promptFor(spec, turn, resumeId)
29306
29303
  }),
29307
- reader: (_turn, resumeId) => new CodexExecTurn(memory, resumeId, { codexHome: codexHomeOf(spec.env), clock })
29304
+ reader: (_turn, resumeId) => new CodexExecTurn(resumeId, { codexHome: codexHomeOf(spec.env), clock })
29308
29305
  };
29309
29306
  }
29310
29307
  function createCodexExecDriver(options = {}) {
@@ -30401,11 +30398,12 @@ var init_codex = __esm({
30401
30398
  ];
30402
30399
  case "thread/tokenUsage/updated":
30403
30400
  return this.#usage(params);
30401
+ // The CLI's own housekeeping (the user's config.toml, unstable features, hook timeouts):
30402
+ // kept in the run log, never shown in the chat, where nothing can act on it.
30404
30403
  case "warning":
30405
30404
  case "configWarning":
30406
- return this.#warning(method, asString(params.message) || asString(params.summary));
30407
30405
  case "deprecationNotice":
30408
- return this.#deprecation(asString(params.summary), asString(params.details));
30406
+ return [cliLog(method, params)];
30409
30407
  case "mcpServer/startupStatus/updated":
30410
30408
  return this.#mcpStatus(params);
30411
30409
  case "error":
@@ -30468,35 +30466,31 @@ var init_codex = __esm({
30468
30466
  )
30469
30467
  ];
30470
30468
  }
30471
- /** Codex repeats its config warnings on every thread and turn; each is shown once per session. */
30472
- #warning(method, message2) {
30473
- const key = `${method}\0${message2}`;
30474
- if (!message2 || this.#memory.shownWarnings.has(key)) return [];
30469
+ /**
30470
+ * Only Alan's own MCP server failing matters in the chat: its tools are gone for the session.
30471
+ * The user's other servers (and their logins) belong to their Codex setup, not to Alan.
30472
+ */
30473
+ #mcpStatus(params) {
30474
+ if (asString(params.status) !== "failed") return [];
30475
+ const name = asString(params.name);
30476
+ if (canonicalizeManagedMcpServerName(name) !== MANAGED_MCP_SERVER_NAME) {
30477
+ const reason2 = asString(params.error) || asString(params.failureReason);
30478
+ return [
30479
+ logUpdate("codex/mcp", `MCP server ${name} failed to start${reason2 ? `: ${reason2}` : "."}`)
30480
+ ];
30481
+ }
30482
+ const reason = asString(params.error) || asString(params.failureReason);
30483
+ const key = `mcp_server_failed\0${reason}`;
30484
+ if (this.#memory.shownWarnings.has(key)) return [];
30475
30485
  this.#memory.shownWarnings.add(key);
30476
30486
  return [
30477
30487
  noticeUpdate(
30478
30488
  "warning",
30479
- method === "configWarning" ? "config_warning" : "provider_warning",
30480
- message2
30489
+ "mcp_server_failed",
30490
+ `Alan tools are unavailable in this session${reason ? `: ${reason}` : "."}`
30481
30491
  )
30482
30492
  ];
30483
30493
  }
30484
- /** Codex telling the user a setting or feature is going away: once per session, never an error. */
30485
- #deprecation(summary, details) {
30486
- const key = `deprecationNotice\0${summary}`;
30487
- if (!summary || this.#memory.shownWarnings.has(key)) return [];
30488
- this.#memory.shownWarnings.add(key);
30489
- return [noticeUpdate("warning", "deprecation", summary, details || void 0)];
30490
- }
30491
- #mcpStatus(params) {
30492
- if (asString(params.status) !== "failed") return [];
30493
- const name = asString(params.name) || "unknown";
30494
- const reason = asString(params.error) || asString(params.failureReason);
30495
- return this.#warning(
30496
- "mcp_server_failed",
30497
- `MCP server ${name} failed to start${reason ? `: ${reason}` : "."}`
30498
- );
30499
- }
30500
30494
  #error(params) {
30501
30495
  const error61 = asRecord(params.error);
30502
30496
  if (params.willRetry === true) {
@@ -30974,14 +30968,12 @@ var init_codex = __esm({
30974
30968
  message: "The agent exited without producing a response. Send your message again to retry."
30975
30969
  };
30976
30970
  CodexExecTurn = class {
30977
- #memory;
30978
30971
  #threadId;
30979
30972
  #end;
30980
30973
  #lastError;
30981
30974
  #answered = false;
30982
30975
  #images;
30983
- constructor(memory, resumeId, rollout) {
30984
- this.#memory = memory;
30976
+ constructor(resumeId, rollout) {
30985
30977
  this.#threadId = resumeId;
30986
30978
  if (!rollout) return;
30987
30979
  this.#images = new CodexRolloutImages(
@@ -31037,7 +31029,9 @@ var init_codex = __esm({
31037
31029
  #item(item, completed) {
31038
31030
  if (!item) return [];
31039
31031
  const type = asString(item.type);
31040
- if (type === "error") return completed ? this.#warning(asString(item.message)) : [];
31032
+ if (type === "error") {
31033
+ return completed ? [logUpdate("codex/warning", asString(item.message))] : [];
31034
+ }
31041
31035
  if (type === "todo_list") {
31042
31036
  return Array.isArray(item.items) ? todoEntries(asString(item.id), item.items) : [];
31043
31037
  }
@@ -31046,12 +31040,6 @@ var init_codex = __esm({
31046
31040
  if (mapped) return itemUpdates(mapped, completed);
31047
31041
  return [{ sessionUpdate: "_alan/unhandled", kind: `item/${type || "(untyped)"}` }];
31048
31042
  }
31049
- /** Exec reports config warnings as `error` items on every turn; each is shown once. */
31050
- #warning(message2) {
31051
- if (!message2 || this.#memory.shownWarnings.has(message2)) return [];
31052
- this.#memory.shownWarnings.add(message2);
31053
- return [noticeUpdate("warning", "provider", message2)];
31054
- }
31055
31043
  #completed(usage) {
31056
31044
  this.#end = { status: "completed" };
31057
31045
  const number4 = (value2) => asFiniteNumber(value2) ?? 0;
@@ -52445,7 +52433,7 @@ var require_websocket_server = __commonJS({
52445
52433
  // package.json
52446
52434
  var package_default = {
52447
52435
  name: "@alan-ai-hq/agent-manager",
52448
- version: "0.1.128",
52436
+ version: "0.1.129",
52449
52437
  private: true,
52450
52438
  type: "module",
52451
52439
  description: "Alan machine runtime (alan-agent): identity, link, reconciler, session holders, run log, uploader, local API",
@@ -55497,13 +55485,15 @@ var import_node_os = require("os");
55497
55485
  var import_node_path9 = require("path");
55498
55486
  var MAX_SOCKET_PATH_BYTES = 100;
55499
55487
  function windowsPipeName(socketsDir, id) {
55500
- const scope = (0, import_node_crypto6.createHash)("sha256").update(socketsDir.toLowerCase()).digest("hex").slice(0, 12);
55501
- return `\\\\.\\pipe\\alan-${scope}-${id}`;
55488
+ return `\\\\.\\pipe\\alan-${socketsScope(socketsDir)}-${id}`;
55489
+ }
55490
+ function socketsScope(socketsDir) {
55491
+ return (0, import_node_crypto6.createHash)("sha256").update(socketsDir.toLowerCase()).digest("hex").slice(0, 12);
55502
55492
  }
55503
55493
  function ipcEndpoint(socketsDir, id, platform3 = process.platform) {
55504
55494
  if (platform3 === "win32") return windowsPipeName(socketsDir, id);
55505
55495
  const preferred = (0, import_node_path9.join)(socketsDir, `${id}.sock`);
55506
- const dir = Buffer.byteLength(preferred) <= MAX_SOCKET_PATH_BYTES ? socketsDir : (0, import_node_path9.join)("/tmp", `alan-${(0, import_node_os.userInfo)().uid}`);
55496
+ const dir = Buffer.byteLength(preferred) <= MAX_SOCKET_PATH_BYTES ? socketsDir : (0, import_node_path9.join)("/tmp", `alan-${(0, import_node_os.userInfo)().uid}-${socketsScope(socketsDir)}`);
55507
55497
  (0, import_node_fs5.mkdirSync)(dir, { recursive: true, mode: 448 });
55508
55498
  return (0, import_node_path9.join)(dir, `${id}.sock`);
55509
55499
  }
@@ -63284,6 +63274,7 @@ var LOCAL_API_ROUTES = {
63284
63274
  setup: "/v2/setup",
63285
63275
  logout: "/v2/logout",
63286
63276
  redial: "/v2/link/redial",
63277
+ quit: "/v2/quit",
63287
63278
  prepareUpdate: "/v2/runtime/prepare-update",
63288
63279
  nativeHook: "/v2/native/hook",
63289
63280
  localSkillInspect: "/v2/skills/local/inspect",
@@ -63376,6 +63367,9 @@ var logoutResponseSchema = external_exports.object({
63376
63367
  var redialResponseSchema = external_exports.object({
63377
63368
  accepted: external_exports.literal(true)
63378
63369
  });
63370
+ var quitResponseSchema = external_exports.object({
63371
+ stopping: external_exports.literal(true)
63372
+ });
63379
63373
  var MAX_PREPARE_UPDATE_WAIT_MS = 25e3;
63380
63374
  var prepareUpdateRequestSchema = external_exports.object({
63381
63375
  waitMs: external_exports.number().int().min(0).max(MAX_PREPARE_UPDATE_WAIT_MS)
@@ -63777,6 +63771,13 @@ function createRuntimeClient(options) {
63777
63771
  parseWith(logoutResponseSchema, await response.json(), "logout response");
63778
63772
  return { kind: "revoked" };
63779
63773
  },
63774
+ quit: async (signal) => {
63775
+ await json2(
63776
+ { method: "POST", path: LOCAL_API_ROUTES.quit, body: {} },
63777
+ quitResponseSchema,
63778
+ signal
63779
+ );
63780
+ },
63780
63781
  redial: async (signal) => {
63781
63782
  await json2(
63782
63783
  { method: "POST", path: LOCAL_API_ROUTES.redial, body: {} },
@@ -67971,6 +67972,35 @@ async function runLogout(argv, signal) {
67971
67972
  // src/cli/commands/run.ts
67972
67973
  var import_node_path71 = require("path");
67973
67974
 
67975
+ // src/local-api/app-attachments.ts
67976
+ function createAppAttachments(clock) {
67977
+ const state = {
67978
+ open: 0,
67979
+ quit: false,
67980
+ lostSinceMs: null
67981
+ };
67982
+ return {
67983
+ attach: () => {
67984
+ state.open += 1;
67985
+ state.lostSinceMs = null;
67986
+ const stream = { closed: false };
67987
+ return {
67988
+ [Symbol.dispose]: () => {
67989
+ if (stream.closed) return;
67990
+ stream.closed = true;
67991
+ state.open -= 1;
67992
+ if (state.open === 0) state.lostSinceMs = clock.monotonic();
67993
+ }
67994
+ };
67995
+ },
67996
+ quit: () => {
67997
+ state.quit = true;
67998
+ },
67999
+ quitRequested: () => state.quit,
68000
+ lostSinceMs: () => state.open === 0 ? state.lostSinceMs : null
68001
+ };
68002
+ }
68003
+
67974
68004
  // src/local-api/run-appends.ts
67975
68005
  function createRunAppends() {
67976
68006
  const waiters = /* @__PURE__ */ new Map();
@@ -68326,10 +68356,11 @@ var emptyBodySchema = external_exports.object({});
68326
68356
  function activeRunIds(runs) {
68327
68357
  return runs.filter((run2) => run2.state !== "ended").map((run2) => run2.runId);
68328
68358
  }
68329
- var streamStatus = async ({ feed }, { res, signal }) => {
68359
+ var streamStatus = async ({ feed, appAttachments }, { res, signal }) => {
68330
68360
  var _stack = [];
68331
68361
  try {
68332
68362
  const snapshot2 = await feed.refresh(signal);
68363
+ const _attachment = __using(_stack, appAttachments.attach());
68333
68364
  startEventStream(res);
68334
68365
  const send2 = (name, event) => writeEvent(res, { name, id: String(event.seq), dataLines: [JSON.stringify(event)] });
68335
68366
  let latest = null;
@@ -68425,6 +68456,12 @@ var redial = async ({ actions }, request2) => {
68425
68456
  const result = { accepted: true };
68426
68457
  sendJson(request2.res, 202, result);
68427
68458
  };
68459
+ var quit = async ({ appAttachments }, request2) => {
68460
+ if (await readBody3(request2, emptyBodySchema) === null) return;
68461
+ appAttachments.quit();
68462
+ const result = { stopping: true };
68463
+ sendJson(request2.res, 202, result);
68464
+ };
68428
68465
  var nativeHook = async ({ actions }, request2) => {
68429
68466
  const body = await readBody3(request2, nativeHookSignalSchema);
68430
68467
  if (body === null) return;
@@ -68455,6 +68492,7 @@ var FIXED_ROUTES = new Map([
68455
68492
  [LOCAL_API_ROUTES.setup, { method: "POST", handle: setup }],
68456
68493
  [LOCAL_API_ROUTES.logout, { method: "POST", handle: logout }],
68457
68494
  [LOCAL_API_ROUTES.redial, { method: "POST", handle: redial }],
68495
+ [LOCAL_API_ROUTES.quit, { method: "POST", handle: quit }],
68458
68496
  [LOCAL_API_ROUTES.prepareUpdate, { method: "POST", handle: prepareUpdate }],
68459
68497
  [LOCAL_API_ROUTES.nativeHook, { method: "POST", handle: nativeHook }],
68460
68498
  ...machineFeatureRoutes
@@ -68580,8 +68618,10 @@ async function serveLocalApi(deps) {
68580
68618
  const port = await listenOnLoopback(server);
68581
68619
  const token = (0, import_node_crypto28.randomBytes)(32).toString("base64url");
68582
68620
  const guard = createRequestGuard({ token, port, rateLimit: limits.rateLimit, clock });
68621
+ const appAttachments = createAppAttachments(clock);
68583
68622
  const routeDeps = {
68584
68623
  feed,
68624
+ appAttachments,
68585
68625
  actions: deps.actions,
68586
68626
  runsDir: deps.runsDir,
68587
68627
  appends: deps.appends,
@@ -68649,6 +68689,7 @@ async function serveLocalApi(deps) {
68649
68689
  refreshStatus: async () => {
68650
68690
  if (feed.subscriberCount() > 0) await feed.refresh(AbortSignal.timeout(ACTION_TIMEOUT_MS));
68651
68691
  },
68692
+ appAttachments,
68652
68693
  [Symbol.asyncDispose]: async () => {
68653
68694
  await followers[Symbol.asyncDispose]();
68654
68695
  await watchedStatus[Symbol.asyncDispose]();
@@ -68662,6 +68703,43 @@ async function serveLocalApi(deps) {
68662
68703
  };
68663
68704
  }
68664
68705
 
68706
+ // src/cli/commands/app-gone.ts
68707
+ var APP_GONE_CHECK_MS = 1e3;
68708
+ var APP_GONE_GRACE_MS = 1e4;
68709
+ function watchAppGone(options) {
68710
+ const { appAttachments, clock, lifecycle, log } = options;
68711
+ const graceMs = options.graceMs ?? APP_GONE_GRACE_MS;
68712
+ const stop = new AbortController();
68713
+ const goneFor = () => {
68714
+ const lostSinceMs = appAttachments.lostSinceMs();
68715
+ return lostSinceMs === null ? null : clock.monotonic() - lostSinceMs;
68716
+ };
68717
+ const check3 = async (signal) => {
68718
+ if (stop.signal.aborted) return;
68719
+ const quit2 = appAttachments.quitRequested();
68720
+ const gone = goneFor();
68721
+ if (!quit2 && (gone === null || gone < graceMs)) return;
68722
+ const stopped = await lifecycle.exclusive("stop_app_gone", async () => {
68723
+ if (!quit2 && goneFor() === null) return false;
68724
+ await options.interruptAllRuns(signal);
68725
+ return true;
68726
+ });
68727
+ if (!stopped) return;
68728
+ log.info(quit2 ? "runtime.app_quit" : "runtime.app_gone_stop", { goneMs: gone });
68729
+ stop.abort();
68730
+ };
68731
+ const maintenance = startMaintenance({
68732
+ everyMs: options.everyMs ?? APP_GONE_CHECK_MS,
68733
+ jobs: [{ name: "runtime.app_gone_check", run: check3 }],
68734
+ clock,
68735
+ log
68736
+ });
68737
+ return {
68738
+ stopRequested: stop.signal,
68739
+ [Symbol.asyncDispose]: () => maintenance[Symbol.asyncDispose]()
68740
+ };
68741
+ }
68742
+
68665
68743
  // src/cli/commands/machine-features.ts
68666
68744
  async function skillRead(read) {
68667
68745
  try {
@@ -72982,6 +73060,12 @@ function startUploader({ api, runsDir, clock, log }) {
72982
73060
  });
72983
73061
  active.set(runId, task);
72984
73062
  };
73063
+ const sweep2 = async () => {
73064
+ for (const name of await (0, import_promises67.readdir)(runsDir).catch(() => [])) {
73065
+ const runId = runIdSchema.safeParse(name);
73066
+ if (runId.success) run2(runId.data);
73067
+ }
73068
+ };
72985
73069
  const isPrunable = async (runId, options) => {
72986
73070
  if (options.keep.has(runId) || active.has(runId)) return false;
72987
73071
  const dir = runDirectory(runsDir, runId);
@@ -73009,10 +73093,11 @@ function startUploader({ api, runsDir, clock, log }) {
73009
73093
  return {
73010
73094
  notify: run2,
73011
73095
  prune,
73012
- sweep: async () => {
73013
- for (const name of await (0, import_promises67.readdir)(runsDir).catch(() => [])) {
73014
- const runId = runIdSchema.safeParse(name);
73015
- if (runId.success) run2(runId.data);
73096
+ sweep: sweep2,
73097
+ flush: async () => {
73098
+ await sweep2();
73099
+ while (active.size > 0 && !controller.signal.aborted) {
73100
+ await Promise.allSettled([...active.values()]);
73016
73101
  }
73017
73102
  },
73018
73103
  [Symbol.asyncDispose]: async () => {
@@ -73767,7 +73852,7 @@ async function startMachinePlane(deps) {
73767
73852
  const result = await workspaces.answer({ method: "workspace.status", path: path4 });
73768
73853
  return result.ok ? { ok: true } : { ok: false, message: result.error.message };
73769
73854
  },
73770
- flushUploads: () => uploader.sweep(),
73855
+ flushUploads: () => uploader.flush(),
73771
73856
  nativeHook: (hookSignal) => nativeIngest.accept(hookSignal),
73772
73857
  rescanLocalSkills: () => skills.rescan(),
73773
73858
  apiUrl: identity.endpoints.apiUrl,
@@ -73783,6 +73868,10 @@ async function startMachinePlane(deps) {
73783
73868
 
73784
73869
  // src/cli/commands/machine-slot.ts
73785
73870
  var NOT_SET_UP_LINK = { state: "stopped" };
73871
+ var FINAL_UPLOAD_WAIT_MS = 2e4;
73872
+ function sameOrigin(requested, configured) {
73873
+ return URL.canParse(requested) && new URL(requested).origin === new URL(configured).origin;
73874
+ }
73786
73875
  function faultMessage(error61) {
73787
73876
  return error61 instanceof Error ? error61.message : String(error61);
73788
73877
  }
@@ -73857,6 +73946,13 @@ function createMachineSlot(deps) {
73857
73946
  message: "This computer is already set up; log out first"
73858
73947
  };
73859
73948
  }
73949
+ if (!sameOrigin(request2.apiUrl, ctx.config.apiUrl)) {
73950
+ return {
73951
+ kind: "refused",
73952
+ code: "setup_failed",
73953
+ message: `This computer's ${ctx.config.profile} runtime serves ${ctx.config.apiUrl}, not ${request2.apiUrl}`
73954
+ };
73955
+ }
73860
73956
  await close2();
73861
73957
  const setupCtx = cliContext({ ...ctx.config, apiUrl: request2.apiUrl });
73862
73958
  try {
@@ -73892,9 +73988,23 @@ function createMachineSlot(deps) {
73892
73988
  throw error61;
73893
73989
  }
73894
73990
  };
73991
+ const interruptAllRuns = async (signal) => {
73992
+ const plane = slot.plane;
73993
+ if (plane === null) return;
73994
+ const stopped = await stopHeldRuns(ctx, logoutDeps(signal), "interrupted");
73995
+ const waited = new AbortController();
73996
+ await Promise.race([
73997
+ plane.flushUploads().catch((error61) => log.warn("runtime.flush_failed", { error: error61 })),
73998
+ clock.sleep(FINAL_UPLOAD_WAIT_MS, AbortSignal.any([signal, waited.signal])).catch(() => {
73999
+ })
74000
+ ]);
74001
+ waited.abort();
74002
+ log.info("runtime.runs_interrupted", { stopped });
74003
+ };
73895
74004
  return {
73896
74005
  open: open5,
73897
74006
  plane: () => slot.plane,
74007
+ interruptAllRuns,
73898
74008
  facts: () => {
73899
74009
  const plane = slot.plane;
73900
74010
  if (plane === null) return { machineId: null, setup: "none", link: NOT_SET_UP_LINK };
@@ -74051,6 +74161,13 @@ async function runService(argv, stop, restart = new AbortController().signal) {
74051
74161
  clock,
74052
74162
  log
74053
74163
  }), true);
74164
+ const appGone = __using(_stack, watchAppGone({
74165
+ appAttachments: localApi.appAttachments,
74166
+ lifecycle,
74167
+ interruptAllRuns: (signal) => machine.interruptAllRuns(signal),
74168
+ clock,
74169
+ log
74170
+ }), true);
74054
74171
  log.info("runtime.started", {
74055
74172
  machineId: machine.facts().machineId,
74056
74173
  setup: machine.facts().setup,
@@ -74059,7 +74176,7 @@ async function runService(argv, stop, restart = new AbortController().signal) {
74059
74176
  });
74060
74177
  return await awaitRuntimeExit(
74061
74178
  {
74062
- stop: AbortSignal.any([stop, stopForUpdate.signal]),
74179
+ stop: AbortSignal.any([stop, stopForUpdate.signal, appGone.stopRequested]),
74063
74180
  restart: AbortSignal.any([
74064
74181
  restart,
74065
74182
  updateInstalled.signal,
package/alan-holder.cjs CHANGED
@@ -26051,14 +26051,8 @@ function hookResponse(event) {
26051
26051
  if (outcome2 === "success" && exitCode === 0) return [];
26052
26052
  const name = asString(event.hook_name) || "hook";
26053
26053
  const detail = asString(event.stderr) || asString(event.output) || asString(event.stdout);
26054
- return [
26055
- noticeUpdate(
26056
- "warning",
26057
- "hook_failed",
26058
- `Hook ${name} failed${exitCode ? ` (exit ${exitCode})` : ""}${outcome2 ? `: ${outcome2}` : ""}.`,
26059
- detail || void 0
26060
- )
26061
- ];
26054
+ const summary = `Hook ${name} failed${exitCode ? ` (exit ${exitCode})` : ""}${outcome2 ? `: ${outcome2}` : ""}.`;
26055
+ return [logUpdate("claude_cli/hook", detail ? `${summary} ${detail}` : summary)];
26062
26056
  }
26063
26057
  function apiRetryNotice(event) {
26064
26058
  const attempt = asFiniteNumber(event.attempt) ?? 0;
@@ -28521,6 +28515,10 @@ function isAuthStatus(error61) {
28521
28515
  const status = httpStatusOf(info);
28522
28516
  return info === "unauthorized" || status === 401 || status === 403;
28523
28517
  }
28518
+ function cliLog(method, params) {
28519
+ const text2 = [asString(params.message) || asString(params.summary), asString(params.details)].filter((part) => part.length > 0).join(" ");
28520
+ return logUpdate(`codex/${method}`, text2);
28521
+ }
28524
28522
  function pendingAnswer(pending, answer) {
28525
28523
  switch (pending.kind) {
28526
28524
  case "approval":
@@ -28770,7 +28768,6 @@ function promptFor(spec, turn, resumeId) {
28770
28768
  return [system?.trim(), turn.text.trim()].filter(Boolean).join("\n\n");
28771
28769
  }
28772
28770
  function provider(spec, clock) {
28773
- const memory = { shownWarnings: /* @__PURE__ */ new Set() };
28774
28771
  return {
28775
28772
  name: "codex-exec",
28776
28773
  launch: async (turn, resumeId) => ({
@@ -28787,7 +28784,7 @@ function provider(spec, clock) {
28787
28784
  }),
28788
28785
  stdin: promptFor(spec, turn, resumeId)
28789
28786
  }),
28790
- reader: (_turn, resumeId) => new CodexExecTurn(memory, resumeId, { codexHome: codexHomeOf(spec.env), clock })
28787
+ reader: (_turn, resumeId) => new CodexExecTurn(resumeId, { codexHome: codexHomeOf(spec.env), clock })
28791
28788
  };
28792
28789
  }
28793
28790
  function createCodexExecDriver(options = {}) {
@@ -29263,11 +29260,12 @@ var init_codex = __esm({
29263
29260
  ];
29264
29261
  case "thread/tokenUsage/updated":
29265
29262
  return this.#usage(params);
29263
+ // The CLI's own housekeeping (the user's config.toml, unstable features, hook timeouts):
29264
+ // kept in the run log, never shown in the chat, where nothing can act on it.
29266
29265
  case "warning":
29267
29266
  case "configWarning":
29268
- return this.#warning(method, asString(params.message) || asString(params.summary));
29269
29267
  case "deprecationNotice":
29270
- return this.#deprecation(asString(params.summary), asString(params.details));
29268
+ return [cliLog(method, params)];
29271
29269
  case "mcpServer/startupStatus/updated":
29272
29270
  return this.#mcpStatus(params);
29273
29271
  case "error":
@@ -29330,35 +29328,31 @@ var init_codex = __esm({
29330
29328
  )
29331
29329
  ];
29332
29330
  }
29333
- /** Codex repeats its config warnings on every thread and turn; each is shown once per session. */
29334
- #warning(method, message) {
29335
- const key = `${method}\0${message}`;
29336
- if (!message || this.#memory.shownWarnings.has(key)) return [];
29331
+ /**
29332
+ * Only Alan's own MCP server failing matters in the chat: its tools are gone for the session.
29333
+ * The user's other servers (and their logins) belong to their Codex setup, not to Alan.
29334
+ */
29335
+ #mcpStatus(params) {
29336
+ if (asString(params.status) !== "failed") return [];
29337
+ const name = asString(params.name);
29338
+ if (canonicalizeManagedMcpServerName(name) !== MANAGED_MCP_SERVER_NAME) {
29339
+ const reason2 = asString(params.error) || asString(params.failureReason);
29340
+ return [
29341
+ logUpdate("codex/mcp", `MCP server ${name} failed to start${reason2 ? `: ${reason2}` : "."}`)
29342
+ ];
29343
+ }
29344
+ const reason = asString(params.error) || asString(params.failureReason);
29345
+ const key = `mcp_server_failed\0${reason}`;
29346
+ if (this.#memory.shownWarnings.has(key)) return [];
29337
29347
  this.#memory.shownWarnings.add(key);
29338
29348
  return [
29339
29349
  noticeUpdate(
29340
29350
  "warning",
29341
- method === "configWarning" ? "config_warning" : "provider_warning",
29342
- message
29351
+ "mcp_server_failed",
29352
+ `Alan tools are unavailable in this session${reason ? `: ${reason}` : "."}`
29343
29353
  )
29344
29354
  ];
29345
29355
  }
29346
- /** Codex telling the user a setting or feature is going away: once per session, never an error. */
29347
- #deprecation(summary, details) {
29348
- const key = `deprecationNotice\0${summary}`;
29349
- if (!summary || this.#memory.shownWarnings.has(key)) return [];
29350
- this.#memory.shownWarnings.add(key);
29351
- return [noticeUpdate("warning", "deprecation", summary, details || void 0)];
29352
- }
29353
- #mcpStatus(params) {
29354
- if (asString(params.status) !== "failed") return [];
29355
- const name = asString(params.name) || "unknown";
29356
- const reason = asString(params.error) || asString(params.failureReason);
29357
- return this.#warning(
29358
- "mcp_server_failed",
29359
- `MCP server ${name} failed to start${reason ? `: ${reason}` : "."}`
29360
- );
29361
- }
29362
29356
  #error(params) {
29363
29357
  const error61 = asRecord(params.error);
29364
29358
  if (params.willRetry === true) {
@@ -29836,14 +29830,12 @@ var init_codex = __esm({
29836
29830
  message: "The agent exited without producing a response. Send your message again to retry."
29837
29831
  };
29838
29832
  CodexExecTurn = class {
29839
- #memory;
29840
29833
  #threadId;
29841
29834
  #end;
29842
29835
  #lastError;
29843
29836
  #answered = false;
29844
29837
  #images;
29845
- constructor(memory, resumeId, rollout) {
29846
- this.#memory = memory;
29838
+ constructor(resumeId, rollout) {
29847
29839
  this.#threadId = resumeId;
29848
29840
  if (!rollout) return;
29849
29841
  this.#images = new CodexRolloutImages(
@@ -29899,7 +29891,9 @@ var init_codex = __esm({
29899
29891
  #item(item, completed) {
29900
29892
  if (!item) return [];
29901
29893
  const type = asString(item.type);
29902
- if (type === "error") return completed ? this.#warning(asString(item.message)) : [];
29894
+ if (type === "error") {
29895
+ return completed ? [logUpdate("codex/warning", asString(item.message))] : [];
29896
+ }
29903
29897
  if (type === "todo_list") {
29904
29898
  return Array.isArray(item.items) ? todoEntries(asString(item.id), item.items) : [];
29905
29899
  }
@@ -29908,12 +29902,6 @@ var init_codex = __esm({
29908
29902
  if (mapped) return itemUpdates(mapped, completed);
29909
29903
  return [{ sessionUpdate: "_alan/unhandled", kind: `item/${type || "(untyped)"}` }];
29910
29904
  }
29911
- /** Exec reports config warnings as `error` items on every turn; each is shown once. */
29912
- #warning(message) {
29913
- if (!message || this.#memory.shownWarnings.has(message)) return [];
29914
- this.#memory.shownWarnings.add(message);
29915
- return [noticeUpdate("warning", "provider", message)];
29916
- }
29917
29905
  #completed(usage) {
29918
29906
  this.#end = { status: "completed" };
29919
29907
  const number4 = (value) => asFiniteNumber(value) ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alan-ai-hq/agent-manager-linux-x64",
3
- "version": "0.1.128",
3
+ "version": "0.1.129",
4
4
  "description": "Alan machine runtime (alan-agent) for one platform: the official Node.js binary, the runtime bundle and its launcher. Installed by @alan-ai-hq/agent-manager.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://tryalan.ai",