@turmind/halo 1.3.4 → 1.4.1

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 (45) hide show
  1. package/admin-out/404.html +1 -1
  2. package/admin-out/_next/static/chunks/989-6a0ec35b8ae2cb39.js +1 -0
  3. package/admin-out/_next/static/chunks/app/page-bf9c0b21ae431c92.js +1 -0
  4. package/admin-out/_next/static/css/c0ea31cd787f7aa7.css +3 -0
  5. package/admin-out/index.html +1 -1
  6. package/admin-out/index.txt +5 -5
  7. package/bundled-docs/design/agent.md +16 -11
  8. package/bundled-docs/design/cron.md +19 -11
  9. package/bundled-docs/design/express-self.md +1 -1
  10. package/bundled-docs/design/prompt-system.md +1 -1
  11. package/bundled-docs/design/storage.md +7 -3
  12. package/bundled-docs/design/wechat.md +1 -1
  13. package/bundled-docs/design/ws.md +2 -1
  14. package/bundled-docs/dev/add-model-provider.md +1 -1
  15. package/bundled-docs/dev/api.md +6 -6
  16. package/bundled-docs/dev/deploy.md +1 -1
  17. package/bundled-docs/dev/desktop-packaging.md +1 -1
  18. package/bundled-docs/dev/env.md +4 -4
  19. package/bundled-docs/dev/tools.md +41 -22
  20. package/bundled-docs/guide/README.md +1 -0
  21. package/bundled-docs/guide/agents.md +2 -0
  22. package/bundled-docs/guide/chat.md +10 -0
  23. package/bundled-docs/guide/cli.md +8 -3
  24. package/bundled-docs/guide/delegation-and-access.md +161 -0
  25. package/bundled-docs/guide/sessions.md +1 -1
  26. package/bundled-docs/requirements/chat.md +8 -0
  27. package/dist/index.js +873 -465
  28. package/package.json +1 -1
  29. package/templates/agents/__apply_agent__/agent.yaml +1 -1
  30. package/templates/agents/__evo_agent__/agent.yaml +1 -1
  31. package/templates/agents/__score__/agent.yaml +1 -1
  32. package/templates/agents/deep-executor/agent.yaml +1 -1
  33. package/templates/agents/default/agent.yaml +1 -1
  34. package/templates/agents/goal/agent.yaml +1 -1
  35. package/templates/models/mimo-token-plan-china.yaml +13 -6
  36. package/templates/skills/agent/SKILL.md +2 -2
  37. package/templates/skills/cron/SKILL.md +15 -0
  38. package/templates/skills/cron/manage-cron.py +28 -3
  39. package/templates/skills/halo/SKILL.md +2 -1
  40. package/templates/skills/send-file/SKILL.md +1 -0
  41. package/admin-out/_next/static/chunks/989-e660d0dd799950f2.js +0 -1
  42. package/admin-out/_next/static/chunks/app/page-18ab83dbdcc3897c.js +0 -1
  43. package/admin-out/_next/static/css/59402ac06b2b1a10.css +0 -3
  44. /package/admin-out/_next/static/{D2iJsfaULMDk0HYCHji6W → 7i420NUxbiDfuLxuofd-l}/_buildManifest.js +0 -0
  45. /package/admin-out/_next/static/{D2iJsfaULMDk0HYCHji6W → 7i420NUxbiDfuLxuofd-l}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // packages/cli/src/server-supervisor.ts
11
+ // src/server-supervisor.ts
12
12
  var server_supervisor_exports = {};
13
13
  __export(server_supervisor_exports, {
14
14
  MAX_RESTARTS: () => MAX_RESTARTS,
@@ -114,7 +114,7 @@ async function superviseServer() {
114
114
  }
115
115
  var SUPERVISE_ENV, MAX_RESTARTS, RESTART_WINDOW_MS, RESTART_DELAY_MS, INTENTIONAL_SIGNALS;
116
116
  var init_server_supervisor = __esm({
117
- "packages/cli/src/server-supervisor.ts"() {
117
+ "src/server-supervisor.ts"() {
118
118
  "use strict";
119
119
  SUPERVISE_ENV = "HALO_SUPERVISE";
120
120
  MAX_RESTARTS = 5;
@@ -124,7 +124,7 @@ var init_server_supervisor = __esm({
124
124
  }
125
125
  });
126
126
 
127
- // packages/server/dist/prompts/md-vars.js
127
+ // ../server/dist/prompts/md-vars.js
128
128
  var md_vars_exports = {};
129
129
  __export(md_vars_exports, {
130
130
  buildRenderContext: () => buildRenderContext,
@@ -294,7 +294,7 @@ async function buildRenderContext(opts) {
294
294
  }
295
295
  var PATTERN, ENV_PATTERN, ARG_PATTERN, PARAM_PATH;
296
296
  var init_md_vars = __esm({
297
- "packages/server/dist/prompts/md-vars.js"() {
297
+ "../server/dist/prompts/md-vars.js"() {
298
298
  "use strict";
299
299
  PATTERN = /\{\{\s*([\w-][\w.-]*)\s*\}\}/g;
300
300
  ENV_PATTERN = /<<([A-Z_][A-Z0-9_]*)>>/g;
@@ -303,7 +303,7 @@ var init_md_vars = __esm({
303
303
  }
304
304
  });
305
305
 
306
- // packages/server/dist/prompts/md-loader.js
306
+ // ../server/dist/prompts/md-loader.js
307
307
  import fs3 from "node:fs/promises";
308
308
  import fsSync from "node:fs";
309
309
  import path3 from "node:path";
@@ -448,14 +448,14 @@ function resolveMdFilePath(agentId, fileType, scope, workspaceRoot) {
448
448
  }
449
449
  var HALO_HOME;
450
450
  var init_md_loader = __esm({
451
- "packages/server/dist/prompts/md-loader.js"() {
451
+ "../server/dist/prompts/md-loader.js"() {
452
452
  "use strict";
453
453
  init_md_vars();
454
454
  HALO_HOME = path3.join(homedir3(), ".halo", "global");
455
455
  }
456
456
  });
457
457
 
458
- // packages/server/dist/settings-schema.js
458
+ // ../server/dist/settings-schema.js
459
459
  import fs4 from "node:fs";
460
460
  import path4 from "node:path";
461
461
  import { homedir as homedir4 } from "node:os";
@@ -513,12 +513,12 @@ function generalSection() {
513
513
  { key: "compact.max_summary_input", type: "int", globalOnly: true, description: "Max chars fed into local truncation fallback", description_zh: "\u672C\u5730\u622A\u65AD\u515C\u5E95\u65F6\u7684\u603B\u8F93\u5165\u5B57\u7B26\u4E0A\u9650", default: "15000" },
514
514
  { key: "compact.max_message_slice", type: "int", globalOnly: true, description: "Max chars kept per old message during local truncation", description_zh: "\u672C\u5730\u622A\u65AD\u515C\u5E95\u65F6\u6BCF\u6761\u65E7\u6D88\u606F\u4FDD\u7559\u7684\u6700\u5927\u5B57\u7B26\u6570", default: "800" },
515
515
  { key: "compact.summarize_timeout_sec", type: "int", globalOnly: true, description: "LLM summarization timeout (seconds)", description_zh: "LLM \u6458\u8981\u8D85\u65F6\u65F6\u95F4\uFF08\u79D2\uFF09", default: "300" },
516
- // sandbox (Linux bwrap only) — global-only: these define the security
516
+ // sandbox (Linux bwrap / macOS sandbox-exec) — global-only: these define the security
517
517
  // boundary agents run inside; a workspace overriding them could lift
518
518
  // its own sandbox constraints.
519
- { key: "sandbox.hidden_dirs", globalOnly: true, description: "Comma-separated dirs hidden by bwrap (Linux only)", description_zh: "\u901A\u8FC7 bwrap tmpfs \u9690\u85CF\u7684\u76EE\u5F55\uFF08\u9017\u53F7\u5206\u9694\uFF0C\u4EC5 Linux\uFF09", default: "~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker,~/.config/gh,~/.halo/global/internal-sessions,~/.halo/global/logs" },
520
- { key: "sandbox.writable_dirs", globalOnly: true, description: "Comma-separated dirs bind-mounted read-write inside the bwrap sandbox (Linux only) \u2014 for external CLIs that keep local state, e.g. ~/.kiro,~/.local/share/kiro-cli. Not applied to readonly sessions.", description_zh: "\u5728 bwrap \u6C99\u7BB1\u5185\u4EE5\u53EF\u5199\u65B9\u5F0F\u6302\u8F7D\u7684\u76EE\u5F55\uFF08\u9017\u53F7\u5206\u9694\uFF0C\u4EC5 Linux\uFF09\u2014\u2014\u7ED9\u9700\u8981\u672C\u5730\u72B6\u6001\u7684\u5916\u90E8 CLI \u7528\uFF0C\u5982 ~/.kiro,~/.local/share/kiro-cli\u3002readonly \u4F1A\u8BDD\u4E0D\u751F\u6548\u3002", default: "" },
521
- { key: "sandbox.hidden_files", globalOnly: true, description: "Comma-separated files hidden by bwrap (Linux only)", description_zh: "\u901A\u8FC7 /dev/null bind \u9690\u85CF\u7684\u6587\u4EF6\uFF08\u9017\u53F7\u5206\u9694\uFF0C\u4EC5 Linux\uFF09", default: "~/.npmrc,~/.bash_history,~/.gitconfig,~/.git-credentials,~/.netrc,~/.halo/global/evo.db,~/.halo/global/evo.db-wal,~/.halo/global/evo.db-shm,~/.halo/global/cron.db,~/.halo/global/cron.db-wal,~/.halo/global/cron.db-shm,~/.halo/global/runs.db,~/.halo/global/runs.db-wal,~/.halo/global/runs.db-shm" },
519
+ { key: "sandbox.hidden_dirs", globalOnly: true, description: "Comma-separated dirs hidden from workspace/readonly sessions (Linux bwrap / macOS sandbox-exec)", description_zh: "\u5BF9 workspace/readonly \u4F1A\u8BDD\u9690\u85CF\u7684\u76EE\u5F55\uFF08\u9017\u53F7\u5206\u9694\uFF0CLinux bwrap / macOS sandbox-exec\uFF09", default: "~/.halo/secrets,~/.aws,~/.ssh,~/.gnupg,~/.docker,~/.config/gh,~/.halo/global/internal-sessions,~/.halo/global/logs" },
520
+ { key: "sandbox.writable_dirs", globalOnly: true, description: "Comma-separated dirs writable inside the sandbox besides the workspace (Linux / macOS) \u2014 for external CLIs that keep local state, e.g. ~/.kiro,~/.local/share/kiro-cli. Not applied to readonly sessions.", description_zh: "\u9664 workspace \u5916\u5728\u6C99\u7BB1\u5185\u53EF\u5199\u7684\u76EE\u5F55\uFF08\u9017\u53F7\u5206\u9694\uFF0CLinux / macOS\uFF09\u2014\u2014\u7ED9\u9700\u8981\u672C\u5730\u72B6\u6001\u7684\u5916\u90E8 CLI \u7528\uFF0C\u5982 ~/.kiro,~/.local/share/kiro-cli\u3002readonly \u4F1A\u8BDD\u4E0D\u751F\u6548\u3002", default: "" },
521
+ { key: "sandbox.hidden_files", globalOnly: true, description: "Comma-separated files hidden from workspace/readonly sessions \u2014 read as empty (Linux / macOS)", description_zh: "\u5BF9 workspace/readonly \u4F1A\u8BDD\u9690\u85CF\u7684\u6587\u4EF6\uFF0C\u8BFB\u5230\u7684\u662F\u7A7A\u6587\u4EF6\uFF08\u9017\u53F7\u5206\u9694\uFF0CLinux / macOS\uFF09", default: "~/.npmrc,~/.bash_history,~/.gitconfig,~/.git-credentials,~/.netrc,~/.halo/global/evo.db,~/.halo/global/evo.db-wal,~/.halo/global/evo.db-shm,~/.halo/global/cron.db,~/.halo/global/cron.db-wal,~/.halo/global/cron.db-shm,~/.halo/global/runs.db,~/.halo/global/runs.db-wal,~/.halo/global/runs.db-shm" },
522
522
  // logging
523
523
  { key: "logging.level", type: "enum", options: ["debug", "info", "warn", "error"], globalOnly: true, description: "Log level", description_zh: "\u65E5\u5FD7\u7EA7\u522B", default: "warn" },
524
524
  // observability (OpenTelemetry). Read once at boot by observability/otel.ts
@@ -718,7 +718,7 @@ function loadSettingsSchema(workspaceRoot) {
718
718
  }
719
719
  var GLOBAL_MODELS_DIR, GLOBAL_SKILLS_DIR, GLOBAL_AGENTS_DIR, VALID_TYPES;
720
720
  var init_settings_schema = __esm({
721
- "packages/server/dist/settings-schema.js"() {
721
+ "../server/dist/settings-schema.js"() {
722
722
  "use strict";
723
723
  GLOBAL_MODELS_DIR = path4.join(homedir4(), ".halo", "global", "models");
724
724
  GLOBAL_SKILLS_DIR = path4.join(homedir4(), ".halo", "global", "skills");
@@ -727,7 +727,7 @@ var init_settings_schema = __esm({
727
727
  }
728
728
  });
729
729
 
730
- // packages/server/dist/config.js
730
+ // ../server/dist/config.js
731
731
  var config_exports = {};
732
732
  __export(config_exports, {
733
733
  HALO_GLOBAL_DIR: () => HALO_GLOBAL_DIR,
@@ -1033,7 +1033,7 @@ function getModelsRegistry() {
1033
1033
  }
1034
1034
  var HALO_HOME2, HALO_GLOBAL_DIR, HALO_SECRETS_DIR, _modelsRegistryCache, SYSTEM_CONFIG_PATH, _systemConfigCache, SETTINGS_PATH, _settingsCache, _schemaDefaultsCache, ENV_PATTERN2, _wsSettingsCache, config, HIDDEN_DIRS_DEFAULT, HIDDEN_FILES_DEFAULT;
1035
1035
  var init_config = __esm({
1036
- "packages/server/dist/config.js"() {
1036
+ "../server/dist/config.js"() {
1037
1037
  "use strict";
1038
1038
  init_settings_schema();
1039
1039
  HALO_HOME2 = path5.join(homedir5(), ".halo");
@@ -1259,7 +1259,7 @@ var init_config = __esm({
1259
1259
  }
1260
1260
  });
1261
1261
 
1262
- // packages/server/dist/agents/conversation-repair.js
1262
+ // ../server/dist/agents/conversation-repair.js
1263
1263
  function getToolUseId(block) {
1264
1264
  const b = block;
1265
1265
  if (b.type === "tool_use" && typeof b.id === "string")
@@ -1377,12 +1377,12 @@ function repairConversationMessages(raw, label = "[Repair]") {
1377
1377
  return messages2;
1378
1378
  }
1379
1379
  var init_conversation_repair = __esm({
1380
- "packages/server/dist/agents/conversation-repair.js"() {
1380
+ "../server/dist/agents/conversation-repair.js"() {
1381
1381
  "use strict";
1382
1382
  }
1383
1383
  });
1384
1384
 
1385
- // packages/server/dist/agents/model-error.js
1385
+ // ../server/dist/agents/model-error.js
1386
1386
  function classifyModelError(err) {
1387
1387
  const msg = err instanceof Error ? err.message : String(err);
1388
1388
  const errName = err instanceof Error ? err.name : "";
@@ -1420,12 +1420,12 @@ function classifyKind(msg, errName, httpStatus) {
1420
1420
  return "fatal";
1421
1421
  }
1422
1422
  var init_model_error = __esm({
1423
- "packages/server/dist/agents/model-error.js"() {
1423
+ "../server/dist/agents/model-error.js"() {
1424
1424
  "use strict";
1425
1425
  }
1426
1426
  });
1427
1427
 
1428
- // packages/server/dist/agents/compact.js
1428
+ // ../server/dist/agents/compact.js
1429
1429
  function splitForCompact(messages2) {
1430
1430
  const keepCount = config.compact.keep_messages;
1431
1431
  let cut = Math.max(0, messages2.length - keepCount);
@@ -1472,13 +1472,13 @@ ${summaryText}` }]
1472
1472
  return { compacted: true, messages: [summaryMsg, ...recentMsgs] };
1473
1473
  }
1474
1474
  var init_compact = __esm({
1475
- "packages/server/dist/agents/compact.js"() {
1475
+ "../server/dist/agents/compact.js"() {
1476
1476
  "use strict";
1477
1477
  init_config();
1478
1478
  }
1479
1479
  });
1480
1480
 
1481
- // packages/server/dist/agents/micro-compact.js
1481
+ // ../server/dist/agents/micro-compact.js
1482
1482
  function microCompactMessages(messages2, keepRecent = DEFAULT_KEEP_RECENT) {
1483
1483
  if (!messages2 || messages2.length === 0) {
1484
1484
  return { compacted: false, cleared: 0, messages: messages2 };
@@ -1526,7 +1526,7 @@ function microCompactMessages(messages2, keepRecent = DEFAULT_KEEP_RECENT) {
1526
1526
  }
1527
1527
  var MICRO_COMPACT_PLACEHOLDER, COMPACTABLE_TOOLS, DEFAULT_KEEP_RECENT;
1528
1528
  var init_micro_compact = __esm({
1529
- "packages/server/dist/agents/micro-compact.js"() {
1529
+ "../server/dist/agents/micro-compact.js"() {
1530
1530
  "use strict";
1531
1531
  MICRO_COMPACT_PLACEHOLDER = "[Old tool result content cleared]";
1532
1532
  COMPACTABLE_TOOLS = /* @__PURE__ */ new Set([
@@ -1543,10 +1543,10 @@ var init_micro_compact = __esm({
1543
1543
  }
1544
1544
  });
1545
1545
 
1546
- // packages/server/dist/agents/agent-loop.js
1546
+ // ../server/dist/agents/agent-loop.js
1547
1547
  var TOOL_ERROR_MARKER, TOOL_WARN_MARKER, MODEL_TIMEOUT_ERROR, AgentLoop;
1548
1548
  var init_agent_loop = __esm({
1549
- "packages/server/dist/agents/agent-loop.js"() {
1549
+ "../server/dist/agents/agent-loop.js"() {
1550
1550
  "use strict";
1551
1551
  init_config();
1552
1552
  TOOL_ERROR_MARKER = "__TOOL_ERROR__";
@@ -1721,7 +1721,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`;
1721
1721
  }
1722
1722
  });
1723
1723
 
1724
- // packages/server/dist/agents/agent-loader.js
1724
+ // ../server/dist/agents/agent-loader.js
1725
1725
  import fs6 from "node:fs/promises";
1726
1726
  import fsSync2 from "node:fs";
1727
1727
  import path6 from "node:path";
@@ -2004,7 +2004,7 @@ function isTeamMember(team, targetId) {
2004
2004
  }
2005
2005
  var GLOBAL_AGENTS_DIR2, GLOBAL_SKILLS_DIR2, SKILL_ID_RE, ACCESS_RANK;
2006
2006
  var init_agent_loader = __esm({
2007
- "packages/server/dist/agents/agent-loader.js"() {
2007
+ "../server/dist/agents/agent-loader.js"() {
2008
2008
  "use strict";
2009
2009
  init_agent_loop();
2010
2010
  GLOBAL_AGENTS_DIR2 = path6.join(homedir6(), ".halo", "global", "agents");
@@ -2019,7 +2019,7 @@ var init_agent_loader = __esm({
2019
2019
  }
2020
2020
  });
2021
2021
 
2022
- // packages/server/dist/ws/broadcast.js
2022
+ // ../server/dist/ws/broadcast.js
2023
2023
  import path7 from "node:path";
2024
2024
  function setBroadcastWss(wss2) {
2025
2025
  _wss = wss2;
@@ -2065,14 +2065,14 @@ function broadcastToWorkspace(workspacePath, event) {
2065
2065
  }
2066
2066
  var _wss, _workspaceOfClient;
2067
2067
  var init_broadcast = __esm({
2068
- "packages/server/dist/ws/broadcast.js"() {
2068
+ "../server/dist/ws/broadcast.js"() {
2069
2069
  "use strict";
2070
2070
  _wss = null;
2071
2071
  _workspaceOfClient = null;
2072
2072
  }
2073
2073
  });
2074
2074
 
2075
- // packages/server/dist/db/schema.js
2075
+ // ../server/dist/db/schema.js
2076
2076
  var schema_exports = {};
2077
2077
  __export(schema_exports, {
2078
2078
  agentSessions: () => agentSessions,
@@ -2081,7 +2081,7 @@ __export(schema_exports, {
2081
2081
  import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
2082
2082
  var agentSessions, disabledItems;
2083
2083
  var init_schema = __esm({
2084
- "packages/server/dist/db/schema.js"() {
2084
+ "../server/dist/db/schema.js"() {
2085
2085
  "use strict";
2086
2086
  agentSessions = sqliteTable("agent_sessions", {
2087
2087
  id: text("id").primaryKey(),
@@ -2122,7 +2122,7 @@ var init_schema = __esm({
2122
2122
  }
2123
2123
  });
2124
2124
 
2125
- // packages/server/dist/init.js
2125
+ // ../server/dist/init.js
2126
2126
  var init_exports = {};
2127
2127
  __export(init_exports, {
2128
2128
  TEMPLATES_DIR: () => TEMPLATES_DIR,
@@ -2130,6 +2130,7 @@ __export(init_exports, {
2130
2130
  describeOptionalSkill: () => describeOptionalSkill,
2131
2131
  ensureHaloHome: () => ensureHaloHome,
2132
2132
  ensureWorkspaceHalo: () => ensureWorkspaceHalo,
2133
+ hasWorkspaceHalo: () => hasWorkspaceHalo,
2133
2134
  listOptionalSkillIds: () => listOptionalSkillIds,
2134
2135
  mergeAgentYaml: () => mergeAgentYaml,
2135
2136
  readInstalledOptionalSkills: () => readInstalledOptionalSkills,
@@ -2458,6 +2459,9 @@ function ensureHaloHome(haloHome2) {
2458
2459
  } catch {
2459
2460
  }
2460
2461
  }
2462
+ function hasWorkspaceHalo(root) {
2463
+ return fs7.existsSync(path8.join(root, ".halo"));
2464
+ }
2461
2465
  function ensureWorkspaceHalo(workspaceRoot) {
2462
2466
  if (!fs7.existsSync(workspaceRoot)) {
2463
2467
  throw new Error(`Workspace root does not exist: ${workspaceRoot}`);
@@ -2489,7 +2493,7 @@ function ensureWorkspaceHalo(workspaceRoot) {
2489
2493
  }
2490
2494
  var __dirname, TEMPLATES_DIR, DOCS_SRC_CANDIDATES, TEMPLATE_VERSION, VERSION_FILE, SKIP_NAMES, BUILTIN_AGENT_IDS, BUILTIN_SKILL_IDS, BUNDLED_DOCS, INSTALLED_OPTIONAL_SKILLS_FILE;
2491
2495
  var init_init = __esm({
2492
- "packages/server/dist/init.js"() {
2496
+ "../server/dist/init.js"() {
2493
2497
  "use strict";
2494
2498
  __dirname = path8.dirname(fileURLToPath(import.meta.url));
2495
2499
  TEMPLATES_DIR = path8.resolve(__dirname, "..", "templates");
@@ -2497,7 +2501,7 @@ var init_init = __esm({
2497
2501
  path8.resolve(__dirname, "..", "bundled-docs"),
2498
2502
  path8.resolve(__dirname, "..", "..", "..", ".halo", "docs")
2499
2503
  ];
2500
- TEMPLATE_VERSION = 60;
2504
+ TEMPLATE_VERSION = 66;
2501
2505
  VERSION_FILE = ".template-version";
2502
2506
  SKIP_NAMES = /* @__PURE__ */ new Set([".DS_Store", "schema.sql", "__pycache__", ".pytest_cache"]);
2503
2507
  BUILTIN_AGENT_IDS = /* @__PURE__ */ new Set([
@@ -2552,6 +2556,7 @@ var init_init = __esm({
2552
2556
  "guide/skills.md",
2553
2557
  "guide/testing-agents-and-skills.md",
2554
2558
  "guide/secrets-and-credentials.md",
2559
+ "guide/delegation-and-access.md",
2555
2560
  "dev/tools.md",
2556
2561
  "dev/add-model-provider.md",
2557
2562
  "dev/add-channel.md",
@@ -2562,7 +2567,7 @@ var init_init = __esm({
2562
2567
  }
2563
2568
  });
2564
2569
 
2565
- // packages/server/dist/db/migrate.js
2570
+ // ../server/dist/db/migrate.js
2566
2571
  function runMigrations(sqlite, migrations) {
2567
2572
  const current = sqlite.pragma("user_version", { simple: true });
2568
2573
  if (current > migrations.length) {
@@ -2583,12 +2588,12 @@ function addColumnIfMissing(sqlite, table, column, decl) {
2583
2588
  sqlite.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${decl}`);
2584
2589
  }
2585
2590
  var init_migrate = __esm({
2586
- "packages/server/dist/db/migrate.js"() {
2591
+ "../server/dist/db/migrate.js"() {
2587
2592
  "use strict";
2588
2593
  }
2589
2594
  });
2590
2595
 
2591
- // packages/server/dist/db/index.js
2596
+ // ../server/dist/db/index.js
2592
2597
  import Database from "better-sqlite3";
2593
2598
  import { drizzle } from "drizzle-orm/better-sqlite3";
2594
2599
  import { eq, and } from "drizzle-orm";
@@ -2651,7 +2656,7 @@ function toggleDisabled(db, itemType, itemId, scope) {
2651
2656
  }
2652
2657
  var SCHEMA_SQL_PATH, HALO_MIGRATIONS, dbCache;
2653
2658
  var init_db = __esm({
2654
- "packages/server/dist/db/index.js"() {
2659
+ "../server/dist/db/index.js"() {
2655
2660
  "use strict";
2656
2661
  init_schema();
2657
2662
  init_init();
@@ -2677,7 +2682,7 @@ var init_db = __esm({
2677
2682
  }
2678
2683
  });
2679
2684
 
2680
- // packages/server/dist/agents/session-tools.js
2685
+ // ../server/dist/agents/session-tools.js
2681
2686
  async function callerTeamFor(sm, sessionId) {
2682
2687
  const callerId = sm.sessions.get(sessionId)?.agentId;
2683
2688
  if (!callerId)
@@ -2957,7 +2962,7 @@ function buildContinueTaskTool(sm, sessionId) {
2957
2962
  };
2958
2963
  }
2959
2964
  var init_session_tools = __esm({
2960
- "packages/server/dist/agents/session-tools.js"() {
2965
+ "../server/dist/agents/session-tools.js"() {
2961
2966
  "use strict";
2962
2967
  init_config();
2963
2968
  init_agent_loader();
@@ -2965,7 +2970,7 @@ var init_session_tools = __esm({
2965
2970
  }
2966
2971
  });
2967
2972
 
2968
- // packages/server/dist/sessions/session-archive.js
2973
+ // ../server/dist/sessions/session-archive.js
2969
2974
  import fsSync3 from "node:fs";
2970
2975
  import fs9 from "node:fs/promises";
2971
2976
  import path10 from "node:path";
@@ -3028,13 +3033,13 @@ async function deleteArchiveSegments(dir, seg) {
3028
3033
  }
3029
3034
  var ARCHIVE_SIZE_THRESHOLD;
3030
3035
  var init_session_archive = __esm({
3031
- "packages/server/dist/sessions/session-archive.js"() {
3036
+ "../server/dist/sessions/session-archive.js"() {
3032
3037
  "use strict";
3033
3038
  ARCHIVE_SIZE_THRESHOLD = 3 * 1024 * 1024;
3034
3039
  }
3035
3040
  });
3036
3041
 
3037
- // packages/server/dist/sessions/session-store.js
3042
+ // ../server/dist/sessions/session-store.js
3038
3043
  import fsSync4 from "node:fs";
3039
3044
  import fs10 from "node:fs/promises";
3040
3045
  import path11 from "node:path";
@@ -3278,13 +3283,13 @@ function findAndUpdateSessionTitle(sessionId, title, projectPath) {
3278
3283
  return false;
3279
3284
  }
3280
3285
  var init_session_store = __esm({
3281
- "packages/server/dist/sessions/session-store.js"() {
3286
+ "../server/dist/sessions/session-store.js"() {
3282
3287
  "use strict";
3283
3288
  init_session_archive();
3284
3289
  }
3285
3290
  });
3286
3291
 
3287
- // packages/server/dist/agents/goal-mode.js
3292
+ // ../server/dist/agents/goal-mode.js
3288
3293
  import fs11 from "node:fs";
3289
3294
  import path12 from "node:path";
3290
3295
  import { createHash } from "node:crypto";
@@ -3756,7 +3761,7 @@ function sweepActiveGoals(host) {
3756
3761
  }
3757
3762
  var GOAL_AGENT_ID, DEFAULT_GOAL_CAPS, NO_PROGRESS_LIMIT, DELEGATED_DECISION_CAP, WORKER_RECENT_MAX_MESSAGES, WORKER_RECENT_MSG_CHARS, WORKER_RECENT_TOTAL_CHARS, NEED_INPUT_MARKER;
3758
3763
  var init_goal_mode = __esm({
3759
- "packages/server/dist/agents/goal-mode.js"() {
3764
+ "../server/dist/agents/goal-mode.js"() {
3760
3765
  "use strict";
3761
3766
  init_schema();
3762
3767
  init_session_store();
@@ -3777,7 +3782,7 @@ var init_goal_mode = __esm({
3777
3782
  }
3778
3783
  });
3779
3784
 
3780
- // packages/server/dist/channels/shared/i18n.js
3785
+ // ../server/dist/channels/shared/i18n.js
3781
3786
  function getLang(account) {
3782
3787
  const v = account.language;
3783
3788
  return v === "en" || v === "zh" ? v : "en";
@@ -3796,7 +3801,7 @@ function t(key, lang, params) {
3796
3801
  }
3797
3802
  var messages;
3798
3803
  var init_i18n = __esm({
3799
- "packages/server/dist/channels/shared/i18n.js"() {
3804
+ "../server/dist/channels/shared/i18n.js"() {
3800
3805
  "use strict";
3801
3806
  messages = {
3802
3807
  // ── /help ──
@@ -3965,10 +3970,10 @@ var init_i18n = __esm({
3965
3970
  }
3966
3971
  });
3967
3972
 
3968
- // packages/server/dist/commands/registry.js
3973
+ // ../server/dist/commands/registry.js
3969
3974
  var CommandRegistry;
3970
3975
  var init_registry = __esm({
3971
- "packages/server/dist/commands/registry.js"() {
3976
+ "../server/dist/commands/registry.js"() {
3972
3977
  "use strict";
3973
3978
  CommandRegistry = class {
3974
3979
  descriptors = /* @__PURE__ */ new Map();
@@ -3982,13 +3987,13 @@ var init_registry = __esm({
3982
3987
  }
3983
3988
  });
3984
3989
 
3985
- // packages/server/dist/commands/index.js
3990
+ // ../server/dist/commands/index.js
3986
3991
  function builtinCommandNames() {
3987
3992
  return commandRegistry.listDescriptors().filter((d) => d.source === "builtin").map((d) => d.name);
3988
3993
  }
3989
3994
  var commandRegistry;
3990
3995
  var init_commands = __esm({
3991
- "packages/server/dist/commands/index.js"() {
3996
+ "../server/dist/commands/index.js"() {
3992
3997
  "use strict";
3993
3998
  init_registry();
3994
3999
  commandRegistry = new CommandRegistry();
@@ -4038,7 +4043,7 @@ var init_commands = __esm({
4038
4043
  }
4039
4044
  });
4040
4045
 
4041
- // packages/server/dist/commands/skill-command.js
4046
+ // ../server/dist/commands/skill-command.js
4042
4047
  import fs12 from "node:fs/promises";
4043
4048
  import path13 from "node:path";
4044
4049
  async function scanDir(dir) {
@@ -4181,7 +4186,7 @@ ${body}`;
4181
4186
  return "ok";
4182
4187
  }
4183
4188
  var init_skill_command = __esm({
4184
- "packages/server/dist/commands/skill-command.js"() {
4189
+ "../server/dist/commands/skill-command.js"() {
4185
4190
  "use strict";
4186
4191
  init_commands();
4187
4192
  init_agent_loader();
@@ -4191,7 +4196,7 @@ var init_skill_command = __esm({
4191
4196
  }
4192
4197
  });
4193
4198
 
4194
- // packages/server/dist/db/evo-db.js
4199
+ // ../server/dist/db/evo-db.js
4195
4200
  import Database2 from "better-sqlite3";
4196
4201
  import { drizzle as drizzle2 } from "drizzle-orm/better-sqlite3";
4197
4202
  import { sqliteTable as sqliteTable2, text as text2, integer as integer2 } from "drizzle-orm/sqlite-core";
@@ -4216,7 +4221,7 @@ function getEvoDb() {
4216
4221
  }
4217
4222
  var evolutionRuns, evolutionApplies, CREATE_SQL, _evoDb;
4218
4223
  var init_evo_db = __esm({
4219
- "packages/server/dist/db/evo-db.js"() {
4224
+ "../server/dist/db/evo-db.js"() {
4220
4225
  "use strict";
4221
4226
  init_migrate();
4222
4227
  evolutionRuns = sqliteTable2("evolution_runs", {
@@ -4299,7 +4304,7 @@ CREATE INDEX IF NOT EXISTS idx_evo_applies_archived ON evolution_applies(archive
4299
4304
  }
4300
4305
  });
4301
4306
 
4302
- // packages/server/dist/paths.js
4307
+ // ../server/dist/paths.js
4303
4308
  import path15 from "node:path";
4304
4309
  import { homedir as homedir8 } from "node:os";
4305
4310
  function haloHome() {
@@ -4345,12 +4350,12 @@ function evoApplyLogFile(applyId) {
4345
4350
  return path15.join(evoLogsDir(), `apply-${applyId}.log`);
4346
4351
  }
4347
4352
  var init_paths = __esm({
4348
- "packages/server/dist/paths.js"() {
4353
+ "../server/dist/paths.js"() {
4349
4354
  "use strict";
4350
4355
  }
4351
4356
  });
4352
4357
 
4353
- // packages/server/dist/evolution/enqueue.js
4358
+ // ../server/dist/evolution/enqueue.js
4354
4359
  import fs14 from "node:fs";
4355
4360
  import path16 from "node:path";
4356
4361
  import { homedir as homedir9 } from "node:os";
@@ -4635,14 +4640,14 @@ function enqueueEvoRun(input) {
4635
4640
  return { ok: true, runId, runDir };
4636
4641
  }
4637
4642
  var init_enqueue = __esm({
4638
- "packages/server/dist/evolution/enqueue.js"() {
4643
+ "../server/dist/evolution/enqueue.js"() {
4639
4644
  "use strict";
4640
4645
  init_evo_db();
4641
4646
  init_paths();
4642
4647
  }
4643
4648
  });
4644
4649
 
4645
- // packages/server/dist/channels/shared/commands.js
4650
+ // ../server/dist/channels/shared/commands.js
4646
4651
  import fs15 from "node:fs";
4647
4652
  import path17 from "node:path";
4648
4653
  import os from "node:os";
@@ -5368,7 +5373,7 @@ function execWsSwitch(ctx, arg) {
5368
5373
  }
5369
5374
  var ALIASES_FILE, aliasCache, CHANNEL_LIST_LIMIT, DISPATCH_COMMANDS, NOT_ROUTED, SUBCOMMAND_ROUTES;
5370
5375
  var init_commands2 = __esm({
5371
- "packages/server/dist/channels/shared/commands.js"() {
5376
+ "../server/dist/channels/shared/commands.js"() {
5372
5377
  "use strict";
5373
5378
  init_agent_loader();
5374
5379
  init_init();
@@ -5443,7 +5448,7 @@ var init_commands2 = __esm({
5443
5448
  }
5444
5449
  });
5445
5450
 
5446
- // packages/server/dist/agents/relay.js
5451
+ // ../server/dist/agents/relay.js
5447
5452
  import fs16 from "node:fs";
5448
5453
  import path18 from "node:path";
5449
5454
  import { and as and3, eq as eq3, isNull as isNull2 } from "drizzle-orm";
@@ -5680,7 +5685,7 @@ ${params.message}`;
5680
5685
  }
5681
5686
  var _registry, WORKSPACE_SESSION_PROPS;
5682
5687
  var init_relay = __esm({
5683
- "packages/server/dist/agents/relay.js"() {
5688
+ "../server/dist/agents/relay.js"() {
5684
5689
  "use strict";
5685
5690
  init_schema();
5686
5691
  init_config();
@@ -5693,7 +5698,7 @@ var init_relay = __esm({
5693
5698
  }
5694
5699
  });
5695
5700
 
5696
- // packages/server/dist/db/runs-db.js
5701
+ // ../server/dist/db/runs-db.js
5697
5702
  import Database3 from "better-sqlite3";
5698
5703
  import { drizzle as drizzle3 } from "drizzle-orm/better-sqlite3";
5699
5704
  import { sqliteTable as sqliteTable3, text as text3, integer as integer3, primaryKey } from "drizzle-orm/sqlite-core";
@@ -5735,7 +5740,7 @@ function listRunningWorkspaces() {
5735
5740
  }
5736
5741
  var runningSessions, CREATE_SQL2, _runsDb;
5737
5742
  var init_runs_db = __esm({
5738
- "packages/server/dist/db/runs-db.js"() {
5743
+ "../server/dist/db/runs-db.js"() {
5739
5744
  "use strict";
5740
5745
  init_migrate();
5741
5746
  runningSessions = sqliteTable3("running_sessions", {
@@ -5757,7 +5762,7 @@ CREATE TABLE IF NOT EXISTS running_sessions (
5757
5762
  }
5758
5763
  });
5759
5764
 
5760
- // packages/server/dist/agents/run-ledger.js
5765
+ // ../server/dist/agents/run-ledger.js
5761
5766
  import fs18 from "node:fs";
5762
5767
  import path20 from "node:path";
5763
5768
  import YAML7 from "yaml";
@@ -5798,7 +5803,7 @@ function sweepInterruptedRuns(host) {
5798
5803
  console.log(`[RunLedger] Boot sweep (${host.workspaceRoot}): nudged ${nudged} interrupted root(s)`);
5799
5804
  }
5800
5805
  var init_run_ledger = __esm({
5801
- "packages/server/dist/agents/run-ledger.js"() {
5806
+ "../server/dist/agents/run-ledger.js"() {
5802
5807
  "use strict";
5803
5808
  init_schema();
5804
5809
  init_runs_db();
@@ -5807,7 +5812,7 @@ var init_run_ledger = __esm({
5807
5812
  }
5808
5813
  });
5809
5814
 
5810
- // packages/server/dist/agents/workspace-runtime-lock.js
5815
+ // ../server/dist/agents/workspace-runtime-lock.js
5811
5816
  import fs19 from "node:fs";
5812
5817
  import path21 from "node:path";
5813
5818
  function isPidAlive(pid) {
@@ -5855,19 +5860,19 @@ function claimWorkspaceRuntime(workspaceRoot) {
5855
5860
  }
5856
5861
  var RUNTIME_LOCK_FILE;
5857
5862
  var init_workspace_runtime_lock = __esm({
5858
- "packages/server/dist/agents/workspace-runtime-lock.js"() {
5863
+ "../server/dist/agents/workspace-runtime-lock.js"() {
5859
5864
  "use strict";
5860
5865
  RUNTIME_LOCK_FILE = "runtime.lock";
5861
5866
  }
5862
5867
  });
5863
5868
 
5864
- // packages/core/dist/workspace/workspace.js
5869
+ // ../core/dist/workspace/workspace.js
5865
5870
  import { readFile, writeFile, mkdir } from "node:fs/promises";
5866
5871
  import { realpathSync } from "node:fs";
5867
5872
  import { resolve, isAbsolute, sep } from "node:path";
5868
5873
  var WorkspaceError, Workspace;
5869
5874
  var init_workspace = __esm({
5870
- "packages/core/dist/workspace/workspace.js"() {
5875
+ "../core/dist/workspace/workspace.js"() {
5871
5876
  "use strict";
5872
5877
  WorkspaceError = class extends Error {
5873
5878
  constructor(message) {
@@ -5912,13 +5917,13 @@ var init_workspace = __esm({
5912
5917
  }
5913
5918
  });
5914
5919
 
5915
- // packages/core/dist/workspace/git-manager.js
5920
+ // ../core/dist/workspace/git-manager.js
5916
5921
  import path22 from "node:path";
5917
5922
  import { promises as fs20 } from "node:fs";
5918
5923
  import simpleGit from "simple-git";
5919
5924
  var GitManagerError, GitManager;
5920
5925
  var init_git_manager = __esm({
5921
- "packages/core/dist/workspace/git-manager.js"() {
5926
+ "../core/dist/workspace/git-manager.js"() {
5922
5927
  "use strict";
5923
5928
  GitManagerError = class extends Error {
5924
5929
  constructor(message) {
@@ -6287,7 +6292,7 @@ var init_git_manager = __esm({
6287
6292
  }
6288
6293
  });
6289
6294
 
6290
- // packages/core/dist/media/mime.js
6295
+ // ../core/dist/media/mime.js
6291
6296
  function normalizeExt(ext) {
6292
6297
  const lower = ext.toLowerCase();
6293
6298
  return lower.startsWith(".") ? lower : `.${lower}`;
@@ -6300,7 +6305,7 @@ function extFromImageMime(mime) {
6300
6305
  }
6301
6306
  var PHOTO_MIME_BY_EXT, SERVE_ONLY_MIME_BY_EXT, IMAGE_MIME_BY_EXT, EXT_BY_PHOTO_MIME, IMAGE_EXTS;
6302
6307
  var init_mime = __esm({
6303
- "packages/core/dist/media/mime.js"() {
6308
+ "../core/dist/media/mime.js"() {
6304
6309
  "use strict";
6305
6310
  PHOTO_MIME_BY_EXT = {
6306
6311
  ".png": "image/png",
@@ -6324,9 +6329,9 @@ var init_mime = __esm({
6324
6329
  }
6325
6330
  });
6326
6331
 
6327
- // packages/core/dist/index.js
6332
+ // ../core/dist/index.js
6328
6333
  var init_dist = __esm({
6329
- "packages/core/dist/index.js"() {
6334
+ "../core/dist/index.js"() {
6330
6335
  "use strict";
6331
6336
  init_workspace();
6332
6337
  init_git_manager();
@@ -6334,7 +6339,7 @@ var init_dist = __esm({
6334
6339
  }
6335
6340
  });
6336
6341
 
6337
- // packages/server/dist/channels/shared/media-store.js
6342
+ // ../server/dist/channels/shared/media-store.js
6338
6343
  import fs21 from "node:fs/promises";
6339
6344
  import path23 from "node:path";
6340
6345
  import { randomBytes } from "node:crypto";
@@ -6395,7 +6400,7 @@ async function saveInboundMedia(params) {
6395
6400
  }
6396
6401
  var VISION_IMAGE_MIME_TYPES, EXT_BY_AV_MIME;
6397
6402
  var init_media_store = __esm({
6398
- "packages/server/dist/channels/shared/media-store.js"() {
6403
+ "../server/dist/channels/shared/media-store.js"() {
6399
6404
  "use strict";
6400
6405
  init_dist();
6401
6406
  VISION_IMAGE_MIME_TYPES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
@@ -6413,7 +6418,7 @@ var init_media_store = __esm({
6413
6418
  }
6414
6419
  });
6415
6420
 
6416
- // packages/server/dist/sessions/ui-log-builder.js
6421
+ // ../server/dist/sessions/ui-log-builder.js
6417
6422
  import { randomUUID } from "node:crypto";
6418
6423
  function createEmptyUIState() {
6419
6424
  return {
@@ -6817,19 +6822,19 @@ function applyEvent(state, event) {
6817
6822
  }
6818
6823
  var msgCounter;
6819
6824
  var init_ui_log_builder = __esm({
6820
- "packages/server/dist/sessions/ui-log-builder.js"() {
6825
+ "../server/dist/sessions/ui-log-builder.js"() {
6821
6826
  "use strict";
6822
6827
  msgCounter = 0;
6823
6828
  }
6824
6829
  });
6825
6830
 
6826
- // packages/server/dist/agents/session-ui-store.js
6831
+ // ../server/dist/agents/session-ui-store.js
6827
6832
  import fsSync5 from "node:fs";
6828
6833
  import path24 from "node:path";
6829
6834
  import { eq as eq6 } from "drizzle-orm";
6830
6835
  var UI_STATE_IDLE_TTL_MS, UI_STATE_SWEEP_PERIOD_MS, SessionUIStore;
6831
6836
  var init_session_ui_store = __esm({
6832
- "packages/server/dist/agents/session-ui-store.js"() {
6837
+ "../server/dist/agents/session-ui-store.js"() {
6833
6838
  "use strict";
6834
6839
  init_broadcast();
6835
6840
  init_schema();
@@ -7343,11 +7348,11 @@ var init_session_ui_store = __esm({
7343
7348
  }
7344
7349
  });
7345
7350
 
7346
- // packages/server/dist/agents/session-query-store.js
7351
+ // ../server/dist/agents/session-query-store.js
7347
7352
  import { eq as eq7, and as and5, isNull as isNull3, desc, lt, gte, inArray } from "drizzle-orm";
7348
7353
  var SessionQueryStore;
7349
7354
  var init_session_query_store = __esm({
7350
- "packages/server/dist/agents/session-query-store.js"() {
7355
+ "../server/dist/agents/session-query-store.js"() {
7351
7356
  "use strict";
7352
7357
  init_schema();
7353
7358
  init_session_store();
@@ -7574,7 +7579,7 @@ var init_session_query_store = __esm({
7574
7579
  }
7575
7580
  });
7576
7581
 
7577
- // packages/server/dist/agents/bedrock-agent.js
7582
+ // ../server/dist/agents/bedrock-agent.js
7578
7583
  import { BedrockRuntimeClient, InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime";
7579
7584
  function effortToBudget(effort, maxTokens) {
7580
7585
  const table = {
@@ -7596,7 +7601,7 @@ function extractRegionFromEndpoint(endpoint) {
7596
7601
  }
7597
7602
  var BedrockAgent;
7598
7603
  var init_bedrock_agent = __esm({
7599
- "packages/server/dist/agents/bedrock-agent.js"() {
7604
+ "../server/dist/agents/bedrock-agent.js"() {
7600
7605
  "use strict";
7601
7606
  init_config();
7602
7607
  init_agent_loop();
@@ -7726,7 +7731,7 @@ var init_bedrock_agent = __esm({
7726
7731
  }
7727
7732
  });
7728
7733
 
7729
- // packages/server/dist/agents/deepseek-agent.js
7734
+ // ../server/dist/agents/deepseek-agent.js
7730
7735
  function safeParse(json) {
7731
7736
  try {
7732
7737
  return JSON.parse(json || "{}");
@@ -7736,7 +7741,7 @@ function safeParse(json) {
7736
7741
  }
7737
7742
  var DeepSeekAgent;
7738
7743
  var init_deepseek_agent = __esm({
7739
- "packages/server/dist/agents/deepseek-agent.js"() {
7744
+ "../server/dist/agents/deepseek-agent.js"() {
7740
7745
  "use strict";
7741
7746
  init_config();
7742
7747
  init_agent_loop();
@@ -7931,7 +7936,7 @@ var init_deepseek_agent = __esm({
7931
7936
  }
7932
7937
  });
7933
7938
 
7934
- // packages/server/dist/agents/kimi-agent.js
7939
+ // ../server/dist/agents/kimi-agent.js
7935
7940
  function safeParse2(json) {
7936
7941
  try {
7937
7942
  return JSON.parse(json || "{}");
@@ -7941,7 +7946,7 @@ function safeParse2(json) {
7941
7946
  }
7942
7947
  var KimiAgent;
7943
7948
  var init_kimi_agent = __esm({
7944
- "packages/server/dist/agents/kimi-agent.js"() {
7949
+ "../server/dist/agents/kimi-agent.js"() {
7945
7950
  "use strict";
7946
7951
  init_config();
7947
7952
  init_agent_loop();
@@ -8137,7 +8142,7 @@ var init_kimi_agent = __esm({
8137
8142
  }
8138
8143
  });
8139
8144
 
8140
- // packages/server/dist/agents/minimax-agent.js
8145
+ // ../server/dist/agents/minimax-agent.js
8141
8146
  function effortToBudget2(effort, maxTokens) {
8142
8147
  const table = {
8143
8148
  low: 2048,
@@ -8154,7 +8159,7 @@ function effortToBudget2(effort, maxTokens) {
8154
8159
  }
8155
8160
  var MiniMaxAgent;
8156
8161
  var init_minimax_agent = __esm({
8157
- "packages/server/dist/agents/minimax-agent.js"() {
8162
+ "../server/dist/agents/minimax-agent.js"() {
8158
8163
  "use strict";
8159
8164
  init_config();
8160
8165
  init_agent_loop();
@@ -8276,7 +8281,7 @@ var init_minimax_agent = __esm({
8276
8281
  }
8277
8282
  });
8278
8283
 
8279
- // packages/server/dist/agents/qwen-agent.js
8284
+ // ../server/dist/agents/qwen-agent.js
8280
8285
  function effortToBudget3(effort, maxTokens) {
8281
8286
  const table = {
8282
8287
  low: 2048,
@@ -8293,7 +8298,7 @@ function effortToBudget3(effort, maxTokens) {
8293
8298
  }
8294
8299
  var QwenAgent;
8295
8300
  var init_qwen_agent = __esm({
8296
- "packages/server/dist/agents/qwen-agent.js"() {
8301
+ "../server/dist/agents/qwen-agent.js"() {
8297
8302
  "use strict";
8298
8303
  init_config();
8299
8304
  init_agent_loop();
@@ -8411,7 +8416,7 @@ var init_qwen_agent = __esm({
8411
8416
  }
8412
8417
  });
8413
8418
 
8414
- // packages/server/dist/agents/hunyuan-agent.js
8419
+ // ../server/dist/agents/hunyuan-agent.js
8415
8420
  function safeParse3(json) {
8416
8421
  try {
8417
8422
  return JSON.parse(json || "{}");
@@ -8421,7 +8426,7 @@ function safeParse3(json) {
8421
8426
  }
8422
8427
  var HunyuanAgent;
8423
8428
  var init_hunyuan_agent = __esm({
8424
- "packages/server/dist/agents/hunyuan-agent.js"() {
8429
+ "../server/dist/agents/hunyuan-agent.js"() {
8425
8430
  "use strict";
8426
8431
  init_config();
8427
8432
  init_agent_loop();
@@ -8592,7 +8597,7 @@ var init_hunyuan_agent = __esm({
8592
8597
  }
8593
8598
  });
8594
8599
 
8595
- // packages/server/dist/agents/doubao-agent.js
8600
+ // ../server/dist/agents/doubao-agent.js
8596
8601
  function safeParse4(json) {
8597
8602
  try {
8598
8603
  return JSON.parse(json || "{}");
@@ -8602,7 +8607,7 @@ function safeParse4(json) {
8602
8607
  }
8603
8608
  var DoubaoAgent;
8604
8609
  var init_doubao_agent = __esm({
8605
- "packages/server/dist/agents/doubao-agent.js"() {
8610
+ "../server/dist/agents/doubao-agent.js"() {
8606
8611
  "use strict";
8607
8612
  init_config();
8608
8613
  init_agent_loop();
@@ -8773,7 +8778,7 @@ var init_doubao_agent = __esm({
8773
8778
  }
8774
8779
  });
8775
8780
 
8776
- // packages/server/dist/agents/openai-agent.js
8781
+ // ../server/dist/agents/openai-agent.js
8777
8782
  function safeParse5(json) {
8778
8783
  try {
8779
8784
  return JSON.parse(json || "{}");
@@ -8783,7 +8788,7 @@ function safeParse5(json) {
8783
8788
  }
8784
8789
  var OpenAIAgent;
8785
8790
  var init_openai_agent = __esm({
8786
- "packages/server/dist/agents/openai-agent.js"() {
8791
+ "../server/dist/agents/openai-agent.js"() {
8787
8792
  "use strict";
8788
8793
  init_config();
8789
8794
  init_agent_loop();
@@ -8955,7 +8960,7 @@ var init_openai_agent = __esm({
8955
8960
  }
8956
8961
  });
8957
8962
 
8958
- // packages/server/dist/agents/mantle-agent.js
8963
+ // ../server/dist/agents/mantle-agent.js
8959
8964
  import { SignatureV4 } from "@smithy/signature-v4";
8960
8965
  import { Sha256 } from "@aws-crypto/sha256-js";
8961
8966
  import { defaultProvider } from "@aws-sdk/credential-provider-node";
@@ -8972,7 +8977,7 @@ function safeParse6(json) {
8972
8977
  }
8973
8978
  var MantleAgent;
8974
8979
  var init_mantle_agent = __esm({
8975
- "packages/server/dist/agents/mantle-agent.js"() {
8980
+ "../server/dist/agents/mantle-agent.js"() {
8976
8981
  "use strict";
8977
8982
  init_config();
8978
8983
  init_agent_loop();
@@ -9191,10 +9196,10 @@ var init_mantle_agent = __esm({
9191
9196
  }
9192
9197
  });
9193
9198
 
9194
- // packages/server/dist/agents/anthropic-agent.js
9199
+ // ../server/dist/agents/anthropic-agent.js
9195
9200
  var AnthropicAgent;
9196
9201
  var init_anthropic_agent = __esm({
9197
- "packages/server/dist/agents/anthropic-agent.js"() {
9202
+ "../server/dist/agents/anthropic-agent.js"() {
9198
9203
  "use strict";
9199
9204
  init_config();
9200
9205
  init_agent_loop();
@@ -9318,7 +9323,7 @@ var init_anthropic_agent = __esm({
9318
9323
  }
9319
9324
  });
9320
9325
 
9321
- // packages/server/dist/agents/model-runtime.js
9326
+ // ../server/dist/agents/model-runtime.js
9322
9327
  function createModelRuntime(providerId, cfg) {
9323
9328
  switch (providerId) {
9324
9329
  case "aws-bedrock-claude-invoke":
@@ -9458,7 +9463,7 @@ function createModelRuntime(providerId, cfg) {
9458
9463
  }
9459
9464
  }
9460
9465
  var init_model_runtime = __esm({
9461
- "packages/server/dist/agents/model-runtime.js"() {
9466
+ "../server/dist/agents/model-runtime.js"() {
9462
9467
  "use strict";
9463
9468
  init_bedrock_agent();
9464
9469
  init_deepseek_agent();
@@ -9473,7 +9478,7 @@ var init_model_runtime = __esm({
9473
9478
  }
9474
9479
  });
9475
9480
 
9476
- // packages/server/dist/child-env.js
9481
+ // ../server/dist/child-env.js
9477
9482
  function cleanChildEnv() {
9478
9483
  const env = { ...process.env };
9479
9484
  delete env.HALO_PASSWORD;
@@ -9481,17 +9486,17 @@ function cleanChildEnv() {
9481
9486
  return env;
9482
9487
  }
9483
9488
  var init_child_env = __esm({
9484
- "packages/server/dist/child-env.js"() {
9489
+ "../server/dist/child-env.js"() {
9485
9490
  "use strict";
9486
9491
  }
9487
9492
  });
9488
9493
 
9489
- // packages/server/dist/tools/sandbox.js
9494
+ // ../server/dist/tools/sandbox.js
9490
9495
  import { exec, execFile, spawn as spawn2 } from "node:child_process";
9491
9496
  import { promisify } from "node:util";
9492
9497
  import path25 from "node:path";
9493
9498
  import { homedir as homedir10 } from "node:os";
9494
- import { existsSync, realpathSync as realpathSync2 } from "node:fs";
9499
+ import { existsSync, lstatSync, mkdirSync, realpathSync as realpathSync2, rmSync, writeFileSync } from "node:fs";
9495
9500
  function decodeWinOutput(buf) {
9496
9501
  try {
9497
9502
  return new TextDecoder("utf-8", { fatal: true }).decode(buf);
@@ -9525,7 +9530,7 @@ async function bwrapExec(args, opts) {
9525
9530
  }
9526
9531
  function spawnGroupExec(command, opts) {
9527
9532
  return new Promise((resolve2, reject) => {
9528
- const child = spawn2(command, { shell: true, detached: true, cwd: opts.cwd, env: cleanChildEnv() });
9533
+ const child = opts.argv ? spawn2(opts.argv[0], opts.argv.slice(1), { detached: true, cwd: opts.cwd, env: opts.env ?? cleanChildEnv() }) : spawn2(command, { shell: true, detached: true, cwd: opts.cwd, env: cleanChildEnv() });
9529
9534
  let stdout = "";
9530
9535
  let stderr = "";
9531
9536
  let killReason = null;
@@ -9637,12 +9642,68 @@ async function isBwrapAvailable() {
9637
9642
  return false;
9638
9643
  }
9639
9644
  }
9640
- function isBwrapCached() {
9641
- return _bwrapAvailable === true;
9645
+ async function isSeatbeltAvailable() {
9646
+ if (process.platform !== "darwin")
9647
+ return false;
9648
+ if (_seatbeltAvailable !== null)
9649
+ return _seatbeltAvailable;
9650
+ try {
9651
+ await execFileAsync(SANDBOX_EXEC, ["-p", "(version 1)(allow default)", "/usr/bin/true"], { timeout: 5e3 });
9652
+ _seatbeltAvailable = true;
9653
+ } catch (err) {
9654
+ console.warn(`[Sandbox] sandbox-exec probe failed (${String(err.message).split("\n")[0]}) \u2014 non-full shell_exec unavailable`);
9655
+ _seatbeltAvailable = false;
9656
+ }
9657
+ return _seatbeltAvailable;
9658
+ }
9659
+ function getSandboxBackend() {
9660
+ if (_bwrapAvailable === true)
9661
+ return "bwrap";
9662
+ if (_seatbeltAvailable === true)
9663
+ return "seatbelt";
9664
+ return null;
9665
+ }
9666
+ async function loadGitIdentity() {
9667
+ const read = async (key) => {
9668
+ try {
9669
+ return String((await execFileAsync("git", ["config", "--global", key], { timeout: 3e3 })).stdout).trim();
9670
+ } catch {
9671
+ return "";
9672
+ }
9673
+ };
9674
+ const [name, email] = await Promise.all([read("user.name"), read("user.email")]);
9675
+ _gitIdentity = { name, email };
9676
+ }
9677
+ function gitIdentityEnv() {
9678
+ const env = {};
9679
+ if (_gitIdentity.name) {
9680
+ env.GIT_AUTHOR_NAME = _gitIdentity.name;
9681
+ env.GIT_COMMITTER_NAME = _gitIdentity.name;
9682
+ }
9683
+ if (_gitIdentity.email) {
9684
+ env.GIT_AUTHOR_EMAIL = _gitIdentity.email;
9685
+ env.GIT_COMMITTER_EMAIL = _gitIdentity.email;
9686
+ }
9687
+ return env;
9642
9688
  }
9643
9689
  async function initBwrapCheck() {
9690
+ await loadGitIdentity();
9691
+ if (process.platform === "darwin")
9692
+ return isSeatbeltAvailable();
9644
9693
  return isBwrapAvailable();
9645
9694
  }
9695
+ function ensureEmptyMaskFile() {
9696
+ try {
9697
+ const st = lstatSync(EMPTY_MASK_FILE);
9698
+ if (st.isFile() && st.size === 0)
9699
+ return EMPTY_MASK_FILE;
9700
+ rmSync(EMPTY_MASK_FILE, { recursive: true, force: true });
9701
+ } catch {
9702
+ }
9703
+ mkdirSync(HALO_HOME3, { recursive: true });
9704
+ writeFileSync(EMPTY_MASK_FILE, "");
9705
+ return EMPTY_MASK_FILE;
9706
+ }
9646
9707
  function expandTilde(p) {
9647
9708
  return p.startsWith("~/") ? path25.join(HOME, p.slice(2)) : p;
9648
9709
  }
@@ -9650,6 +9711,20 @@ function setSandboxHiddenPaths(dirs, files, writableDirs = []) {
9650
9711
  _hiddenDirs = dirs;
9651
9712
  _hiddenFiles = files;
9652
9713
  _writableDirs = writableDirs;
9714
+ _resolvedLists = null;
9715
+ }
9716
+ function resolvedLists() {
9717
+ if (_resolvedLists)
9718
+ return _resolvedLists;
9719
+ const both = (raws) => [...new Set(raws.flatMap((raw) => {
9720
+ const p = path25.resolve(expandTilde(raw));
9721
+ return [p, realpathBounded(p)];
9722
+ }))];
9723
+ _resolvedLists = { hiddenDirs: both(_hiddenDirs), hiddenFiles: both(_hiddenFiles), writableDirs: both(_writableDirs) };
9724
+ return _resolvedLists;
9725
+ }
9726
+ function isUnder(p, dir) {
9727
+ return p === dir || p.startsWith(dir.endsWith("/") ? dir : dir + "/");
9653
9728
  }
9654
9729
  function buildBwrapArgs(opts) {
9655
9730
  const args = [];
@@ -9660,10 +9735,11 @@ function buildBwrapArgs(opts) {
9660
9735
  if (existsSync(dir))
9661
9736
  args.push("--tmpfs", dir);
9662
9737
  }
9738
+ const emptyFile = ensureEmptyMaskFile();
9663
9739
  for (const raw of _hiddenFiles) {
9664
9740
  const file = expandTilde(raw);
9665
9741
  if (existsSync(file))
9666
- args.push("--ro-bind", "/dev/null", file);
9742
+ args.push("--ro-bind", emptyFile, file);
9667
9743
  }
9668
9744
  if (opts.accessLevel !== "readonly") {
9669
9745
  args.push("--bind", opts.workspaceRoot, opts.workspaceRoot);
@@ -9683,7 +9759,7 @@ function buildBwrapArgs(opts) {
9683
9759
  for (const rel of WORKSPACE_HIDDEN_FILES) {
9684
9760
  const file = path25.join(opts.workspaceRoot, rel);
9685
9761
  if (existsSync(file))
9686
- args.push("--ro-bind", "/dev/null", file);
9762
+ args.push("--ro-bind", emptyFile, file);
9687
9763
  }
9688
9764
  args.push("--proc", "/proc");
9689
9765
  args.push("--dev", "/dev");
@@ -9691,6 +9767,8 @@ function buildBwrapArgs(opts) {
9691
9767
  args.push("--setenv", "PATH", `${HOME}/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`);
9692
9768
  args.push("--setenv", "HOME", HOME);
9693
9769
  args.push("--setenv", "TERM", "xterm-256color");
9770
+ for (const [k, v] of Object.entries(gitIdentityEnv()))
9771
+ args.push("--setenv", k, v);
9694
9772
  args.push("--die-with-parent");
9695
9773
  return args;
9696
9774
  }
@@ -9718,31 +9796,57 @@ function assertPathAllowed(filePath, opts, write = false) {
9718
9796
  return path25.resolve(filePath);
9719
9797
  const resolved = realpathBounded(filePath);
9720
9798
  const wsRoot = realpathBounded(opts.workspaceRoot);
9721
- if (resolved === wsRoot || resolved.startsWith(wsRoot + "/")) {
9722
- if (isHiddenWorkspacePath(resolved, wsRoot)) {
9723
- throw new Error(`Access denied: "${filePath}" is outside the allowed sandbox paths`);
9724
- }
9725
- if (write && opts.accessLevel === "readonly") {
9726
- throw new Error(`Access denied: readonly session cannot write to "${filePath}"`);
9727
- }
9728
- return resolved;
9799
+ const inWorkspace = isUnder(resolved, wsRoot);
9800
+ if (inWorkspace && isHiddenWorkspacePath(resolved, wsRoot) || isHiddenHostPath(resolved)) {
9801
+ throw new Error(`Access denied: "${filePath}" is outside the allowed sandbox paths`);
9729
9802
  }
9730
- if (!write && (resolved === GLOBAL_DIR || resolved.startsWith(GLOBAL_DIR + "/")) && !isHiddenGlobalPath(resolved)) {
9803
+ if (!write)
9731
9804
  return resolved;
9805
+ if (opts.accessLevel === "readonly") {
9806
+ throw new Error(`Access denied: readonly session cannot write to "${filePath}"`);
9732
9807
  }
9808
+ if (inWorkspace || resolvedLists().writableDirs.some((d) => isUnder(resolved, d)))
9809
+ return resolved;
9733
9810
  throw new Error(`Access denied: "${filePath}" is outside the allowed sandbox paths`);
9734
9811
  }
9735
- function isHiddenGlobalPath(resolved) {
9736
- for (const raw of _hiddenFiles) {
9737
- if (resolved === expandTilde(raw))
9738
- return true;
9739
- }
9740
- for (const raw of _hiddenDirs) {
9741
- const dir = expandTilde(raw);
9742
- if (resolved === dir || resolved.startsWith(dir + "/"))
9743
- return true;
9812
+ function isHiddenHostPath(resolved) {
9813
+ const { hiddenDirs, hiddenFiles } = resolvedLists();
9814
+ return hiddenFiles.includes(resolved) || hiddenDirs.some((d) => isUnder(resolved, d));
9815
+ }
9816
+ function buildSeatbeltProfile(opts) {
9817
+ const q = (p) => `"${p.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
9818
+ const wsRoot = realpathBounded(opts.workspaceRoot);
9819
+ const lists = resolvedLists();
9820
+ const writable = ["/private/tmp", "/private/var/folders", "/dev"];
9821
+ if (opts.accessLevel !== "readonly")
9822
+ writable.unshift(wsRoot, ...lists.writableDirs);
9823
+ const hiddenDirs = [...lists.hiddenDirs, ...WORKSPACE_HIDDEN_DIRS.map((rel) => path25.join(wsRoot, rel))];
9824
+ const hiddenFiles = [...lists.hiddenFiles, ...WORKSPACE_HIDDEN_FILES.map((rel) => path25.join(wsRoot, rel))];
9825
+ return [
9826
+ "(version 1)",
9827
+ "(allow default)",
9828
+ "(deny file-write*)",
9829
+ `(allow file-write* ${writable.map((p) => `(subpath ${q(p)})`).join(" ")})`,
9830
+ `(deny file-read* file-write* ${[
9831
+ ...hiddenDirs.map((p) => `(subpath ${q(p)})`),
9832
+ ...hiddenFiles.map((p) => `(literal ${q(p)})`)
9833
+ ].join(" ")})`
9834
+ ].join("\n");
9835
+ }
9836
+ function seatbeltEnv() {
9837
+ const env = {
9838
+ PATH: `${HOME}/.local/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin`,
9839
+ HOME,
9840
+ TERM: "xterm-256color",
9841
+ GIT_CONFIG_GLOBAL: "/dev/null",
9842
+ NPM_CONFIG_USERCONFIG: "/dev/null",
9843
+ ...gitIdentityEnv()
9844
+ };
9845
+ for (const k of ["TMPDIR", "USER", "LOGNAME", "LANG", "LC_ALL"]) {
9846
+ if (process.env[k])
9847
+ env[k] = process.env[k];
9744
9848
  }
9745
- return false;
9849
+ return env;
9746
9850
  }
9747
9851
  function isHiddenWorkspacePath(resolved, wsRoot) {
9748
9852
  for (const rel of WORKSPACE_HIDDEN_FILES) {
@@ -9766,8 +9870,173 @@ function buildWriteScriptArgs(filePath, content) {
9766
9870
  function buildReaddirScriptArgs(dirPath) {
9767
9871
  return ["bash", "-c", 'ls -1ap "$1"', "bash", dirPath];
9768
9872
  }
9873
+ function shellSegments(command) {
9874
+ const segments = [];
9875
+ let words = [];
9876
+ let cur = "";
9877
+ let inWord = false;
9878
+ let quote = null;
9879
+ const heredocs = [];
9880
+ const endWord = () => {
9881
+ if (inWord)
9882
+ words.push(cur);
9883
+ cur = "";
9884
+ inWord = false;
9885
+ };
9886
+ const endSegment = () => {
9887
+ endWord();
9888
+ if (words.length)
9889
+ segments.push(words);
9890
+ words = [];
9891
+ };
9892
+ for (let i = 0; i < command.length; i++) {
9893
+ const c = command[i];
9894
+ if (quote) {
9895
+ if (c === quote)
9896
+ quote = null;
9897
+ else if (c === "\\" && quote === '"' && i + 1 < command.length)
9898
+ cur += command[++i];
9899
+ else
9900
+ cur += c;
9901
+ continue;
9902
+ }
9903
+ if (c === "<" && command[i + 1] === "<" && command[i + 2] !== "<") {
9904
+ const m = /^<<(-?)\s*(['"]?)([A-Za-z0-9_.-]+)\2/.exec(command.slice(i));
9905
+ if (m) {
9906
+ endWord();
9907
+ heredocs.push({ delim: m[3], dash: m[1] === "-" });
9908
+ i += m[0].length - 1;
9909
+ continue;
9910
+ }
9911
+ }
9912
+ if (c === "\n" && heredocs.length) {
9913
+ endSegment();
9914
+ let pos = i + 1;
9915
+ for (const h of heredocs.splice(0)) {
9916
+ while (pos < command.length) {
9917
+ const eol = command.indexOf("\n", pos);
9918
+ const line = command.slice(pos, eol === -1 ? command.length : eol);
9919
+ pos = eol === -1 ? command.length : eol + 1;
9920
+ if ((h.dash ? line.replace(/^\t+/, "") : line) === h.delim)
9921
+ break;
9922
+ }
9923
+ }
9924
+ i = pos - 1;
9925
+ continue;
9926
+ }
9927
+ if (c === '"' || c === "'") {
9928
+ quote = c;
9929
+ inWord = true;
9930
+ } else if (c === "\\" && command[i + 1] === "\n")
9931
+ i++;
9932
+ else if (c === "\\" && i + 1 < command.length) {
9933
+ cur += command[++i];
9934
+ inWord = true;
9935
+ } else if (c === ";" || c === "&" || c === "|" || c === "\n")
9936
+ endSegment();
9937
+ else if (c === " " || c === " " || c === "\r")
9938
+ endWord();
9939
+ else {
9940
+ cur += c;
9941
+ inWord = true;
9942
+ }
9943
+ }
9944
+ endSegment();
9945
+ return segments;
9946
+ }
9947
+ function expandRmWord(word, cwd) {
9948
+ return word.replace(/^~(?=\/|$)/, HOME).replace(/\$\{HOME\}|\$HOME\b/g, HOME).replace(/\$\{PWD\}|\$PWD\b|\$\(pwd\)|`pwd`/g, cwd).replace(/\$\{[^}]*\}|\$\([^)]*\)|`[^`]*`|\$[A-Za-z_][A-Za-z0-9_]*|\$\d/g, "");
9949
+ }
9950
+ function stripSubshellClose(word) {
9951
+ let w = word;
9952
+ while (w.endsWith(")") && (w.match(/\(/g)?.length ?? 0) < (w.match(/\)/g)?.length ?? 0))
9953
+ w = w.slice(0, -1);
9954
+ return w;
9955
+ }
9956
+ function rmProtectedReason(target, wsRoot) {
9957
+ if (target === "/")
9958
+ return "the filesystem root";
9959
+ if (isUnder(HOME, target))
9960
+ return "the home directory or a parent of it";
9961
+ if (isUnder(HALO_HOME3, target))
9962
+ return "~/.halo or a parent of it";
9963
+ if (isUnder(wsRoot, target))
9964
+ return "the workspace root or a parent of it";
9965
+ if (RM_EXACT_DIRS.includes(target))
9966
+ return "a system directory";
9967
+ for (const d of RM_SYSTEM_DIRS) {
9968
+ if (target === d || path25.dirname(target) === d)
9969
+ return "a system directory";
9970
+ }
9971
+ return null;
9972
+ }
9973
+ function assertRmSafe(command, workspaceRoot) {
9974
+ const wsRoot = path25.resolve(workspaceRoot);
9975
+ let cwd = wsRoot;
9976
+ for (const words of shellSegments(command)) {
9977
+ let i = 0;
9978
+ let cmd = "";
9979
+ for (; i < words.length; i++) {
9980
+ cmd = words[i].replace(/^[({!]+/, "");
9981
+ if (!cmd || /^[A-Za-z_][A-Za-z0-9_]*=/.test(cmd))
9982
+ continue;
9983
+ if (RM_WRAPPERS.has(path25.basename(cmd))) {
9984
+ while (i + 1 < words.length && words[i + 1].startsWith("-"))
9985
+ i++;
9986
+ continue;
9987
+ }
9988
+ break;
9989
+ }
9990
+ if (i >= words.length)
9991
+ continue;
9992
+ if (cmd === "cd") {
9993
+ const dest = words[i + 1];
9994
+ if (dest === void 0)
9995
+ cwd = HOME;
9996
+ else if (dest !== "-")
9997
+ cwd = path25.resolve(cwd, expandRmWord(stripSubshellClose(dest), cwd) || ".");
9998
+ continue;
9999
+ }
10000
+ const base = path25.basename(cmd);
10001
+ if (base !== "rm" && base !== "rmdir")
10002
+ continue;
10003
+ let optionsDone = false;
10004
+ for (let j = i + 1; j < words.length; j++) {
10005
+ const raw = words[j];
10006
+ if (!optionsDone && raw === "--") {
10007
+ optionsDone = true;
10008
+ continue;
10009
+ }
10010
+ if (!optionsDone && raw.startsWith("-"))
10011
+ continue;
10012
+ if (/^(\d*|&)?[<>]/.test(raw)) {
10013
+ if (/^(\d*|&)?[<>]+&?$/.test(raw))
10014
+ j++;
10015
+ continue;
10016
+ }
10017
+ const word = expandRmWord(stripSubshellClose(raw), cwd);
10018
+ if (!word)
10019
+ continue;
10020
+ const abs = path25.resolve(cwd, word);
10021
+ const parts = abs.split("/");
10022
+ const globAt = parts.findIndex((p) => /[*?[]/.test(p));
10023
+ let target = abs;
10024
+ if (globAt !== -1) {
10025
+ if (!/^[.*?]+$/.test(parts[globAt]))
10026
+ continue;
10027
+ target = parts.slice(0, globAt).join("/") || "/";
10028
+ }
10029
+ const reason = rmProtectedReason(target, wsRoot);
10030
+ if (reason) {
10031
+ throw new Error(`[Sandbox] rm blocked: "${raw}" resolves to ${target}, which is ${reason}. Name the specific files or subdirectories to delete instead.`);
10032
+ }
10033
+ }
10034
+ }
10035
+ }
9769
10036
  async function sandboxExec(command, opts) {
9770
10037
  opts = normalizeOptsForPlatform(opts);
10038
+ if (process.platform !== "win32")
10039
+ assertRmSafe(command, opts.workspaceRoot);
9771
10040
  if (opts.accessLevel === "full") {
9772
10041
  if (process.platform === "win32") {
9773
10042
  const result = await execAsync(`chcp 65001 >nul 2>&1 & ${command}`, {
@@ -9789,10 +10058,21 @@ async function sandboxExec(command, opts) {
9789
10058
  signal: opts.signal
9790
10059
  });
9791
10060
  }
9792
- const bwrapOk = await isBwrapAvailable();
9793
- if (!bwrapOk) {
9794
- throw new Error("Access denied: shell_exec requires bubblewrap (bwrap) for non-full access levels. Install with: apt install bubblewrap");
10061
+ if (process.platform === "darwin") {
10062
+ if (!await isSeatbeltAvailable())
10063
+ throw new Error(NO_SANDBOX_MSG);
10064
+ return spawnGroupExec(command, {
10065
+ cwd: opts.workspaceRoot,
10066
+ timeout: opts.timeout,
10067
+ maxBuffer: opts.maxBuffer,
10068
+ signal: opts.signal,
10069
+ argv: [SANDBOX_EXEC, "-p", buildSeatbeltProfile(opts), ...buildExecScriptArgs(opts.workspaceRoot, command)],
10070
+ env: seatbeltEnv()
10071
+ });
9795
10072
  }
10073
+ const bwrapOk = await isBwrapAvailable();
10074
+ if (!bwrapOk)
10075
+ throw new Error(NO_SANDBOX_MSG);
9796
10076
  const bwrapArgs = buildBwrapArgs(opts);
9797
10077
  return bwrapExec([...bwrapArgs, "--", ...buildExecScriptArgs(opts.workspaceRoot, command)], {
9798
10078
  timeout: opts.timeout,
@@ -9959,18 +10239,21 @@ async function sandboxReaddir(dirPath, opts) {
9959
10239
  return { name: isDir ? name.slice(0, -1) : name, isDirectory: isDir };
9960
10240
  });
9961
10241
  }
9962
- var execAsync, execFileAsync, HOME, HALO_HOME3, GLOBAL_DIR, KILL_GRACE_MS, _bwrapAvailable, DEFAULT_HIDDEN_DIRS, DEFAULT_HIDDEN_FILES, WORKSPACE_HIDDEN_DIRS, WORKSPACE_HIDDEN_FILES, _hiddenDirs, _hiddenFiles, _writableDirs;
10242
+ var execAsync, execFileAsync, HOME, HALO_HOME3, KILL_GRACE_MS, _bwrapAvailable, SANDBOX_EXEC, _seatbeltAvailable, _gitIdentity, EMPTY_MASK_FILE, DEFAULT_HIDDEN_DIRS, DEFAULT_HIDDEN_FILES, WORKSPACE_HIDDEN_DIRS, WORKSPACE_HIDDEN_FILES, _hiddenDirs, _hiddenFiles, _writableDirs, _resolvedLists, RM_SYSTEM_DIRS, RM_EXACT_DIRS, RM_WRAPPERS, NO_SANDBOX_MSG;
9963
10243
  var init_sandbox = __esm({
9964
- "packages/server/dist/tools/sandbox.js"() {
10244
+ "../server/dist/tools/sandbox.js"() {
9965
10245
  "use strict";
9966
10246
  init_child_env();
9967
10247
  execAsync = promisify(exec);
9968
10248
  execFileAsync = promisify(execFile);
9969
10249
  HOME = homedir10();
9970
10250
  HALO_HOME3 = path25.join(HOME, ".halo");
9971
- GLOBAL_DIR = path25.join(HALO_HOME3, "global");
9972
10251
  KILL_GRACE_MS = 2e3;
9973
10252
  _bwrapAvailable = null;
10253
+ SANDBOX_EXEC = "/usr/bin/sandbox-exec";
10254
+ _seatbeltAvailable = null;
10255
+ _gitIdentity = { name: "", email: "" };
10256
+ EMPTY_MASK_FILE = path25.join(HALO_HOME3, ".sandbox-empty");
9974
10257
  DEFAULT_HIDDEN_DIRS = [
9975
10258
  "~/.halo/secrets",
9976
10259
  "~/.aws",
@@ -10011,10 +10294,42 @@ var init_sandbox = __esm({
10011
10294
  _hiddenDirs = DEFAULT_HIDDEN_DIRS;
10012
10295
  _hiddenFiles = DEFAULT_HIDDEN_FILES;
10013
10296
  _writableDirs = [];
10297
+ _resolvedLists = null;
10298
+ RM_SYSTEM_DIRS = [
10299
+ "/bin",
10300
+ "/boot",
10301
+ "/dev",
10302
+ "/etc",
10303
+ "/home",
10304
+ "/lib",
10305
+ "/lib32",
10306
+ "/lib64",
10307
+ "/libx32",
10308
+ "/media",
10309
+ "/mnt",
10310
+ "/opt",
10311
+ "/proc",
10312
+ "/run",
10313
+ "/sbin",
10314
+ "/snap",
10315
+ "/srv",
10316
+ "/sys",
10317
+ "/usr",
10318
+ "/var",
10319
+ "/Applications",
10320
+ "/Library",
10321
+ "/System",
10322
+ "/Users",
10323
+ "/Volumes",
10324
+ "/private"
10325
+ ];
10326
+ RM_EXACT_DIRS = ["/tmp", "/private/tmp", "/root"];
10327
+ RM_WRAPPERS = /* @__PURE__ */ new Set(["sudo", "command", "env", "xargs", "nohup", "time", "exec", "nice", "if", "then", "else", "elif", "do", "while", "until"]);
10328
+ NO_SANDBOX_MSG = "Access denied: shell_exec at workspace/readonly access needs an OS sandbox (bubblewrap on Linux, sandbox-exec on macOS) and none works on this host. Switch the session to Full, or on Linux install bubblewrap (apt install bubblewrap).";
10014
10329
  }
10015
10330
  });
10016
10331
 
10017
- // packages/server/dist/tools/workspace-tools.js
10332
+ // ../server/dist/tools/workspace-tools.js
10018
10333
  import fs22 from "node:fs/promises";
10019
10334
  import path26 from "node:path";
10020
10335
  import crypto from "node:crypto";
@@ -10530,10 +10845,13 @@ Error: old_string appears more than once in ${input.path}. Either expand it with
10530
10845
  STDERR: ${stderr}` : "")).trim() || "(no output)");
10531
10846
  } catch (err) {
10532
10847
  const error = err;
10533
- return mask(`${TOOL_ERROR_MARKER}
10534
- Command failed: ${error.message}
10848
+ const out = `${error.message}
10535
10849
  ${error.stdout ?? ""}
10536
- ${error.stderr ?? ""}`);
10850
+ ${error.stderr ?? ""}`;
10851
+ const hint = accessLevel !== "full" && SANDBOX_DENIED_RE.test(out) ? `
10852
+ [Sandbox] This session runs at "${accessLevel}" access: writes are limited to the workspace${accessLevel === "readonly" ? " (readonly: nowhere)" : ""} and /tmp is discarded after each command. If the command needs more, ask the user to switch the access level to Full in the chat input box.` : "";
10853
+ return mask(`${TOOL_ERROR_MARKER}
10854
+ Command failed: ${out}${hint}`);
10537
10855
  }
10538
10856
  }
10539
10857
  };
@@ -10698,7 +11016,7 @@ Error: ${error.message}`;
10698
11016
  };
10699
11017
  const visionTools = supportsVision ? [viewImage] : [];
10700
11018
  const allTools = [fileRead, ...visionTools, fileWrite, fileEdit, fileList, shellExec, grepTool, globTool, webFetch];
10701
- if (accessLevel === "readonly" && !isBwrapCached()) {
11019
+ if (accessLevel === "readonly" && getSandboxBackend() === null) {
10702
11020
  return [fileRead, ...visionTools, fileList, grepTool, globTool];
10703
11021
  }
10704
11022
  return allTools;
@@ -10731,9 +11049,9 @@ function imageDimensions(buf, mediaType) {
10731
11049
  }
10732
11050
  return null;
10733
11051
  }
10734
- var SKIP_DIRS, SKIP_HALO_SUBDIRS, GLOB_MAX_RESULTS, HOME2, PARAMS_PATTERN, ENV_PATTERN3;
11052
+ var SKIP_DIRS, SKIP_HALO_SUBDIRS, GLOB_MAX_RESULTS, SANDBOX_DENIED_RE, HOME2, PARAMS_PATTERN, ENV_PATTERN3;
10735
11053
  var init_workspace_tools = __esm({
10736
- "packages/server/dist/tools/workspace-tools.js"() {
11054
+ "../server/dist/tools/workspace-tools.js"() {
10737
11055
  "use strict";
10738
11056
  init_config();
10739
11057
  init_sandbox();
@@ -10744,13 +11062,14 @@ var init_workspace_tools = __esm({
10744
11062
  SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", ".next", "dist"]);
10745
11063
  SKIP_HALO_SUBDIRS = /* @__PURE__ */ new Set(["sessions", "logs", "evo", "tmp", "assets", "canvas"]);
10746
11064
  GLOB_MAX_RESULTS = 5e3;
11065
+ SANDBOX_DENIED_RE = /Read-only file system|Operation not permitted|Permission denied|EROFS|EPERM/;
10747
11066
  HOME2 = homedir11();
10748
11067
  PARAMS_PATTERN = /\{\{\s*([\w-]+)\.params\.([\w-][\w.-]*)\s*\}\}/g;
10749
11068
  ENV_PATTERN3 = /<<([A-Z_][A-Z0-9_]*)>>/g;
10750
11069
  }
10751
11070
  });
10752
11071
 
10753
- // packages/server/dist/tools/draft-tool.js
11072
+ // ../server/dist/tools/draft-tool.js
10754
11073
  function createDraftTool() {
10755
11074
  let drafts = 0;
10756
11075
  const tool = {
@@ -10785,7 +11104,7 @@ Error: draft requires non-empty \`content\` \u2014 put your full draft answer th
10785
11104
  }
10786
11105
  var MAX_DRAFTS, REVIEW_CHECKLIST;
10787
11106
  var init_draft_tool = __esm({
10788
- "packages/server/dist/tools/draft-tool.js"() {
11107
+ "../server/dist/tools/draft-tool.js"() {
10789
11108
  "use strict";
10790
11109
  init_agent_loop();
10791
11110
  MAX_DRAFTS = 3;
@@ -10799,7 +11118,7 @@ If the draft clears all three, write the final answer now. If not, fix it (gathe
10799
11118
  }
10800
11119
  });
10801
11120
 
10802
- // packages/server/dist/prompts/system-prompts.js
11121
+ // ../server/dist/prompts/system-prompts.js
10803
11122
  import fs23 from "node:fs/promises";
10804
11123
  import path27 from "node:path";
10805
11124
  import { homedir as homedir12 } from "node:os";
@@ -10885,17 +11204,17 @@ async function loadSystemPrompts(workspaceRoot) {
10885
11204
  }
10886
11205
  var GLOBAL_PROMPTS_DIR;
10887
11206
  var init_system_prompts = __esm({
10888
- "packages/server/dist/prompts/system-prompts.js"() {
11207
+ "../server/dist/prompts/system-prompts.js"() {
10889
11208
  "use strict";
10890
11209
  GLOBAL_PROMPTS_DIR = path27.join(homedir12(), ".halo", "global", "prompts");
10891
11210
  }
10892
11211
  });
10893
11212
 
10894
- // packages/server/dist/agents/session-agent-builder.js
11213
+ // ../server/dist/agents/session-agent-builder.js
10895
11214
  import path28 from "node:path";
10896
11215
  var SessionAgentBuilder;
10897
11216
  var init_session_agent_builder = __esm({
10898
- "packages/server/dist/agents/session-agent-builder.js"() {
11217
+ "../server/dist/agents/session-agent-builder.js"() {
10899
11218
  "use strict";
10900
11219
  init_model_runtime();
10901
11220
  init_workspace_tools();
@@ -11267,7 +11586,7 @@ ${roster}`;
11267
11586
  }
11268
11587
  });
11269
11588
 
11270
- // packages/server/dist/agents/session-skill-commands.js
11589
+ // ../server/dist/agents/session-skill-commands.js
11271
11590
  import { eq as eq8 } from "drizzle-orm";
11272
11591
  function commandVisibilityGate(d) {
11273
11592
  if (!d.verbs || d.verbs.length === 0)
@@ -11284,7 +11603,7 @@ function commandVisibilityGate(d) {
11284
11603
  }
11285
11604
  var SessionSkillCommands;
11286
11605
  var init_session_skill_commands = __esm({
11287
- "packages/server/dist/agents/session-skill-commands.js"() {
11606
+ "../server/dist/agents/session-skill-commands.js"() {
11288
11607
  "use strict";
11289
11608
  init_db();
11290
11609
  init_schema();
@@ -11349,12 +11668,12 @@ var init_session_skill_commands = __esm({
11349
11668
  }
11350
11669
  });
11351
11670
 
11352
- // packages/server/dist/agents/session-state-store.js
11671
+ // ../server/dist/agents/session-state-store.js
11353
11672
  import fsSync6 from "node:fs";
11354
11673
  import path29 from "node:path";
11355
11674
  var SessionStateStore;
11356
11675
  var init_session_state_store = __esm({
11357
- "packages/server/dist/agents/session-state-store.js"() {
11676
+ "../server/dist/agents/session-state-store.js"() {
11358
11677
  "use strict";
11359
11678
  init_session_store();
11360
11679
  SessionStateStore = class {
@@ -11418,7 +11737,7 @@ var init_session_state_store = __esm({
11418
11737
  }
11419
11738
  });
11420
11739
 
11421
- // packages/server/dist/observability/otel-sdk.js
11740
+ // ../server/dist/observability/otel-sdk.js
11422
11741
  var otel_sdk_exports = {};
11423
11742
  __export(otel_sdk_exports, {
11424
11743
  registerSdk: () => registerSdk
@@ -11457,12 +11776,12 @@ function registerSdk(serviceName, serviceVersion) {
11457
11776
  return [tracerProvider, meterProvider, loggerProvider];
11458
11777
  }
11459
11778
  var init_otel_sdk = __esm({
11460
- "packages/server/dist/observability/otel-sdk.js"() {
11779
+ "../server/dist/observability/otel-sdk.js"() {
11461
11780
  "use strict";
11462
11781
  }
11463
11782
  });
11464
11783
 
11465
- // packages/server/dist/observability/otel.js
11784
+ // ../server/dist/observability/otel.js
11466
11785
  import { trace, metrics as metrics2, ProxyTracerProvider } from "@opentelemetry/api";
11467
11786
  import { logs as logs2 } from "@opentelemetry/api-logs";
11468
11787
  function externalSdkRegistered() {
@@ -11487,7 +11806,7 @@ async function initObservability() {
11487
11806
  return true;
11488
11807
  }
11489
11808
  const { registerSdk: registerSdk2 } = await Promise.resolve().then(() => (init_otel_sdk(), otel_sdk_exports));
11490
- providers = registerSdk2(process.env.OTEL_SERVICE_NAME, "1.3.4");
11809
+ providers = registerSdk2(process.env.OTEL_SERVICE_NAME, "1.4.1");
11491
11810
  console.log(`[Observability] OTLP export \u2192 ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT} (service.name=${process.env.OTEL_SERVICE_NAME}, capture_content=${config.observability.captureContent})`);
11492
11811
  return true;
11493
11812
  }
@@ -11508,7 +11827,7 @@ async function shutdownObservability() {
11508
11827
  }
11509
11828
  var SCOPE, enabled, tracer, getMeter, otelLogger, captureContent, providers;
11510
11829
  var init_otel = __esm({
11511
- "packages/server/dist/observability/otel.js"() {
11830
+ "../server/dist/observability/otel.js"() {
11512
11831
  "use strict";
11513
11832
  init_config();
11514
11833
  SCOPE = "opentelemetry.instrumentation.halo";
@@ -11521,7 +11840,7 @@ var init_otel = __esm({
11521
11840
  }
11522
11841
  });
11523
11842
 
11524
- // packages/server/dist/observability/genai-spans.js
11843
+ // ../server/dist/observability/genai-spans.js
11525
11844
  import { context, trace as trace2, SpanStatusCode } from "@opentelemetry/api";
11526
11845
  function instruments() {
11527
11846
  const meter = getMeter();
@@ -11747,7 +12066,7 @@ function recordRetry(kind) {
11747
12066
  }
11748
12067
  var turns, SYSTEM, PART_CAP, SYSTEM_PROMPT_CAP, ATTR_CAP, cachedInstruments, metricsFor;
11749
12068
  var init_genai_spans = __esm({
11750
- "packages/server/dist/observability/genai-spans.js"() {
12069
+ "../server/dist/observability/genai-spans.js"() {
11751
12070
  "use strict";
11752
12071
  init_otel();
11753
12072
  turns = /* @__PURE__ */ new Map();
@@ -11760,7 +12079,7 @@ var init_genai_spans = __esm({
11760
12079
  }
11761
12080
  });
11762
12081
 
11763
- // packages/server/dist/agents/session-manager.js
12082
+ // ../server/dist/agents/session-manager.js
11764
12083
  import fsSync7 from "node:fs";
11765
12084
  import path30 from "node:path";
11766
12085
  import { eq as eq9, and as and6, isNull as isNull4, isNotNull as isNotNull2 } from "drizzle-orm";
@@ -11863,7 +12182,7 @@ function generateSessionId() {
11863
12182
  }
11864
12183
  var CONTINUE_TASK_KICK, SessionManager;
11865
12184
  var init_session_manager = __esm({
11866
- "packages/server/dist/agents/session-manager.js"() {
12185
+ "../server/dist/agents/session-manager.js"() {
11867
12186
  "use strict";
11868
12187
  init_md_loader();
11869
12188
  init_config();
@@ -12483,6 +12802,24 @@ var init_session_manager = __esm({
12483
12802
  dropUIState(sessionId) {
12484
12803
  this.uiStore.dropUIState(sessionId);
12485
12804
  }
12805
+ /** Another process (a cron `halo cli` child) just wrote this root session's
12806
+ * files. Drop the idle in-memory copies — the tree's AgentSessions (raw
12807
+ * history, loaded by any view via ensureSession and never evicted while
12808
+ * idle) and the root's UIState — WITHOUT saving, so the next view/message
12809
+ * re-reads disk instead of overwriting the other writer's turn with this
12810
+ * process's stale snapshot. Returns false (and drops nothing) while any
12811
+ * turn/compact in the tree is in flight: live state can't be discarded,
12812
+ * and the two writers race — the accepted cost of sharing a session. */
12813
+ forgetExternalWrite(rootId) {
12814
+ if (this.hasActiveWorkInTree(rootId))
12815
+ return false;
12816
+ for (const id of [...this.sessions.keys()]) {
12817
+ if (id === rootId || id.startsWith(`${rootId}>`))
12818
+ this.sessions.delete(id);
12819
+ }
12820
+ this.uiStore.dropUIState(rootId);
12821
+ return true;
12822
+ }
12486
12823
  // ── Loop detection ──────────────────────────────────────────────────
12487
12824
  static LOOP_EXEMPT_TOOLS = /* @__PURE__ */ new Set([
12488
12825
  "session_list",
@@ -13614,29 +13951,6 @@ ${result.summary}`, agentName: "user", report: true, taskId });
13614
13951
  opts?.onProgress?.("done");
13615
13952
  }
13616
13953
  }
13617
- /**
13618
- * Reset agent instance (destroy + allow rebuild) without destroying sub-sessions.
13619
- * Used after compact to rebuild with new context.
13620
- */
13621
- async resetAgent(sessionId) {
13622
- const session = this.sessions.get(sessionId);
13623
- if (!session)
13624
- return;
13625
- if (session.abortController) {
13626
- session.abortController.abort();
13627
- session.abortController = null;
13628
- }
13629
- session.toolCallLog = [];
13630
- session.warnedToolHashes.clear();
13631
- session.interruptRequested = false;
13632
- const savedMessages = session.agent.messages;
13633
- const { agent, modelId, systemPrompt, draftReset } = await this.buildAgentInstance(session.agentId, sessionId, session.parentId, session.workingDir ?? void 0, session.accessLevel);
13634
- session.agent = agent;
13635
- session.agent.messages = savedMessages;
13636
- session.currentModelId = modelId;
13637
- session.systemPrompt = systemPrompt;
13638
- session.draftReset = draftReset;
13639
- }
13640
13954
  /**
13641
13955
  * Set raw agent messages directly (for compact rebuild).
13642
13956
  */
@@ -13980,11 +14294,11 @@ ${q.text}` : q.text);
13980
14294
  }
13981
14295
  });
13982
14296
 
13983
- // packages/server/dist/agents/session-manager-registry.js
14297
+ // ../server/dist/agents/session-manager-registry.js
13984
14298
  import fs24 from "node:fs";
13985
14299
  var SessionManagerRegistry;
13986
14300
  var init_session_manager_registry = __esm({
13987
- "packages/server/dist/agents/session-manager-registry.js"() {
14301
+ "../server/dist/agents/session-manager-registry.js"() {
13988
14302
  "use strict";
13989
14303
  init_session_manager();
13990
14304
  init_init();
@@ -14039,7 +14353,7 @@ var init_session_manager_registry = __esm({
14039
14353
  }
14040
14354
  });
14041
14355
 
14042
- // packages/server/dist/logger.js
14356
+ // ../server/dist/logger.js
14043
14357
  import fs25 from "node:fs";
14044
14358
  import path31 from "node:path";
14045
14359
  import { homedir as homedir13 } from "node:os";
@@ -14159,7 +14473,7 @@ function initLogger() {
14159
14473
  }
14160
14474
  var LOG_FILENAME, logDir, logFile, currentSize, LEVEL_ORDER, OTEL_SEVERITY;
14161
14475
  var init_logger = __esm({
14162
- "packages/server/dist/logger.js"() {
14476
+ "../server/dist/logger.js"() {
14163
14477
  "use strict";
14164
14478
  init_config();
14165
14479
  init_otel();
@@ -14177,7 +14491,7 @@ var init_logger = __esm({
14177
14491
  }
14178
14492
  });
14179
14493
 
14180
- // packages/cli/src/harness.ts
14494
+ // src/harness.ts
14181
14495
  var harness_exports = {};
14182
14496
  __export(harness_exports, {
14183
14497
  createHarness: () => createHarness,
@@ -14418,7 +14732,7 @@ async function createHarness(opts) {
14418
14732
  }
14419
14733
  var SESSION_PREFIX, USER_ID;
14420
14734
  var init_harness = __esm({
14421
- "packages/cli/src/harness.ts"() {
14735
+ "src/harness.ts"() {
14422
14736
  "use strict";
14423
14737
  init_session_manager();
14424
14738
  init_session_manager_registry();
@@ -14435,7 +14749,7 @@ var init_harness = __esm({
14435
14749
  }
14436
14750
  });
14437
14751
 
14438
- // packages/server/dist/middleware/password-hash.js
14752
+ // ../server/dist/middleware/password-hash.js
14439
14753
  var password_hash_exports = {};
14440
14754
  __export(password_hash_exports, {
14441
14755
  generateJwtSecret: () => generateJwtSecret,
@@ -14485,7 +14799,7 @@ function generateJwtSecret() {
14485
14799
  }
14486
14800
  var scryptAsync, COST, KEY_LEN;
14487
14801
  var init_password_hash = __esm({
14488
- "packages/server/dist/middleware/password-hash.js"() {
14802
+ "../server/dist/middleware/password-hash.js"() {
14489
14803
  "use strict";
14490
14804
  scryptAsync = promisify2(crypto2.scrypt);
14491
14805
  COST = { N: 16384, r: 8, p: 1 };
@@ -14493,7 +14807,7 @@ var init_password_hash = __esm({
14493
14807
  }
14494
14808
  });
14495
14809
 
14496
- // packages/server/dist/setup-config.js
14810
+ // ../server/dist/setup-config.js
14497
14811
  var setup_config_exports = {};
14498
14812
  __export(setup_config_exports, {
14499
14813
  configLeafSet: () => configLeafSet,
@@ -14534,13 +14848,13 @@ function configLeafSet(dotPath) {
14534
14848
  }
14535
14849
  var CONFIG_PATH;
14536
14850
  var init_setup_config = __esm({
14537
- "packages/server/dist/setup-config.js"() {
14851
+ "../server/dist/setup-config.js"() {
14538
14852
  "use strict";
14539
14853
  CONFIG_PATH = path33.join(homedir14(), ".halo", "secrets", "config.yaml");
14540
14854
  }
14541
14855
  });
14542
14856
 
14543
- // packages/server/dist/setup-settings.js
14857
+ // ../server/dist/setup-settings.js
14544
14858
  var setup_settings_exports = {};
14545
14859
  __export(setup_settings_exports, {
14546
14860
  maskSecret: () => maskSecret,
@@ -14619,13 +14933,13 @@ function maskSecret(value) {
14619
14933
  }
14620
14934
  var SETTINGS_PATH2;
14621
14935
  var init_setup_settings = __esm({
14622
- "packages/server/dist/setup-settings.js"() {
14936
+ "../server/dist/setup-settings.js"() {
14623
14937
  "use strict";
14624
14938
  SETTINGS_PATH2 = path34.join(homedir15(), ".halo", "secrets", "settings.yaml");
14625
14939
  }
14626
14940
  });
14627
14941
 
14628
- // packages/server/dist/setup-providers.js
14942
+ // ../server/dist/setup-providers.js
14629
14943
  var setup_providers_exports = {};
14630
14944
  __export(setup_providers_exports, {
14631
14945
  AWS_CREDENTIAL_CHAIN_PROVIDER: () => AWS_CREDENTIAL_CHAIN_PROVIDER,
@@ -14831,7 +15145,7 @@ function listRequiredSkillsWithSecrets() {
14831
15145
  }
14832
15146
  var AWS_CREDENTIAL_CHAIN_PROVIDER, REBIND_BUILTIN_AGENT_IDS, GLOBAL_AGENTS_DIR3;
14833
15147
  var init_setup_providers = __esm({
14834
- "packages/server/dist/setup-providers.js"() {
15148
+ "../server/dist/setup-providers.js"() {
14835
15149
  "use strict";
14836
15150
  init_init();
14837
15151
  init_setup_settings();
@@ -14841,7 +15155,7 @@ var init_setup_providers = __esm({
14841
15155
  }
14842
15156
  });
14843
15157
 
14844
- // packages/cli/src/setup-bind-provider.ts
15158
+ // src/setup-bind-provider.ts
14845
15159
  var setup_bind_provider_exports = {};
14846
15160
  __export(setup_bind_provider_exports, {
14847
15161
  AWS_CHAIN_PROVIDER: () => AWS_CHAIN_PROVIDER,
@@ -14881,14 +15195,14 @@ function buildBindProviderPlan(configured, currentProvider, currentProviderHasKe
14881
15195
  }
14882
15196
  var AWS_CHAIN_PROVIDER, KEEP_CURRENT;
14883
15197
  var init_setup_bind_provider = __esm({
14884
- "packages/cli/src/setup-bind-provider.ts"() {
15198
+ "src/setup-bind-provider.ts"() {
14885
15199
  "use strict";
14886
15200
  AWS_CHAIN_PROVIDER = "aws-bedrock-claude-invoke";
14887
15201
  KEEP_CURRENT = "__keep__";
14888
15202
  }
14889
15203
  });
14890
15204
 
14891
- // packages/cli/src/setup-prompts.ts
15205
+ // src/setup-prompts.ts
14892
15206
  var setup_prompts_exports = {};
14893
15207
  __export(setup_prompts_exports, {
14894
15208
  promptMultiSelect: () => promptMultiSelect,
@@ -15174,12 +15488,12 @@ function promptMultiSelectRich(question, options) {
15174
15488
  });
15175
15489
  }
15176
15490
  var init_setup_prompts = __esm({
15177
- "packages/cli/src/setup-prompts.ts"() {
15491
+ "src/setup-prompts.ts"() {
15178
15492
  "use strict";
15179
15493
  }
15180
15494
  });
15181
15495
 
15182
- // packages/cli/src/upgrade-verify.ts
15496
+ // src/upgrade-verify.ts
15183
15497
  var upgrade_verify_exports = {};
15184
15498
  __export(upgrade_verify_exports, {
15185
15499
  ALLOW_SCRIPTS: () => ALLOW_SCRIPTS,
@@ -15204,7 +15518,7 @@ function verifyNativeModules(pkgRoot) {
15204
15518
  }
15205
15519
  var NATIVE_MODULE_SMOKES, ALLOW_SCRIPTS;
15206
15520
  var init_upgrade_verify = __esm({
15207
- "packages/cli/src/upgrade-verify.ts"() {
15521
+ "src/upgrade-verify.ts"() {
15208
15522
  "use strict";
15209
15523
  NATIVE_MODULE_SMOKES = [
15210
15524
  { name: "better-sqlite3", smoke: "new (require(process.argv[1]))(':memory:')" },
@@ -15214,7 +15528,7 @@ var init_upgrade_verify = __esm({
15214
15528
  }
15215
15529
  });
15216
15530
 
15217
- // packages/cli/src/render-md.ts
15531
+ // src/render-md.ts
15218
15532
  import { marked } from "marked";
15219
15533
  import { markedTerminal } from "marked-terminal";
15220
15534
  function renderMarkdown(text6) {
@@ -15222,14 +15536,14 @@ function renderMarkdown(text6) {
15222
15536
  return rendered.replace(/\n{3,}/g, "\n\n").trimEnd();
15223
15537
  }
15224
15538
  var init_render_md = __esm({
15225
- "packages/cli/src/render-md.ts"() {
15539
+ "src/render-md.ts"() {
15226
15540
  "use strict";
15227
15541
  marked.use(markedTerminal({ reflowText: true, width: Math.min(process.stdout.columns || 80, 120) }));
15228
15542
  marked.use({ breaks: true });
15229
15543
  }
15230
15544
  });
15231
15545
 
15232
- // packages/cli/src/resolve-refs.ts
15546
+ // src/resolve-refs.ts
15233
15547
  import fs31 from "node:fs";
15234
15548
  import path37 from "node:path";
15235
15549
  function resolveRefs(input, workspace) {
@@ -15308,7 +15622,7 @@ ${content}
15308
15622
  }
15309
15623
  var MAX_FILE_BYTES, MAX_IMAGE_BYTES, REF_PATTERN;
15310
15624
  var init_resolve_refs = __esm({
15311
- "packages/cli/src/resolve-refs.ts"() {
15625
+ "src/resolve-refs.ts"() {
15312
15626
  "use strict";
15313
15627
  init_dist();
15314
15628
  MAX_FILE_BYTES = 100 * 1024;
@@ -15317,7 +15631,7 @@ var init_resolve_refs = __esm({
15317
15631
  }
15318
15632
  });
15319
15633
 
15320
- // packages/cli/src/format-usage.ts
15634
+ // src/format-usage.ts
15321
15635
  function fmtK(n) {
15322
15636
  return `${(n / 1e3).toFixed(1)}K`;
15323
15637
  }
@@ -15361,7 +15675,7 @@ function formatUsageLine(event) {
15361
15675
  }
15362
15676
  var ANSI;
15363
15677
  var init_format_usage = __esm({
15364
- "packages/cli/src/format-usage.ts"() {
15678
+ "src/format-usage.ts"() {
15365
15679
  "use strict";
15366
15680
  ANSI = {
15367
15681
  reset: "\x1B[0m",
@@ -15375,7 +15689,7 @@ var init_format_usage = __esm({
15375
15689
  }
15376
15690
  });
15377
15691
 
15378
- // packages/cli/src/tui/components/banner.tsx
15692
+ // src/tui/components/banner.tsx
15379
15693
  import { Box, Text } from "ink";
15380
15694
  import { jsx } from "react/jsx-runtime";
15381
15695
  function Banner() {
@@ -15383,7 +15697,7 @@ function Banner() {
15383
15697
  }
15384
15698
  var LINES, COLORS;
15385
15699
  var init_banner = __esm({
15386
- "packages/cli/src/tui/components/banner.tsx"() {
15700
+ "src/tui/components/banner.tsx"() {
15387
15701
  "use strict";
15388
15702
  LINES = [
15389
15703
  " \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
@@ -15397,7 +15711,7 @@ var init_banner = __esm({
15397
15711
  }
15398
15712
  });
15399
15713
 
15400
- // packages/cli/src/tui/components/messages.tsx
15714
+ // src/tui/components/messages.tsx
15401
15715
  import { Box as Box2, Static, Text as Text2 } from "ink";
15402
15716
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
15403
15717
  function Messages({ blocks }) {
@@ -15455,7 +15769,7 @@ function Block({ block }) {
15455
15769
  }
15456
15770
  var BANNER_ID;
15457
15771
  var init_messages = __esm({
15458
- "packages/cli/src/tui/components/messages.tsx"() {
15772
+ "src/tui/components/messages.tsx"() {
15459
15773
  "use strict";
15460
15774
  init_format_usage();
15461
15775
  init_banner();
@@ -15463,7 +15777,7 @@ var init_messages = __esm({
15463
15777
  }
15464
15778
  });
15465
15779
 
15466
- // packages/cli/src/tui/terminal-text.ts
15780
+ // src/tui/terminal-text.ts
15467
15781
  function sanitizeToolOutput(s) {
15468
15782
  return s.replace(ESCAPE_SEQ_RE, "").replace(/\r\n?/g, "\n").replace(/\t/g, " ").replace(C0_RE, "");
15469
15783
  }
@@ -15493,14 +15807,14 @@ function tailByRows(text6, cols, maxRows) {
15493
15807
  }
15494
15808
  var ESCAPE_SEQ_RE, C0_RE;
15495
15809
  var init_terminal_text = __esm({
15496
- "packages/cli/src/tui/terminal-text.ts"() {
15810
+ "src/tui/terminal-text.ts"() {
15497
15811
  "use strict";
15498
15812
  ESCAPE_SEQ_RE = /\x1b\][^\x07\n]*\x07|\x1b\[[0-9;?]*[ -/]*[@-~]|\x1b[@-Z\\-_]/g;
15499
15813
  C0_RE = /[\x00-\x09\x0b-\x1f\x7f]/g;
15500
15814
  }
15501
15815
  });
15502
15816
 
15503
- // packages/cli/src/tui/components/streaming.tsx
15817
+ // src/tui/components/streaming.tsx
15504
15818
  import { useEffect, useState } from "react";
15505
15819
  import { Box as Box3, Text as Text3, useStdout } from "ink";
15506
15820
  import Spinner from "ink-spinner";
@@ -15553,13 +15867,13 @@ function Streaming({ spinnerLabel, liveText, liveThinking, activeSubs, turnStart
15553
15867
  ] });
15554
15868
  }
15555
15869
  var init_streaming = __esm({
15556
- "packages/cli/src/tui/components/streaming.tsx"() {
15870
+ "src/tui/components/streaming.tsx"() {
15557
15871
  "use strict";
15558
15872
  init_terminal_text();
15559
15873
  }
15560
15874
  });
15561
15875
 
15562
- // packages/cli/src/tui/history.ts
15876
+ // src/tui/history.ts
15563
15877
  import fs32 from "node:fs";
15564
15878
  import path38 from "node:path";
15565
15879
  import os2 from "node:os";
@@ -15585,14 +15899,14 @@ function appendHistory(entry) {
15585
15899
  }
15586
15900
  var HISTORY_FILE, MAX_ENTRIES;
15587
15901
  var init_history = __esm({
15588
- "packages/cli/src/tui/history.ts"() {
15902
+ "src/tui/history.ts"() {
15589
15903
  "use strict";
15590
15904
  HISTORY_FILE = path38.join(os2.homedir(), ".halo", "global", "tui-history.json");
15591
15905
  MAX_ENTRIES = 100;
15592
15906
  }
15593
15907
  });
15594
15908
 
15595
- // packages/cli/src/tui/components/status-bar.tsx
15909
+ // src/tui/components/status-bar.tsx
15596
15910
  import { Box as Box4, Text as Text4 } from "ink";
15597
15911
  import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
15598
15912
  function shortModel(modelId) {
@@ -15628,12 +15942,12 @@ function StatusBar({ agentName, modelId, contextPercent, workspace, sessionId, v
15628
15942
  ] });
15629
15943
  }
15630
15944
  var init_status_bar = __esm({
15631
- "packages/cli/src/tui/components/status-bar.tsx"() {
15945
+ "src/tui/components/status-bar.tsx"() {
15632
15946
  "use strict";
15633
15947
  }
15634
15948
  });
15635
15949
 
15636
- // packages/cli/src/tui/components/slash-suggest.tsx
15950
+ // src/tui/components/slash-suggest.tsx
15637
15951
  import { Box as Box5, Text as Text5 } from "ink";
15638
15952
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
15639
15953
  function SlashSuggest({ items, selectedIdx, maxWidth = 80 }) {
@@ -15660,12 +15974,12 @@ function SlashSuggest({ items, selectedIdx, maxWidth = 80 }) {
15660
15974
  ] });
15661
15975
  }
15662
15976
  var init_slash_suggest = __esm({
15663
- "packages/cli/src/tui/components/slash-suggest.tsx"() {
15977
+ "src/tui/components/slash-suggest.tsx"() {
15664
15978
  "use strict";
15665
15979
  }
15666
15980
  });
15667
15981
 
15668
- // packages/cli/src/tui/components/path-suggest.tsx
15982
+ // src/tui/components/path-suggest.tsx
15669
15983
  import { Box as Box6, Text as Text6 } from "ink";
15670
15984
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
15671
15985
  function PathSuggest({ items, selectedIdx, cwdLabel }) {
@@ -15692,12 +16006,12 @@ function PathSuggest({ items, selectedIdx, cwdLabel }) {
15692
16006
  ] });
15693
16007
  }
15694
16008
  var init_path_suggest = __esm({
15695
- "packages/cli/src/tui/components/path-suggest.tsx"() {
16009
+ "src/tui/components/path-suggest.tsx"() {
15696
16010
  "use strict";
15697
16011
  }
15698
16012
  });
15699
16013
 
15700
- // packages/cli/src/tui/path-suggest-engine.ts
16014
+ // src/tui/path-suggest-engine.ts
15701
16015
  import fs33 from "node:fs";
15702
16016
  import path39 from "node:path";
15703
16017
  function detectActiveRef(value) {
@@ -15783,13 +16097,13 @@ function applyPathPick(value, ref, pick) {
15783
16097
  return `${before}@${kind} ${path70}`;
15784
16098
  }
15785
16099
  var init_path_suggest_engine = __esm({
15786
- "packages/cli/src/tui/path-suggest-engine.ts"() {
16100
+ "src/tui/path-suggest-engine.ts"() {
15787
16101
  "use strict";
15788
16102
  init_dist();
15789
16103
  }
15790
16104
  });
15791
16105
 
15792
- // packages/cli/src/tui/line-editor.ts
16106
+ // src/tui/line-editor.ts
15793
16107
  function toGraphemes(s) {
15794
16108
  if (s === "") return [];
15795
16109
  return [...segmenter.segment(s)].map((seg) => seg.segment);
@@ -15843,13 +16157,13 @@ function deleteToEnd(e) {
15843
16157
  }
15844
16158
  var segmenter;
15845
16159
  var init_line_editor = __esm({
15846
- "packages/cli/src/tui/line-editor.ts"() {
16160
+ "src/tui/line-editor.ts"() {
15847
16161
  "use strict";
15848
16162
  segmenter = new Intl.Segmenter();
15849
16163
  }
15850
16164
  });
15851
16165
 
15852
- // packages/cli/src/tui/components/text-input.tsx
16166
+ // src/tui/components/text-input.tsx
15853
16167
  import { Text as Text7 } from "ink";
15854
16168
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
15855
16169
  function TextInputView({ value, cursor, placeholder }) {
@@ -15874,13 +16188,13 @@ function TextInputView({ value, cursor, placeholder }) {
15874
16188
  ] });
15875
16189
  }
15876
16190
  var init_text_input = __esm({
15877
- "packages/cli/src/tui/components/text-input.tsx"() {
16191
+ "src/tui/components/text-input.tsx"() {
15878
16192
  "use strict";
15879
16193
  init_line_editor();
15880
16194
  }
15881
16195
  });
15882
16196
 
15883
- // packages/cli/src/tui/components/input-box.tsx
16197
+ // src/tui/components/input-box.tsx
15884
16198
  import { useState as useState2, useEffect as useEffect2, useMemo, useRef } from "react";
15885
16199
  import { Box as Box7, Text as Text8, useInput, usePaste } from "ink";
15886
16200
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
@@ -16131,7 +16445,7 @@ function InputBox({ enabled: enabled2, placeholder, history, onSubmit, hint, com
16131
16445
  ] });
16132
16446
  }
16133
16447
  var init_input_box = __esm({
16134
- "packages/cli/src/tui/components/input-box.tsx"() {
16448
+ "src/tui/components/input-box.tsx"() {
16135
16449
  "use strict";
16136
16450
  init_slash_suggest();
16137
16451
  init_path_suggest();
@@ -16141,7 +16455,7 @@ var init_input_box = __esm({
16141
16455
  }
16142
16456
  });
16143
16457
 
16144
- // packages/cli/src/tui/components/log-navigator.tsx
16458
+ // src/tui/components/log-navigator.tsx
16145
16459
  import { useState as useState3, useMemo as useMemo2, useEffect as useEffect3 } from "react";
16146
16460
  import { Box as Box8, Text as Text9, useInput as useInput2 } from "ink";
16147
16461
  import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -16220,12 +16534,12 @@ function LogNavigator({ tree, onPick, onCancel }) {
16220
16534
  ] });
16221
16535
  }
16222
16536
  var init_log_navigator = __esm({
16223
- "packages/cli/src/tui/components/log-navigator.tsx"() {
16537
+ "src/tui/components/log-navigator.tsx"() {
16224
16538
  "use strict";
16225
16539
  }
16226
16540
  });
16227
16541
 
16228
- // packages/cli/src/tui/components/log-viewer.tsx
16542
+ // src/tui/components/log-viewer.tsx
16229
16543
  import { useState as useState4, useMemo as useMemo3, useEffect as useEffect4, useRef as useRef2 } from "react";
16230
16544
  import { Box as Box9, Text as Text10, useInput as useInput3, useStdout as useStdout2 } from "ink";
16231
16545
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -16298,12 +16612,12 @@ function LogViewer({ title, lines, live, onClose }) {
16298
16612
  ] });
16299
16613
  }
16300
16614
  var init_log_viewer = __esm({
16301
- "packages/cli/src/tui/components/log-viewer.tsx"() {
16615
+ "src/tui/components/log-viewer.tsx"() {
16302
16616
  "use strict";
16303
16617
  }
16304
16618
  });
16305
16619
 
16306
- // packages/cli/src/tui/app.tsx
16620
+ // src/tui/app.tsx
16307
16621
  import { useEffect as useEffect5, useMemo as useMemo4, useReducer, useState as useState5, useRef as useRef3 } from "react";
16308
16622
  import { Box as Box10, useApp, useInput as useInput4 } from "ink";
16309
16623
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
@@ -17013,7 +17327,7 @@ ${lines.join("\n")}` });
17013
17327
  }
17014
17328
  var MAX_CONTEXT_TOKENS_FALLBACK, blockSeq, ANSI2;
17015
17329
  var init_app = __esm({
17016
- "packages/cli/src/tui/app.tsx"() {
17330
+ "src/tui/app.tsx"() {
17017
17331
  "use strict";
17018
17332
  init_render_md();
17019
17333
  init_resolve_refs();
@@ -17041,7 +17355,7 @@ var init_app = __esm({
17041
17355
  }
17042
17356
  });
17043
17357
 
17044
- // packages/cli/src/tui.tsx
17358
+ // src/tui.tsx
17045
17359
  var tui_exports = {};
17046
17360
  __export(tui_exports, {
17047
17361
  runTui: () => runTui
@@ -17056,13 +17370,13 @@ async function runTui(harness, opts = {}) {
17056
17370
  await instance.waitUntilExit();
17057
17371
  }
17058
17372
  var init_tui = __esm({
17059
- "packages/cli/src/tui.tsx"() {
17373
+ "src/tui.tsx"() {
17060
17374
  "use strict";
17061
17375
  init_app();
17062
17376
  }
17063
17377
  });
17064
17378
 
17065
- // packages/cli/src/cli.ts
17379
+ // src/cli.ts
17066
17380
  var cli_exports = {};
17067
17381
  __export(cli_exports, {
17068
17382
  runCli: () => runCli
@@ -17246,7 +17560,7 @@ ${tag}${formatUsageLine(event)}
17246
17560
  return errorText ? 1 : 0;
17247
17561
  }
17248
17562
  var init_cli = __esm({
17249
- "packages/cli/src/cli.ts"() {
17563
+ "src/cli.ts"() {
17250
17564
  "use strict";
17251
17565
  init_render_md();
17252
17566
  init_resolve_refs();
@@ -17254,7 +17568,7 @@ var init_cli = __esm({
17254
17568
  }
17255
17569
  });
17256
17570
 
17257
- // packages/server/dist/channels/shared/media.js
17571
+ // ../server/dist/channels/shared/media.js
17258
17572
  import path40 from "node:path";
17259
17573
  import os3 from "node:os";
17260
17574
  function tempDir() {
@@ -17295,7 +17609,7 @@ function classifyMedia(filePath) {
17295
17609
  }
17296
17610
  var MEDIA_MARKER_RE, VIDEO_EXTS, VOICE_EXTS;
17297
17611
  var init_media = __esm({
17298
- "packages/server/dist/channels/shared/media.js"() {
17612
+ "../server/dist/channels/shared/media.js"() {
17299
17613
  "use strict";
17300
17614
  init_dist();
17301
17615
  MEDIA_MARKER_RE = /^MEDIA:\s*(\S.*?)\s*$/gm;
@@ -17304,7 +17618,7 @@ var init_media = __esm({
17304
17618
  }
17305
17619
  });
17306
17620
 
17307
- // packages/server/dist/routes/workspace-path.js
17621
+ // ../server/dist/routes/workspace-path.js
17308
17622
  import fs34 from "node:fs/promises";
17309
17623
  import { existsSync as existsSync2, realpathSync as realpathSync3 } from "node:fs";
17310
17624
  import path41 from "node:path";
@@ -17348,12 +17662,12 @@ function isSafeIdSegment(id) {
17348
17662
  return /^[\w.:>\u4e00-\u9fff-]+$/.test(id);
17349
17663
  }
17350
17664
  var init_workspace_path = __esm({
17351
- "packages/server/dist/routes/workspace-path.js"() {
17665
+ "../server/dist/routes/workspace-path.js"() {
17352
17666
  "use strict";
17353
17667
  }
17354
17668
  });
17355
17669
 
17356
- // packages/server/dist/routes/files.js
17670
+ // ../server/dist/routes/files.js
17357
17671
  import { Hono } from "hono";
17358
17672
  import fs35 from "node:fs/promises";
17359
17673
  import { createReadStream } from "node:fs";
@@ -17893,7 +18207,7 @@ function createFileRoutes() {
17893
18207
  return app2;
17894
18208
  }
17895
18209
  var init_files = __esm({
17896
- "packages/server/dist/routes/files.js"() {
18210
+ "../server/dist/routes/files.js"() {
17897
18211
  "use strict";
17898
18212
  init_dist();
17899
18213
  init_media();
@@ -17901,7 +18215,7 @@ var init_files = __esm({
17901
18215
  }
17902
18216
  });
17903
18217
 
17904
- // packages/server/dist/routes/data-preview.js
18218
+ // ../server/dist/routes/data-preview.js
17905
18219
  import { Hono as Hono2 } from "hono";
17906
18220
  import fs36 from "node:fs/promises";
17907
18221
  import { createReadStream as createReadStream2 } from "node:fs";
@@ -18126,7 +18440,7 @@ function createDataPreviewRoutes() {
18126
18440
  }
18127
18441
  var DEFAULT_LIMIT, MAX_LIMIT, MAX_ROW_CHARS, QUOTE, CR, LF, COMMA, SEMI, TAB, CsvScanner;
18128
18442
  var init_data_preview = __esm({
18129
- "packages/server/dist/routes/data-preview.js"() {
18443
+ "../server/dist/routes/data-preview.js"() {
18130
18444
  "use strict";
18131
18445
  init_workspace_path();
18132
18446
  DEFAULT_LIMIT = 100;
@@ -18227,7 +18541,7 @@ var init_data_preview = __esm({
18227
18541
  }
18228
18542
  });
18229
18543
 
18230
- // packages/server/dist/git-credentials.js
18544
+ // ../server/dist/git-credentials.js
18231
18545
  import fs37 from "node:fs";
18232
18546
  import path44 from "node:path";
18233
18547
  import { homedir as homedir18 } from "node:os";
@@ -18293,13 +18607,13 @@ function deleteGitCredential(host) {
18293
18607
  }
18294
18608
  var GIT_CREDENTIALS_PATH;
18295
18609
  var init_git_credentials = __esm({
18296
- "packages/server/dist/git-credentials.js"() {
18610
+ "../server/dist/git-credentials.js"() {
18297
18611
  "use strict";
18298
18612
  GIT_CREDENTIALS_PATH = path44.join(homedir18(), ".git-credentials");
18299
18613
  }
18300
18614
  });
18301
18615
 
18302
- // packages/server/dist/git-ssh.js
18616
+ // ../server/dist/git-ssh.js
18303
18617
  import fs38 from "node:fs";
18304
18618
  import os4 from "node:os";
18305
18619
  import path45 from "node:path";
@@ -18476,7 +18790,7 @@ function getRemoteProtocol(projectRoot) {
18476
18790
  }
18477
18791
  var SSH_DIR, NON_KEY_NAMES, ownedAgentPid, ASKPASS_SCRIPT;
18478
18792
  var init_git_ssh = __esm({
18479
- "packages/server/dist/git-ssh.js"() {
18793
+ "../server/dist/git-ssh.js"() {
18480
18794
  "use strict";
18481
18795
  SSH_DIR = path45.join(os4.homedir(), ".ssh");
18482
18796
  NON_KEY_NAMES = /* @__PURE__ */ new Set(["known_hosts", "known_hosts2", "authorized_keys", "config"]);
@@ -18489,7 +18803,7 @@ printf '%s\\n' "$HALO_SSH_PASSPHRASE"
18489
18803
  }
18490
18804
  });
18491
18805
 
18492
- // packages/server/dist/routes/git.js
18806
+ // ../server/dist/routes/git.js
18493
18807
  import { Hono as Hono3 } from "hono";
18494
18808
  import os5 from "node:os";
18495
18809
  import path46 from "node:path";
@@ -18855,7 +19169,7 @@ function createGitRoutes() {
18855
19169
  return app2;
18856
19170
  }
18857
19171
  var init_git = __esm({
18858
- "packages/server/dist/routes/git.js"() {
19172
+ "../server/dist/routes/git.js"() {
18859
19173
  "use strict";
18860
19174
  init_dist();
18861
19175
  init_workspace_path();
@@ -18865,7 +19179,7 @@ var init_git = __esm({
18865
19179
  }
18866
19180
  });
18867
19181
 
18868
- // packages/server/dist/routes/mtime-cache.js
19182
+ // ../server/dist/routes/mtime-cache.js
18869
19183
  function createMtimeCache() {
18870
19184
  const entries = /* @__PURE__ */ new Map();
18871
19185
  return {
@@ -18880,12 +19194,12 @@ function createMtimeCache() {
18880
19194
  };
18881
19195
  }
18882
19196
  var init_mtime_cache = __esm({
18883
- "packages/server/dist/routes/mtime-cache.js"() {
19197
+ "../server/dist/routes/mtime-cache.js"() {
18884
19198
  "use strict";
18885
19199
  }
18886
19200
  });
18887
19201
 
18888
- // packages/server/dist/routes/agent-configs.js
19202
+ // ../server/dist/routes/agent-configs.js
18889
19203
  import { Hono as Hono4 } from "hono";
18890
19204
  import fs39 from "node:fs/promises";
18891
19205
  import path47 from "node:path";
@@ -19077,7 +19391,7 @@ function createAgentConfigRoutes() {
19077
19391
  if (wsIds.has(a.id))
19078
19392
  a.overridden = true;
19079
19393
  }
19080
- const disabledSet = projectId ? getDisabledSet(getWorkspaceDb(projectId).db, "agent") : /* @__PURE__ */ new Set();
19394
+ const disabledSet = projectId && hasWorkspaceHalo(projectId) ? getDisabledSet(getWorkspaceDb(projectId).db, "agent") : /* @__PURE__ */ new Set();
19081
19395
  const allAgents = [...globalAgents, ...workspaceAgents];
19082
19396
  for (const a of allAgents) {
19083
19397
  a.disabled = disabledSet.has(`${a.scope}:${a.id}`);
@@ -19419,7 +19733,7 @@ ${body.description ?? ""}
19419
19733
  }
19420
19734
  var _cachedTools, GLOBAL_AGENTS_DIR4, FALLBACK_SCAFFOLD_PROVIDER, _yamlCache;
19421
19735
  var init_agent_configs = __esm({
19422
- "packages/server/dist/routes/agent-configs.js"() {
19736
+ "../server/dist/routes/agent-configs.js"() {
19423
19737
  "use strict";
19424
19738
  init_workspace_tools();
19425
19739
  init_draft_tool();
@@ -19427,6 +19741,7 @@ var init_agent_configs = __esm({
19427
19741
  init_md_loader();
19428
19742
  init_config();
19429
19743
  init_db();
19744
+ init_init();
19430
19745
  init_workspace_path();
19431
19746
  init_mtime_cache();
19432
19747
  _cachedTools = null;
@@ -19436,7 +19751,7 @@ var init_agent_configs = __esm({
19436
19751
  }
19437
19752
  });
19438
19753
 
19439
- // packages/server/dist/routes/skills.js
19754
+ // ../server/dist/routes/skills.js
19440
19755
  import { Hono as Hono5 } from "hono";
19441
19756
  import fs40 from "node:fs/promises";
19442
19757
  import path48 from "node:path";
@@ -19451,7 +19766,7 @@ function defaultSkillSettings() {
19451
19766
  "",
19452
19767
  "global.anthropic.claude-sonnet-4-6",
19453
19768
  "global.anthropic.claude-haiku-4-5-20251001",
19454
- "global.anthropic.claude-opus-4-6"
19769
+ "global.anthropic.claude-opus-5-5"
19455
19770
  ]
19456
19771
  }
19457
19772
  };
@@ -19631,7 +19946,7 @@ function createSkillRoutes() {
19631
19946
  }
19632
19947
  var GLOBAL_SETTINGS_PATH, _skillMdCache;
19633
19948
  var init_skills = __esm({
19634
- "packages/server/dist/routes/skills.js"() {
19949
+ "../server/dist/routes/skills.js"() {
19635
19950
  "use strict";
19636
19951
  init_agent_loader();
19637
19952
  init_db();
@@ -19642,7 +19957,7 @@ var init_skills = __esm({
19642
19957
  }
19643
19958
  });
19644
19959
 
19645
- // packages/server/dist/routes/settings.js
19960
+ // ../server/dist/routes/settings.js
19646
19961
  import { Hono as Hono6 } from "hono";
19647
19962
  import fs41 from "node:fs/promises";
19648
19963
  import path49 from "node:path";
@@ -19911,7 +20226,7 @@ function createSettingsRoutes() {
19911
20226
  }
19912
20227
  var GLOBAL_SETTINGS_PATH2, _changeListeners;
19913
20228
  var init_settings = __esm({
19914
- "packages/server/dist/routes/settings.js"() {
20229
+ "../server/dist/routes/settings.js"() {
19915
20230
  "use strict";
19916
20231
  init_settings_schema();
19917
20232
  init_workspace_path();
@@ -19920,7 +20235,7 @@ var init_settings = __esm({
19920
20235
  }
19921
20236
  });
19922
20237
 
19923
- // packages/server/dist/evolution/archive.js
20238
+ // ../server/dist/evolution/archive.js
19924
20239
  import fs42 from "node:fs";
19925
20240
  import path50 from "node:path";
19926
20241
  import { pipeline } from "node:stream/promises";
@@ -20087,7 +20402,7 @@ function stopArchiveDaemon() {
20087
20402
  }
20088
20403
  var TERMINAL_RUN_STATUSES, TERMINAL_APPLY_STATUSES, DAY_MS, ARCHIVE_AFTER_MS, PURGE_AFTER_MS, _archiveTimer, _startupTimer;
20089
20404
  var init_archive = __esm({
20090
- "packages/server/dist/evolution/archive.js"() {
20405
+ "../server/dist/evolution/archive.js"() {
20091
20406
  "use strict";
20092
20407
  init_evo_db();
20093
20408
  init_paths();
@@ -20101,7 +20416,7 @@ var init_archive = __esm({
20101
20416
  }
20102
20417
  });
20103
20418
 
20104
- // packages/server/dist/db/raw-sqlite.js
20419
+ // ../server/dist/db/raw-sqlite.js
20105
20420
  function rawSqlite(db) {
20106
20421
  const withClient = db;
20107
20422
  const client = withClient.$client ?? withClient.session?.client;
@@ -20110,12 +20425,12 @@ function rawSqlite(db) {
20110
20425
  return client;
20111
20426
  }
20112
20427
  var init_raw_sqlite = __esm({
20113
- "packages/server/dist/db/raw-sqlite.js"() {
20428
+ "../server/dist/db/raw-sqlite.js"() {
20114
20429
  "use strict";
20115
20430
  }
20116
20431
  });
20117
20432
 
20118
- // packages/server/dist/routes/evolution.js
20433
+ // ../server/dist/routes/evolution.js
20119
20434
  import { Hono as Hono7 } from "hono";
20120
20435
  import { eq as eq11, desc as desc2, lt as lt3, and as and8, or, sql } from "drizzle-orm";
20121
20436
  import fs43 from "node:fs/promises";
@@ -20373,7 +20688,7 @@ function extractText(content) {
20373
20688
  }
20374
20689
  var UNDELETABLE_RUN_STATUSES;
20375
20690
  var init_evolution = __esm({
20376
- "packages/server/dist/routes/evolution.js"() {
20691
+ "../server/dist/routes/evolution.js"() {
20377
20692
  "use strict";
20378
20693
  init_evo_db();
20379
20694
  init_archive();
@@ -20384,7 +20699,7 @@ var init_evolution = __esm({
20384
20699
  }
20385
20700
  });
20386
20701
 
20387
- // packages/server/dist/routes/sessions.js
20702
+ // ../server/dist/routes/sessions.js
20388
20703
  import { Hono as Hono8 } from "hono";
20389
20704
  import { and as and9, eq as eq12, gte as gte2, lt as lt4 } from "drizzle-orm";
20390
20705
  function rawId() {
@@ -20498,6 +20813,8 @@ function createSessionRoutes(smRegistry) {
20498
20813
  return c.json({ error: "session manager not initialized" }, 500);
20499
20814
  if (!projectId)
20500
20815
  return c.json({ error: "projectId required" }, 400);
20816
+ if (!hasWorkspaceHalo(projectId))
20817
+ return c.json({ sessions: [], nextCursor: null });
20501
20818
  const sm = smRegistry.getOrCreate(projectId);
20502
20819
  let parentId;
20503
20820
  if (parentIdParam === void 0)
@@ -20639,7 +20956,7 @@ function createSessionRoutes(smRegistry) {
20639
20956
  }
20640
20957
  var msgCounter2;
20641
20958
  var init_sessions = __esm({
20642
- "packages/server/dist/routes/sessions.js"() {
20959
+ "../server/dist/routes/sessions.js"() {
20643
20960
  "use strict";
20644
20961
  init_db();
20645
20962
  init_schema();
@@ -20647,11 +20964,12 @@ var init_sessions = __esm({
20647
20964
  init_goal_mode();
20648
20965
  init_broadcast();
20649
20966
  init_workspace_path();
20967
+ init_init();
20650
20968
  msgCounter2 = 0;
20651
20969
  }
20652
20970
  });
20653
20971
 
20654
- // packages/server/dist/routes/session-archive.js
20972
+ // ../server/dist/routes/session-archive.js
20655
20973
  import { Hono as Hono9 } from "hono";
20656
20974
  function createSessionArchiveRoutes(smRegistry) {
20657
20975
  const app2 = new Hono9();
@@ -20684,7 +21002,7 @@ function createSessionArchiveRoutes(smRegistry) {
20684
21002
  return app2;
20685
21003
  }
20686
21004
  var init_session_archive2 = __esm({
20687
- "packages/server/dist/routes/session-archive.js"() {
21005
+ "../server/dist/routes/session-archive.js"() {
20688
21006
  "use strict";
20689
21007
  init_db();
20690
21008
  init_session_store();
@@ -20693,7 +21011,7 @@ var init_session_archive2 = __esm({
20693
21011
  }
20694
21012
  });
20695
21013
 
20696
- // packages/server/dist/db/channel-db.js
21014
+ // ../server/dist/db/channel-db.js
20697
21015
  import Database5 from "better-sqlite3";
20698
21016
  import { drizzle as drizzle4 } from "drizzle-orm/better-sqlite3";
20699
21017
  import { sqliteTable as sqliteTable4, text as text4, integer as integer4 } from "drizzle-orm/sqlite-core";
@@ -20719,7 +21037,7 @@ function getChannelDb() {
20719
21037
  }
20720
21038
  var channelAccounts, CREATE_SQL3, _channelDb;
20721
21039
  var init_channel_db = __esm({
20722
- "packages/server/dist/db/channel-db.js"() {
21040
+ "../server/dist/db/channel-db.js"() {
20723
21041
  "use strict";
20724
21042
  init_migrate();
20725
21043
  channelAccounts = sqliteTable4("channel_accounts", {
@@ -20753,7 +21071,7 @@ CREATE INDEX IF NOT EXISTS idx_channel_accounts_type ON channel_accounts(channel
20753
21071
  }
20754
21072
  });
20755
21073
 
20756
- // packages/server/dist/channels/shared/accounts.js
21074
+ // ../server/dist/channels/shared/accounts.js
20757
21075
  import fs45 from "node:fs";
20758
21076
  import path53 from "node:path";
20759
21077
  import { eq as eq13, and as and10 } from "drizzle-orm";
@@ -20874,7 +21192,7 @@ function deleteAccount(db, accountId) {
20874
21192
  }
20875
21193
  var ACCOUNT_ACCESS_LEVELS, CHAT_ACCESS_LEVELS, _lastActiveChatCache, _wechatContextTokenCache;
20876
21194
  var init_accounts = __esm({
20877
- "packages/server/dist/channels/shared/accounts.js"() {
21195
+ "../server/dist/channels/shared/accounts.js"() {
20878
21196
  "use strict";
20879
21197
  init_channel_db();
20880
21198
  init_init();
@@ -20885,7 +21203,7 @@ var init_accounts = __esm({
20885
21203
  }
20886
21204
  });
20887
21205
 
20888
- // packages/server/dist/channels/web/accounts.js
21206
+ // ../server/dist/channels/web/accounts.js
20889
21207
  function toWeb(a) {
20890
21208
  const c = a.config;
20891
21209
  return {
@@ -20948,14 +21266,14 @@ function deleteAccount2(db, accountId) {
20948
21266
  }
20949
21267
  var CH;
20950
21268
  var init_accounts2 = __esm({
20951
- "packages/server/dist/channels/web/accounts.js"() {
21269
+ "../server/dist/channels/web/accounts.js"() {
20952
21270
  "use strict";
20953
21271
  init_accounts();
20954
21272
  CH = "web";
20955
21273
  }
20956
21274
  });
20957
21275
 
20958
- // packages/server/dist/middleware/brute-force.js
21276
+ // ../server/dist/middleware/brute-force.js
20959
21277
  import { getConnInfo } from "@hono/node-server/conninfo";
20960
21278
  function bucket(name) {
20961
21279
  let b = buckets.get(name);
@@ -21006,7 +21324,7 @@ function clearFailures(bucketName, ip) {
21006
21324
  }
21007
21325
  var MAX_ATTEMPTS, LOCKOUT_MS, buckets;
21008
21326
  var init_brute_force = __esm({
21009
- "packages/server/dist/middleware/brute-force.js"() {
21327
+ "../server/dist/middleware/brute-force.js"() {
21010
21328
  "use strict";
21011
21329
  init_config();
21012
21330
  MAX_ATTEMPTS = 5;
@@ -21015,7 +21333,7 @@ var init_brute_force = __esm({
21015
21333
  }
21016
21334
  });
21017
21335
 
21018
- // packages/server/dist/middleware/web-token.js
21336
+ // ../server/dist/middleware/web-token.js
21019
21337
  function resolveTokenAuth(c, db) {
21020
21338
  const ip = getClientIp(c);
21021
21339
  if (isLockedOut(TOKEN_BUCKET, ip))
@@ -21037,7 +21355,7 @@ function tokenAuthJsonError(c, reason) {
21037
21355
  }
21038
21356
  var TOKEN_BUCKET, TOKEN_AUTH_STATUS, JSON_ERROR;
21039
21357
  var init_web_token = __esm({
21040
- "packages/server/dist/middleware/web-token.js"() {
21358
+ "../server/dist/middleware/web-token.js"() {
21041
21359
  "use strict";
21042
21360
  init_accounts2();
21043
21361
  init_brute_force();
@@ -21055,17 +21373,17 @@ var init_web_token = __esm({
21055
21373
  }
21056
21374
  });
21057
21375
 
21058
- // packages/server/dist/channels/shared/session-prefix.js
21376
+ // ../server/dist/channels/shared/session-prefix.js
21059
21377
  function sessionPrefix(channel, userId) {
21060
21378
  return `${channel}_${userId}_`;
21061
21379
  }
21062
21380
  var init_session_prefix = __esm({
21063
- "packages/server/dist/channels/shared/session-prefix.js"() {
21381
+ "../server/dist/channels/shared/session-prefix.js"() {
21064
21382
  "use strict";
21065
21383
  }
21066
21384
  });
21067
21385
 
21068
- // packages/server/dist/channels/web/handler.js
21386
+ // ../server/dist/channels/web/handler.js
21069
21387
  function buildWebSessionPrefix(accountId) {
21070
21388
  return sessionPrefix("web", accountId);
21071
21389
  }
@@ -21482,7 +21800,7 @@ function createMediaBuffer() {
21482
21800
  };
21483
21801
  }
21484
21802
  var init_handler = __esm({
21485
- "packages/server/dist/channels/web/handler.js"() {
21803
+ "../server/dist/channels/web/handler.js"() {
21486
21804
  "use strict";
21487
21805
  init_ui_log_builder();
21488
21806
  init_accounts2();
@@ -21499,7 +21817,7 @@ var init_handler = __esm({
21499
21817
  }
21500
21818
  });
21501
21819
 
21502
- // packages/core/dist/protocol/session-message.js
21820
+ // ../core/dist/protocol/session-message.js
21503
21821
  function inferMessageType(msg) {
21504
21822
  if (msg.type)
21505
21823
  return msg.type;
@@ -21518,20 +21836,20 @@ function inferMessageType(msg) {
21518
21836
  return "notification";
21519
21837
  }
21520
21838
  var init_session_message = __esm({
21521
- "packages/core/dist/protocol/session-message.js"() {
21839
+ "../core/dist/protocol/session-message.js"() {
21522
21840
  "use strict";
21523
21841
  }
21524
21842
  });
21525
21843
 
21526
- // packages/core/dist/protocol/index.js
21844
+ // ../core/dist/protocol/index.js
21527
21845
  var init_protocol = __esm({
21528
- "packages/core/dist/protocol/index.js"() {
21846
+ "../core/dist/protocol/index.js"() {
21529
21847
  "use strict";
21530
21848
  init_session_message();
21531
21849
  }
21532
21850
  });
21533
21851
 
21534
- // packages/server/dist/sessions/session-types.js
21852
+ // ../server/dist/sessions/session-types.js
21535
21853
  function messageToolCalls(msg) {
21536
21854
  if (msg.contentBlocks) {
21537
21855
  return msg.contentBlocks.filter((b) => b.type === "tool_call").map((b) => b.toolCall);
@@ -21539,13 +21857,13 @@ function messageToolCalls(msg) {
21539
21857
  return msg.toolCalls ?? [];
21540
21858
  }
21541
21859
  var init_session_types = __esm({
21542
- "packages/server/dist/sessions/session-types.js"() {
21860
+ "../server/dist/sessions/session-types.js"() {
21543
21861
  "use strict";
21544
21862
  init_protocol();
21545
21863
  }
21546
21864
  });
21547
21865
 
21548
- // packages/server/dist/routes/halo-city.js
21866
+ // ../server/dist/routes/halo-city.js
21549
21867
  import { Hono as Hono10 } from "hono";
21550
21868
  import fs46 from "node:fs";
21551
21869
  import path54 from "node:path";
@@ -21932,7 +22250,7 @@ function createShowRoutes(registry2) {
21932
22250
  }
21933
22251
  var SESSIONS_PER_WS, _skillCache, _metaCache, _roReaders, SESSION_LOG_MAX_MSGS, _birthCache;
21934
22252
  var init_halo_city = __esm({
21935
- "packages/server/dist/routes/halo-city.js"() {
22253
+ "../server/dist/routes/halo-city.js"() {
21936
22254
  "use strict";
21937
22255
  init_channel_db();
21938
22256
  init_web_token();
@@ -21950,7 +22268,7 @@ var init_halo_city = __esm({
21950
22268
  }
21951
22269
  });
21952
22270
 
21953
- // packages/server/dist/routes/metrics.js
22271
+ // ../server/dist/routes/metrics.js
21954
22272
  import { Hono as Hono11 } from "hono";
21955
22273
  function family(name, type, help, samples) {
21956
22274
  const lines = [`# HELP ${name} ${help}`, `# TYPE ${name} ${type}`];
@@ -22029,7 +22347,7 @@ function createMetricsRoutes(registry2) {
22029
22347
  }
22030
22348
  var TEXT_ERROR, SESSIONS_PER_WS2;
22031
22349
  var init_metrics = __esm({
22032
- "packages/server/dist/routes/metrics.js"() {
22350
+ "../server/dist/routes/metrics.js"() {
22033
22351
  "use strict";
22034
22352
  init_channel_db();
22035
22353
  init_web_token();
@@ -22043,7 +22361,7 @@ var init_metrics = __esm({
22043
22361
  }
22044
22362
  });
22045
22363
 
22046
- // packages/server/dist/routes/commands.js
22364
+ // ../server/dist/routes/commands.js
22047
22365
  import { Hono as Hono12 } from "hono";
22048
22366
  function createCommandRoutes(registry2, smRegistry) {
22049
22367
  const app2 = new Hono12();
@@ -22068,12 +22386,12 @@ function createCommandRoutes(registry2, smRegistry) {
22068
22386
  return app2;
22069
22387
  }
22070
22388
  var init_commands3 = __esm({
22071
- "packages/server/dist/routes/commands.js"() {
22389
+ "../server/dist/routes/commands.js"() {
22072
22390
  "use strict";
22073
22391
  }
22074
22392
  });
22075
22393
 
22076
- // packages/server/dist/routes/agentcore.js
22394
+ // ../server/dist/routes/agentcore.js
22077
22395
  import { Hono as Hono13 } from "hono";
22078
22396
  import path55 from "node:path";
22079
22397
  import fs47 from "node:fs";
@@ -22422,7 +22740,7 @@ ${fullText}`, images.length > 0 ? images : void 0);
22422
22740
  }
22423
22741
  var SESSION_HEADER, MAX_IMAGES_PER_MESSAGE, MAX_IMAGE_BASE64_LENGTH, MAX_PENDING_UPLOADS, MAX_CHUNKS_PER_UPLOAD, activeOverrides;
22424
22742
  var init_agentcore = __esm({
22425
- "packages/server/dist/routes/agentcore.js"() {
22743
+ "../server/dist/routes/agentcore.js"() {
22426
22744
  "use strict";
22427
22745
  init_commands2();
22428
22746
  init_ui_log_builder();
@@ -22437,7 +22755,7 @@ var init_agentcore = __esm({
22437
22755
  }
22438
22756
  });
22439
22757
 
22440
- // packages/server/dist/ws/file-watcher.js
22758
+ // ../server/dist/ws/file-watcher.js
22441
22759
  import fs48 from "node:fs";
22442
22760
  import path56 from "node:path";
22443
22761
  function enqueueNativeOp(op) {
@@ -22459,7 +22777,7 @@ function isUnwatchablePath(absPath) {
22459
22777
  }
22460
22778
  var IGNORED_SEGMENTS, IS_WIN32, IGNORED_SEGMENT_SET, NATIVE_IGNORE, nativeOpChain, WorkspaceWatcher;
22461
22779
  var init_file_watcher = __esm({
22462
- "packages/server/dist/ws/file-watcher.js"() {
22780
+ "../server/dist/ws/file-watcher.js"() {
22463
22781
  "use strict";
22464
22782
  IGNORED_SEGMENTS = [
22465
22783
  // VCS
@@ -22681,12 +22999,12 @@ var init_file_watcher = __esm({
22681
22999
  }
22682
23000
  });
22683
23001
 
22684
- // packages/server/dist/ws/git-dir-watcher.js
23002
+ // ../server/dist/ws/git-dir-watcher.js
22685
23003
  import fs49 from "node:fs";
22686
23004
  import path57 from "node:path";
22687
23005
  var GitDirWatcher;
22688
23006
  var init_git_dir_watcher = __esm({
22689
- "packages/server/dist/ws/git-dir-watcher.js"() {
23007
+ "../server/dist/ws/git-dir-watcher.js"() {
22690
23008
  "use strict";
22691
23009
  GitDirWatcher = class {
22692
23010
  watcher = null;
@@ -22805,7 +23123,7 @@ var init_git_dir_watcher = __esm({
22805
23123
  }
22806
23124
  });
22807
23125
 
22808
- // packages/server/dist/ws/event-processor.js
23126
+ // ../server/dist/ws/event-processor.js
22809
23127
  function sendJson(ws, data) {
22810
23128
  if (ws.readyState === ws.OPEN) {
22811
23129
  try {
@@ -22904,16 +23222,16 @@ function bufferDetachedNotification(event, pendingEvents) {
22904
23222
  }
22905
23223
  }
22906
23224
  var init_event_processor = __esm({
22907
- "packages/server/dist/ws/event-processor.js"() {
23225
+ "../server/dist/ws/event-processor.js"() {
22908
23226
  "use strict";
22909
23227
  init_ui_log_builder();
22910
23228
  }
22911
23229
  });
22912
23230
 
22913
- // packages/server/dist/ws/watcher-pool.js
23231
+ // ../server/dist/ws/watcher-pool.js
22914
23232
  var WatcherPool;
22915
23233
  var init_watcher_pool = __esm({
22916
- "packages/server/dist/ws/watcher-pool.js"() {
23234
+ "../server/dist/ws/watcher-pool.js"() {
22917
23235
  "use strict";
22918
23236
  init_file_watcher();
22919
23237
  init_git_dir_watcher();
@@ -22971,7 +23289,7 @@ var init_watcher_pool = __esm({
22971
23289
  }
22972
23290
  });
22973
23291
 
22974
- // packages/server/dist/ws/terminal-manager.js
23292
+ // ../server/dist/ws/terminal-manager.js
22975
23293
  import { homedir as homedir22 } from "node:os";
22976
23294
  import { basename } from "node:path";
22977
23295
  import { createRequire } from "node:module";
@@ -23002,7 +23320,7 @@ function attachListenersOnce(t2) {
23002
23320
  }
23003
23321
  var requireFromHere, ptyModule, TERMINAL_GRACE_MS, terminals, TerminalManager;
23004
23322
  var init_terminal_manager = __esm({
23005
- "packages/server/dist/ws/terminal-manager.js"() {
23323
+ "../server/dist/ws/terminal-manager.js"() {
23006
23324
  "use strict";
23007
23325
  init_config();
23008
23326
  init_child_env();
@@ -23150,7 +23468,7 @@ var init_terminal_manager = __esm({
23150
23468
  }
23151
23469
  });
23152
23470
 
23153
- // packages/server/dist/ws/handler.js
23471
+ // ../server/dist/ws/handler.js
23154
23472
  import path58 from "node:path";
23155
23473
  function setupWebSocketHandler(deps) {
23156
23474
  const { wss: wss2, registry: registry2 } = deps;
@@ -23618,7 +23936,8 @@ ${msg.message}` : markers.join("\n");
23618
23936
  rememberChat(msg);
23619
23937
  ackChat(msg);
23620
23938
  console.debug(`[WS] Chat: session=${msg.sessionId}, project=${msg.projectId}, agent=${msg.agentId ?? client2.agentId}`);
23621
- sm.sendUserMessage(sid, msg.message, msg.images).catch((err) => {
23939
+ const accessLevel = msg.accessLevel === void 0 ? void 0 : msg.accessLevel === "full" || getSandboxBackend() === null ? null : msg.accessLevel;
23940
+ sm.sendUserMessage(sid, msg.message, msg.images, accessLevel).catch((err) => {
23622
23941
  console.debug(`[WS] Chat error: ${err instanceof Error ? err.message : String(err)}`);
23623
23942
  sendJson(ws, { type: "error", error: err instanceof Error ? err.message : String(err) });
23624
23943
  saveSession(client2);
@@ -23678,7 +23997,7 @@ ${msg.message}` : markers.join("\n");
23678
23997
  const running = client2.sessionManager.isSessionRunning(client2.sessionId);
23679
23998
  const messages3 = state2 ? running ? [...state2.messageLog] : [...createSaveSnapshot(state2)] : [];
23680
23999
  const detachedSession = client2.sessionManager.getSessionById(client2.sessionId);
23681
- sendJson(ws, { type: "state:snapshot", snapshot: { recentMessages: messages3, sessionId: msg.sessionId, maxContextTokens: ctxConfig.maxTokens, agentId: detachedSession?.agentId, archiveCount: archiveCountFor(client2, client2.sessionId, detachedSession?.agentId) } });
24000
+ sendJson(ws, { type: "state:snapshot", snapshot: { recentMessages: messages3, sessionId: msg.sessionId, maxContextTokens: ctxConfig.maxTokens, agentId: detachedSession?.agentId, archiveCount: archiveCountFor(client2, client2.sessionId, detachedSession?.agentId), accessLevel: detachedSession?.accessLevel ?? null } });
23682
24001
  if (state2 && state2.contextTokens > 0) {
23683
24002
  sendJson(ws, { type: "chat:usage", contextTokens: state2.contextTokens, outputTokens: state2.outputTokens });
23684
24003
  }
@@ -23722,12 +24041,14 @@ ${msg.message}` : markers.join("\n");
23722
24041
  }
23723
24042
  }
23724
24043
  let agentId;
24044
+ let accessLevel;
23725
24045
  if (msg.sessionId && client2.sessionManager) {
23726
24046
  const existingSession = client2.sessionManager.getSessionById(msg.sessionId);
23727
24047
  if (existingSession) {
23728
24048
  client2.sessionId = msg.sessionId;
23729
24049
  client2.unsubscribeEvents = client2.sessionManager.registerEventListener(msg.sessionId, createEventListener(client2));
23730
24050
  agentId = existingSession.agentId;
24051
+ accessLevel = existingSession.accessLevel ?? null;
23731
24052
  }
23732
24053
  }
23733
24054
  let maxContextTokens = config.model.maxContextTokens;
@@ -23739,7 +24060,7 @@ ${msg.message}` : markers.join("\n");
23739
24060
  }
23740
24061
  const state = getState(client2);
23741
24062
  const messages2 = state ? [...createSaveSnapshot(state)] : [];
23742
- sendJson(ws, { type: "state:snapshot", snapshot: { recentMessages: messages2, sessionId: msg.sessionId, maxContextTokens, agentId, archiveCount: msg.sessionId ? archiveCountFor(client2, msg.sessionId, agentId) : 0 } });
24063
+ sendJson(ws, { type: "state:snapshot", snapshot: { recentMessages: messages2, sessionId: msg.sessionId, maxContextTokens, agentId, archiveCount: msg.sessionId ? archiveCountFor(client2, msg.sessionId, agentId) : 0, accessLevel } });
23743
24064
  if (state && state.contextTokens > 0) {
23744
24065
  sendJson(ws, { type: "chat:usage", contextTokens: state.contextTokens, outputTokens: state.outputTokens });
23745
24066
  }
@@ -23766,8 +24087,9 @@ ${msg.message}` : markers.join("\n");
23766
24087
  }
23767
24088
  var CLIENT_SILENCE_LIMIT_MS, detachedSessions;
23768
24089
  var init_handler2 = __esm({
23769
- "packages/server/dist/ws/handler.js"() {
24090
+ "../server/dist/ws/handler.js"() {
23770
24091
  "use strict";
24092
+ init_sandbox();
23771
24093
  init_ui_log_builder();
23772
24094
  init_config();
23773
24095
  init_watcher_pool();
@@ -23784,7 +24106,7 @@ var init_handler2 = __esm({
23784
24106
  }
23785
24107
  });
23786
24108
 
23787
- // packages/server/dist/db/cron-db.js
24109
+ // ../server/dist/db/cron-db.js
23788
24110
  import Database7 from "better-sqlite3";
23789
24111
  import { drizzle as drizzle5 } from "drizzle-orm/better-sqlite3";
23790
24112
  import { sqliteTable as sqliteTable5, text as text5, integer as integer5 } from "drizzle-orm/sqlite-core";
@@ -23809,7 +24131,7 @@ function getCronDb() {
23809
24131
  }
23810
24132
  var cronJobs, cronRuns, CREATE_SQL4, CRON_MIGRATIONS, _cronDb;
23811
24133
  var init_cron_db = __esm({
23812
- "packages/server/dist/db/cron-db.js"() {
24134
+ "../server/dist/db/cron-db.js"() {
23813
24135
  "use strict";
23814
24136
  init_migrate();
23815
24137
  cronJobs = sqliteTable5("cron_jobs", {
@@ -23838,6 +24160,10 @@ var init_cron_db = __esm({
23838
24160
  * it. NULL = default 3600 (runner.ts CLI_TIMEOUT_SEC). Range 60–21600,
23839
24161
  * enforced at the write points (REST routes / skill helper). */
23840
24162
  timeoutSec: integer5("timeout_sec"),
24163
+ /** Root session id the cli runs in. NULL = the job's own `cron-<jobId>`
24164
+ * session. When it names an existing session the cli resumes it with that
24165
+ * session's own agent (`agentId` only applies when the session is new). */
24166
+ sessionId: text5("session_id"),
23841
24167
  /** JSON array of `{channelType, accountId}` records. Cron output (final
23842
24168
  * assistant text) is dispatched to each one. Empty array = log only. */
23843
24169
  targets: text5("targets").notNull().default("[]"),
@@ -23888,6 +24214,7 @@ CREATE TABLE IF NOT EXISTS cron_jobs (
23888
24214
  run_at INTEGER,
23889
24215
  timezone TEXT,
23890
24216
  timeout_sec INTEGER,
24217
+ session_id TEXT,
23891
24218
  targets TEXT NOT NULL DEFAULT '[]',
23892
24219
  enabled INTEGER NOT NULL DEFAULT 1,
23893
24220
  last_run_status TEXT,
@@ -23923,13 +24250,15 @@ CREATE INDEX IF NOT EXISTS idx_cron_runs_status ON cron_runs(status);
23923
24250
  addColumnIfMissing(s, "cron_jobs", "run_at", "INTEGER");
23924
24251
  addColumnIfMissing(s, "cron_jobs", "timeout_sec", "INTEGER");
23925
24252
  addColumnIfMissing(s, "cron_runs", "pid", "INTEGER");
23926
- }
24253
+ },
24254
+ // v2: `session_id` — run the job in a chosen root session instead of cron-<jobId>.
24255
+ (s) => addColumnIfMissing(s, "cron_jobs", "session_id", "TEXT")
23927
24256
  ];
23928
24257
  _cronDb = null;
23929
24258
  }
23930
24259
  });
23931
24260
 
23932
- // packages/server/dist/cron/dispatcher.js
24261
+ // ../server/dist/cron/dispatcher.js
23933
24262
  function registerCronDispatcher(d) {
23934
24263
  _registry2.set(d.channelType, d);
23935
24264
  }
@@ -23976,14 +24305,14 @@ async function dispatchToTargets(rawText, targets, workspacePath) {
23976
24305
  }
23977
24306
  var _registry2;
23978
24307
  var init_dispatcher = __esm({
23979
- "packages/server/dist/cron/dispatcher.js"() {
24308
+ "../server/dist/cron/dispatcher.js"() {
23980
24309
  "use strict";
23981
24310
  init_media();
23982
24311
  _registry2 = /* @__PURE__ */ new Map();
23983
24312
  }
23984
24313
  });
23985
24314
 
23986
- // packages/server/dist/cron/runner.js
24315
+ // ../server/dist/cron/runner.js
23987
24316
  import { spawn as spawn3, execFileSync } from "node:child_process";
23988
24317
  import fs51 from "node:fs";
23989
24318
  import path60 from "node:path";
@@ -24048,14 +24377,30 @@ function killTreeHard(rootPid) {
24048
24377
  }
24049
24378
  }
24050
24379
  }
24051
- function isCronCliProcess(pid, jobId) {
24380
+ function isCronCliProcess(pid, sessionId) {
24052
24381
  try {
24053
24382
  const args = execFileSync("ps", ["-p", String(pid), "-o", "args="], { encoding: "utf-8" });
24054
- return args.includes(`cron-${jobId}`);
24383
+ return args.trim().split(/\s+/).includes(sessionId);
24055
24384
  } catch {
24056
24385
  return false;
24057
24386
  }
24058
24387
  }
24388
+ function effectiveSessionId(job) {
24389
+ return job.sessionId ?? `cron-${job.id}`;
24390
+ }
24391
+ function sessionKeyFor(workspacePath, sessionId) {
24392
+ let ws;
24393
+ try {
24394
+ ws = fs51.realpathSync(workspacePath);
24395
+ } catch {
24396
+ ws = path60.resolve(workspacePath);
24397
+ }
24398
+ return `${ws}
24399
+ ${sessionId}`;
24400
+ }
24401
+ function setCronSessionRegistry(r) {
24402
+ _sessionRegistry = r;
24403
+ }
24059
24404
  function logsDir() {
24060
24405
  return path60.join(homedir23(), ".halo", "global", "logs", "cron");
24061
24406
  }
@@ -24072,14 +24417,24 @@ function sweepOrphanRuns(opts) {
24072
24417
  const now = Date.now();
24073
24418
  for (const row of rows) {
24074
24419
  const { id: runId, jobId, pid } = row;
24420
+ const job = db.select().from(cronJobs).where(eq14(cronJobs.id, jobId)).get();
24421
+ const sessionId = effectiveSessionId(job ?? { id: jobId, sessionId: null });
24422
+ const sessionKey = job ? sessionKeyFor(job.workspacePath, sessionId) : null;
24075
24423
  _inflight.add(jobId);
24424
+ if (sessionKey)
24425
+ _inflightSessions.add(sessionKey);
24426
+ const release = () => {
24427
+ _inflight.delete(jobId);
24428
+ if (sessionKey)
24429
+ _inflightSessions.delete(sessionKey);
24430
+ };
24076
24431
  let needsKill = false;
24077
24432
  let disposition;
24078
24433
  if (process.platform === "win32") {
24079
24434
  disposition = pid == null ? "no pid recorded" : `pid ${pid} not killed (Windows: cannot verify process identity)`;
24080
24435
  } else if (pid == null) {
24081
24436
  disposition = "no pid recorded";
24082
- } else if (!isCronCliProcess(pid, jobId)) {
24437
+ } else if (!isCronCliProcess(pid, sessionId)) {
24083
24438
  disposition = `pid ${pid} already dead (or pid reused by another process); not killed`;
24084
24439
  } else {
24085
24440
  needsKill = true;
@@ -24093,7 +24448,7 @@ function sweepOrphanRuns(opts) {
24093
24448
  broadcast({ type: "cron:run_changed", jobId, runId, status: "failed" });
24094
24449
  console.log(`[Cron] orphan sweep: run ${runId} (job ${jobId}) \u2014 ${disposition}`);
24095
24450
  if (!needsKill || pid == null) {
24096
- _inflight.delete(jobId);
24451
+ release();
24097
24452
  continue;
24098
24453
  }
24099
24454
  try {
@@ -24101,11 +24456,11 @@ function sweepOrphanRuns(opts) {
24101
24456
  } catch {
24102
24457
  }
24103
24458
  const timer = setTimeout(() => {
24104
- if (isCronCliProcess(pid, jobId)) {
24459
+ if (isCronCliProcess(pid, sessionId)) {
24105
24460
  console.log(`[Cron] orphan sweep: pid ${pid} (job ${jobId}) survived SIGTERM \u2014 SIGKILL tree`);
24106
24461
  killTreeHard(pid);
24107
24462
  }
24108
- _inflight.delete(jobId);
24463
+ release();
24109
24464
  }, graceMs);
24110
24465
  timer.unref();
24111
24466
  }
@@ -24269,7 +24624,11 @@ async function runJob(jobId, triggerKind) {
24269
24624
  const startedAt = Date.now();
24270
24625
  const logPath = logPathFor(runId);
24271
24626
  fs51.mkdirSync(logsDir(), { recursive: true });
24272
- if (_inflight.has(jobId)) {
24627
+ const sessionId = effectiveSessionId(job);
24628
+ const sessionKey = sessionKeyFor(job.workspacePath, sessionId);
24629
+ const host = _sessionRegistry?.peek(job.workspacePath);
24630
+ const skipReason = _inflight.has(jobId) ? "previous run still in progress" : _inflightSessions.has(sessionKey) ? `session ${sessionId} busy: another cron run is in progress` : host?.hasActiveWorkInTree(sessionId) ? `session ${sessionId} busy: a turn is running in it` : null;
24631
+ if (skipReason) {
24273
24632
  db.insert(cronRuns).values({
24274
24633
  id: runId,
24275
24634
  jobId,
@@ -24279,7 +24638,7 @@ async function runJob(jobId, triggerKind) {
24279
24638
  completedAt: startedAt,
24280
24639
  output: null,
24281
24640
  exitCode: null,
24282
- failureReason: "previous run still in progress",
24641
+ failureReason: skipReason,
24283
24642
  logPath: null,
24284
24643
  dispatchResults: null
24285
24644
  }).run();
@@ -24287,6 +24646,7 @@ async function runJob(jobId, triggerKind) {
24287
24646
  return runId;
24288
24647
  }
24289
24648
  _inflight.add(jobId);
24649
+ _inflightSessions.add(sessionKey);
24290
24650
  try {
24291
24651
  db.insert(cronRuns).values({
24292
24652
  id: runId,
@@ -24314,14 +24674,16 @@ async function runJob(jobId, triggerKind) {
24314
24674
  return runId;
24315
24675
  }
24316
24676
  const cli = resolveHaloCli();
24317
- const sessionId = `cron-${job.id}`;
24318
24677
  const args = ["cli", "-a", job.agentId, "-s", sessionId, "-w", job.workspacePath];
24678
+ const accessLevel = readSessionAccessLevel(job.workspacePath, sessionId);
24679
+ if (accessLevel)
24680
+ args.push("--access", accessLevel);
24319
24681
  const [spawnBin, spawnArgs] = process.platform === "win32" && cli.endsWith(".cmd") ? ["cmd.exe", ["/c", cli, ...args]] : [cli, args];
24320
24682
  const timeoutSec = job.timeoutSec ?? CLI_TIMEOUT_SEC;
24321
24683
  const teeStream = fs51.createWriteStream(logPath, { flags: "a" });
24322
24684
  teeStream.write(`=== ${(/* @__PURE__ */ new Date()).toISOString()} cron run ${runId} job=${jobId} trigger=${triggerKind} ===
24323
24685
  `);
24324
- teeStream.write(`agent=${job.agentId} workspace=${job.workspacePath} schedule=${job.schedule}
24686
+ teeStream.write(`agent=${job.agentId} session=${sessionId}${accessLevel ? ` access=${accessLevel}` : ""} workspace=${job.workspacePath} schedule=${job.schedule}
24325
24687
  `);
24326
24688
  teeStream.write(`prompt: ${job.userPrompt}
24327
24689
 
@@ -24393,6 +24755,10 @@ ${job.userPrompt}`);
24393
24755
  resolve2({ exitCode: 1 });
24394
24756
  });
24395
24757
  });
24758
+ const hostAfter = _sessionRegistry?.peek(job.workspacePath);
24759
+ if (hostAfter && !hostAfter.forgetExternalWrite(sessionId)) {
24760
+ console.warn(`[Cron] ${jobId}: session ${sessionId} had a server-side turn running when the cli exited; one of the two turns may be missing from its history`);
24761
+ }
24396
24762
  const trimmedOut = stdout.trim();
24397
24763
  let status;
24398
24764
  let failureReason = null;
@@ -24427,6 +24793,17 @@ ${job.userPrompt}`);
24427
24793
  return runId;
24428
24794
  } finally {
24429
24795
  _inflight.delete(jobId);
24796
+ _inflightSessions.delete(sessionKey);
24797
+ }
24798
+ }
24799
+ function readSessionAccessLevel(workspacePath, sessionId) {
24800
+ try {
24801
+ const row = getWorkspaceDb(workspacePath).db.select({ accessLevel: agentSessions.accessLevel }).from(agentSessions).where(eq14(agentSessions.id, sessionId)).get();
24802
+ if (!row)
24803
+ return null;
24804
+ return row.accessLevel === "workspace" || row.accessLevel === "readonly" ? row.accessLevel : "full";
24805
+ } catch {
24806
+ return null;
24430
24807
  }
24431
24808
  }
24432
24809
  function finalize(runId, jobId, a) {
@@ -24508,12 +24885,14 @@ function pruneOldLogs() {
24508
24885
  const dbCutoff = Date.now() - 2 * LOG_RETENTION_DAYS * DAY_MS2;
24509
24886
  db.delete(cronRuns).where(lt5(cronRuns.startedAt, dbCutoff)).run();
24510
24887
  }
24511
- var DAY_MS2, CLI_TIMEOUT_SEC, KILL_GRACE_SEC, UNATTENDED_PREAMBLE, RUNS_PER_JOB_KEEP, LOG_RETENTION_DAYS, _active, _inflight, _fingerprint, _daemonTimers, _lastCronDataVersion;
24888
+ var DAY_MS2, CLI_TIMEOUT_SEC, KILL_GRACE_SEC, UNATTENDED_PREAMBLE, RUNS_PER_JOB_KEEP, LOG_RETENTION_DAYS, _sessionRegistry, _active, _inflight, _inflightSessions, _fingerprint, _daemonTimers, _lastCronDataVersion;
24512
24889
  var init_runner = __esm({
24513
- "packages/server/dist/cron/runner.js"() {
24890
+ "../server/dist/cron/runner.js"() {
24514
24891
  "use strict";
24515
24892
  init_cron_db();
24516
24893
  init_raw_sqlite();
24894
+ init_db();
24895
+ init_schema();
24517
24896
  init_dispatcher();
24518
24897
  init_broadcast();
24519
24898
  init_child_env();
@@ -24523,15 +24902,17 @@ var init_runner = __esm({
24523
24902
  UNATTENDED_PREAMBLE = "[Unattended cron run \u2014 nobody will answer questions. Deliver the result directly; if genuinely blocked, state what's blocked in one line and stop.]";
24524
24903
  RUNS_PER_JOB_KEEP = 100;
24525
24904
  LOG_RETENTION_DAYS = 30;
24905
+ _sessionRegistry = null;
24526
24906
  _active = /* @__PURE__ */ new Map();
24527
24907
  _inflight = /* @__PURE__ */ new Set();
24908
+ _inflightSessions = /* @__PURE__ */ new Set();
24528
24909
  _fingerprint = /* @__PURE__ */ new Map();
24529
24910
  _daemonTimers = [];
24530
24911
  _lastCronDataVersion = null;
24531
24912
  }
24532
24913
  });
24533
24914
 
24534
- // packages/server/dist/routes/cron.js
24915
+ // ../server/dist/routes/cron.js
24535
24916
  import { Hono as Hono14 } from "hono";
24536
24917
  import { eq as eq15, desc as desc3, lt as lt6, and as and11 } from "drizzle-orm";
24537
24918
  import fs52 from "node:fs/promises";
@@ -24556,6 +24937,19 @@ function validateTimeoutSec(v) {
24556
24937
  }
24557
24938
  return null;
24558
24939
  }
24940
+ function parseSessionId(v) {
24941
+ if (v === void 0 || v === null)
24942
+ return { sessionId: null };
24943
+ if (typeof v !== "string")
24944
+ return { error: "sessionId must be a string or null" };
24945
+ const s = v.trim();
24946
+ if (s.length === 0)
24947
+ return { sessionId: null };
24948
+ if (!SESSION_ID_RE.test(s)) {
24949
+ return { error: 'sessionId must be a root session id (letters, digits, _ : - only; no ">" sub-session path)' };
24950
+ }
24951
+ return { sessionId: s };
24952
+ }
24559
24953
  function createCronRoutes() {
24560
24954
  const router = new Hono14();
24561
24955
  router.get("/cron/jobs", async (c) => {
@@ -24604,6 +24998,9 @@ function createCronRoutes() {
24604
24998
  if (err)
24605
24999
  return c.json({ error: err }, 400);
24606
25000
  }
25001
+ const session = parseSessionId(body.sessionId);
25002
+ if ("error" in session)
25003
+ return c.json({ error: session.error }, 400);
24607
25004
  const id = newJobId();
24608
25005
  const now = Date.now();
24609
25006
  getCronDb().insert(cronJobs).values({
@@ -24616,6 +25013,7 @@ function createCronRoutes() {
24616
25013
  runAt: hasRunAt ? body.runAt : null,
24617
25014
  timezone: body.timezone ?? null,
24618
25015
  timeoutSec: body.timeoutSec ?? null,
25016
+ sessionId: session.sessionId,
24619
25017
  targets: JSON.stringify(body.targets ?? []),
24620
25018
  enabled: body.enabled === false ? 0 : 1,
24621
25019
  lastRunStatus: null,
@@ -24657,6 +25055,9 @@ function createCronRoutes() {
24657
25055
  if (err)
24658
25056
  return c.json({ error: err }, 400);
24659
25057
  }
25058
+ const session = parseSessionId(body.sessionId);
25059
+ if ("error" in session)
25060
+ return c.json({ error: session.error }, 400);
24660
25061
  const hasSchedule = typeof body.schedule === "string" && body.schedule.trim().length > 0;
24661
25062
  const hasRunAt = typeof body.runAt === "number";
24662
25063
  if (hasSchedule && hasRunAt) {
@@ -24686,6 +25087,8 @@ function createCronRoutes() {
24686
25087
  patch.timezone = body.timezone || null;
24687
25088
  if (body.timeoutSec !== void 0)
24688
25089
  patch.timeoutSec = body.timeoutSec;
25090
+ if (body.sessionId !== void 0)
25091
+ patch.sessionId = session.sessionId;
24689
25092
  if (body.targets !== void 0)
24690
25093
  patch.targets = JSON.stringify(body.targets);
24691
25094
  if (body.enabled !== void 0)
@@ -24801,9 +25204,9 @@ function computeNextRun(j) {
24801
25204
  return null;
24802
25205
  }
24803
25206
  }
24804
- var TIMEOUT_SEC_MIN, TIMEOUT_SEC_MAX;
25207
+ var TIMEOUT_SEC_MIN, TIMEOUT_SEC_MAX, SESSION_ID_RE;
24805
25208
  var init_cron = __esm({
24806
- "packages/server/dist/routes/cron.js"() {
25209
+ "../server/dist/routes/cron.js"() {
24807
25210
  "use strict";
24808
25211
  init_cron_db();
24809
25212
  init_runner();
@@ -24811,10 +25214,11 @@ var init_cron = __esm({
24811
25214
  init_broadcast();
24812
25215
  TIMEOUT_SEC_MIN = 60;
24813
25216
  TIMEOUT_SEC_MAX = 21600;
25217
+ SESSION_ID_RE = /^[A-Za-z0-9_:-]{1,200}$/;
24814
25218
  }
24815
25219
  });
24816
25220
 
24817
- // packages/server/dist/evolution/ticker.js
25221
+ // ../server/dist/evolution/ticker.js
24818
25222
  import { eq as eq16, and as and12, or as or2, asc, isNull as isNull6, sql as sql2 } from "drizzle-orm";
24819
25223
  function setEvoSpawner(fn) {
24820
25224
  _spawner = fn;
@@ -25040,7 +25444,7 @@ function claimApply(id) {
25040
25444
  }
25041
25445
  var _lastRunStatus, _lastApplyStatus, _spawner, TICK_INTERVAL_MS, _interval, _startupTimer2;
25042
25446
  var init_ticker = __esm({
25043
- "packages/server/dist/evolution/ticker.js"() {
25447
+ "../server/dist/evolution/ticker.js"() {
25044
25448
  "use strict";
25045
25449
  init_config();
25046
25450
  init_evo_db();
@@ -25056,13 +25460,13 @@ var init_ticker = __esm({
25056
25460
  }
25057
25461
  });
25058
25462
 
25059
- // packages/server/dist/evolution/spawn.js
25463
+ // ../server/dist/evolution/spawn.js
25060
25464
  import path61 from "node:path";
25061
25465
  import { spawn as spawn4 } from "node:child_process";
25062
25466
  import { fileURLToPath as fileURLToPath2 } from "node:url";
25063
25467
  var __dirname2, WRAPPER_PATH, realEvoSpawner;
25064
25468
  var init_spawn = __esm({
25065
- "packages/server/dist/evolution/spawn.js"() {
25469
+ "../server/dist/evolution/spawn.js"() {
25066
25470
  "use strict";
25067
25471
  init_child_env();
25068
25472
  __dirname2 = path61.dirname(fileURLToPath2(import.meta.url));
@@ -25084,7 +25488,7 @@ var init_spawn = __esm({
25084
25488
  }
25085
25489
  });
25086
25490
 
25087
- // packages/server/dist/channels/registry.js
25491
+ // ../server/dist/channels/registry.js
25088
25492
  function bootChannels(app2, descriptors, deps) {
25089
25493
  for (const d of descriptors) {
25090
25494
  if (d.registerCronDispatcher)
@@ -25109,13 +25513,13 @@ async function shutdownChannels() {
25109
25513
  }
25110
25514
  var _running;
25111
25515
  var init_registry2 = __esm({
25112
- "packages/server/dist/channels/registry.js"() {
25516
+ "../server/dist/channels/registry.js"() {
25113
25517
  "use strict";
25114
25518
  _running = [];
25115
25519
  }
25116
25520
  });
25117
25521
 
25118
- // packages/server/dist/channels/telegram/accounts.js
25522
+ // ../server/dist/channels/telegram/accounts.js
25119
25523
  function toTelegram(a) {
25120
25524
  const c = a.config;
25121
25525
  return {
@@ -25189,14 +25593,14 @@ function deleteAccount3(db, accountId) {
25189
25593
  }
25190
25594
  var CH2;
25191
25595
  var init_accounts3 = __esm({
25192
- "packages/server/dist/channels/telegram/accounts.js"() {
25596
+ "../server/dist/channels/telegram/accounts.js"() {
25193
25597
  "use strict";
25194
25598
  init_accounts();
25195
25599
  CH2 = "telegram";
25196
25600
  }
25197
25601
  });
25198
25602
 
25199
- // packages/server/dist/channels/shared/chunk.js
25603
+ // ../server/dist/channels/shared/chunk.js
25200
25604
  function splitText(text6, limit) {
25201
25605
  const out = [];
25202
25606
  let rest = text6;
@@ -25212,15 +25616,15 @@ function splitText(text6, limit) {
25212
25616
  return out;
25213
25617
  }
25214
25618
  var init_chunk = __esm({
25215
- "packages/server/dist/channels/shared/chunk.js"() {
25619
+ "../server/dist/channels/shared/chunk.js"() {
25216
25620
  "use strict";
25217
25621
  }
25218
25622
  });
25219
25623
 
25220
- // packages/server/dist/channels/telegram/event-adapter.js
25624
+ // ../server/dist/channels/telegram/event-adapter.js
25221
25625
  var HARD_CHARS, TelegramResponder;
25222
25626
  var init_event_adapter = __esm({
25223
- "packages/server/dist/channels/telegram/event-adapter.js"() {
25627
+ "../server/dist/channels/telegram/event-adapter.js"() {
25224
25628
  "use strict";
25225
25629
  init_chunk();
25226
25630
  init_media();
@@ -25303,7 +25707,7 @@ var init_event_adapter = __esm({
25303
25707
  }
25304
25708
  });
25305
25709
 
25306
- // packages/server/dist/channels/shared/busy-hint.js
25710
+ // ../server/dist/channels/shared/busy-hint.js
25307
25711
  function busyHint(sm, sessionId, lang) {
25308
25712
  if (sm.isSessionCompacting(sessionId))
25309
25713
  return t("handler.compacting", lang);
@@ -25312,13 +25716,13 @@ function busyHint(sm, sessionId, lang) {
25312
25716
  return null;
25313
25717
  }
25314
25718
  var init_busy_hint = __esm({
25315
- "packages/server/dist/channels/shared/busy-hint.js"() {
25719
+ "../server/dist/channels/shared/busy-hint.js"() {
25316
25720
  "use strict";
25317
25721
  init_i18n();
25318
25722
  }
25319
25723
  });
25320
25724
 
25321
- // packages/server/dist/channels/shared/inbound.js
25725
+ // ../server/dist/channels/shared/inbound.js
25322
25726
  function sessionAccess(accountAccessLevel) {
25323
25727
  return accountAccessLevel === "full" ? null : accountAccessLevel === "workspace" ? "workspace" : "readonly";
25324
25728
  }
@@ -25376,7 +25780,7 @@ async function dispatchChannelCommand(ctx, command, arg, opts) {
25376
25780
  }
25377
25781
  var InboundBridge;
25378
25782
  var init_inbound = __esm({
25379
- "packages/server/dist/channels/shared/inbound.js"() {
25783
+ "../server/dist/channels/shared/inbound.js"() {
25380
25784
  "use strict";
25381
25785
  init_goal_mode();
25382
25786
  init_accounts();
@@ -25446,7 +25850,7 @@ var init_inbound = __esm({
25446
25850
  }
25447
25851
  });
25448
25852
 
25449
- // packages/server/dist/channels/telegram/handler.js
25853
+ // ../server/dist/channels/telegram/handler.js
25450
25854
  import { Bot, InputFile } from "grammy";
25451
25855
  function inferMediaKind(filePath) {
25452
25856
  const cls = classifyMedia(filePath);
@@ -25544,7 +25948,7 @@ function startTelegramChannel(deps) {
25544
25948
  if (!route)
25545
25949
  return;
25546
25950
  if (!isMediaPathAllowed(filePath, account.workspacePath)) {
25547
- console.log(`[Telegram] sendMedia blocked: ${filePath} not under workspace`);
25951
+ console.warn(`[Telegram] sendMedia blocked: ${filePath} not under workspace`);
25548
25952
  return;
25549
25953
  }
25550
25954
  const kind = inferMediaKind(filePath);
@@ -25833,7 +26237,7 @@ async function handleUserMessage(args) {
25833
26237
  }
25834
26238
  var MAX_TG_DOWNLOAD_BYTES;
25835
26239
  var init_handler3 = __esm({
25836
- "packages/server/dist/channels/telegram/handler.js"() {
26240
+ "../server/dist/channels/telegram/handler.js"() {
25837
26241
  "use strict";
25838
26242
  init_accounts3();
25839
26243
  init_event_adapter();
@@ -25848,7 +26252,7 @@ var init_handler3 = __esm({
25848
26252
  }
25849
26253
  });
25850
26254
 
25851
- // packages/server/dist/routes/telegram.js
26255
+ // ../server/dist/routes/telegram.js
25852
26256
  import { Hono as Hono15 } from "hono";
25853
26257
  import { Bot as Bot2 } from "grammy";
25854
26258
  import fs53 from "node:fs";
@@ -25967,14 +26371,14 @@ function createTelegramRoutes(deps) {
25967
26371
  return app2;
25968
26372
  }
25969
26373
  var init_telegram = __esm({
25970
- "packages/server/dist/routes/telegram.js"() {
26374
+ "../server/dist/routes/telegram.js"() {
25971
26375
  "use strict";
25972
26376
  init_accounts3();
25973
26377
  init_accounts();
25974
26378
  }
25975
26379
  });
25976
26380
 
25977
- // packages/server/dist/channels/telegram/cron-dispatcher.js
26381
+ // ../server/dist/channels/telegram/cron-dispatcher.js
25978
26382
  import { Bot as Bot3 } from "grammy";
25979
26383
  async function dispatch(accountId, text6, explicitChatId) {
25980
26384
  const acct = getAccount3(getChannelDb(), accountId);
@@ -26023,7 +26427,7 @@ function registerTelegramCronDispatcher() {
26023
26427
  registerCronDispatcher({ channelType: "telegram", dispatch, listTargets });
26024
26428
  }
26025
26429
  var init_cron_dispatcher = __esm({
26026
- "packages/server/dist/channels/telegram/cron-dispatcher.js"() {
26430
+ "../server/dist/channels/telegram/cron-dispatcher.js"() {
26027
26431
  "use strict";
26028
26432
  init_channel_db();
26029
26433
  init_accounts3();
@@ -26031,10 +26435,10 @@ var init_cron_dispatcher = __esm({
26031
26435
  }
26032
26436
  });
26033
26437
 
26034
- // packages/server/dist/channels/telegram/descriptor.js
26438
+ // ../server/dist/channels/telegram/descriptor.js
26035
26439
  var telegramDescriptor;
26036
26440
  var init_descriptor = __esm({
26037
- "packages/server/dist/channels/telegram/descriptor.js"() {
26441
+ "../server/dist/channels/telegram/descriptor.js"() {
26038
26442
  "use strict";
26039
26443
  init_handler3();
26040
26444
  init_telegram();
@@ -26049,7 +26453,7 @@ var init_descriptor = __esm({
26049
26453
  }
26050
26454
  });
26051
26455
 
26052
- // packages/server/dist/channels/wechat/api.js
26456
+ // ../server/dist/channels/wechat/api.js
26053
26457
  import crypto3 from "node:crypto";
26054
26458
  function buildClientVersion(version) {
26055
26459
  const [ma, mi, pa] = version.split(".").map((p) => parseInt(p, 10));
@@ -26238,7 +26642,7 @@ async function notifyStop(params) {
26238
26642
  }
26239
26643
  var QR_BASE_URL, DEFAULT_BOT_TYPE, CHANNEL_VERSION, ILINK_APP_ID, ILINK_APP_CLIENT_VERSION, DEFAULT_LONG_POLL_TIMEOUT_MS, DEFAULT_API_TIMEOUT_MS;
26240
26644
  var init_api = __esm({
26241
- "packages/server/dist/channels/wechat/api.js"() {
26645
+ "../server/dist/channels/wechat/api.js"() {
26242
26646
  "use strict";
26243
26647
  QR_BASE_URL = "https://ilinkai.weixin.qq.com";
26244
26648
  DEFAULT_BOT_TYPE = "3";
@@ -26250,10 +26654,10 @@ var init_api = __esm({
26250
26654
  }
26251
26655
  });
26252
26656
 
26253
- // packages/server/dist/channels/wechat/types.js
26657
+ // ../server/dist/channels/wechat/types.js
26254
26658
  var MessageItemType, MessageType, MessageState, UploadMediaType;
26255
26659
  var init_types = __esm({
26256
- "packages/server/dist/channels/wechat/types.js"() {
26660
+ "../server/dist/channels/wechat/types.js"() {
26257
26661
  "use strict";
26258
26662
  MessageItemType = {
26259
26663
  NONE: 0,
@@ -26282,7 +26686,7 @@ var init_types = __esm({
26282
26686
  }
26283
26687
  });
26284
26688
 
26285
- // packages/server/dist/channels/wechat/accounts.js
26689
+ // ../server/dist/channels/wechat/accounts.js
26286
26690
  function toWechat(a) {
26287
26691
  const c = a.config;
26288
26692
  return {
@@ -26364,17 +26768,17 @@ function saveSyncBuf(db, accountId, syncBuf) {
26364
26768
  }
26365
26769
  var CH3;
26366
26770
  var init_accounts4 = __esm({
26367
- "packages/server/dist/channels/wechat/accounts.js"() {
26771
+ "../server/dist/channels/wechat/accounts.js"() {
26368
26772
  "use strict";
26369
26773
  init_accounts();
26370
26774
  CH3 = "wechat";
26371
26775
  }
26372
26776
  });
26373
26777
 
26374
- // packages/server/dist/channels/wechat/event-adapter.js
26778
+ // ../server/dist/channels/wechat/event-adapter.js
26375
26779
  var WECHAT_TEXT_LIMIT, WechatResponder;
26376
26780
  var init_event_adapter2 = __esm({
26377
- "packages/server/dist/channels/wechat/event-adapter.js"() {
26781
+ "../server/dist/channels/wechat/event-adapter.js"() {
26378
26782
  "use strict";
26379
26783
  init_chunk();
26380
26784
  init_media();
@@ -26478,7 +26882,7 @@ var init_event_adapter2 = __esm({
26478
26882
  }
26479
26883
  });
26480
26884
 
26481
- // packages/server/dist/channels/wechat/cdn.js
26885
+ // ../server/dist/channels/wechat/cdn.js
26482
26886
  import { createDecipheriv, createCipheriv, randomBytes as randomBytes2, createHash as createHash2 } from "node:crypto";
26483
26887
  function decryptAesEcb(ciphertext, key) {
26484
26888
  const decipher = createDecipheriv("aes-128-ecb", key, null);
@@ -26577,14 +26981,14 @@ async function uploadCiphertext(params) {
26577
26981
  }
26578
26982
  var CDN_BASE_URL, UPLOAD_MAX_RETRIES;
26579
26983
  var init_cdn = __esm({
26580
- "packages/server/dist/channels/wechat/cdn.js"() {
26984
+ "../server/dist/channels/wechat/cdn.js"() {
26581
26985
  "use strict";
26582
26986
  CDN_BASE_URL = "https://novac2c.cdn.weixin.qq.com/c2c";
26583
26987
  UPLOAD_MAX_RETRIES = 3;
26584
26988
  }
26585
26989
  });
26586
26990
 
26587
- // packages/server/dist/channels/wechat/send-media.js
26991
+ // ../server/dist/channels/wechat/send-media.js
26588
26992
  import fs54 from "node:fs/promises";
26589
26993
  import path62 from "node:path";
26590
26994
  function inferKind(filePath) {
@@ -26678,7 +27082,7 @@ function buildMessageItem(args) {
26678
27082
  };
26679
27083
  }
26680
27084
  var init_send_media = __esm({
26681
- "packages/server/dist/channels/wechat/send-media.js"() {
27085
+ "../server/dist/channels/wechat/send-media.js"() {
26682
27086
  "use strict";
26683
27087
  init_api();
26684
27088
  init_cdn();
@@ -26687,7 +27091,7 @@ var init_send_media = __esm({
26687
27091
  }
26688
27092
  });
26689
27093
 
26690
- // packages/server/dist/channels/wechat/login.js
27094
+ // ../server/dist/channels/wechat/login.js
26691
27095
  import { randomUUID as randomUUID2 } from "node:crypto";
26692
27096
  function isFresh(l) {
26693
27097
  return Date.now() - l.startedAt < ACTIVE_TTL_MS;
@@ -26789,7 +27193,7 @@ async function waitLogin(params) {
26789
27193
  }
26790
27194
  var ACTIVE_TTL_MS, MAX_QR_REFRESH, activeLogins;
26791
27195
  var init_login = __esm({
26792
- "packages/server/dist/channels/wechat/login.js"() {
27196
+ "../server/dist/channels/wechat/login.js"() {
26793
27197
  "use strict";
26794
27198
  init_api();
26795
27199
  ACTIVE_TTL_MS = 5 * 6e4;
@@ -26798,7 +27202,7 @@ var init_login = __esm({
26798
27202
  }
26799
27203
  });
26800
27204
 
26801
- // packages/server/dist/channels/wechat/handler.js
27205
+ // ../server/dist/channels/wechat/handler.js
26802
27206
  import fs55 from "node:fs";
26803
27207
  import path63 from "node:path";
26804
27208
  import QRCode from "qrcode";
@@ -26841,7 +27245,7 @@ function startWechatChannel(deps) {
26841
27245
  if (!route)
26842
27246
  return;
26843
27247
  if (!isMediaPathAllowed(filePath, account.workspacePath)) {
26844
- console.log(`[WeChat] sendMedia blocked: ${filePath} not under workspace`);
27248
+ console.warn(`[WeChat] sendMedia blocked: ${filePath} not under workspace`);
26845
27249
  return;
26846
27250
  }
26847
27251
  await sendMediaFile({
@@ -27256,7 +27660,7 @@ function sleep2(ms, signal) {
27256
27660
  }
27257
27661
  var MAX_CONSECUTIVE_FAILURES, BACKOFF_DELAY_MS, RETRY_DELAY_MS;
27258
27662
  var init_handler4 = __esm({
27259
- "packages/server/dist/channels/wechat/handler.js"() {
27663
+ "../server/dist/channels/wechat/handler.js"() {
27260
27664
  "use strict";
27261
27665
  init_api();
27262
27666
  init_types();
@@ -27278,7 +27682,7 @@ var init_handler4 = __esm({
27278
27682
  }
27279
27683
  });
27280
27684
 
27281
- // packages/server/dist/routes/wechat.js
27685
+ // ../server/dist/routes/wechat.js
27282
27686
  import { Hono as Hono16 } from "hono";
27283
27687
  import path64 from "node:path";
27284
27688
  import fs56 from "node:fs";
@@ -27393,7 +27797,7 @@ function stripSecrets(acc) {
27393
27797
  return rest;
27394
27798
  }
27395
27799
  var init_wechat = __esm({
27396
- "packages/server/dist/routes/wechat.js"() {
27800
+ "../server/dist/routes/wechat.js"() {
27397
27801
  "use strict";
27398
27802
  init_login();
27399
27803
  init_accounts4();
@@ -27401,7 +27805,7 @@ var init_wechat = __esm({
27401
27805
  }
27402
27806
  });
27403
27807
 
27404
- // packages/server/dist/channels/wechat/cron-dispatcher.js
27808
+ // ../server/dist/channels/wechat/cron-dispatcher.js
27405
27809
  function readLastActiveChatId(accountId) {
27406
27810
  const acct = getAccount(getChannelDb(), accountId);
27407
27811
  if (!acct)
@@ -27482,7 +27886,7 @@ function registerWechatCronDispatcher() {
27482
27886
  registerCronDispatcher({ channelType: "wechat", supportsMedia: true, dispatch: dispatch2, listTargets: listTargets2 });
27483
27887
  }
27484
27888
  var init_cron_dispatcher2 = __esm({
27485
- "packages/server/dist/channels/wechat/cron-dispatcher.js"() {
27889
+ "../server/dist/channels/wechat/cron-dispatcher.js"() {
27486
27890
  "use strict";
27487
27891
  init_channel_db();
27488
27892
  init_accounts();
@@ -27496,10 +27900,10 @@ var init_cron_dispatcher2 = __esm({
27496
27900
  }
27497
27901
  });
27498
27902
 
27499
- // packages/server/dist/channels/wechat/descriptor.js
27903
+ // ../server/dist/channels/wechat/descriptor.js
27500
27904
  var wechatDescriptor;
27501
27905
  var init_descriptor2 = __esm({
27502
- "packages/server/dist/channels/wechat/descriptor.js"() {
27906
+ "../server/dist/channels/wechat/descriptor.js"() {
27503
27907
  "use strict";
27504
27908
  init_handler4();
27505
27909
  init_wechat();
@@ -27514,7 +27918,7 @@ var init_descriptor2 = __esm({
27514
27918
  }
27515
27919
  });
27516
27920
 
27517
- // packages/server/dist/routes/web.js
27921
+ // ../server/dist/routes/web.js
27518
27922
  import { Hono as Hono17 } from "hono";
27519
27923
  import { streamSSE } from "hono/streaming";
27520
27924
  import crypto4 from "node:crypto";
@@ -27751,7 +28155,7 @@ function createWebRoutes(deps) {
27751
28155
  return app2;
27752
28156
  }
27753
28157
  var init_web = __esm({
27754
- "packages/server/dist/routes/web.js"() {
28158
+ "../server/dist/routes/web.js"() {
27755
28159
  "use strict";
27756
28160
  init_dist();
27757
28161
  init_handler();
@@ -27763,10 +28167,10 @@ var init_web = __esm({
27763
28167
  }
27764
28168
  });
27765
28169
 
27766
- // packages/server/dist/channels/web/descriptor.js
28170
+ // ../server/dist/channels/web/descriptor.js
27767
28171
  var webDescriptor;
27768
28172
  var init_descriptor3 = __esm({
27769
- "packages/server/dist/channels/web/descriptor.js"() {
28173
+ "../server/dist/channels/web/descriptor.js"() {
27770
28174
  "use strict";
27771
28175
  init_handler();
27772
28176
  init_web();
@@ -27782,7 +28186,7 @@ var init_descriptor3 = __esm({
27782
28186
  }
27783
28187
  });
27784
28188
 
27785
- // packages/server/dist/channels/slack/accounts.js
28189
+ // ../server/dist/channels/slack/accounts.js
27786
28190
  function toSlack(a) {
27787
28191
  const c = a.config;
27788
28192
  return {
@@ -27858,14 +28262,14 @@ function deleteAccount5(db, accountId) {
27858
28262
  }
27859
28263
  var CH4;
27860
28264
  var init_accounts5 = __esm({
27861
- "packages/server/dist/channels/slack/accounts.js"() {
28265
+ "../server/dist/channels/slack/accounts.js"() {
27862
28266
  "use strict";
27863
28267
  init_accounts();
27864
28268
  CH4 = "slack";
27865
28269
  }
27866
28270
  });
27867
28271
 
27868
- // packages/server/dist/channels/shared/markdown.js
28272
+ // ../server/dist/channels/shared/markdown.js
27869
28273
  function formatForSlack(input) {
27870
28274
  if (!input)
27871
28275
  return "";
@@ -27944,15 +28348,15 @@ function stripCommonMark(line) {
27944
28348
  return line;
27945
28349
  }
27946
28350
  var init_markdown = __esm({
27947
- "packages/server/dist/channels/shared/markdown.js"() {
28351
+ "../server/dist/channels/shared/markdown.js"() {
27948
28352
  "use strict";
27949
28353
  }
27950
28354
  });
27951
28355
 
27952
- // packages/server/dist/channels/slack/event-adapter.js
28356
+ // ../server/dist/channels/slack/event-adapter.js
27953
28357
  var HARD_CHARS2, SlackResponder;
27954
28358
  var init_event_adapter3 = __esm({
27955
- "packages/server/dist/channels/slack/event-adapter.js"() {
28359
+ "../server/dist/channels/slack/event-adapter.js"() {
27956
28360
  "use strict";
27957
28361
  init_chunk();
27958
28362
  init_markdown();
@@ -28045,7 +28449,7 @@ var init_event_adapter3 = __esm({
28045
28449
  }
28046
28450
  });
28047
28451
 
28048
- // packages/server/dist/channels/slack/api.js
28452
+ // ../server/dist/channels/slack/api.js
28049
28453
  async function slackPost(endpoint, token, body) {
28050
28454
  const isForm = body instanceof FormData;
28051
28455
  const res = await fetch(`${SLACK_API}/${endpoint}`, {
@@ -28233,13 +28637,13 @@ async function downloadFile(botToken, urlPrivate) {
28233
28637
  }
28234
28638
  var SLACK_API;
28235
28639
  var init_api2 = __esm({
28236
- "packages/server/dist/channels/slack/api.js"() {
28640
+ "../server/dist/channels/slack/api.js"() {
28237
28641
  "use strict";
28238
28642
  SLACK_API = "https://slack.com/api";
28239
28643
  }
28240
28644
  });
28241
28645
 
28242
- // packages/server/dist/channels/slack/handler.js
28646
+ // ../server/dist/channels/slack/handler.js
28243
28647
  import path65 from "node:path";
28244
28648
  import { WebSocket } from "ws";
28245
28649
  function slashToBang(text6, commandNames) {
@@ -28347,7 +28751,7 @@ function startSlackChannel(deps) {
28347
28751
  return;
28348
28752
  const resolved = path65.resolve(filePath);
28349
28753
  if (!isMediaPathAllowed(resolved, account.workspacePath)) {
28350
- console.log(`[Slack] sendMedia blocked: ${filePath} not under workspace`);
28754
+ console.warn(`[Slack] sendMedia blocked: ${filePath} not under workspace`);
28351
28755
  return;
28352
28756
  }
28353
28757
  try {
@@ -28602,7 +29006,7 @@ function buildCmdCtx(args) {
28602
29006
  }
28603
29007
  var SLACK_EXTRA_COMMANDS, SEEN_EVENT_IDS, SEEN_EVENT_IDS_MAX;
28604
29008
  var init_handler5 = __esm({
28605
- "packages/server/dist/channels/slack/handler.js"() {
29009
+ "../server/dist/channels/slack/handler.js"() {
28606
29010
  "use strict";
28607
29011
  init_accounts5();
28608
29012
  init_event_adapter3();
@@ -28622,7 +29026,7 @@ var init_handler5 = __esm({
28622
29026
  }
28623
29027
  });
28624
29028
 
28625
- // packages/server/dist/routes/slack.js
29029
+ // ../server/dist/routes/slack.js
28626
29030
  import { Hono as Hono18 } from "hono";
28627
29031
  import fs58 from "node:fs";
28628
29032
  function createSlackRoutes(deps) {
@@ -28756,7 +29160,7 @@ function createSlackRoutes(deps) {
28756
29160
  return app2;
28757
29161
  }
28758
29162
  var init_slack = __esm({
28759
- "packages/server/dist/routes/slack.js"() {
29163
+ "../server/dist/routes/slack.js"() {
28760
29164
  "use strict";
28761
29165
  init_accounts5();
28762
29166
  init_accounts();
@@ -28764,7 +29168,7 @@ var init_slack = __esm({
28764
29168
  }
28765
29169
  });
28766
29170
 
28767
- // packages/server/dist/channels/slack/cron-dispatcher.js
29171
+ // ../server/dist/channels/slack/cron-dispatcher.js
28768
29172
  function parseChatId(raw) {
28769
29173
  const idx = raw.indexOf(":");
28770
29174
  if (idx < 0)
@@ -28828,7 +29232,7 @@ function registerSlackCronDispatcher() {
28828
29232
  registerCronDispatcher({ channelType: "slack", supportsMedia: true, dispatch: dispatch3, listTargets: listTargets3 });
28829
29233
  }
28830
29234
  var init_cron_dispatcher3 = __esm({
28831
- "packages/server/dist/channels/slack/cron-dispatcher.js"() {
29235
+ "../server/dist/channels/slack/cron-dispatcher.js"() {
28832
29236
  "use strict";
28833
29237
  init_channel_db();
28834
29238
  init_accounts5();
@@ -28838,10 +29242,10 @@ var init_cron_dispatcher3 = __esm({
28838
29242
  }
28839
29243
  });
28840
29244
 
28841
- // packages/server/dist/channels/slack/descriptor.js
29245
+ // ../server/dist/channels/slack/descriptor.js
28842
29246
  var slackDescriptor;
28843
29247
  var init_descriptor4 = __esm({
28844
- "packages/server/dist/channels/slack/descriptor.js"() {
29248
+ "../server/dist/channels/slack/descriptor.js"() {
28845
29249
  "use strict";
28846
29250
  init_handler5();
28847
29251
  init_slack();
@@ -28856,7 +29260,7 @@ var init_descriptor4 = __esm({
28856
29260
  }
28857
29261
  });
28858
29262
 
28859
- // packages/server/dist/channels/feishu/accounts.js
29263
+ // ../server/dist/channels/feishu/accounts.js
28860
29264
  function toFeishu(a) {
28861
29265
  const c = a.config;
28862
29266
  return {
@@ -28934,17 +29338,17 @@ function deleteAccount6(db, accountId) {
28934
29338
  }
28935
29339
  var CH5;
28936
29340
  var init_accounts6 = __esm({
28937
- "packages/server/dist/channels/feishu/accounts.js"() {
29341
+ "../server/dist/channels/feishu/accounts.js"() {
28938
29342
  "use strict";
28939
29343
  init_accounts();
28940
29344
  CH5 = "feishu";
28941
29345
  }
28942
29346
  });
28943
29347
 
28944
- // packages/server/dist/channels/feishu/event-adapter.js
29348
+ // ../server/dist/channels/feishu/event-adapter.js
28945
29349
  var HARD_CHARS3, FeishuResponder;
28946
29350
  var init_event_adapter4 = __esm({
28947
- "packages/server/dist/channels/feishu/event-adapter.js"() {
29351
+ "../server/dist/channels/feishu/event-adapter.js"() {
28948
29352
  "use strict";
28949
29353
  init_chunk();
28950
29354
  init_markdown();
@@ -29037,7 +29441,7 @@ var init_event_adapter4 = __esm({
29037
29441
  }
29038
29442
  });
29039
29443
 
29040
- // packages/server/dist/channels/feishu/api.js
29444
+ // ../server/dist/channels/feishu/api.js
29041
29445
  async function getTenantAccessToken(args) {
29042
29446
  const cached = tokenCache.get(args.appId);
29043
29447
  if (cached && cached.expiresAt - Date.now() > 6e4)
@@ -29301,14 +29705,14 @@ async function searchFeishuTargets(args) {
29301
29705
  }
29302
29706
  var FEISHU_BASE, tokenCache;
29303
29707
  var init_api3 = __esm({
29304
- "packages/server/dist/channels/feishu/api.js"() {
29708
+ "../server/dist/channels/feishu/api.js"() {
29305
29709
  "use strict";
29306
29710
  FEISHU_BASE = "https://open.feishu.cn";
29307
29711
  tokenCache = /* @__PURE__ */ new Map();
29308
29712
  }
29309
29713
  });
29310
29714
 
29311
- // packages/server/dist/channels/feishu/handler.js
29715
+ // ../server/dist/channels/feishu/handler.js
29312
29716
  import path66 from "node:path";
29313
29717
  import * as Lark from "@larksuiteoapi/node-sdk";
29314
29718
  function buildSessionPrefixForThread2(chatId, rootId) {
@@ -29493,7 +29897,7 @@ function startFeishuChannel(deps) {
29493
29897
  return;
29494
29898
  const resolved = path66.resolve(filePath);
29495
29899
  if (!isMediaPathAllowed(resolved, account.workspacePath)) {
29496
- console.log(`[Feishu] sendMedia blocked: ${filePath} not under workspace`);
29900
+ console.warn(`[Feishu] sendMedia blocked: ${filePath} not under workspace`);
29497
29901
  return;
29498
29902
  }
29499
29903
  try {
@@ -29781,7 +30185,7 @@ function buildCmdCtx2(args) {
29781
30185
  }
29782
30186
  var MAX_FEISHU_DOWNLOAD_BYTES;
29783
30187
  var init_handler6 = __esm({
29784
- "packages/server/dist/channels/feishu/handler.js"() {
30188
+ "../server/dist/channels/feishu/handler.js"() {
29785
30189
  "use strict";
29786
30190
  init_accounts6();
29787
30191
  init_event_adapter4();
@@ -29797,7 +30201,7 @@ var init_handler6 = __esm({
29797
30201
  }
29798
30202
  });
29799
30203
 
29800
- // packages/server/dist/routes/feishu.js
30204
+ // ../server/dist/routes/feishu.js
29801
30205
  import { Hono as Hono19 } from "hono";
29802
30206
  import fs59 from "node:fs";
29803
30207
  function createFeishuRoutes(deps) {
@@ -29934,7 +30338,7 @@ function createFeishuRoutes(deps) {
29934
30338
  return app2;
29935
30339
  }
29936
30340
  var init_feishu = __esm({
29937
- "packages/server/dist/routes/feishu.js"() {
30341
+ "../server/dist/routes/feishu.js"() {
29938
30342
  "use strict";
29939
30343
  init_accounts6();
29940
30344
  init_accounts();
@@ -29942,7 +30346,7 @@ var init_feishu = __esm({
29942
30346
  }
29943
30347
  });
29944
30348
 
29945
- // packages/server/dist/channels/feishu/cron-dispatcher.js
30349
+ // ../server/dist/channels/feishu/cron-dispatcher.js
29946
30350
  function parseChatId2(raw) {
29947
30351
  const idx = raw.indexOf(":");
29948
30352
  return { chatId: idx < 0 ? raw : raw.slice(0, idx) };
@@ -29992,7 +30396,7 @@ function registerFeishuCronDispatcher() {
29992
30396
  registerCronDispatcher({ channelType: "feishu", dispatch: dispatch4, listTargets: listTargets4 });
29993
30397
  }
29994
30398
  var init_cron_dispatcher4 = __esm({
29995
- "packages/server/dist/channels/feishu/cron-dispatcher.js"() {
30399
+ "../server/dist/channels/feishu/cron-dispatcher.js"() {
29996
30400
  "use strict";
29997
30401
  init_channel_db();
29998
30402
  init_accounts6();
@@ -30001,10 +30405,10 @@ var init_cron_dispatcher4 = __esm({
30001
30405
  }
30002
30406
  });
30003
30407
 
30004
- // packages/server/dist/channels/feishu/descriptor.js
30408
+ // ../server/dist/channels/feishu/descriptor.js
30005
30409
  var feishuDescriptor;
30006
30410
  var init_descriptor5 = __esm({
30007
- "packages/server/dist/channels/feishu/descriptor.js"() {
30411
+ "../server/dist/channels/feishu/descriptor.js"() {
30008
30412
  "use strict";
30009
30413
  init_handler6();
30010
30414
  init_feishu();
@@ -30019,7 +30423,7 @@ var init_descriptor5 = __esm({
30019
30423
  }
30020
30424
  });
30021
30425
 
30022
- // packages/server/dist/channels/wecom/accounts.js
30426
+ // ../server/dist/channels/wecom/accounts.js
30023
30427
  function toWecom(a) {
30024
30428
  const c = a.config;
30025
30429
  return {
@@ -30094,17 +30498,17 @@ function deleteAccount7(db, accountId) {
30094
30498
  }
30095
30499
  var CH6;
30096
30500
  var init_accounts7 = __esm({
30097
- "packages/server/dist/channels/wecom/accounts.js"() {
30501
+ "../server/dist/channels/wecom/accounts.js"() {
30098
30502
  "use strict";
30099
30503
  init_accounts();
30100
30504
  CH6 = "wecom";
30101
30505
  }
30102
30506
  });
30103
30507
 
30104
- // packages/server/dist/channels/wecom/event-adapter.js
30508
+ // ../server/dist/channels/wecom/event-adapter.js
30105
30509
  var HARD_CHARS4, WecomResponder;
30106
30510
  var init_event_adapter5 = __esm({
30107
- "packages/server/dist/channels/wecom/event-adapter.js"() {
30511
+ "../server/dist/channels/wecom/event-adapter.js"() {
30108
30512
  "use strict";
30109
30513
  init_chunk();
30110
30514
  init_media();
@@ -30195,7 +30599,7 @@ var init_event_adapter5 = __esm({
30195
30599
  }
30196
30600
  });
30197
30601
 
30198
- // packages/server/dist/channels/wecom/handler.js
30602
+ // ../server/dist/channels/wecom/handler.js
30199
30603
  import path67 from "node:path";
30200
30604
  import fs60 from "node:fs/promises";
30201
30605
  import { WSClient as WSClient2, generateReqId } from "@wecom/aibot-node-sdk";
@@ -30356,7 +30760,7 @@ function startWecomChannel(deps) {
30356
30760
  return;
30357
30761
  const resolved = path67.resolve(filePath);
30358
30762
  if (!isMediaPathAllowed(resolved, account.workspacePath)) {
30359
- console.log(`[WeCom] sendMedia blocked: ${filePath} not under workspace`);
30763
+ console.warn(`[WeCom] sendMedia blocked: ${filePath} not under workspace`);
30360
30764
  return;
30361
30765
  }
30362
30766
  try {
@@ -30564,7 +30968,7 @@ function buildCmdCtx3(args) {
30564
30968
  }
30565
30969
  var liveClients, DEDUPE_CAP, MAX_WECOM_DOWNLOAD_BYTES;
30566
30970
  var init_handler7 = __esm({
30567
- "packages/server/dist/channels/wecom/handler.js"() {
30971
+ "../server/dist/channels/wecom/handler.js"() {
30568
30972
  "use strict";
30569
30973
  init_accounts7();
30570
30974
  init_event_adapter5();
@@ -30580,7 +30984,7 @@ var init_handler7 = __esm({
30580
30984
  }
30581
30985
  });
30582
30986
 
30583
- // packages/server/dist/routes/wecom.js
30987
+ // ../server/dist/routes/wecom.js
30584
30988
  import { Hono as Hono20 } from "hono";
30585
30989
  import fs61 from "node:fs";
30586
30990
  function createWecomRoutes(deps) {
@@ -30687,14 +31091,14 @@ function createWecomRoutes(deps) {
30687
31091
  return app2;
30688
31092
  }
30689
31093
  var init_wecom = __esm({
30690
- "packages/server/dist/routes/wecom.js"() {
31094
+ "../server/dist/routes/wecom.js"() {
30691
31095
  "use strict";
30692
31096
  init_accounts7();
30693
31097
  init_accounts();
30694
31098
  }
30695
31099
  });
30696
31100
 
30697
- // packages/server/dist/channels/wecom/cron-dispatcher.js
31101
+ // ../server/dist/channels/wecom/cron-dispatcher.js
30698
31102
  async function dispatch5(accountId, text6, explicitChatId) {
30699
31103
  const acct = getAccount7(getChannelDb(), accountId);
30700
31104
  if (!acct)
@@ -30736,7 +31140,7 @@ function registerWecomCronDispatcher() {
30736
31140
  registerCronDispatcher({ channelType: "wecom", dispatch: dispatch5, listTargets: listTargets5 });
30737
31141
  }
30738
31142
  var init_cron_dispatcher5 = __esm({
30739
- "packages/server/dist/channels/wecom/cron-dispatcher.js"() {
31143
+ "../server/dist/channels/wecom/cron-dispatcher.js"() {
30740
31144
  "use strict";
30741
31145
  init_channel_db();
30742
31146
  init_accounts7();
@@ -30745,10 +31149,10 @@ var init_cron_dispatcher5 = __esm({
30745
31149
  }
30746
31150
  });
30747
31151
 
30748
- // packages/server/dist/channels/wecom/descriptor.js
31152
+ // ../server/dist/channels/wecom/descriptor.js
30749
31153
  var wecomDescriptor;
30750
31154
  var init_descriptor6 = __esm({
30751
- "packages/server/dist/channels/wecom/descriptor.js"() {
31155
+ "../server/dist/channels/wecom/descriptor.js"() {
30752
31156
  "use strict";
30753
31157
  init_handler7();
30754
31158
  init_wecom();
@@ -30763,10 +31167,10 @@ var init_descriptor6 = __esm({
30763
31167
  }
30764
31168
  });
30765
31169
 
30766
- // packages/server/dist/channels/descriptors.js
31170
+ // ../server/dist/channels/descriptors.js
30767
31171
  var defaultChannelDescriptors;
30768
31172
  var init_descriptors = __esm({
30769
- "packages/server/dist/channels/descriptors.js"() {
31173
+ "../server/dist/channels/descriptors.js"() {
30770
31174
  "use strict";
30771
31175
  init_descriptor();
30772
31176
  init_descriptor2();
@@ -30785,7 +31189,7 @@ var init_descriptors = __esm({
30785
31189
  }
30786
31190
  });
30787
31191
 
30788
- // packages/server/dist/middleware/auth.js
31192
+ // ../server/dist/middleware/auth.js
30789
31193
  import { Hono as Hono21 } from "hono";
30790
31194
  import { getCookie, setCookie } from "hono/cookie";
30791
31195
  import crypto5 from "node:crypto";
@@ -30978,7 +31382,7 @@ function authMiddleware() {
30978
31382
  }
30979
31383
  var TOKEN_MAX_AGE, REFRESH_AFTER, COOKIE_NAME, ADMIN_LOGIN_BUCKET, isLockedOut2, recordFailure2, clearFailures2, PUBLIC_PATHS;
30980
31384
  var init_auth = __esm({
30981
- "packages/server/dist/middleware/auth.js"() {
31385
+ "../server/dist/middleware/auth.js"() {
30982
31386
  "use strict";
30983
31387
  init_config();
30984
31388
  init_password_hash();
@@ -30995,7 +31399,7 @@ var init_auth = __esm({
30995
31399
  }
30996
31400
  });
30997
31401
 
30998
- // packages/server/dist/index.js
31402
+ // ../server/dist/index.js
30999
31403
  var dist_exports = {};
31000
31404
  import { Hono as Hono22 } from "hono";
31001
31405
  import { cors } from "hono/cors";
@@ -31124,7 +31528,7 @@ async function gracefulShutdown(signal) {
31124
31528
  }
31125
31529
  var __dirname3, PORT, HALO_VERSION, PROJECT_ROOT, HALO_HOME4, GIT_SHA, AGENTCORE, app, allowlist, authRoutes, fileRoutes, dataPreviewRoutes, gitRoutes, agentConfigRoutes, skillRoutes, settingsRoutes, evolutionRoutes, cronRoutes, channelDb, registry, sessionRoutes, sessionArchiveRoutes, showRoutes, metricsRoutes, commandRoutes, FRONTEND_DIR, server, wss;
31126
31530
  var init_dist2 = __esm({
31127
- async "packages/server/dist/index.js"() {
31531
+ async "../server/dist/index.js"() {
31128
31532
  "use strict";
31129
31533
  init_files();
31130
31534
  init_data_preview();
@@ -31166,7 +31570,7 @@ var init_dist2 = __esm({
31166
31570
  init_git_ssh();
31167
31571
  __dirname3 = path68.dirname(fileURLToPath3(import.meta.url));
31168
31572
  PORT = config.server.port;
31169
- HALO_VERSION = "1.3.4";
31573
+ HALO_VERSION = "1.4.1";
31170
31574
  PROJECT_ROOT = findProjectRoot();
31171
31575
  HALO_HOME4 = path68.join(homedir24(), ".halo");
31172
31576
  GIT_SHA = readGitSha();
@@ -31213,7 +31617,7 @@ var init_dist2 = __esm({
31213
31617
  const { hiddenDirs, hiddenFiles, writableDirs } = reloadSandboxConfig();
31214
31618
  setSandboxHiddenPaths(hiddenDirs, hiddenFiles, writableDirs);
31215
31619
  });
31216
- console.log(`[Server] bwrap sandbox: ${isBwrapCached() ? "available" : "NOT available (app-level fallback only)"}`);
31620
+ console.log(`[Server] OS sandbox: ${getSandboxBackend() ?? "NOT available (non-full sessions: no shell_exec, file tools path-checked in-process)"}`);
31217
31621
  ensureSshAgent();
31218
31622
  console.log(`[Server] Halo home: ${HALO_HOME4}`);
31219
31623
  console.log("[Server] Services initialized (ModelRuntime)");
@@ -31242,7 +31646,10 @@ var init_dist2 = __esm({
31242
31646
  uptime: process.uptime(),
31243
31647
  engine: "agent",
31244
31648
  version: HALO_VERSION,
31245
- gitSha: GIT_SHA
31649
+ gitSha: GIT_SHA,
31650
+ // OS sandbox backing non-full access levels; null → admin locks the
31651
+ // access-level selector to Full.
31652
+ sandbox: getSandboxBackend()
31246
31653
  });
31247
31654
  });
31248
31655
  fileRoutes = createFileRoutes();
@@ -31273,6 +31680,7 @@ var init_dist2 = __esm({
31273
31680
  }
31274
31681
  registry = new SessionManagerRegistry({ reconcileOrphansOnBoot: true });
31275
31682
  setRelayRegistry(registry);
31683
+ setCronSessionRegistry(registry);
31276
31684
  for (const ws of listRunningWorkspaces()) {
31277
31685
  if (!fs62.existsSync(path68.join(ws, ".halo")))
31278
31686
  continue;
@@ -31357,7 +31765,7 @@ var init_dist2 = __esm({
31357
31765
  }
31358
31766
  });
31359
31767
 
31360
- // packages/acp-adapter/dist/halo-client.js
31768
+ // ../acp-adapter/dist/halo-client.js
31361
31769
  async function safeText(res) {
31362
31770
  try {
31363
31771
  return (await res.text()).slice(0, 500);
@@ -31400,7 +31808,7 @@ async function* parseSseStream(body) {
31400
31808
  }
31401
31809
  var HaloClient;
31402
31810
  var init_halo_client = __esm({
31403
- "packages/acp-adapter/dist/halo-client.js"() {
31811
+ "../acp-adapter/dist/halo-client.js"() {
31404
31812
  "use strict";
31405
31813
  HaloClient = class {
31406
31814
  opts;
@@ -31500,7 +31908,7 @@ var init_halo_client = __esm({
31500
31908
  }
31501
31909
  });
31502
31910
 
31503
- // packages/acp-adapter/dist/adapter.js
31911
+ // ../acp-adapter/dist/adapter.js
31504
31912
  function newError(message, code = -32603) {
31505
31913
  const e = new Error(message);
31506
31914
  e.code = code;
@@ -31508,7 +31916,7 @@ function newError(message, code = -32603) {
31508
31916
  }
31509
31917
  var AcpAdapter;
31510
31918
  var init_adapter = __esm({
31511
- "packages/acp-adapter/dist/adapter.js"() {
31919
+ "../acp-adapter/dist/adapter.js"() {
31512
31920
  "use strict";
31513
31921
  init_halo_client();
31514
31922
  AcpAdapter = class {
@@ -31795,10 +32203,10 @@ var init_adapter = __esm({
31795
32203
  }
31796
32204
  });
31797
32205
 
31798
- // packages/acp-adapter/dist/jsonrpc.js
32206
+ // ../acp-adapter/dist/jsonrpc.js
31799
32207
  var ERROR_PARSE, ERROR_METHOD_NOT_FOUND, ERROR_INTERNAL, JsonRpcConnection;
31800
32208
  var init_jsonrpc = __esm({
31801
- "packages/acp-adapter/dist/jsonrpc.js"() {
32209
+ "../acp-adapter/dist/jsonrpc.js"() {
31802
32210
  "use strict";
31803
32211
  ERROR_PARSE = -32700;
31804
32212
  ERROR_METHOD_NOT_FOUND = -32601;
@@ -31931,7 +32339,7 @@ var init_jsonrpc = __esm({
31931
32339
  }
31932
32340
  });
31933
32341
 
31934
- // packages/acp-adapter/dist/index.js
32342
+ // ../acp-adapter/dist/index.js
31935
32343
  var dist_exports2 = {};
31936
32344
  __export(dist_exports2, {
31937
32345
  main: () => main
@@ -32047,7 +32455,7 @@ function main(argv = process.argv.slice(2)) {
32047
32455
  }
32048
32456
  var HELP;
32049
32457
  var init_dist3 = __esm({
32050
- "packages/acp-adapter/dist/index.js"() {
32458
+ "../acp-adapter/dist/index.js"() {
32051
32459
  "use strict";
32052
32460
  init_adapter();
32053
32461
  init_jsonrpc();
@@ -32086,7 +32494,7 @@ Stdio:
32086
32494
  }
32087
32495
  });
32088
32496
 
32089
- // packages/cli/src/silence-warnings.ts
32497
+ // src/silence-warnings.ts
32090
32498
  var emit = process.emitWarning.bind(process);
32091
32499
  process.emitWarning = (warning, ...args) => {
32092
32500
  const opt = args[0];
@@ -32095,13 +32503,13 @@ process.emitWarning = (warning, ...args) => {
32095
32503
  return emit(warning, ...args);
32096
32504
  };
32097
32505
 
32098
- // packages/cli/src/index.ts
32506
+ // src/index.ts
32099
32507
  init_server_supervisor();
32100
32508
  import path69 from "node:path";
32101
32509
  import fs63 from "node:fs";
32102
32510
  import { homedir as homedir25 } from "node:os";
32103
32511
  import { parseArgs as parseArgs2 } from "node:util";
32104
- var VERSION = "1.3.4";
32512
+ var VERSION = "1.4.1";
32105
32513
  var HELP_TOP = `Usage: halo <command> [options]
32106
32514
 
32107
32515
  Commands: