@askexenow/exe-os 0.9.77 → 0.9.78

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 (72) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +2 -2
  2. package/dist/bin/agentic-reflection-backfill.js +2 -2
  3. package/dist/bin/agentic-semantic-label.js +2 -2
  4. package/dist/bin/backfill-conversations.js +2 -2
  5. package/dist/bin/backfill-responses.js +2 -2
  6. package/dist/bin/backfill-vectors.js +2 -2
  7. package/dist/bin/bulk-sync-postgres.js +2 -2
  8. package/dist/bin/cleanup-stale-review-tasks.js +2 -2
  9. package/dist/bin/cli.js +759 -524
  10. package/dist/bin/customer-readiness.js +19 -0
  11. package/dist/bin/exe-agent.js +2 -2
  12. package/dist/bin/exe-assign.js +2 -2
  13. package/dist/bin/exe-boot.js +2 -2
  14. package/dist/bin/exe-call.js +2 -2
  15. package/dist/bin/exe-cloud.js +2 -2
  16. package/dist/bin/exe-dispatch.js +2 -2
  17. package/dist/bin/exe-doctor.js +2 -2
  18. package/dist/bin/exe-export-behaviors.js +2 -2
  19. package/dist/bin/exe-forget.js +2 -2
  20. package/dist/bin/exe-gateway.js +158 -16
  21. package/dist/bin/exe-heartbeat.js +2 -2
  22. package/dist/bin/exe-kill.js +2 -2
  23. package/dist/bin/exe-launch-agent.js +2 -2
  24. package/dist/bin/exe-new-employee.js +2 -2
  25. package/dist/bin/exe-pending-messages.js +2 -2
  26. package/dist/bin/exe-pending-notifications.js +2 -2
  27. package/dist/bin/exe-pending-reviews.js +2 -2
  28. package/dist/bin/exe-rename.js +2 -2
  29. package/dist/bin/exe-review.js +2 -2
  30. package/dist/bin/exe-search.js +2 -2
  31. package/dist/bin/exe-session-cleanup.js +2 -2
  32. package/dist/bin/exe-start-codex.js +2 -2
  33. package/dist/bin/exe-start-opencode.js +2 -2
  34. package/dist/bin/exe-status.js +2 -2
  35. package/dist/bin/exe-support.js +461 -0
  36. package/dist/bin/exe-team.js +2 -2
  37. package/dist/bin/git-sweep.js +2 -2
  38. package/dist/bin/graph-backfill.js +2 -2
  39. package/dist/bin/graph-export.js +2 -2
  40. package/dist/bin/intercom-check.js +2 -2
  41. package/dist/bin/scan-tasks.js +2 -2
  42. package/dist/bin/setup.js +3 -2
  43. package/dist/bin/shard-migrate.js +2 -2
  44. package/dist/bin/update.js +9 -0
  45. package/dist/gateway/index.js +2 -2
  46. package/dist/hooks/bug-report-worker.js +2 -2
  47. package/dist/hooks/codex-stop-task-finalizer.js +2 -2
  48. package/dist/hooks/commit-complete.js +2 -2
  49. package/dist/hooks/error-recall.js +2 -2
  50. package/dist/hooks/ingest.js +2 -2
  51. package/dist/hooks/instructions-loaded.js +2 -2
  52. package/dist/hooks/notification.js +2 -2
  53. package/dist/hooks/post-compact.js +2 -2
  54. package/dist/hooks/post-tool-combined.js +2 -2
  55. package/dist/hooks/pre-compact.js +2 -2
  56. package/dist/hooks/pre-tool-use.js +2 -2
  57. package/dist/hooks/prompt-submit.js +2 -2
  58. package/dist/hooks/session-end.js +2 -2
  59. package/dist/hooks/session-start.js +2 -2
  60. package/dist/hooks/stop.js +2 -2
  61. package/dist/hooks/subagent-stop.js +2 -2
  62. package/dist/hooks/summary-worker.js +2 -2
  63. package/dist/index.js +2 -2
  64. package/dist/lib/employee-templates.js +2 -2
  65. package/dist/lib/exe-daemon.js +28 -16
  66. package/dist/lib/hybrid-search.js +2 -2
  67. package/dist/lib/schedules.js +2 -2
  68. package/dist/lib/store.js +2 -2
  69. package/dist/mcp/server.js +27 -15
  70. package/dist/runtime/index.js +2 -2
  71. package/dist/tui/App.js +2 -2
  72. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -2619,8 +2619,8 @@ function deriveMachineKey() {
2619
2619
  }
2620
2620
  function readMachineId() {
2621
2621
  try {
2622
- const { readFileSync: readFileSync36 } = __require("fs");
2623
- return readFileSync36("/etc/machine-id", "utf-8").trim();
2622
+ const { readFileSync: readFileSync37 } = __require("fs");
2623
+ return readFileSync37("/etc/machine-id", "utf-8").trim();
2624
2624
  } catch {
2625
2625
  return "";
2626
2626
  }
@@ -8667,7 +8667,7 @@ var init_platform_procedures = __esm({
8667
8667
  title: "Customer patch triage \u2014 upstream bug vs customization",
8668
8668
  domain: "support",
8669
8669
  priority: "p0",
8670
- content: "When an agent encounters a suspected Exe OS bug, update breakage, MCP/tool failure, installer issue, memory/orchestration defect, or customer-local patch need, it MUST use create_bug_report. Do this before or alongside any local workaround so the report reaches AskExe support directly via the customer's license. Do NOT ask the founder for permission to file a required bug report. If create_bug_report is deferred/lazy-loaded, load it and call it. If it is unavailable in the live MCP surface, report 'create_bug_report unavailable in this session' and save a local report in exe/output \u2014 never claim the tool does not exist unless the live MCP surface was checked. Classify first: upstream_bug = reproducible exe-os/platform defect; customer_customization = identity, behavior, procedure, config, branding, workflow preference that belongs in customer-owned layers; emergency_hotfix = temporary local patch. For upstream bugs/emergency hotfixes include version, repro steps, expected/actual, files changed, workaround, and local diff summary. Avoid permanent platform-code patches unless founder approves; if a hotfix is unavoidable, document it in the bug report and re-check after npm update."
8670
+ content: "When an agent encounters a suspected Exe OS bug, update breakage, MCP/tool failure, installer issue, memory/orchestration defect, or customer-local patch need, it MUST use create_bug_report. Do this before or alongside any local workaround so the report reaches AskExe support directly via the customer's license. Do NOT ask the founder for permission to file a required bug report. If create_bug_report is deferred/lazy-loaded, load it and call it. If it is unavailable in the live MCP surface, report 'create_bug_report unavailable in this session' and save a local report in exe/output \u2014 never claim the tool does not exist unless the live MCP surface was checked. If upstream delivery fails, run `exe-os support test` and include its result in the local report so AskExe can distinguish customer setup, license provisioning, and server intake issues. Classify first: upstream_bug = reproducible exe-os/platform defect; customer_customization = identity, behavior, procedure, config, branding, workflow preference that belongs in customer-owned layers; emergency_hotfix = temporary local patch. For upstream bugs/emergency hotfixes include version, repro steps, expected/actual, files changed, workaround, and local diff summary. Avoid permanent platform-code patches unless founder approves; if a hotfix is unavoidable, document it in the bug report and re-check after npm update."
8671
8671
  },
8672
8672
  // --- Operations ---
8673
8673
  {
@@ -8749,7 +8749,7 @@ var init_platform_procedures = __esm({
8749
8749
  title: "MCP tools \u2014 identity, behavior, and decisions",
8750
8750
  domain: "tool-use",
8751
8751
  priority: "p1",
8752
- content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: customer-facing bug/support intake; use whenever an Exe OS bug or emergency hotfix is encountered so the report reaches AskExe directly. Customers only get report access; internal list/get/triage support tools are AskExe-only."
8752
+ content: "get_identity: read an agent's exe.md (Layer 1 identity). update_identity: write an agent's exe.md. Identity > behavior \u2014 use for permanent rules. store_behavior: record a correction or pattern for an agent (Layer 2 expertise). list_behaviors: view an agent's active behaviors. deactivate_behavior: soft-delete a stale or conflicting behavior. store_decision: record an ADR (architectural decision record). get_decision: retrieve a past decision by query. create_bug_report: customer-facing bug/support intake; use whenever an Exe OS bug or emergency hotfix is encountered so the report reaches AskExe directly. Customers only get report access; internal list/get/triage support tools are AskExe-only. If a customer-side agent cannot send upstream, run `exe-os support test` from the terminal to verify local file write, license auth, support endpoint health, and upstream POST."
8753
8753
  },
8754
8754
  {
8755
8755
  title: "MCP tools \u2014 communication and messaging",
@@ -10945,12 +10945,234 @@ var init_exe_key = __esm({
10945
10945
  }
10946
10946
  });
10947
10947
 
10948
+ // src/bin/exe-support.ts
10949
+ var exe_support_exports = {};
10950
+ __export(exe_support_exports, {
10951
+ main: () => main4
10952
+ });
10953
+ import { mkdirSync as mkdirSync13, readFileSync as readFileSync14, unlinkSync as unlinkSync7, writeFileSync as writeFileSync13 } from "fs";
10954
+ import path20 from "path";
10955
+ import { randomUUID as randomUUID4 } from "crypto";
10956
+ async function main4(argv = process.argv.slice(2)) {
10957
+ const command = argv[0] && !argv[0].startsWith("--") ? argv[0] : "test";
10958
+ const json = argv.includes("--json");
10959
+ const project = getArg(argv, "--project") ?? "support-smoke";
10960
+ if (command === "health") {
10961
+ const result = await runHealth();
10962
+ output(result, json);
10963
+ process.exitCode = result.some((row) => !row.ok) ? 1 : 0;
10964
+ return;
10965
+ }
10966
+ if (command === "test") {
10967
+ const result = await runTest(project);
10968
+ output(result, json);
10969
+ process.exitCode = result.some((row) => !row.ok) ? 1 : 0;
10970
+ return;
10971
+ }
10972
+ console.error("Usage: exe-os support health|test [--project <name>] [--json]");
10973
+ process.exitCode = 1;
10974
+ }
10975
+ async function runHealth() {
10976
+ const checks = [];
10977
+ const endpoints = await resolveEndpoints();
10978
+ checks.push(checkLocalWrite());
10979
+ checks.push({
10980
+ check: "license_key_present",
10981
+ ok: Boolean(loadLicense()),
10982
+ detail: loadLicense() ? "license.key found" : "missing ~/.exe-os/license.key; run exe-os setup or exe-os cloud setup"
10983
+ });
10984
+ checks.push({
10985
+ check: "license_token_cached",
10986
+ ok: Boolean(readCachedLicenseToken()),
10987
+ detail: readCachedLicenseToken() ? "cached license token found" : "no cached token yet; support can still use license.key"
10988
+ });
10989
+ try {
10990
+ const res = await fetch(endpoints.healthEndpoint, { method: "GET", signal: AbortSignal.timeout(1e4) });
10991
+ const body = await safeJson2(res);
10992
+ checks.push({
10993
+ check: "support_health_endpoint",
10994
+ ok: res.ok && body?.status !== "down",
10995
+ detail: `${res.status} ${body?.status ?? res.statusText}`
10996
+ });
10997
+ for (const remote of body?.checks ?? []) {
10998
+ checks.push({
10999
+ check: `server_${remote.name ?? "unknown"}`,
11000
+ ok: remote.ok === true,
11001
+ detail: remote.detail ?? (remote.ok ? "ok" : "failed")
11002
+ });
11003
+ }
11004
+ } catch (err) {
11005
+ checks.push({
11006
+ check: "support_health_endpoint",
11007
+ ok: false,
11008
+ detail: err instanceof Error ? err.message : String(err)
11009
+ });
11010
+ }
11011
+ return checks;
11012
+ }
11013
+ async function runTest(project) {
11014
+ const checks = await runHealth();
11015
+ const endpoints = await resolveEndpoints();
11016
+ const licenseKey = loadLicense();
11017
+ const licenseToken = readCachedLicenseToken();
11018
+ const id = randomUUID4();
11019
+ const version = readPackageVersion();
11020
+ const reportPath = writeLocalTestReport(id, project, version);
11021
+ checks.push({ check: "local_report_file", ok: true, detail: reportPath });
11022
+ if (!licenseKey && !licenseToken) {
11023
+ checks.push({ check: "upstream_post", ok: false, detail: "missing license key/token" });
11024
+ return checks;
11025
+ }
11026
+ const payload = {
11027
+ id,
11028
+ title: `TEST \u2014 ${project} support intake (${version})`,
11029
+ classification: "unclear",
11030
+ severity: "p3",
11031
+ summary: "Synthetic exe-os support intake smoke test. Safe to close.",
11032
+ customer_impact: "No customer impact; diagnostic only.",
11033
+ reproduction_steps: ["Run exe-os support test"],
11034
+ expected: "The report reaches AskExe support intake and can be triaged.",
11035
+ actual: "Smoke test submitted by exe-os support test.",
11036
+ package_version: `@askexenow/exe-os@${version}`,
11037
+ project_name: project,
11038
+ agent_id: "support-test",
11039
+ agent_role: "diagnostic",
11040
+ report_path: reportPath,
11041
+ markdown: readFileSync14(reportPath, "utf8")
11042
+ };
11043
+ try {
11044
+ const headers = { "content-type": "application/json" };
11045
+ if (licenseKey) headers["x-exe-license-key"] = licenseKey;
11046
+ if (licenseToken) headers["x-exe-license-token"] = licenseToken;
11047
+ const res = await fetch(endpoints.bugEndpoint, {
11048
+ method: "POST",
11049
+ headers,
11050
+ body: JSON.stringify(payload),
11051
+ signal: AbortSignal.timeout(15e3)
11052
+ });
11053
+ const data = await safeJson2(res);
11054
+ checks.push({
11055
+ check: "upstream_post",
11056
+ ok: res.ok,
11057
+ detail: res.ok ? `sent id=${String(data?.id ?? id)}` : `${res.status} ${JSON.stringify(data)}`
11058
+ });
11059
+ if (res.ok) {
11060
+ checks.push(await maybeCloseAdmin(String(data?.id ?? id), endpoints.adminEndpoint, version));
11061
+ }
11062
+ } catch (err) {
11063
+ checks.push({ check: "upstream_post", ok: false, detail: err instanceof Error ? err.message : String(err) });
11064
+ }
11065
+ return checks;
11066
+ }
11067
+ async function resolveEndpoints() {
11068
+ const config = await loadConfig();
11069
+ const bugEndpoint = process.env.EXE_SUPPORT_BUG_REPORT_ENDPOINT ?? config.support?.bugReportEndpoint ?? DEFAULT_BUG_ENDPOINT;
11070
+ const healthEndpoint = process.env.EXE_SUPPORT_HEALTH_ENDPOINT ?? bugEndpoint.replace(/\/bug-reports\/?$/, "/health");
11071
+ const adminEndpoint = process.env.ASKEXE_SUPPORT_ADMIN_ENDPOINT ?? process.env.EXE_SUPPORT_ADMIN_ENDPOINT ?? DEFAULT_ADMIN_ENDPOINT;
11072
+ return { bugEndpoint, healthEndpoint, adminEndpoint };
11073
+ }
11074
+ function checkLocalWrite() {
11075
+ const dir = path20.join(EXE_AI_DIR, "bug-reports");
11076
+ const testPath = path20.join(dir, ".support-write-test");
11077
+ try {
11078
+ mkdirSync13(dir, { recursive: true, mode: 448 });
11079
+ writeFileSync13(testPath, "ok\n", { mode: 384 });
11080
+ unlinkSync7(testPath);
11081
+ return { check: "local_bug_report_dir_writable", ok: true, detail: dir };
11082
+ } catch (err) {
11083
+ return { check: "local_bug_report_dir_writable", ok: false, detail: err instanceof Error ? err.message : String(err) };
11084
+ }
11085
+ }
11086
+ function writeLocalTestReport(id, project, version) {
11087
+ const dir = path20.join(EXE_AI_DIR, "bug-reports");
11088
+ mkdirSync13(dir, { recursive: true, mode: 448 });
11089
+ const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
11090
+ const filePath = path20.join(dir, `${date}-support-intake-test-${id.slice(0, 8)}.md`);
11091
+ writeFileSync13(filePath, `# TEST \u2014 ${project} support intake
11092
+
11093
+ Report ID: ${id}
11094
+ Package: @askexenow/exe-os@${version}
11095
+
11096
+ Synthetic smoke test from \`exe-os support test\`. Safe to close.
11097
+ `, { mode: 384 });
11098
+ return filePath;
11099
+ }
11100
+ async function maybeCloseAdmin(id, adminEndpoint, version) {
11101
+ const token = process.env.ASKEXE_SUPPORT_ADMIN_TOKEN ?? process.env.EXE_SUPPORT_ADMIN_TOKEN;
11102
+ if (!token) {
11103
+ return { check: "askexe_admin_autoclose", ok: true, detail: "skipped; admin token is AskExe-only" };
11104
+ }
11105
+ try {
11106
+ const res = await fetch(`${adminEndpoint}/${encodeURIComponent(id)}`, {
11107
+ method: "PATCH",
11108
+ headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
11109
+ body: JSON.stringify({
11110
+ status: "closed",
11111
+ triage_notes: "Auto-closed synthetic support smoke test.",
11112
+ fixed_version: version
11113
+ }),
11114
+ signal: AbortSignal.timeout(1e4)
11115
+ });
11116
+ return { check: "askexe_admin_autoclose", ok: res.ok, detail: res.ok ? "closed" : `${res.status} ${await res.text()}` };
11117
+ } catch (err) {
11118
+ return { check: "askexe_admin_autoclose", ok: false, detail: err instanceof Error ? err.message : String(err) };
11119
+ }
11120
+ }
11121
+ function readPackageVersion() {
11122
+ let dir = path20.dirname(new URL(import.meta.url).pathname);
11123
+ for (let i = 0; i < 6; i++) {
11124
+ const pkg = path20.join(dir, "package.json");
11125
+ try {
11126
+ const parsed = JSON.parse(readFileSync14(pkg, "utf8"));
11127
+ if (parsed.version) return parsed.version;
11128
+ } catch {
11129
+ }
11130
+ dir = path20.dirname(dir);
11131
+ }
11132
+ return "unknown";
11133
+ }
11134
+ async function safeJson2(res) {
11135
+ try {
11136
+ return await res.json();
11137
+ } catch {
11138
+ return null;
11139
+ }
11140
+ }
11141
+ function getArg(argv, name) {
11142
+ const idx = argv.indexOf(name);
11143
+ if (idx >= 0) return argv[idx + 1];
11144
+ const prefix = `${name}=`;
11145
+ const found = argv.find((arg) => arg.startsWith(prefix));
11146
+ return found?.slice(prefix.length);
11147
+ }
11148
+ function output(rows, json) {
11149
+ if (json) {
11150
+ console.log(JSON.stringify({ ok: rows.every((row) => row.ok), checks: rows }, null, 2));
11151
+ return;
11152
+ }
11153
+ console.log("\nexe-os support diagnostics\n");
11154
+ for (const row of rows) {
11155
+ console.log(`${row.ok ? "\u2705" : "\u274C"} ${row.check}: ${row.detail}`);
11156
+ }
11157
+ console.log("");
11158
+ }
11159
+ var DEFAULT_BUG_ENDPOINT, DEFAULT_ADMIN_ENDPOINT;
11160
+ var init_exe_support = __esm({
11161
+ "src/bin/exe-support.ts"() {
11162
+ "use strict";
11163
+ init_config();
11164
+ init_license();
11165
+ DEFAULT_BUG_ENDPOINT = "https://askexe.com/v1/support/bug-reports";
11166
+ DEFAULT_ADMIN_ENDPOINT = "https://askexe.com/admin/support/bug-reports";
11167
+ }
11168
+ });
11169
+
10948
11170
  // src/bin/bulk-sync-postgres.ts
10949
11171
  var bulk_sync_postgres_exports = {};
10950
11172
  __export(bulk_sync_postgres_exports, {
10951
- main: () => main4
11173
+ main: () => main5
10952
11174
  });
10953
- async function main4() {
11175
+ async function main5() {
10954
11176
  process.env.EXE_IS_DAEMON = "1";
10955
11177
  await initStore({ lightweight: true });
10956
11178
  const client = getClient();
@@ -11013,7 +11235,7 @@ var init_bulk_sync_postgres = __esm({
11013
11235
  init_cloud_sync();
11014
11236
  BATCH_SIZE = 500;
11015
11237
  if (import.meta.url === `file://${process.argv[1]}`) {
11016
- main4().catch((err) => {
11238
+ main5().catch((err) => {
11017
11239
  process.stderr.write(`[bulk-sync] FATAL: ${err instanceof Error ? err.message : String(err)}
11018
11240
  `);
11019
11241
  process.exit(1);
@@ -11030,12 +11252,12 @@ __export(backfill_conversations_exports, {
11030
11252
  import crypto6 from "crypto";
11031
11253
  import { createReadStream } from "fs";
11032
11254
  import { readdir as readdir2, stat } from "fs/promises";
11033
- import path20 from "path";
11255
+ import path21 from "path";
11034
11256
  import { createInterface as createInterface3 } from "readline";
11035
11257
  import { homedir as homedir3 } from "os";
11036
11258
  import { parseArgs } from "util";
11037
11259
  async function findJsonlFiles(sinceDate, projectFilter) {
11038
- const projectsDir = path20.join(homedir3(), ".claude", "projects");
11260
+ const projectsDir = path21.join(homedir3(), ".claude", "projects");
11039
11261
  const files = [];
11040
11262
  async function walk(dir, depth = 0) {
11041
11263
  if (depth > MAX_WALK_DEPTH) return;
@@ -11046,7 +11268,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
11046
11268
  return;
11047
11269
  }
11048
11270
  for (const entry of entries) {
11049
- const full = path20.join(dir, entry.name);
11271
+ const full = path21.join(dir, entry.name);
11050
11272
  if (entry.isDirectory()) {
11051
11273
  if (entry.name === "subagents" || entry.name === "tool-results") continue;
11052
11274
  await walk(full, depth + 1);
@@ -11071,7 +11293,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
11071
11293
  if (!entry.isDirectory()) continue;
11072
11294
  const decoded = decodeProjectDir(entry.name);
11073
11295
  if (decoded.toLowerCase().includes(projectFilter.toLowerCase())) {
11074
- await walk(path20.join(projectsDir, entry.name));
11296
+ await walk(path21.join(projectsDir, entry.name));
11075
11297
  }
11076
11298
  }
11077
11299
  } else {
@@ -11088,14 +11310,14 @@ function decodeProjectDir(dirName) {
11088
11310
  return dirName;
11089
11311
  }
11090
11312
  function projectNameFromPath(filePath) {
11091
- const projectsDir = path20.join(homedir3(), ".claude", "projects");
11092
- const relative = path20.relative(projectsDir, filePath);
11093
- const projectDir = relative.split(path20.sep)[0] ?? "unknown";
11313
+ const projectsDir = path21.join(homedir3(), ".claude", "projects");
11314
+ const relative = path21.relative(projectsDir, filePath);
11315
+ const projectDir = relative.split(path21.sep)[0] ?? "unknown";
11094
11316
  return decodeProjectDir(projectDir);
11095
11317
  }
11096
11318
  async function parseConversation(filePath) {
11097
11319
  const conv = {
11098
- sessionId: path20.basename(filePath, ".jsonl"),
11320
+ sessionId: path21.basename(filePath, ".jsonl"),
11099
11321
  projectName: projectNameFromPath(filePath),
11100
11322
  cwd: void 0,
11101
11323
  startTime: void 0,
@@ -11159,7 +11381,7 @@ async function parseConversation(filePath) {
11159
11381
  }
11160
11382
  }
11161
11383
  if (conv.cwd) {
11162
- conv.projectName = path20.basename(conv.cwd);
11384
+ conv.projectName = path21.basename(conv.cwd);
11163
11385
  const worktreeMatch = conv.cwd.match(/\.worktrees\/([^/]+)/);
11164
11386
  if (worktreeMatch?.[1]) {
11165
11387
  conv.agentId = worktreeMatch[1];
@@ -11811,9 +12033,9 @@ Unclassified: ${unclassified}
11811
12033
  }
11812
12034
  async function exportBatches(options) {
11813
12035
  const fs8 = await import("fs");
11814
- const path55 = await import("path");
12036
+ const path56 = await import("path");
11815
12037
  const client = getClient();
11816
- const outDir = path55.join(process.cwd(), "exe/output/classifications/input");
12038
+ const outDir = path56.join(process.cwd(), "exe/output/classifications/input");
11817
12039
  fs8.mkdirSync(outDir, { recursive: true });
11818
12040
  const countResult = await client.execute({
11819
12041
  sql: "SELECT COUNT(*) as cnt FROM memories WHERE intent IS NULL AND outcome IS NULL AND domain IS NULL",
@@ -11837,7 +12059,7 @@ async function exportBatches(options) {
11837
12059
  const text = String(row.text || "").replace(/\n/g, " ");
11838
12060
  return JSON.stringify({ id: row.id, text });
11839
12061
  });
11840
- const batchFile = path55.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
12062
+ const batchFile = path56.join(outDir, `batch-${String(batchNum).padStart(4, "0")}.jsonl`);
11841
12063
  fs8.writeFileSync(batchFile, lines.join("\n") + "\n");
11842
12064
  exported += batch.rows.length;
11843
12065
  offset += options.batchSize;
@@ -11853,7 +12075,7 @@ async function exportBatches(options) {
11853
12075
  }
11854
12076
  async function importClassifications(importDir) {
11855
12077
  const fs8 = await import("fs");
11856
- const path55 = await import("path");
12078
+ const path56 = await import("path");
11857
12079
  const client = getClient();
11858
12080
  const files = fs8.readdirSync(importDir).filter((f) => f.endsWith(".jsonl")).sort();
11859
12081
  process.stderr.write(`[backfill-metadata] Found ${files.length} JSONL files to import from ${importDir}
@@ -11861,7 +12083,7 @@ async function importClassifications(importDir) {
11861
12083
  let imported = 0;
11862
12084
  let invalid = 0;
11863
12085
  for (const file of files) {
11864
- const lines = fs8.readFileSync(path55.join(importDir, file), "utf-8").split("\n").filter(Boolean);
12086
+ const lines = fs8.readFileSync(path56.join(importDir, file), "utf-8").split("\n").filter(Boolean);
11865
12087
  for (const line of lines) {
11866
12088
  try {
11867
12089
  const rec = JSON.parse(line);
@@ -12002,17 +12224,17 @@ __export(identity_exports, {
12002
12224
  listIdentities: () => listIdentities,
12003
12225
  updateIdentity: () => updateIdentity
12004
12226
  });
12005
- import { existsSync as existsSync20, mkdirSync as mkdirSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "fs";
12227
+ import { existsSync as existsSync20, mkdirSync as mkdirSync14, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
12006
12228
  import { readdirSync as readdirSync4 } from "fs";
12007
- import path21 from "path";
12229
+ import path22 from "path";
12008
12230
  import { createHash as createHash5 } from "crypto";
12009
12231
  function ensureDir() {
12010
12232
  if (!existsSync20(IDENTITY_DIR2)) {
12011
- mkdirSync13(IDENTITY_DIR2, { recursive: true });
12233
+ mkdirSync14(IDENTITY_DIR2, { recursive: true });
12012
12234
  }
12013
12235
  }
12014
12236
  function identityPath(agentId) {
12015
- return path21.join(IDENTITY_DIR2, `${agentId}.md`);
12237
+ return path22.join(IDENTITY_DIR2, `${agentId}.md`);
12016
12238
  }
12017
12239
  function sanitizeIdentityBody(body) {
12018
12240
  return body.replace(/<!--[\s\S]*?-->/g, "").trim();
@@ -12057,7 +12279,7 @@ function contentHash(content) {
12057
12279
  function getIdentity(agentId) {
12058
12280
  const filePath = identityPath(agentId);
12059
12281
  if (!existsSync20(filePath)) return null;
12060
- const raw = readFileSync14(filePath, "utf-8");
12282
+ const raw = readFileSync15(filePath, "utf-8");
12061
12283
  const { frontmatter, body } = parseFrontmatter(raw);
12062
12284
  return {
12063
12285
  agentId,
@@ -12071,7 +12293,7 @@ async function updateIdentity(agentId, content, updatedBy) {
12071
12293
  ensureDir();
12072
12294
  const filePath = identityPath(agentId);
12073
12295
  const hash = contentHash(content);
12074
- writeFileSync13(filePath, content, "utf-8");
12296
+ writeFileSync14(filePath, content, "utf-8");
12075
12297
  try {
12076
12298
  const client = getClient();
12077
12299
  await client.execute({
@@ -12129,15 +12351,15 @@ var init_identity = __esm({
12129
12351
  "use strict";
12130
12352
  init_config();
12131
12353
  init_database();
12132
- IDENTITY_DIR2 = path21.join(EXE_AI_DIR, "identity");
12354
+ IDENTITY_DIR2 = path22.join(EXE_AI_DIR, "identity");
12133
12355
  }
12134
12356
  });
12135
12357
 
12136
12358
  // src/lib/orchestration-package.ts
12137
- import { randomUUID as randomUUID4 } from "crypto";
12138
- import { copyFileSync as copyFileSync4, existsSync as existsSync21, mkdirSync as mkdirSync14, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
12359
+ import { randomUUID as randomUUID5 } from "crypto";
12360
+ import { copyFileSync as copyFileSync4, existsSync as existsSync21, mkdirSync as mkdirSync15, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
12139
12361
  import os13 from "os";
12140
- import path22 from "path";
12362
+ import path23 from "path";
12141
12363
  function ensureObject(value, label) {
12142
12364
  if (value == null || Array.isArray(value) || typeof value !== "object") {
12143
12365
  throw new Error(`${label} must be an object`);
@@ -12196,15 +12418,15 @@ function validateProcedureEntry(value, index) {
12196
12418
  };
12197
12419
  }
12198
12420
  function getRosterPath() {
12199
- return path22.join(os13.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
12421
+ return path23.join(os13.homedir(), EXE_OS_DIRNAME, ROSTER_FILENAME);
12200
12422
  }
12201
12423
  function getBackupPath() {
12202
- return path22.join(os13.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
12424
+ return path23.join(os13.homedir(), EXE_OS_DIRNAME, ROSTER_BACKUP_FILENAME);
12203
12425
  }
12204
12426
  function readRosterFile() {
12205
12427
  const rosterPath = getRosterPath();
12206
12428
  if (!existsSync21(rosterPath)) return [];
12207
- const raw = readFileSync15(rosterPath, "utf-8");
12429
+ const raw = readFileSync16(rosterPath, "utf-8");
12208
12430
  const parsed = JSON.parse(raw);
12209
12431
  if (!Array.isArray(parsed)) {
12210
12432
  throw new Error("Roster file must contain a JSON array");
@@ -12216,7 +12438,7 @@ function writeRosterFile(roster) {
12216
12438
  throw new Error("Refusing to write empty roster \u2014 this would delete all employees");
12217
12439
  }
12218
12440
  const rosterPath = getRosterPath();
12219
- mkdirSync14(path22.dirname(rosterPath), { recursive: true });
12441
+ mkdirSync15(path23.dirname(rosterPath), { recursive: true });
12220
12442
  if (existsSync21(rosterPath)) {
12221
12443
  const currentRoster = readRosterFile();
12222
12444
  if (roster.length < currentRoster.length) {
@@ -12226,7 +12448,7 @@ function writeRosterFile(roster) {
12226
12448
  }
12227
12449
  copyFileSync4(rosterPath, getBackupPath());
12228
12450
  }
12229
- writeFileSync14(rosterPath, `${JSON.stringify(roster, null, 2)}
12451
+ writeFileSync15(rosterPath, `${JSON.stringify(roster, null, 2)}
12230
12452
  `, "utf-8");
12231
12453
  }
12232
12454
  function buildImportedRosterEntries(roster, timestamp) {
@@ -12246,7 +12468,7 @@ async function insertBehaviors(behaviors, timestamp) {
12246
12468
  sql: `INSERT INTO behaviors (id, agent_id, project_name, domain, priority, content, active, created_at, updated_at)
12247
12469
  VALUES (?, ?, ?, ?, ?, ?, 1, ?, ?)`,
12248
12470
  args: [
12249
- randomUUID4(),
12471
+ randomUUID5(),
12250
12472
  behavior.agent_id,
12251
12473
  behavior.project_name,
12252
12474
  behavior.domain,
@@ -12271,7 +12493,7 @@ async function insertProcedures(procedures, timestamp, options) {
12271
12493
  sql: `INSERT INTO company_procedures (id, title, content, priority, domain, active, created_at, updated_at)
12272
12494
  VALUES (?, ?, ?, ?, ?, 1, ?, ?)`,
12273
12495
  args: [
12274
- randomUUID4(),
12496
+ randomUUID5(),
12275
12497
  procedure.title,
12276
12498
  procedure.content,
12277
12499
  procedure.priority,
@@ -12493,8 +12715,8 @@ var exe_export_exports = {};
12493
12715
  __export(exe_export_exports, {
12494
12716
  runExeExport: () => runExeExport
12495
12717
  });
12496
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync15 } from "fs";
12497
- import path23 from "path";
12718
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16 } from "fs";
12719
+ import path24 from "path";
12498
12720
  function printUsage() {
12499
12721
  process.stdout.write("Usage: exe-os export --output <path>\n");
12500
12722
  }
@@ -12515,8 +12737,8 @@ async function runExeExport(argv = process.argv.slice(2)) {
12515
12737
  await initStore();
12516
12738
  try {
12517
12739
  const pkg = await exportOrchestration("cli");
12518
- mkdirSync15(path23.dirname(outputPath), { recursive: true });
12519
- writeFileSync15(outputPath, `${JSON.stringify(pkg, null, 2)}
12740
+ mkdirSync16(path24.dirname(outputPath), { recursive: true });
12741
+ writeFileSync16(outputPath, `${JSON.stringify(pkg, null, 2)}
12520
12742
  `, "utf-8");
12521
12743
  process.stdout.write(
12522
12744
  `Exported ${pkg.roster.length} roster entries, ${Object.keys(pkg.identities).length} identities, ${pkg.behaviors.length} behaviors, ${pkg.procedures.length} procedures to ${outputPath}
@@ -12552,7 +12774,7 @@ var exe_import_exports = {};
12552
12774
  __export(exe_import_exports, {
12553
12775
  runExeImport: () => runExeImport
12554
12776
  });
12555
- import { readFileSync as readFileSync16 } from "fs";
12777
+ import { readFileSync as readFileSync17 } from "fs";
12556
12778
  function printUsage2() {
12557
12779
  process.stdout.write("Usage: exe-os import --from <path> [--merge]\n");
12558
12780
  }
@@ -12575,7 +12797,7 @@ async function runExeImport(argv = process.argv.slice(2)) {
12575
12797
  if (parsed == null) return;
12576
12798
  await initStore();
12577
12799
  try {
12578
- const raw = readFileSync16(parsed.packagePath, "utf-8");
12800
+ const raw = readFileSync17(parsed.packagePath, "utf-8");
12579
12801
  const pkg = validatePackage(JSON.parse(raw));
12580
12802
  const result = await importOrchestration(pkg, parsed.strategy);
12581
12803
  process.stdout.write(
@@ -12616,14 +12838,14 @@ __export(session_registry_exports, {
12616
12838
  refreshSessionProject: () => refreshSessionProject,
12617
12839
  registerSession: () => registerSession
12618
12840
  });
12619
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync16, mkdirSync as mkdirSync16, existsSync as existsSync22 } from "fs";
12841
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, existsSync as existsSync22 } from "fs";
12620
12842
  import { execSync as execSync5 } from "child_process";
12621
- import path24 from "path";
12843
+ import path25 from "path";
12622
12844
  import os14 from "os";
12623
12845
  function registerSession(entry) {
12624
- const dir = path24.dirname(REGISTRY_PATH);
12846
+ const dir = path25.dirname(REGISTRY_PATH);
12625
12847
  if (!existsSync22(dir)) {
12626
- mkdirSync16(dir, { recursive: true });
12848
+ mkdirSync17(dir, { recursive: true });
12627
12849
  }
12628
12850
  const sessions = listSessions();
12629
12851
  const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
@@ -12632,7 +12854,7 @@ function registerSession(entry) {
12632
12854
  } else {
12633
12855
  sessions.push(entry);
12634
12856
  }
12635
- writeFileSync16(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12857
+ writeFileSync17(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12636
12858
  }
12637
12859
  function refreshSessionProject(windowName, projectDir) {
12638
12860
  const sessions = listSessions();
@@ -12640,13 +12862,13 @@ function refreshSessionProject(windowName, projectDir) {
12640
12862
  if (!entry || entry.projectDir === projectDir) return;
12641
12863
  entry.projectDir = projectDir;
12642
12864
  try {
12643
- writeFileSync16(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12865
+ writeFileSync17(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
12644
12866
  } catch {
12645
12867
  }
12646
12868
  }
12647
12869
  function listSessions() {
12648
12870
  try {
12649
- const raw = readFileSync17(REGISTRY_PATH, "utf8");
12871
+ const raw = readFileSync18(REGISTRY_PATH, "utf8");
12650
12872
  return JSON.parse(raw);
12651
12873
  } catch {
12652
12874
  return [];
@@ -12667,7 +12889,7 @@ function pruneStaleSessions() {
12667
12889
  const alive = sessions.filter((s) => liveSet.has(s.windowName));
12668
12890
  const pruned = sessions.length - alive.length;
12669
12891
  if (pruned > 0) {
12670
- writeFileSync16(REGISTRY_PATH, JSON.stringify(alive, null, 2));
12892
+ writeFileSync17(REGISTRY_PATH, JSON.stringify(alive, null, 2));
12671
12893
  }
12672
12894
  return pruned;
12673
12895
  }
@@ -12675,7 +12897,7 @@ var REGISTRY_PATH;
12675
12897
  var init_session_registry = __esm({
12676
12898
  "src/lib/session-registry.ts"() {
12677
12899
  "use strict";
12678
- REGISTRY_PATH = path24.join(os14.homedir(), ".exe-os", "session-registry.json");
12900
+ REGISTRY_PATH = path25.join(os14.homedir(), ".exe-os", "session-registry.json");
12679
12901
  }
12680
12902
  });
12681
12903
 
@@ -12931,17 +13153,17 @@ __export(intercom_queue_exports, {
12931
13153
  queueIntercom: () => queueIntercom,
12932
13154
  readQueue: () => readQueue
12933
13155
  });
12934
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, renameSync as renameSync5, existsSync as existsSync23, mkdirSync as mkdirSync17 } from "fs";
12935
- import path25 from "path";
13156
+ import { readFileSync as readFileSync19, writeFileSync as writeFileSync18, renameSync as renameSync5, existsSync as existsSync23, mkdirSync as mkdirSync18 } from "fs";
13157
+ import path26 from "path";
12936
13158
  import os15 from "os";
12937
13159
  function ensureDir2() {
12938
- const dir = path25.dirname(QUEUE_PATH);
12939
- if (!existsSync23(dir)) mkdirSync17(dir, { recursive: true });
13160
+ const dir = path26.dirname(QUEUE_PATH);
13161
+ if (!existsSync23(dir)) mkdirSync18(dir, { recursive: true });
12940
13162
  }
12941
13163
  function readQueue() {
12942
13164
  try {
12943
13165
  if (!existsSync23(QUEUE_PATH)) return [];
12944
- return JSON.parse(readFileSync18(QUEUE_PATH, "utf8"));
13166
+ return JSON.parse(readFileSync19(QUEUE_PATH, "utf8"));
12945
13167
  } catch {
12946
13168
  return [];
12947
13169
  }
@@ -12949,7 +13171,7 @@ function readQueue() {
12949
13171
  function writeQueue(queue) {
12950
13172
  ensureDir2();
12951
13173
  const tmp = `${QUEUE_PATH}.tmp`;
12952
- writeFileSync17(tmp, JSON.stringify(queue, null, 2));
13174
+ writeFileSync18(tmp, JSON.stringify(queue, null, 2));
12953
13175
  renameSync5(tmp, QUEUE_PATH);
12954
13176
  }
12955
13177
  function queueIntercom(targetSession, reason) {
@@ -13041,20 +13263,20 @@ var QUEUE_PATH, MAX_RETRIES2, TTL_MS, INTERCOM_LOG;
13041
13263
  var init_intercom_queue = __esm({
13042
13264
  "src/lib/intercom-queue.ts"() {
13043
13265
  "use strict";
13044
- QUEUE_PATH = path25.join(os15.homedir(), ".exe-os", "intercom-queue.json");
13266
+ QUEUE_PATH = path26.join(os15.homedir(), ".exe-os", "intercom-queue.json");
13045
13267
  MAX_RETRIES2 = 5;
13046
13268
  TTL_MS = 60 * 60 * 1e3;
13047
- INTERCOM_LOG = path25.join(os15.homedir(), ".exe-os", "intercom.log");
13269
+ INTERCOM_LOG = path26.join(os15.homedir(), ".exe-os", "intercom.log");
13048
13270
  }
13049
13271
  });
13050
13272
 
13051
13273
  // src/lib/plan-limits.ts
13052
- import { readFileSync as readFileSync19, existsSync as existsSync24 } from "fs";
13053
- import path26 from "path";
13274
+ import { readFileSync as readFileSync20, existsSync as existsSync24 } from "fs";
13275
+ import path27 from "path";
13054
13276
  function getLicenseSync() {
13055
13277
  try {
13056
13278
  if (!existsSync24(CACHE_PATH2)) return freeLicense();
13057
- const raw = JSON.parse(readFileSync19(CACHE_PATH2, "utf8"));
13279
+ const raw = JSON.parse(readFileSync20(CACHE_PATH2, "utf8"));
13058
13280
  if (!raw.token || typeof raw.token !== "string") return freeLicense();
13059
13281
  const parts = raw.token.split(".");
13060
13282
  if (parts.length !== 3) return freeLicense();
@@ -13093,7 +13315,7 @@ function assertEmployeeLimitSync(rosterPath) {
13093
13315
  let count = 0;
13094
13316
  try {
13095
13317
  if (existsSync24(filePath)) {
13096
- const raw = readFileSync19(filePath, "utf8");
13318
+ const raw = readFileSync20(filePath, "utf8");
13097
13319
  const employees = JSON.parse(raw);
13098
13320
  count = Array.isArray(employees) ? employees.length : 0;
13099
13321
  }
@@ -13122,7 +13344,7 @@ var init_plan_limits = __esm({
13122
13344
  this.name = "PlanLimitError";
13123
13345
  }
13124
13346
  };
13125
- CACHE_PATH2 = path26.join(EXE_AI_DIR, "license-cache.json");
13347
+ CACHE_PATH2 = path27.join(EXE_AI_DIR, "license-cache.json");
13126
13348
  }
13127
13349
  });
13128
13350
 
@@ -13167,12 +13389,12 @@ var init_task_scope = __esm({
13167
13389
 
13168
13390
  // src/lib/notifications.ts
13169
13391
  import crypto7 from "crypto";
13170
- import path27 from "path";
13392
+ import path28 from "path";
13171
13393
  import os16 from "os";
13172
13394
  import {
13173
- readFileSync as readFileSync20,
13395
+ readFileSync as readFileSync21,
13174
13396
  readdirSync as readdirSync5,
13175
- unlinkSync as unlinkSync7,
13397
+ unlinkSync as unlinkSync8,
13176
13398
  existsSync as existsSync25,
13177
13399
  rmdirSync
13178
13400
  } from "fs";
@@ -13258,7 +13480,7 @@ var init_session_kill_telemetry = __esm({
13258
13480
 
13259
13481
  // src/lib/project-name.ts
13260
13482
  import { execSync as execSync8 } from "child_process";
13261
- import path28 from "path";
13483
+ import path29 from "path";
13262
13484
  function getProjectName(cwd2) {
13263
13485
  const dir = cwd2 ?? process.cwd();
13264
13486
  if (_cached2 && _cachedCwd === dir) return _cached2;
@@ -13271,7 +13493,7 @@ function getProjectName(cwd2) {
13271
13493
  timeout: 2e3,
13272
13494
  stdio: ["pipe", "pipe", "pipe"]
13273
13495
  }).trim();
13274
- repoRoot = path28.dirname(gitCommonDir);
13496
+ repoRoot = path29.dirname(gitCommonDir);
13275
13497
  } catch {
13276
13498
  repoRoot = execSync8("git rev-parse --show-toplevel", {
13277
13499
  cwd: dir,
@@ -13280,11 +13502,11 @@ function getProjectName(cwd2) {
13280
13502
  stdio: ["pipe", "pipe", "pipe"]
13281
13503
  }).trim();
13282
13504
  }
13283
- _cached2 = path28.basename(repoRoot);
13505
+ _cached2 = path29.basename(repoRoot);
13284
13506
  _cachedCwd = dir;
13285
13507
  return _cached2;
13286
13508
  } catch {
13287
- _cached2 = path28.basename(dir);
13509
+ _cached2 = path29.basename(dir);
13288
13510
  _cachedCwd = dir;
13289
13511
  return _cached2;
13290
13512
  }
@@ -13378,11 +13600,11 @@ __export(tasks_crud_exports, {
13378
13600
  writeCheckpoint: () => writeCheckpoint
13379
13601
  });
13380
13602
  import crypto9 from "crypto";
13381
- import path29 from "path";
13603
+ import path30 from "path";
13382
13604
  import os17 from "os";
13383
13605
  import { execSync as execSync9 } from "child_process";
13384
13606
  import { mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
13385
- import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
13607
+ import { existsSync as existsSync26, readFileSync as readFileSync22 } from "fs";
13386
13608
  async function writeCheckpoint(input) {
13387
13609
  const client = getClient();
13388
13610
  const row = await resolveTask(client, input.taskId);
@@ -13581,8 +13803,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
13581
13803
  }
13582
13804
  if (input.baseDir) {
13583
13805
  try {
13584
- await mkdir5(path29.join(input.baseDir, "exe", "output"), { recursive: true });
13585
- await mkdir5(path29.join(input.baseDir, "exe", "research"), { recursive: true });
13806
+ await mkdir5(path30.join(input.baseDir, "exe", "output"), { recursive: true });
13807
+ await mkdir5(path30.join(input.baseDir, "exe", "research"), { recursive: true });
13586
13808
  await ensureArchitectureDoc(input.baseDir, input.projectName);
13587
13809
  await ensureGitignoreExe(input.baseDir);
13588
13810
  } catch {
@@ -13618,9 +13840,9 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
13618
13840
  });
13619
13841
  if (input.baseDir) {
13620
13842
  try {
13621
- const EXE_OS_DIR = path29.join(os17.homedir(), ".exe-os");
13622
- const mdPath = path29.join(EXE_OS_DIR, taskFile);
13623
- const mdDir = path29.dirname(mdPath);
13843
+ const EXE_OS_DIR = path30.join(os17.homedir(), ".exe-os");
13844
+ const mdPath = path30.join(EXE_OS_DIR, taskFile);
13845
+ const mdDir = path30.dirname(mdPath);
13624
13846
  if (!existsSync26(mdDir)) await mkdir5(mdDir, { recursive: true });
13625
13847
  const reviewer = input.reviewer ?? input.assignedBy;
13626
13848
  const mdContent = `# ${input.title}
@@ -13725,12 +13947,12 @@ function isTmuxSessionAlive(identifier) {
13725
13947
  if (!identifier || identifier === "unknown") return true;
13726
13948
  try {
13727
13949
  if (identifier.startsWith("%")) {
13728
- const output = execSync9("tmux list-panes -a -F '#{pane_id}'", {
13950
+ const output2 = execSync9("tmux list-panes -a -F '#{pane_id}'", {
13729
13951
  timeout: 2e3,
13730
13952
  encoding: "utf8",
13731
13953
  stdio: ["pipe", "pipe", "pipe"]
13732
13954
  });
13733
- return output.split("\n").some((l) => l.trim() === identifier);
13955
+ return output2.split("\n").some((l) => l.trim() === identifier);
13734
13956
  } else {
13735
13957
  execSync9(`tmux has-session -t ${JSON.stringify(identifier)}`, {
13736
13958
  timeout: 2e3,
@@ -13921,7 +14143,7 @@ async function deleteTaskCore(taskId, _baseDir) {
13921
14143
  return { taskFile, assignedTo, assignedBy, taskSlug };
13922
14144
  }
13923
14145
  async function ensureArchitectureDoc(baseDir, projectName) {
13924
- const archPath = path29.join(baseDir, "exe", "ARCHITECTURE.md");
14146
+ const archPath = path30.join(baseDir, "exe", "ARCHITECTURE.md");
13925
14147
  try {
13926
14148
  if (existsSync26(archPath)) return;
13927
14149
  const template = [
@@ -13956,10 +14178,10 @@ async function ensureArchitectureDoc(baseDir, projectName) {
13956
14178
  }
13957
14179
  }
13958
14180
  async function ensureGitignoreExe(baseDir) {
13959
- const gitignorePath = path29.join(baseDir, ".gitignore");
14181
+ const gitignorePath = path30.join(baseDir, ".gitignore");
13960
14182
  try {
13961
14183
  if (existsSync26(gitignorePath)) {
13962
- const content = readFileSync21(gitignorePath, "utf-8");
14184
+ const content = readFileSync22(gitignorePath, "utf-8");
13963
14185
  if (/^\/?exe\/?$/m.test(content)) return;
13964
14186
  await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
13965
14187
  } else {
@@ -14002,8 +14224,8 @@ __export(tasks_review_exports, {
14002
14224
  isStale: () => isStale,
14003
14225
  listPendingReviews: () => listPendingReviews
14004
14226
  });
14005
- import path30 from "path";
14006
- import { existsSync as existsSync27, readdirSync as readdirSync6, unlinkSync as unlinkSync8 } from "fs";
14227
+ import path31 from "path";
14228
+ import { existsSync as existsSync27, readdirSync as readdirSync6, unlinkSync as unlinkSync9 } from "fs";
14007
14229
  function formatAge(isoTimestamp) {
14008
14230
  if (!isoTimestamp) return "";
14009
14231
  const ms = Date.now() - new Date(isoTimestamp).getTime();
@@ -14272,11 +14494,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
14272
14494
  );
14273
14495
  }
14274
14496
  try {
14275
- const cacheDir = path30.join(EXE_AI_DIR, "session-cache");
14497
+ const cacheDir = path31.join(EXE_AI_DIR, "session-cache");
14276
14498
  if (existsSync27(cacheDir)) {
14277
14499
  for (const f of readdirSync6(cacheDir)) {
14278
14500
  if (f.startsWith("review-notified-")) {
14279
- unlinkSync8(path30.join(cacheDir, f));
14501
+ unlinkSync9(path31.join(cacheDir, f));
14280
14502
  }
14281
14503
  }
14282
14504
  }
@@ -14298,7 +14520,7 @@ var init_tasks_review = __esm({
14298
14520
  });
14299
14521
 
14300
14522
  // src/lib/tasks-chain.ts
14301
- import path31 from "path";
14523
+ import path32 from "path";
14302
14524
  import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
14303
14525
  async function cascadeUnblock(taskId, baseDir, now2) {
14304
14526
  const client = getClient();
@@ -14315,7 +14537,7 @@ async function cascadeUnblock(taskId, baseDir, now2) {
14315
14537
  });
14316
14538
  for (const ur of unblockedRows.rows) {
14317
14539
  try {
14318
- const ubFile = path31.join(baseDir, String(ur.task_file));
14540
+ const ubFile = path32.join(baseDir, String(ur.task_file));
14319
14541
  let ubContent = await readFile5(ubFile, "utf-8");
14320
14542
  ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
14321
14543
  ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
@@ -14500,8 +14722,8 @@ async function embedDirect(text) {
14500
14722
  const llamaCpp = await import("node-llama-cpp");
14501
14723
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
14502
14724
  const { existsSync: existsSync41 } = await import("fs");
14503
- const path55 = await import("path");
14504
- const modelPath = path55.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
14725
+ const path56 = await import("path");
14726
+ const modelPath = path56.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
14505
14727
  if (!existsSync41(modelPath)) {
14506
14728
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
14507
14729
  }
@@ -14868,8 +15090,8 @@ __export(tasks_exports, {
14868
15090
  updateTaskStatus: () => updateTaskStatus,
14869
15091
  writeCheckpoint: () => writeCheckpoint
14870
15092
  });
14871
- import path32 from "path";
14872
- import { writeFileSync as writeFileSync18, mkdirSync as mkdirSync18, unlinkSync as unlinkSync9 } from "fs";
15093
+ import path33 from "path";
15094
+ import { writeFileSync as writeFileSync19, mkdirSync as mkdirSync19, unlinkSync as unlinkSync10 } from "fs";
14873
15095
  async function createTask(input) {
14874
15096
  const result = await createTaskCore(input);
14875
15097
  if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
@@ -14888,14 +15110,14 @@ async function updateTask(input) {
14888
15110
  const { row, taskFile, now: now2, taskId } = await updateTaskStatus(input);
14889
15111
  try {
14890
15112
  const agent = String(row.assigned_to);
14891
- const cacheDir = path32.join(EXE_AI_DIR, "session-cache");
14892
- const cachePath = path32.join(cacheDir, `current-task-${agent}.json`);
15113
+ const cacheDir = path33.join(EXE_AI_DIR, "session-cache");
15114
+ const cachePath = path33.join(cacheDir, `current-task-${agent}.json`);
14893
15115
  if (input.status === "in_progress") {
14894
- mkdirSync18(cacheDir, { recursive: true });
14895
- writeFileSync18(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
15116
+ mkdirSync19(cacheDir, { recursive: true });
15117
+ writeFileSync19(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
14896
15118
  } else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
14897
15119
  try {
14898
- unlinkSync9(cachePath);
15120
+ unlinkSync10(cachePath);
14899
15121
  } catch {
14900
15122
  }
14901
15123
  }
@@ -15361,13 +15583,13 @@ __export(tmux_routing_exports, {
15361
15583
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
15362
15584
  });
15363
15585
  import { execFileSync as execFileSync3, execSync as execSync10 } from "child_process";
15364
- import { readFileSync as readFileSync22, writeFileSync as writeFileSync19, mkdirSync as mkdirSync19, existsSync as existsSync28, appendFileSync as appendFileSync2, readdirSync as readdirSync7 } from "fs";
15365
- import path33 from "path";
15586
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync20, mkdirSync as mkdirSync20, existsSync as existsSync28, appendFileSync as appendFileSync2, readdirSync as readdirSync7 } from "fs";
15587
+ import path34 from "path";
15366
15588
  import os18 from "os";
15367
15589
  import { fileURLToPath as fileURLToPath4 } from "url";
15368
- import { unlinkSync as unlinkSync10 } from "fs";
15590
+ import { unlinkSync as unlinkSync11 } from "fs";
15369
15591
  function spawnLockPath(sessionName) {
15370
- return path33.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
15592
+ return path34.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
15371
15593
  }
15372
15594
  function isProcessAlive(pid) {
15373
15595
  try {
@@ -15379,12 +15601,12 @@ function isProcessAlive(pid) {
15379
15601
  }
15380
15602
  function acquireSpawnLock2(sessionName) {
15381
15603
  if (!existsSync28(SPAWN_LOCK_DIR)) {
15382
- mkdirSync19(SPAWN_LOCK_DIR, { recursive: true });
15604
+ mkdirSync20(SPAWN_LOCK_DIR, { recursive: true });
15383
15605
  }
15384
15606
  const lockFile = spawnLockPath(sessionName);
15385
15607
  if (existsSync28(lockFile)) {
15386
15608
  try {
15387
- const lock = JSON.parse(readFileSync22(lockFile, "utf8"));
15609
+ const lock = JSON.parse(readFileSync23(lockFile, "utf8"));
15388
15610
  const age = Date.now() - lock.timestamp;
15389
15611
  if (isProcessAlive(lock.pid) && age < 6e4) {
15390
15612
  return false;
@@ -15392,20 +15614,20 @@ function acquireSpawnLock2(sessionName) {
15392
15614
  } catch {
15393
15615
  }
15394
15616
  }
15395
- writeFileSync19(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
15617
+ writeFileSync20(lockFile, JSON.stringify({ pid: process.pid, timestamp: Date.now() }));
15396
15618
  return true;
15397
15619
  }
15398
15620
  function releaseSpawnLock2(sessionName) {
15399
15621
  try {
15400
- unlinkSync10(spawnLockPath(sessionName));
15622
+ unlinkSync11(spawnLockPath(sessionName));
15401
15623
  } catch {
15402
15624
  }
15403
15625
  }
15404
15626
  function resolveBehaviorsExporterScript() {
15405
15627
  try {
15406
15628
  const thisFile = fileURLToPath4(import.meta.url);
15407
- const scriptPath = path33.join(
15408
- path33.dirname(thisFile),
15629
+ const scriptPath = path34.join(
15630
+ path34.dirname(thisFile),
15409
15631
  "..",
15410
15632
  "bin",
15411
15633
  "exe-export-behaviors.js"
@@ -15419,12 +15641,12 @@ function exportBehaviorsSync(agentId, projectName, sessionKey) {
15419
15641
  const script = resolveBehaviorsExporterScript();
15420
15642
  if (!script) return null;
15421
15643
  try {
15422
- const output = execFileSync3(
15644
+ const output2 = execFileSync3(
15423
15645
  process.execPath,
15424
15646
  [script, agentId, projectName, sessionKey],
15425
15647
  { encoding: "utf-8", timeout: BEHAVIORS_EXPORT_TIMEOUT_MS }
15426
15648
  ).trim();
15427
- return output.length > 0 ? output : null;
15649
+ return output2.length > 0 ? output2 : null;
15428
15650
  } catch (err) {
15429
15651
  process.stderr.write(
15430
15652
  `[tmux-routing] behaviors export failed for ${agentId}: ${err instanceof Error ? err.message : String(err)}
@@ -15477,11 +15699,11 @@ function extractRootExe(name) {
15477
15699
  }
15478
15700
  function registerParentExe(sessionKey, parentExe, dispatchedBy) {
15479
15701
  if (!existsSync28(SESSION_CACHE)) {
15480
- mkdirSync19(SESSION_CACHE, { recursive: true });
15702
+ mkdirSync20(SESSION_CACHE, { recursive: true });
15481
15703
  }
15482
15704
  const rootExe = extractRootExe(parentExe) ?? parentExe;
15483
- const filePath = path33.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
15484
- writeFileSync19(filePath, JSON.stringify({
15705
+ const filePath = path34.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
15706
+ writeFileSync20(filePath, JSON.stringify({
15485
15707
  parentExe: rootExe,
15486
15708
  dispatchedBy: dispatchedBy || rootExe,
15487
15709
  registeredAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -15489,7 +15711,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
15489
15711
  }
15490
15712
  function getParentExe(sessionKey) {
15491
15713
  try {
15492
- const data = JSON.parse(readFileSync22(path33.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
15714
+ const data = JSON.parse(readFileSync23(path34.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
15493
15715
  return data.parentExe || null;
15494
15716
  } catch {
15495
15717
  return null;
@@ -15497,8 +15719,8 @@ function getParentExe(sessionKey) {
15497
15719
  }
15498
15720
  function getDispatchedBy(sessionKey) {
15499
15721
  try {
15500
- const data = JSON.parse(readFileSync22(
15501
- path33.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
15722
+ const data = JSON.parse(readFileSync23(
15723
+ path34.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
15502
15724
  "utf8"
15503
15725
  ));
15504
15726
  return data.dispatchedBy ?? data.parentExe ?? null;
@@ -15569,7 +15791,7 @@ async function verifyPaneAtCapacity(sessionName) {
15569
15791
  function readDebounceState() {
15570
15792
  try {
15571
15793
  if (!existsSync28(DEBOUNCE_FILE)) return {};
15572
- const raw = JSON.parse(readFileSync22(DEBOUNCE_FILE, "utf8"));
15794
+ const raw = JSON.parse(readFileSync23(DEBOUNCE_FILE, "utf8"));
15573
15795
  const state = {};
15574
15796
  for (const [key, val] of Object.entries(raw)) {
15575
15797
  if (typeof val === "number") {
@@ -15585,8 +15807,8 @@ function readDebounceState() {
15585
15807
  }
15586
15808
  function writeDebounceState(state) {
15587
15809
  try {
15588
- if (!existsSync28(SESSION_CACHE)) mkdirSync19(SESSION_CACHE, { recursive: true });
15589
- writeFileSync19(DEBOUNCE_FILE, JSON.stringify(state));
15810
+ if (!existsSync28(SESSION_CACHE)) mkdirSync20(SESSION_CACHE, { recursive: true });
15811
+ writeFileSync20(DEBOUNCE_FILE, JSON.stringify(state));
15590
15812
  } catch {
15591
15813
  }
15592
15814
  }
@@ -15685,7 +15907,7 @@ function sendIntercom(targetSession) {
15685
15907
  try {
15686
15908
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
15687
15909
  const agent = baseAgentName(rawAgent);
15688
- const markerPath = path33.join(SESSION_CACHE, `current-task-${agent}.json`);
15910
+ const markerPath = path34.join(SESSION_CACHE, `current-task-${agent}.json`);
15689
15911
  if (existsSync28(markerPath)) {
15690
15912
  logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
15691
15913
  return "debounced";
@@ -15696,7 +15918,7 @@ function sendIntercom(targetSession) {
15696
15918
  try {
15697
15919
  const rawAgent = targetSession.split("-")[0] ?? targetSession;
15698
15920
  const agent = baseAgentName(rawAgent);
15699
- const taskDir = path33.join(process.cwd(), "exe", agent);
15921
+ const taskDir = path34.join(process.cwd(), "exe", agent);
15700
15922
  if (existsSync28(taskDir)) {
15701
15923
  const files = readdirSync7(taskDir).filter(
15702
15924
  (f) => f.endsWith(".md") && f !== "DONE.txt"
@@ -15856,26 +16078,26 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15856
16078
  const transport = getTransport();
15857
16079
  const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
15858
16080
  const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
15859
- const logDir = path33.join(os18.homedir(), ".exe-os", "session-logs");
15860
- const logFile = path33.join(logDir, `${instanceLabel}-${Date.now()}.log`);
16081
+ const logDir = path34.join(os18.homedir(), ".exe-os", "session-logs");
16082
+ const logFile = path34.join(logDir, `${instanceLabel}-${Date.now()}.log`);
15861
16083
  if (!existsSync28(logDir)) {
15862
- mkdirSync19(logDir, { recursive: true });
16084
+ mkdirSync20(logDir, { recursive: true });
15863
16085
  }
15864
16086
  transport.kill(sessionName);
15865
16087
  let cleanupSuffix = "";
15866
16088
  try {
15867
16089
  const thisFile = fileURLToPath4(import.meta.url);
15868
- const cleanupScript = path33.join(path33.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
16090
+ const cleanupScript = path34.join(path34.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
15869
16091
  if (existsSync28(cleanupScript)) {
15870
16092
  cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
15871
16093
  }
15872
16094
  } catch {
15873
16095
  }
15874
16096
  try {
15875
- const claudeJsonPath = path33.join(os18.homedir(), ".claude.json");
16097
+ const claudeJsonPath = path34.join(os18.homedir(), ".claude.json");
15876
16098
  let claudeJson = {};
15877
16099
  try {
15878
- claudeJson = JSON.parse(readFileSync22(claudeJsonPath, "utf8"));
16100
+ claudeJson = JSON.parse(readFileSync23(claudeJsonPath, "utf8"));
15879
16101
  } catch {
15880
16102
  }
15881
16103
  if (!claudeJson.projects) claudeJson.projects = {};
@@ -15883,17 +16105,17 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15883
16105
  const trustDir = opts?.cwd ?? projectDir;
15884
16106
  if (!projects[trustDir]) projects[trustDir] = {};
15885
16107
  projects[trustDir].hasTrustDialogAccepted = true;
15886
- writeFileSync19(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
16108
+ writeFileSync20(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
15887
16109
  } catch {
15888
16110
  }
15889
16111
  try {
15890
- const settingsDir = path33.join(os18.homedir(), ".claude", "projects");
16112
+ const settingsDir = path34.join(os18.homedir(), ".claude", "projects");
15891
16113
  const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
15892
- const projSettingsDir = path33.join(settingsDir, normalizedKey);
15893
- const settingsPath = path33.join(projSettingsDir, "settings.json");
16114
+ const projSettingsDir = path34.join(settingsDir, normalizedKey);
16115
+ const settingsPath = path34.join(projSettingsDir, "settings.json");
15894
16116
  let settings = {};
15895
16117
  try {
15896
- settings = JSON.parse(readFileSync22(settingsPath, "utf8"));
16118
+ settings = JSON.parse(readFileSync23(settingsPath, "utf8"));
15897
16119
  } catch {
15898
16120
  }
15899
16121
  const perms = settings.permissions ?? {};
@@ -15921,8 +16143,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15921
16143
  if (changed) {
15922
16144
  perms.allow = allow;
15923
16145
  settings.permissions = perms;
15924
- mkdirSync19(projSettingsDir, { recursive: true });
15925
- writeFileSync19(settingsPath, JSON.stringify(settings, null, 2) + "\n");
16146
+ mkdirSync20(projSettingsDir, { recursive: true });
16147
+ writeFileSync20(settingsPath, JSON.stringify(settings, null, 2) + "\n");
15926
16148
  }
15927
16149
  } catch {
15928
16150
  }
@@ -15937,7 +16159,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15937
16159
  let behaviorsFlag = "";
15938
16160
  let legacyFallbackWarned = false;
15939
16161
  if (!useExeAgent && !useBinSymlink) {
15940
- const identityPath2 = path33.join(
16162
+ const identityPath2 = path34.join(
15941
16163
  os18.homedir(),
15942
16164
  ".exe-os",
15943
16165
  "identity",
@@ -15960,7 +16182,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15960
16182
  }
15961
16183
  const behaviorsFile = exportBehaviorsSync(
15962
16184
  employeeName,
15963
- path33.basename(spawnCwd),
16185
+ path34.basename(spawnCwd),
15964
16186
  sessionName
15965
16187
  );
15966
16188
  if (behaviorsFile) {
@@ -15975,16 +16197,16 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
15975
16197
  }
15976
16198
  let sessionContextFlag = "";
15977
16199
  try {
15978
- const ctxDir = path33.join(os18.homedir(), ".exe-os", "session-cache");
15979
- mkdirSync19(ctxDir, { recursive: true });
15980
- const ctxFile = path33.join(ctxDir, `session-context-${sessionName}.md`);
16200
+ const ctxDir = path34.join(os18.homedir(), ".exe-os", "session-cache");
16201
+ mkdirSync20(ctxDir, { recursive: true });
16202
+ const ctxFile = path34.join(ctxDir, `session-context-${sessionName}.md`);
15981
16203
  const ctxContent = [
15982
16204
  `## Session Context`,
15983
16205
  `You are running in tmux session: ${sessionName}.`,
15984
16206
  `Your parent coordinator session is ${exeSession}.`,
15985
16207
  `Your employees (if any) use the -${exeSession} suffix.`
15986
16208
  ].join("\n");
15987
- writeFileSync19(ctxFile, ctxContent);
16209
+ writeFileSync20(ctxFile, ctxContent);
15988
16210
  sessionContextFlag = ` --append-system-prompt-file ${ctxFile}`;
15989
16211
  } catch {
15990
16212
  }
@@ -16067,8 +16289,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
16067
16289
  transport.pipeLog(sessionName, logFile);
16068
16290
  try {
16069
16291
  const mySession = getMySession();
16070
- const dispatchInfo = path33.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
16071
- writeFileSync19(dispatchInfo, JSON.stringify({
16292
+ const dispatchInfo = path34.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
16293
+ writeFileSync20(dispatchInfo, JSON.stringify({
16072
16294
  dispatchedBy: mySession,
16073
16295
  rootExe: exeSession,
16074
16296
  provider: useBinSymlink ? ccProvider : useExeAgent ? opts.provider : useCodex ? "openai" : useOpencode ? "opencode" : "anthropic",
@@ -16143,15 +16365,15 @@ var init_tmux_routing = __esm({
16143
16365
  init_plan_limits();
16144
16366
  init_employees();
16145
16367
  init_agent_symlinks();
16146
- SPAWN_LOCK_DIR = path33.join(os18.homedir(), ".exe-os", "spawn-locks");
16147
- SESSION_CACHE = path33.join(os18.homedir(), ".exe-os", "session-cache");
16368
+ SPAWN_LOCK_DIR = path34.join(os18.homedir(), ".exe-os", "spawn-locks");
16369
+ SESSION_CACHE = path34.join(os18.homedir(), ".exe-os", "session-cache");
16148
16370
  BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
16149
16371
  VALID_SESSION_NAME = /^[a-z]+\d*-[a-zA-Z0-9_]+$/;
16150
16372
  VERIFY_PANE_LINES = 200;
16151
16373
  INTERCOM_DEBOUNCE_MS = 3e4;
16152
16374
  CODEX_DEBOUNCE_MS = 12e4;
16153
- INTERCOM_LOG2 = path33.join(os18.homedir(), ".exe-os", "intercom.log");
16154
- DEBOUNCE_FILE = path33.join(SESSION_CACHE, "intercom-debounce.json");
16375
+ INTERCOM_LOG2 = path34.join(os18.homedir(), ".exe-os", "intercom.log");
16376
+ DEBOUNCE_FILE = path34.join(SESSION_CACHE, "intercom-debounce.json");
16155
16377
  DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
16156
16378
  BUSY_PATTERN = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
16157
16379
  }
@@ -16453,9 +16675,9 @@ __export(active_agent_exports, {
16453
16675
  resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
16454
16676
  writeActiveAgent: () => writeActiveAgent
16455
16677
  });
16456
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync20, mkdirSync as mkdirSync20, unlinkSync as unlinkSync11, readdirSync as readdirSync8 } from "fs";
16678
+ import { readFileSync as readFileSync24, writeFileSync as writeFileSync21, mkdirSync as mkdirSync21, unlinkSync as unlinkSync12, readdirSync as readdirSync8 } from "fs";
16457
16679
  import { execSync as execSync11 } from "child_process";
16458
- import path34 from "path";
16680
+ import path35 from "path";
16459
16681
  function isNameWithOptionalInstance(candidate, baseName) {
16460
16682
  if (candidate === baseName) return true;
16461
16683
  if (!candidate.startsWith(baseName)) return false;
@@ -16499,12 +16721,12 @@ function resolveActiveAgentFromTmuxSession(sessionName) {
16499
16721
  return null;
16500
16722
  }
16501
16723
  function getMarkerPath() {
16502
- return path34.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
16724
+ return path35.join(CACHE_DIR, `active-agent-${getSessionKey()}.json`);
16503
16725
  }
16504
16726
  function writeActiveAgent(agentId, agentRole) {
16505
16727
  try {
16506
- mkdirSync20(CACHE_DIR, { recursive: true });
16507
- writeFileSync20(
16728
+ mkdirSync21(CACHE_DIR, { recursive: true });
16729
+ writeFileSync21(
16508
16730
  getMarkerPath(),
16509
16731
  JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
16510
16732
  );
@@ -16513,7 +16735,7 @@ function writeActiveAgent(agentId, agentRole) {
16513
16735
  }
16514
16736
  function clearActiveAgent() {
16515
16737
  try {
16516
- unlinkSync11(getMarkerPath());
16738
+ unlinkSync12(getMarkerPath());
16517
16739
  } catch {
16518
16740
  }
16519
16741
  }
@@ -16522,14 +16744,14 @@ function getActiveAgent() {
16522
16744
  if (httpCtx) return httpCtx;
16523
16745
  try {
16524
16746
  const markerPath = getMarkerPath();
16525
- const raw = readFileSync23(markerPath, "utf8");
16747
+ const raw = readFileSync24(markerPath, "utf8");
16526
16748
  const data = JSON.parse(raw);
16527
16749
  if (data.agentId) {
16528
16750
  if (data.startedAt) {
16529
16751
  const age = Date.now() - new Date(data.startedAt).getTime();
16530
16752
  if (age > STALE_MS) {
16531
16753
  try {
16532
- unlinkSync11(markerPath);
16754
+ unlinkSync12(markerPath);
16533
16755
  } catch {
16534
16756
  }
16535
16757
  } else {
@@ -16570,14 +16792,14 @@ function getAllActiveAgents() {
16570
16792
  const key = file.slice("active-agent-".length, -".json".length);
16571
16793
  if (key === "undefined") continue;
16572
16794
  try {
16573
- const raw = readFileSync23(path34.join(CACHE_DIR, file), "utf8");
16795
+ const raw = readFileSync24(path35.join(CACHE_DIR, file), "utf8");
16574
16796
  const data = JSON.parse(raw);
16575
16797
  if (!data.agentId) continue;
16576
16798
  if (data.startedAt) {
16577
16799
  const age = Date.now() - new Date(data.startedAt).getTime();
16578
16800
  if (age > STALE_MS) {
16579
16801
  try {
16580
- unlinkSync11(path34.join(CACHE_DIR, file));
16802
+ unlinkSync12(path35.join(CACHE_DIR, file));
16581
16803
  } catch {
16582
16804
  }
16583
16805
  continue;
@@ -16600,11 +16822,11 @@ function getAllActiveAgents() {
16600
16822
  function cleanupSessionMarkers() {
16601
16823
  const key = getSessionKey();
16602
16824
  try {
16603
- unlinkSync11(path34.join(CACHE_DIR, `active-agent-${key}.json`));
16825
+ unlinkSync12(path35.join(CACHE_DIR, `active-agent-${key}.json`));
16604
16826
  } catch {
16605
16827
  }
16606
16828
  try {
16607
- unlinkSync11(path34.join(CACHE_DIR, "active-agent-undefined.json"));
16829
+ unlinkSync12(path35.join(CACHE_DIR, "active-agent-undefined.json"));
16608
16830
  } catch {
16609
16831
  }
16610
16832
  }
@@ -16616,7 +16838,7 @@ var init_active_agent = __esm({
16616
16838
  init_session_key();
16617
16839
  init_agent_context();
16618
16840
  init_employees();
16619
- CACHE_DIR = path34.join(EXE_AI_DIR, "session-cache");
16841
+ CACHE_DIR = path35.join(EXE_AI_DIR, "session-cache");
16620
16842
  STALE_MS = 24 * 60 * 60 * 1e3;
16621
16843
  }
16622
16844
  });
@@ -17269,17 +17491,17 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
17269
17491
  // src/bin/exe-rename.ts
17270
17492
  var exe_rename_exports = {};
17271
17493
  __export(exe_rename_exports, {
17272
- main: () => main5,
17494
+ main: () => main6,
17273
17495
  renameEmployee: () => renameEmployee
17274
17496
  });
17275
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync21, renameSync as renameSync6, unlinkSync as unlinkSync12, existsSync as existsSync29 } from "fs";
17497
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync22, renameSync as renameSync6, unlinkSync as unlinkSync13, existsSync as existsSync29 } from "fs";
17276
17498
  import { execSync as execSync12 } from "child_process";
17277
- import path35 from "path";
17499
+ import path36 from "path";
17278
17500
  import { homedir as homedir4 } from "os";
17279
17501
  async function renameEmployee(oldName, newName, opts = {}) {
17280
- const rosterPath = opts.rosterPath ?? path35.join(homedir4(), ".exe-os", "exe-employees.json");
17281
- const identityDir = opts.identityDir ?? path35.join(homedir4(), ".exe-os", "identity");
17282
- const agentsDir = opts.agentsDir ?? path35.join(homedir4(), ".claude", "agents");
17502
+ const rosterPath = opts.rosterPath ?? path36.join(homedir4(), ".exe-os", "exe-employees.json");
17503
+ const identityDir = opts.identityDir ?? path36.join(homedir4(), ".exe-os", "identity");
17504
+ const agentsDir = opts.agentsDir ?? path36.join(homedir4(), ".claude", "agents");
17283
17505
  const validation = validateEmployeeName(newName);
17284
17506
  if (!validation.valid) {
17285
17507
  return { success: false, error: validation.error };
@@ -17309,39 +17531,39 @@ async function renameEmployee(oldName, newName, opts = {}) {
17309
17531
  undo: () => {
17310
17532
  employee.name = originalName;
17311
17533
  employee.systemPrompt = originalPrompt;
17312
- writeFileSync21(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
17534
+ writeFileSync22(rosterPath, JSON.stringify(employees, null, 2) + "\n", "utf-8");
17313
17535
  }
17314
17536
  });
17315
- const oldIdentityPath = path35.join(identityDir, `${rosterOldName}.md`);
17316
- const newIdentityPath = path35.join(identityDir, `${newName}.md`);
17537
+ const oldIdentityPath = path36.join(identityDir, `${rosterOldName}.md`);
17538
+ const newIdentityPath = path36.join(identityDir, `${newName}.md`);
17317
17539
  if (existsSync29(oldIdentityPath)) {
17318
- const content = readFileSync24(oldIdentityPath, "utf-8");
17540
+ const content = readFileSync25(oldIdentityPath, "utf-8");
17319
17541
  const updatedContent = rewriteRenamedEmployeeContent(content, rosterOldName, newName);
17320
17542
  renameSync6(oldIdentityPath, newIdentityPath);
17321
- writeFileSync21(newIdentityPath, updatedContent, "utf-8");
17543
+ writeFileSync22(newIdentityPath, updatedContent, "utf-8");
17322
17544
  rollbackStack.push({
17323
17545
  description: "restore identity file",
17324
17546
  undo: () => {
17325
17547
  if (existsSync29(newIdentityPath)) {
17326
- writeFileSync21(newIdentityPath, content, "utf-8");
17548
+ writeFileSync22(newIdentityPath, content, "utf-8");
17327
17549
  renameSync6(newIdentityPath, oldIdentityPath);
17328
17550
  }
17329
17551
  }
17330
17552
  });
17331
17553
  }
17332
- const oldAgentPath = path35.join(agentsDir, `${rosterOldName}.md`);
17333
- const newAgentPath = path35.join(agentsDir, `${newName}.md`);
17554
+ const oldAgentPath = path36.join(agentsDir, `${rosterOldName}.md`);
17555
+ const newAgentPath = path36.join(agentsDir, `${newName}.md`);
17334
17556
  if (existsSync29(oldAgentPath)) {
17335
- const agentContent = readFileSync24(oldAgentPath, "utf-8");
17557
+ const agentContent = readFileSync25(oldAgentPath, "utf-8");
17336
17558
  const updatedAgentContent = rewriteRenamedEmployeeContent(agentContent, rosterOldName, newName);
17337
17559
  renameSync6(oldAgentPath, newAgentPath);
17338
- writeFileSync21(newAgentPath, updatedAgentContent, "utf-8");
17560
+ writeFileSync22(newAgentPath, updatedAgentContent, "utf-8");
17339
17561
  rollbackStack.push({
17340
17562
  description: "restore agent file",
17341
17563
  undo: () => {
17342
17564
  if (existsSync29(newAgentPath)) {
17343
17565
  renameSync6(newAgentPath, oldAgentPath);
17344
- writeFileSync21(oldAgentPath, agentContent, "utf-8");
17566
+ writeFileSync22(oldAgentPath, agentContent, "utf-8");
17345
17567
  }
17346
17568
  }
17347
17569
  });
@@ -17423,12 +17645,12 @@ function removeOldSymlinks(name) {
17423
17645
  try {
17424
17646
  const exeBinPath = findExeBin2();
17425
17647
  if (!exeBinPath) return;
17426
- const binDir = path35.dirname(exeBinPath);
17648
+ const binDir = path36.dirname(exeBinPath);
17427
17649
  for (const suffix of ["", "-opencode"]) {
17428
- const linkPath = path35.join(binDir, `${name}${suffix}`);
17650
+ const linkPath = path36.join(binDir, `${name}${suffix}`);
17429
17651
  if (existsSync29(linkPath)) {
17430
17652
  try {
17431
- unlinkSync12(linkPath);
17653
+ unlinkSync13(linkPath);
17432
17654
  } catch {
17433
17655
  }
17434
17656
  }
@@ -17436,7 +17658,7 @@ function removeOldSymlinks(name) {
17436
17658
  } catch {
17437
17659
  }
17438
17660
  }
17439
- async function main5() {
17661
+ async function main6() {
17440
17662
  const args2 = process.argv.slice(2);
17441
17663
  if (args2.length < 2) {
17442
17664
  console.error("Usage: exe-os rename <oldName> <newName>");
@@ -17464,7 +17686,7 @@ var init_exe_rename = __esm({
17464
17686
  init_employee_templates();
17465
17687
  init_is_main();
17466
17688
  if (isMainModule(import.meta.url)) {
17467
- main5().catch((err) => {
17689
+ main6().catch((err) => {
17468
17690
  console.error(err instanceof Error ? err.message : String(err));
17469
17691
  process.exit(1);
17470
17692
  });
@@ -17473,13 +17695,13 @@ var init_exe_rename = __esm({
17473
17695
  });
17474
17696
 
17475
17697
  // src/lib/model-downloader.ts
17476
- import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync30, unlinkSync as unlinkSync13, renameSync as renameSync7 } from "fs";
17698
+ import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync30, unlinkSync as unlinkSync14, renameSync as renameSync7 } from "fs";
17477
17699
  import { mkdir as mkdir6 } from "fs/promises";
17478
17700
  import { createHash as createHash6 } from "crypto";
17479
- import path36 from "path";
17701
+ import path37 from "path";
17480
17702
  async function downloadModel(opts) {
17481
17703
  const { destDir, onProgress, fetchFn = globalThis.fetch } = opts;
17482
- const destPath = path36.join(destDir, LOCAL_FILENAME);
17704
+ const destPath = path37.join(destDir, LOCAL_FILENAME);
17483
17705
  const tmpPath = destPath + ".tmp";
17484
17706
  await mkdir6(destDir, { recursive: true });
17485
17707
  if (existsSync30(destPath)) {
@@ -17494,7 +17716,7 @@ async function downloadModel(opts) {
17494
17716
  let downloaded = 0;
17495
17717
  for (let attempt = 1; attempt <= MAX_RETRIES4; attempt++) {
17496
17718
  try {
17497
- if (existsSync30(tmpPath)) unlinkSync13(tmpPath);
17719
+ if (existsSync30(tmpPath)) unlinkSync14(tmpPath);
17498
17720
  const response = await fetchFn(GGUF_URL, {
17499
17721
  redirect: "follow",
17500
17722
  signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
@@ -17526,7 +17748,7 @@ async function downloadModel(opts) {
17526
17748
  }
17527
17749
  const actualHash = hash.digest("hex");
17528
17750
  if (actualHash !== EXPECTED_SHA256) {
17529
- unlinkSync13(tmpPath);
17751
+ unlinkSync14(tmpPath);
17530
17752
  throw new Error(
17531
17753
  `SHA256 mismatch: expected ${EXPECTED_SHA256}, got ${actualHash}`
17532
17754
  );
@@ -17539,7 +17761,7 @@ async function downloadModel(opts) {
17539
17761
  process.stderr.write(`
17540
17762
  Download attempt ${attempt} failed, retrying...
17541
17763
  `);
17542
- if (existsSync30(tmpPath)) unlinkSync13(tmpPath);
17764
+ if (existsSync30(tmpPath)) unlinkSync14(tmpPath);
17543
17765
  }
17544
17766
  }
17545
17767
  }
@@ -18113,37 +18335,37 @@ __export(session_wrappers_exports, {
18113
18335
  });
18114
18336
  import {
18115
18337
  existsSync as existsSync31,
18116
- readFileSync as readFileSync25,
18117
- writeFileSync as writeFileSync22,
18118
- mkdirSync as mkdirSync21,
18338
+ readFileSync as readFileSync26,
18339
+ writeFileSync as writeFileSync23,
18340
+ mkdirSync as mkdirSync22,
18119
18341
  chmodSync as chmodSync3,
18120
18342
  readdirSync as readdirSync9,
18121
- unlinkSync as unlinkSync14
18343
+ unlinkSync as unlinkSync15
18122
18344
  } from "fs";
18123
18345
  import { execSync as execSync13 } from "child_process";
18124
- import path37 from "path";
18346
+ import path38 from "path";
18125
18347
  import { homedir as homedir5 } from "os";
18126
18348
  function generateSessionWrappers(packageRoot, homeDir) {
18127
18349
  const home = homeDir ?? homedir5();
18128
- const binDir = path37.join(home, ".exe-os", "bin");
18129
- const rosterPath = path37.join(home, ".exe-os", "exe-employees.json");
18350
+ const binDir = path38.join(home, ".exe-os", "bin");
18351
+ const rosterPath = path38.join(home, ".exe-os", "exe-employees.json");
18130
18352
  const shouldMirrorToGlobalBin = homeDir === void 0;
18131
- mkdirSync21(binDir, { recursive: true });
18132
- const exeStartDst = path37.join(binDir, "exe-start");
18353
+ mkdirSync22(binDir, { recursive: true });
18354
+ const exeStartDst = path38.join(binDir, "exe-start");
18133
18355
  const candidates = [
18134
- path37.join(packageRoot, "dist", "bin", "exe-start.sh"),
18135
- path37.join(packageRoot, "src", "bin", "exe-start.sh")
18356
+ path38.join(packageRoot, "dist", "bin", "exe-start.sh"),
18357
+ path38.join(packageRoot, "src", "bin", "exe-start.sh")
18136
18358
  ];
18137
18359
  for (const src of candidates) {
18138
18360
  if (existsSync31(src)) {
18139
- writeFileSync22(exeStartDst, readFileSync25(src));
18361
+ writeFileSync23(exeStartDst, readFileSync26(src));
18140
18362
  chmodSync3(exeStartDst, 493);
18141
18363
  break;
18142
18364
  }
18143
18365
  }
18144
18366
  let employees = [];
18145
18367
  try {
18146
- employees = JSON.parse(readFileSync25(rosterPath, "utf8"));
18368
+ employees = JSON.parse(readFileSync26(rosterPath, "utf8"));
18147
18369
  } catch {
18148
18370
  return { created: 0, pathConfigured: false };
18149
18371
  }
@@ -18153,11 +18375,11 @@ function generateSessionWrappers(packageRoot, homeDir) {
18153
18375
  try {
18154
18376
  for (const f of readdirSync9(binDir)) {
18155
18377
  if (f === "exe-start") continue;
18156
- const fPath = path37.join(binDir, f);
18378
+ const fPath = path38.join(binDir, f);
18157
18379
  try {
18158
- const content = readFileSync25(fPath, "utf8");
18380
+ const content = readFileSync26(fPath, "utf8");
18159
18381
  if (content.includes("exe-start")) {
18160
- unlinkSync14(fPath);
18382
+ unlinkSync15(fPath);
18161
18383
  }
18162
18384
  } catch {
18163
18385
  }
@@ -18171,21 +18393,21 @@ exec "${exeStartDst}" "$0" "$@"
18171
18393
  const globalBinDir = shouldMirrorToGlobalBin ? resolveGlobalBinDir() : null;
18172
18394
  for (const emp of employees) {
18173
18395
  for (let n = 1; n <= MAX_N; n++) {
18174
- writeWrapper(path37.join(binDir, `${emp.name}${n}`), wrapperContent);
18396
+ writeWrapper(path38.join(binDir, `${emp.name}${n}`), wrapperContent);
18175
18397
  if (globalBinDir) {
18176
- writeWrapper(path37.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
18398
+ writeWrapper(path38.join(globalBinDir, `${emp.name}${n}`), wrapperContent);
18177
18399
  }
18178
18400
  created++;
18179
- writeWrapper(path37.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
18401
+ writeWrapper(path38.join(binDir, `${emp.name}${n}-codex`), wrapperContent);
18180
18402
  if (globalBinDir) {
18181
- writeWrapper(path37.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
18403
+ writeWrapper(path38.join(globalBinDir, `${emp.name}${n}-codex`), wrapperContent);
18182
18404
  }
18183
18405
  created++;
18184
18406
  }
18185
18407
  }
18186
18408
  const codexLauncherCandidates = [
18187
- path37.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
18188
- path37.join(packageRoot, "src", "bin", "exe-start-codex.ts")
18409
+ path38.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
18410
+ path38.join(packageRoot, "src", "bin", "exe-start-codex.ts")
18189
18411
  ];
18190
18412
  let codexLauncher = null;
18191
18413
  for (const c of codexLauncherCandidates) {
@@ -18196,11 +18418,11 @@ exec "${exeStartDst}" "$0" "$@"
18196
18418
  }
18197
18419
  if (codexLauncher) {
18198
18420
  for (const emp of employees) {
18199
- const wrapperPath = path37.join(binDir, `${emp.name}-codex`);
18421
+ const wrapperPath = path38.join(binDir, `${emp.name}-codex`);
18200
18422
  const content = `#!/bin/bash
18201
18423
  exec node "${codexLauncher}" --agent ${emp.name} "$@"
18202
18424
  `;
18203
- writeFileSync22(wrapperPath, content);
18425
+ writeFileSync23(wrapperPath, content);
18204
18426
  chmodSync3(wrapperPath, 493);
18205
18427
  created++;
18206
18428
  }
@@ -18210,7 +18432,7 @@ exec node "${codexLauncher}" --agent ${emp.name} "$@"
18210
18432
  }
18211
18433
  function writeWrapper(wrapperPath, content) {
18212
18434
  try {
18213
- writeFileSync22(wrapperPath, content);
18435
+ writeFileSync23(wrapperPath, content);
18214
18436
  chmodSync3(wrapperPath, 493);
18215
18437
  } catch {
18216
18438
  }
@@ -18218,12 +18440,12 @@ function writeWrapper(wrapperPath, content) {
18218
18440
  function resolveGlobalBinDir() {
18219
18441
  try {
18220
18442
  const exeOsPath = execSync13("command -v exe-os", { encoding: "utf8", timeout: 3e3 }).trim().split("\n")[0];
18221
- if (exeOsPath) return path37.dirname(exeOsPath);
18443
+ if (exeOsPath) return path38.dirname(exeOsPath);
18222
18444
  } catch {
18223
18445
  }
18224
18446
  try {
18225
18447
  const prefix = execSync13("npm prefix -g", { encoding: "utf8", timeout: 3e3 }).trim();
18226
- if (prefix) return path37.join(prefix, "bin");
18448
+ if (prefix) return path38.join(prefix, "bin");
18227
18449
  } catch {
18228
18450
  }
18229
18451
  return null;
@@ -18239,24 +18461,24 @@ export PATH="${binDir}:$PATH"
18239
18461
  const shell = process.env.SHELL ?? "/bin/bash";
18240
18462
  const profilePaths = [];
18241
18463
  if (shell.includes("zsh")) {
18242
- profilePaths.push(path37.join(home, ".zshrc"));
18464
+ profilePaths.push(path38.join(home, ".zshrc"));
18243
18465
  } else if (shell.includes("bash")) {
18244
- profilePaths.push(path37.join(home, ".bashrc"));
18245
- profilePaths.push(path37.join(home, ".bash_profile"));
18466
+ profilePaths.push(path38.join(home, ".bashrc"));
18467
+ profilePaths.push(path38.join(home, ".bash_profile"));
18246
18468
  } else {
18247
- profilePaths.push(path37.join(home, ".profile"));
18469
+ profilePaths.push(path38.join(home, ".profile"));
18248
18470
  }
18249
18471
  for (const profilePath of profilePaths) {
18250
18472
  try {
18251
18473
  let content = "";
18252
18474
  try {
18253
- content = readFileSync25(profilePath, "utf8");
18475
+ content = readFileSync26(profilePath, "utf8");
18254
18476
  } catch {
18255
18477
  }
18256
18478
  if (content.includes(".exe-os/bin")) {
18257
18479
  return false;
18258
18480
  }
18259
- writeFileSync22(profilePath, content + exportLine);
18481
+ writeFileSync23(profilePath, content + exportLine);
18260
18482
  return true;
18261
18483
  } catch {
18262
18484
  continue;
@@ -18279,40 +18501,40 @@ __export(setup_wizard_exports, {
18279
18501
  validateModel: () => validateModel
18280
18502
  });
18281
18503
  import crypto13 from "crypto";
18282
- import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync26, writeFileSync as writeFileSync23, unlinkSync as unlinkSync15 } from "fs";
18504
+ import { existsSync as existsSync32, mkdirSync as mkdirSync23, readFileSync as readFileSync27, writeFileSync as writeFileSync24, unlinkSync as unlinkSync16 } from "fs";
18283
18505
  import os19 from "os";
18284
- import path38 from "path";
18506
+ import path39 from "path";
18285
18507
  import { createInterface as createInterface4 } from "readline";
18286
18508
  function findPackageRoot2() {
18287
- let dir = path38.dirname(new URL(import.meta.url).pathname);
18288
- const root = path38.parse(dir).root;
18509
+ let dir = path39.dirname(new URL(import.meta.url).pathname);
18510
+ const root = path39.parse(dir).root;
18289
18511
  while (dir !== root) {
18290
- const pkgPath = path38.join(dir, "package.json");
18512
+ const pkgPath = path39.join(dir, "package.json");
18291
18513
  if (existsSync32(pkgPath)) {
18292
18514
  try {
18293
- const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
18515
+ const pkg = JSON.parse(readFileSync27(pkgPath, "utf-8"));
18294
18516
  if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
18295
18517
  } catch {
18296
18518
  }
18297
18519
  }
18298
- dir = path38.dirname(dir);
18520
+ dir = path39.dirname(dir);
18299
18521
  }
18300
18522
  return null;
18301
18523
  }
18302
18524
  function loadSetupState() {
18303
18525
  try {
18304
- return JSON.parse(readFileSync26(SETUP_STATE_PATH, "utf8"));
18526
+ return JSON.parse(readFileSync27(SETUP_STATE_PATH, "utf8"));
18305
18527
  } catch {
18306
18528
  return { completedSteps: [], startedAt: (/* @__PURE__ */ new Date()).toISOString() };
18307
18529
  }
18308
18530
  }
18309
18531
  function saveSetupState(state) {
18310
- mkdirSync22(path38.dirname(SETUP_STATE_PATH), { recursive: true });
18311
- writeFileSync23(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
18532
+ mkdirSync23(path39.dirname(SETUP_STATE_PATH), { recursive: true });
18533
+ writeFileSync24(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
18312
18534
  }
18313
18535
  function clearSetupState() {
18314
18536
  try {
18315
- unlinkSync15(SETUP_STATE_PATH);
18537
+ unlinkSync16(SETUP_STATE_PATH);
18316
18538
  } catch {
18317
18539
  }
18318
18540
  }
@@ -18358,7 +18580,7 @@ async function validateModel(log) {
18358
18580
  if (totalGB <= 8 || isLowMemory()) {
18359
18581
  log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
18360
18582
  log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
18361
- const modelPath = path38.join(MODELS_DIR, LOCAL_FILENAME);
18583
+ const modelPath = path39.join(MODELS_DIR, LOCAL_FILENAME);
18362
18584
  if (existsSync32(modelPath)) {
18363
18585
  const { statSync: statSync8 } = await import("fs");
18364
18586
  const size = statSync8(modelPath).size;
@@ -18645,10 +18867,10 @@ async function runSetupWizard(opts = {}) {
18645
18867
  await saveConfig(config);
18646
18868
  log("");
18647
18869
  try {
18648
- const claudeJsonPath = path38.join(os19.homedir(), ".claude.json");
18870
+ const claudeJsonPath = path39.join(os19.homedir(), ".claude.json");
18649
18871
  let claudeJson = {};
18650
18872
  try {
18651
- claudeJson = JSON.parse(readFileSync26(claudeJsonPath, "utf8"));
18873
+ claudeJson = JSON.parse(readFileSync27(claudeJsonPath, "utf8"));
18652
18874
  } catch {
18653
18875
  }
18654
18876
  if (!claudeJson.projects) claudeJson.projects = {};
@@ -18657,7 +18879,7 @@ async function runSetupWizard(opts = {}) {
18657
18879
  if (!projects[dir]) projects[dir] = {};
18658
18880
  projects[dir].hasTrustDialogAccepted = true;
18659
18881
  }
18660
- writeFileSync23(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
18882
+ writeFileSync24(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
18661
18883
  } catch {
18662
18884
  }
18663
18885
  state.completedSteps.push(5);
@@ -18671,7 +18893,7 @@ async function runSetupWizard(opts = {}) {
18671
18893
  const prefs = { ...existingPrefs };
18672
18894
  log("=== Config Defaults ===");
18673
18895
  log("");
18674
- const ghosttyDetected = existsSync32(path38.join(os19.homedir(), ".config", "ghostty")) || existsSync32(path38.join(os19.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
18896
+ const ghosttyDetected = existsSync32(path39.join(os19.homedir(), ".config", "ghostty")) || existsSync32(path39.join(os19.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
18675
18897
  if (ghosttyDetected) {
18676
18898
  const ghosttyAnswer = await ask3(rl, "Detected Ghostty terminal. Use exe-os Ghostty defaults? (Y/n) ");
18677
18899
  prefs.ghostty = ghosttyAnswer.toLowerCase() !== "n";
@@ -18809,9 +19031,9 @@ async function runSetupWizard(opts = {}) {
18809
19031
  const cooIdentityContent = getIdentityTemplate("coo");
18810
19032
  if (cooIdentityContent) {
18811
19033
  const cooIdPath = identityPath2(cooName);
18812
- mkdirSync22(path38.dirname(cooIdPath), { recursive: true });
19034
+ mkdirSync23(path39.dirname(cooIdPath), { recursive: true });
18813
19035
  const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
18814
- writeFileSync23(cooIdPath, replaced, "utf-8");
19036
+ writeFileSync24(cooIdPath, replaced, "utf-8");
18815
19037
  }
18816
19038
  registerBinSymlinks2(cooName);
18817
19039
  createdEmployees.push({ name: cooName, role: "COO" });
@@ -18927,9 +19149,9 @@ async function runSetupWizard(opts = {}) {
18927
19149
  const ctoIdentityContent = getIdentityTemplate("cto");
18928
19150
  if (ctoIdentityContent) {
18929
19151
  const ctoIdPath = identityPath2(ctoName);
18930
- mkdirSync22(path38.dirname(ctoIdPath), { recursive: true });
19152
+ mkdirSync23(path39.dirname(ctoIdPath), { recursive: true });
18931
19153
  const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
18932
- writeFileSync23(ctoIdPath, replaced, "utf-8");
19154
+ writeFileSync24(ctoIdPath, replaced, "utf-8");
18933
19155
  }
18934
19156
  registerBinSymlinks2(ctoName);
18935
19157
  createdEmployees.push({ name: ctoName, role: "CTO" });
@@ -18950,9 +19172,9 @@ async function runSetupWizard(opts = {}) {
18950
19172
  const cmoIdentityContent = getIdentityTemplate("cmo");
18951
19173
  if (cmoIdentityContent) {
18952
19174
  const cmoIdPath = identityPath2(cmoName);
18953
- mkdirSync22(path38.dirname(cmoIdPath), { recursive: true });
19175
+ mkdirSync23(path39.dirname(cmoIdPath), { recursive: true });
18954
19176
  const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
18955
- writeFileSync23(cmoIdPath, replaced, "utf-8");
19177
+ writeFileSync24(cmoIdPath, replaced, "utf-8");
18956
19178
  }
18957
19179
  registerBinSymlinks2(cmoName);
18958
19180
  createdEmployees.push({ name: cmoName, role: "CMO" });
@@ -18975,7 +19197,7 @@ async function runSetupWizard(opts = {}) {
18975
19197
  log(`Session shortcuts generated (${cooName}1, ${cooName}2, ...)`);
18976
19198
  }
18977
19199
  if (wrapResult.pathConfigured) {
18978
- const binDir = path38.join(os19.homedir(), ".exe-os", "bin");
19200
+ const binDir = path39.join(os19.homedir(), ".exe-os", "bin");
18979
19201
  process.env.PATH = `${binDir}:${process.env.PATH ?? ""}`;
18980
19202
  pathJustConfigured = true;
18981
19203
  }
@@ -19018,7 +19240,7 @@ async function runSetupWizard(opts = {}) {
19018
19240
  const pkgRoot2 = findPackageRoot2();
19019
19241
  if (pkgRoot2) {
19020
19242
  try {
19021
- version = JSON.parse(readFileSync26(path38.join(pkgRoot2, "package.json"), "utf-8")).version;
19243
+ version = JSON.parse(readFileSync27(path39.join(pkgRoot2, "package.json"), "utf-8")).version;
19022
19244
  } catch {
19023
19245
  }
19024
19246
  }
@@ -19034,6 +19256,7 @@ async function runSetupWizard(opts = {}) {
19034
19256
  log("");
19035
19257
  log(" Recommended start: Phase 1 \u2014 talk to your COO first");
19036
19258
  log(" Check/change phase: exe-os org phase");
19259
+ log(" Verify support intake: exe-os support test");
19037
19260
  log(" Unlock executives later: exe-os org unlock executives");
19038
19261
  log("");
19039
19262
  log(` cd into a project folder: cd ~/my-project`);
@@ -19056,46 +19279,46 @@ var init_setup_wizard = __esm({
19056
19279
  init_config();
19057
19280
  init_keychain();
19058
19281
  init_model_downloader();
19059
- SETUP_STATE_PATH = path38.join(os19.homedir(), ".exe-os", "setup-state.json");
19282
+ SETUP_STATE_PATH = path39.join(os19.homedir(), ".exe-os", "setup-state.json");
19060
19283
  }
19061
19284
  });
19062
19285
 
19063
19286
  // src/lib/update-backup.ts
19064
19287
  import { copyFile, readFile as readFile6, readdir as readdir3, writeFile as writeFile7, rm as rm2, mkdir as mkdir7, cp } from "fs/promises";
19065
19288
  import { existsSync as existsSync33 } from "fs";
19066
- import path39 from "path";
19289
+ import path40 from "path";
19067
19290
  import os20 from "os";
19068
19291
  function resolveDataDir2() {
19069
19292
  if (process.env.EXE_OS_DIR) return process.env.EXE_OS_DIR;
19070
19293
  if (process.env.EXE_MEM_DIR) return process.env.EXE_MEM_DIR;
19071
- return path39.join(os20.homedir(), ".exe-os");
19294
+ return path40.join(os20.homedir(), ".exe-os");
19072
19295
  }
19073
19296
  function externalBackupTargets(homeDir) {
19074
19297
  return [
19075
- { name: "claude.json", path: path39.join(homeDir, ".claude.json") },
19076
- { name: "claude-settings.json", path: path39.join(homeDir, ".claude", "settings.json") },
19077
- { name: "claude-CLAUDE.md", path: path39.join(homeDir, ".claude", "CLAUDE.md") },
19078
- { name: "tmux.conf", path: path39.join(homeDir, ".tmux.conf") },
19079
- { name: "zshrc", path: path39.join(homeDir, ".zshrc") },
19080
- { name: "bashrc", path: path39.join(homeDir, ".bashrc") },
19081
- { name: "ghostty-config", path: path39.join(homeDir, ".config", "ghostty", "config") },
19082
- { name: "codex-config.toml", path: path39.join(homeDir, ".codex", "config.toml") },
19083
- { name: "codex-hooks.json", path: path39.join(homeDir, ".codex", "hooks.json") },
19084
- { name: "opencode-config.json", path: path39.join(homeDir, ".config", "opencode", "opencode.json") }
19298
+ { name: "claude.json", path: path40.join(homeDir, ".claude.json") },
19299
+ { name: "claude-settings.json", path: path40.join(homeDir, ".claude", "settings.json") },
19300
+ { name: "claude-CLAUDE.md", path: path40.join(homeDir, ".claude", "CLAUDE.md") },
19301
+ { name: "tmux.conf", path: path40.join(homeDir, ".tmux.conf") },
19302
+ { name: "zshrc", path: path40.join(homeDir, ".zshrc") },
19303
+ { name: "bashrc", path: path40.join(homeDir, ".bashrc") },
19304
+ { name: "ghostty-config", path: path40.join(homeDir, ".config", "ghostty", "config") },
19305
+ { name: "codex-config.toml", path: path40.join(homeDir, ".codex", "config.toml") },
19306
+ { name: "codex-hooks.json", path: path40.join(homeDir, ".codex", "hooks.json") },
19307
+ { name: "opencode-config.json", path: path40.join(homeDir, ".config", "opencode", "opencode.json") }
19085
19308
  ];
19086
19309
  }
19087
19310
  async function createUpdateBackup(currentVersion, dataDir2, homeDir = os20.homedir()) {
19088
19311
  const dir = dataDir2 ?? resolveDataDir2();
19089
- const backupDir = path39.join(dir, BACKUP_DIR_NAME);
19312
+ const backupDir = path40.join(dir, BACKUP_DIR_NAME);
19090
19313
  if (existsSync33(backupDir)) {
19091
19314
  await rm2(backupDir, { recursive: true, force: true });
19092
19315
  }
19093
19316
  await mkdir7(backupDir, { recursive: true });
19094
19317
  const backedUpFiles = [];
19095
19318
  for (const target of BACKUP_TARGETS) {
19096
- const src = path39.join(dir, target.name);
19319
+ const src = path40.join(dir, target.name);
19097
19320
  if (!existsSync33(src)) continue;
19098
- const dest = path39.join(backupDir, target.name);
19321
+ const dest = path40.join(backupDir, target.name);
19099
19322
  if (target.type === "file") {
19100
19323
  await copyFile(src, dest);
19101
19324
  } else {
@@ -19106,18 +19329,18 @@ async function createUpdateBackup(currentVersion, dataDir2, homeDir = os20.homed
19106
19329
  const entries = await readdir3(dir, { withFileTypes: true });
19107
19330
  for (const entry of entries) {
19108
19331
  if (entry.isFile() && entry.name.endsWith(".db") && entry.name !== BACKUP_DIR_NAME) {
19109
- const src = path39.join(dir, entry.name);
19110
- const dest = path39.join(backupDir, entry.name);
19332
+ const src = path40.join(dir, entry.name);
19333
+ const dest = path40.join(backupDir, entry.name);
19111
19334
  await copyFile(src, dest);
19112
19335
  backedUpFiles.push(entry.name);
19113
19336
  }
19114
19337
  }
19115
19338
  const externalFiles = [];
19116
- const externalDir = path39.join(backupDir, "external");
19339
+ const externalDir = path40.join(backupDir, "external");
19117
19340
  for (const target of externalBackupTargets(homeDir)) {
19118
19341
  if (!existsSync33(target.path)) continue;
19119
19342
  await mkdir7(externalDir, { recursive: true });
19120
- await copyFile(target.path, path39.join(externalDir, target.name));
19343
+ await copyFile(target.path, path40.join(externalDir, target.name));
19121
19344
  externalFiles.push(target);
19122
19345
  }
19123
19346
  const manifest = {
@@ -19127,15 +19350,15 @@ async function createUpdateBackup(currentVersion, dataDir2, homeDir = os20.homed
19127
19350
  ...externalFiles.length > 0 ? { externalFiles } : {}
19128
19351
  };
19129
19352
  await writeFile7(
19130
- path39.join(backupDir, "manifest.json"),
19353
+ path40.join(backupDir, "manifest.json"),
19131
19354
  JSON.stringify(manifest, null, 2) + "\n"
19132
19355
  );
19133
19356
  return manifest;
19134
19357
  }
19135
19358
  async function restoreFromBackup(dataDir2) {
19136
19359
  const dir = dataDir2 ?? resolveDataDir2();
19137
- const backupDir = path39.join(dir, BACKUP_DIR_NAME);
19138
- const manifestPath = path39.join(backupDir, "manifest.json");
19360
+ const backupDir = path40.join(dir, BACKUP_DIR_NAME);
19361
+ const manifestPath = path40.join(backupDir, "manifest.json");
19139
19362
  if (!existsSync33(manifestPath)) {
19140
19363
  throw new Error(
19141
19364
  `No backup found at ${backupDir}. Nothing to restore.`
@@ -19145,8 +19368,8 @@ async function restoreFromBackup(dataDir2) {
19145
19368
  await readFile6(manifestPath, "utf-8")
19146
19369
  );
19147
19370
  for (const fileName of manifest.files) {
19148
- const src = path39.join(backupDir, fileName);
19149
- const dest = path39.join(dir, fileName);
19371
+ const src = path40.join(backupDir, fileName);
19372
+ const dest = path40.join(dir, fileName);
19150
19373
  if (!existsSync33(src)) continue;
19151
19374
  const stat2 = await import("fs/promises").then((m) => m.stat(src));
19152
19375
  if (stat2.isDirectory()) {
@@ -19156,16 +19379,16 @@ async function restoreFromBackup(dataDir2) {
19156
19379
  }
19157
19380
  }
19158
19381
  for (const external of manifest.externalFiles ?? []) {
19159
- const src = path39.join(backupDir, "external", external.name);
19382
+ const src = path40.join(backupDir, "external", external.name);
19160
19383
  if (!existsSync33(src)) continue;
19161
- await mkdir7(path39.dirname(external.path), { recursive: true });
19384
+ await mkdir7(path40.dirname(external.path), { recursive: true });
19162
19385
  await copyFile(src, external.path);
19163
19386
  }
19164
19387
  return manifest;
19165
19388
  }
19166
19389
  async function deleteBackup(dataDir2) {
19167
19390
  const dir = dataDir2 ?? resolveDataDir2();
19168
- const backupDir = path39.join(dir, BACKUP_DIR_NAME);
19391
+ const backupDir = path40.join(dir, BACKUP_DIR_NAME);
19169
19392
  if (existsSync33(backupDir)) {
19170
19393
  await rm2(backupDir, { recursive: true, force: true });
19171
19394
  }
@@ -19191,21 +19414,21 @@ var init_update_backup = __esm({
19191
19414
 
19192
19415
  // src/lib/update-check.ts
19193
19416
  import { execSync as execSync14 } from "child_process";
19194
- import { readFileSync as readFileSync27 } from "fs";
19195
- import path40 from "path";
19417
+ import { readFileSync as readFileSync28 } from "fs";
19418
+ import path41 from "path";
19196
19419
  function getLocalVersion(packageRoot) {
19197
- const pkgPath = path40.join(packageRoot, "package.json");
19198
- const pkg = JSON.parse(readFileSync27(pkgPath, "utf-8"));
19420
+ const pkgPath = path41.join(packageRoot, "package.json");
19421
+ const pkg = JSON.parse(readFileSync28(pkgPath, "utf-8"));
19199
19422
  return pkg.version;
19200
19423
  }
19201
19424
  function getRemoteVersion() {
19202
19425
  try {
19203
- const output = execSync14("npm view @askexenow/exe-os version", {
19426
+ const output2 = execSync14("npm view @askexenow/exe-os version", {
19204
19427
  encoding: "utf-8",
19205
19428
  timeout: 15e3,
19206
19429
  stdio: ["pipe", "pipe", "pipe"]
19207
19430
  });
19208
- return output.trim();
19431
+ return output2.trim();
19209
19432
  } catch {
19210
19433
  return null;
19211
19434
  }
@@ -19415,6 +19638,15 @@ async function runUpdate(cliArgs) {
19415
19638
  }
19416
19639
  } catch {
19417
19640
  }
19641
+ try {
19642
+ console.log("\u{1FA7A} Checking AskExe support intake...");
19643
+ execSync15("exe-os support health", {
19644
+ stdio: ["pipe", "inherit", "inherit"],
19645
+ timeout: 3e4
19646
+ });
19647
+ } catch {
19648
+ console.log(" \u26A0\uFE0F Support health check failed. Run: exe-os support test");
19649
+ }
19418
19650
  console.log("\n\u{1F680} Ready. Start your COO session to use the new version.\n");
19419
19651
  }
19420
19652
  var init_update = __esm({
@@ -19436,10 +19668,10 @@ var init_update = __esm({
19436
19668
  // src/lib/stack-update.ts
19437
19669
  import { execFileSync as execFileSync4 } from "child_process";
19438
19670
  import { createVerify, verify as verifySignature } from "crypto";
19439
- import { existsSync as existsSync34, mkdirSync as mkdirSync23, readdirSync as readdirSync10, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as writeFileSync24 } from "fs";
19671
+ import { existsSync as existsSync34, mkdirSync as mkdirSync24, readdirSync as readdirSync10, readFileSync as readFileSync29, renameSync as renameSync8, writeFileSync as writeFileSync25 } from "fs";
19440
19672
  import http from "http";
19441
19673
  import https from "https";
19442
- import path41 from "path";
19674
+ import path42 from "path";
19443
19675
  function isSignedEnvelope(value) {
19444
19676
  return !!value && typeof value === "object" && "manifest" in value && "signature" in value;
19445
19677
  }
@@ -19473,21 +19705,21 @@ function stableJson(value) {
19473
19705
  return `{${Object.keys(obj).sort().map((key) => `${JSON.stringify(key)}:${stableJson(obj[key])}`).join(",")}}`;
19474
19706
  }
19475
19707
  function findLatestBackupEnvFile(envFile) {
19476
- const backupDir = path41.join(path41.dirname(envFile), ".exe-stack-backups");
19708
+ const backupDir = path42.join(path42.dirname(envFile), ".exe-stack-backups");
19477
19709
  if (!existsSync34(backupDir)) return null;
19478
19710
  const backups = readdirSync10(backupDir).filter((name) => name.startsWith("env-") && name.endsWith(".bak")).sort();
19479
19711
  const latest = backups.at(-1);
19480
- return latest ? path41.join(backupDir, latest) : null;
19712
+ return latest ? path42.join(backupDir, latest) : null;
19481
19713
  }
19482
19714
  async function rollbackStackUpdate(options) {
19483
19715
  const exec2 = options.exec ?? defaultExec;
19484
- const backupEnvFile = options.lockFile && existsSync34(options.lockFile) ? JSON.parse(readFileSync28(options.lockFile, "utf8")).backupEnvFile : void 0;
19716
+ const backupEnvFile = options.lockFile && existsSync34(options.lockFile) ? JSON.parse(readFileSync29(options.lockFile, "utf8")).backupEnvFile : void 0;
19485
19717
  const rollbackEnv = backupEnvFile && existsSync34(backupEnvFile) ? backupEnvFile : findLatestBackupEnvFile(options.envFile);
19486
19718
  if (!rollbackEnv) throw new Error(`No stack backup env found beside ${options.envFile}`);
19487
- writeFileSync24(options.envFile, readFileSync28(rollbackEnv), { mode: 384 });
19719
+ writeFileSync25(options.envFile, readFileSync29(rollbackEnv), { mode: 384 });
19488
19720
  const composeArgs = ["compose", "--file", options.composeFile, "--env-file", options.envFile];
19489
19721
  exec2("docker", [...composeArgs, "up", "-d"]);
19490
- return { status: "rolled_back", targetVersion: "previous", changes: [], backupEnvFile: rollbackEnv, lockFile: options.lockFile ?? path41.join(path41.dirname(options.envFile), ".exe-stack-lock.json") };
19722
+ return { status: "rolled_back", targetVersion: "previous", changes: [], backupEnvFile: rollbackEnv, lockFile: options.lockFile ?? path42.join(path42.dirname(options.envFile), ".exe-stack-lock.json") };
19491
19723
  }
19492
19724
  function parseStackManifest(raw, publicKey) {
19493
19725
  const parsedRaw = JSON.parse(raw);
@@ -19512,7 +19744,7 @@ function parseStackManifest(raw, publicKey) {
19512
19744
  }
19513
19745
  async function loadStackManifest(ref, fetchText = defaultFetchText, publicKey, authToken) {
19514
19746
  if (/^https?:\/\//.test(ref)) return parseStackManifest(await fetchTextWithAuth(ref, fetchText, authToken), publicKey);
19515
- return parseStackManifest(readFileSync28(ref, "utf8"), publicKey);
19747
+ return parseStackManifest(readFileSync29(ref, "utf8"), publicKey);
19516
19748
  }
19517
19749
  async function fetchTextWithAuth(ref, fetchText, authToken) {
19518
19750
  if (!authToken || fetchText !== defaultFetchText) return fetchText(ref);
@@ -19641,9 +19873,9 @@ Emergency override requires --break-glass <reason> and writes an audit file.`
19641
19873
  function writeBreakGlassAudit(plan, issues, options) {
19642
19874
  const now2 = options.now ?? (() => /* @__PURE__ */ new Date());
19643
19875
  const stamp = now2().toISOString().replace(/[:.]/g, "-");
19644
- const defaultDir = existsSync34("exe/output") ? "exe/output" : path41.dirname(options.envFile ?? ".");
19645
- const auditFile = options.breakGlassAuditFile ?? path41.join(defaultDir, `stack-update-break-glass-${stamp}.md`);
19646
- mkdirSync23(path41.dirname(auditFile), { recursive: true });
19876
+ const defaultDir = existsSync34("exe/output") ? "exe/output" : path42.dirname(options.envFile ?? ".");
19877
+ const auditFile = options.breakGlassAuditFile ?? path42.join(defaultDir, `stack-update-break-glass-${stamp}.md`);
19878
+ mkdirSync24(path42.dirname(auditFile), { recursive: true });
19647
19879
  const body = [
19648
19880
  `# Stack Update Break-Glass Audit \u2014 ${now2().toISOString()}`,
19649
19881
  "",
@@ -19657,7 +19889,7 @@ function writeBreakGlassAudit(plan, issues, options) {
19657
19889
  "Return this deployment to the standard pinned GHCR image path immediately after the emergency is resolved.",
19658
19890
  ""
19659
19891
  ].join("\n");
19660
- writeFileSync24(auditFile, body, { mode: 384 });
19892
+ writeFileSync25(auditFile, body, { mode: 384 });
19661
19893
  console.warn(`[stack-update] BREAK-GLASS deploy override recorded: ${auditFile}`);
19662
19894
  }
19663
19895
  function assertBreakingChangesAllowed(plan, allowedIds) {
@@ -19679,33 +19911,33 @@ async function runStackUpdate(options) {
19679
19911
  const now2 = options.now ?? (() => /* @__PURE__ */ new Date());
19680
19912
  if (options.rollback) return rollbackStackUpdate(options);
19681
19913
  const manifest = await loadStackManifest(options.manifestRef, options.fetchText, options.manifestPublicKey, options.manifestAuthToken);
19682
- const envRaw = readFileSync28(options.envFile, "utf8");
19914
+ const envRaw = readFileSync29(options.envFile, "utf8");
19683
19915
  const plan = createStackUpdatePlan(manifest, envRaw, options.targetVersion);
19684
19916
  assertBreakingChangesAllowed(plan, options.allowedBreakingChangeIds ?? []);
19685
19917
  assertDeploymentScopeAllowed(plan, options.deploymentPersona ?? "customer");
19686
19918
  const plannedEnvRaw = patchEnv(envRaw, Object.fromEntries(plan.changes.map((c) => [c.key, c.after])));
19687
- const composeRaw = readFileSync28(options.composeFile, "utf8");
19919
+ const composeRaw = readFileSync29(options.composeFile, "utf8");
19688
19920
  assertProductionDeployGate(plan, plannedEnvRaw, composeRaw, {
19689
19921
  breakGlassReason: options.breakGlassReason,
19690
19922
  breakGlassAuditFile: options.breakGlassAuditFile,
19691
19923
  now: now2,
19692
19924
  envFile: options.envFile
19693
19925
  });
19694
- const lockFile = options.lockFile ?? path41.join(path41.dirname(options.envFile), ".exe-stack-lock.json");
19926
+ const lockFile = options.lockFile ?? path42.join(path42.dirname(options.envFile), ".exe-stack-lock.json");
19695
19927
  const previousVersion = readCurrentStackVersion(lockFile);
19696
19928
  if (options.dryRun || plan.changes.length === 0) {
19697
19929
  return { status: "planned", targetVersion: plan.targetVersion, changes: plan.changes, lockFile };
19698
19930
  }
19699
19931
  await postDeployAudit(options, "started", plan.targetVersion, previousVersion);
19700
- const backupDir = path41.join(path41.dirname(options.envFile), ".exe-stack-backups");
19701
- mkdirSync23(backupDir, { recursive: true });
19932
+ const backupDir = path42.join(path42.dirname(options.envFile), ".exe-stack-backups");
19933
+ mkdirSync24(backupDir, { recursive: true });
19702
19934
  const stamp = now2().toISOString().replace(/[:.]/g, "-");
19703
- const backupEnvFile = path41.join(backupDir, `env-${stamp}.bak`);
19704
- writeFileSync24(backupEnvFile, envRaw, { mode: 384 });
19935
+ const backupEnvFile = path42.join(backupDir, `env-${stamp}.bak`);
19936
+ writeFileSync25(backupEnvFile, envRaw, { mode: 384 });
19705
19937
  const updates = Object.fromEntries(plan.changes.map((c) => [c.key, c.after]));
19706
19938
  const patched = patchEnv(envRaw, updates);
19707
19939
  const tmp = `${options.envFile}.tmp-${process.pid}`;
19708
- writeFileSync24(tmp, patched, { mode: 384 });
19940
+ writeFileSync25(tmp, patched, { mode: 384 });
19709
19941
  renameSync8(tmp, options.envFile);
19710
19942
  const composeArgs = ["compose", "--file", options.composeFile, "--env-file", options.envFile];
19711
19943
  let registryForLogout;
@@ -19718,11 +19950,11 @@ async function runStackUpdate(options) {
19718
19950
  exec2("docker", [...composeArgs, "pull"]);
19719
19951
  exec2("docker", [...composeArgs, "up", "-d"]);
19720
19952
  await verifyReleaseHealth(plan.release, options.healthRetries ?? 12, options.healthDelayMs ?? 5e3);
19721
- writeFileSync24(lockFile, JSON.stringify({ stackVersion: plan.targetVersion, updatedAt: now2().toISOString(), backupEnvFile, services: plan.release.services }, null, 2) + "\n");
19953
+ writeFileSync25(lockFile, JSON.stringify({ stackVersion: plan.targetVersion, updatedAt: now2().toISOString(), backupEnvFile, services: plan.release.services }, null, 2) + "\n");
19722
19954
  await postDeployAudit(options, "success", plan.targetVersion, previousVersion, void 0, { changes: plan.changes.length });
19723
19955
  return { status: "updated", targetVersion: plan.targetVersion, changes: plan.changes, backupEnvFile, lockFile };
19724
19956
  } catch (err) {
19725
- writeFileSync24(options.envFile, envRaw, { mode: 384 });
19957
+ writeFileSync25(options.envFile, envRaw, { mode: 384 });
19726
19958
  try {
19727
19959
  exec2("docker", [...composeArgs, "up", "-d"]);
19728
19960
  } catch {
@@ -19755,7 +19987,7 @@ async function fetchImageCredentials(options) {
19755
19987
  function readCurrentStackVersion(lockFile) {
19756
19988
  if (!existsSync34(lockFile)) return void 0;
19757
19989
  try {
19758
- const parsed = JSON.parse(readFileSync28(lockFile, "utf8"));
19990
+ const parsed = JSON.parse(readFileSync29(lockFile, "utf8"));
19759
19991
  return parsed.stackVersion;
19760
19992
  } catch {
19761
19993
  return void 0;
@@ -19843,8 +20075,8 @@ async function defaultPostJson(url, body, authToken) {
19843
20075
  if (!res.ok) throw new Error(`Failed to POST ${url}: HTTP ${res.status}`);
19844
20076
  }
19845
20077
  function defaultStackPaths() {
19846
- const cwdCompose = path41.resolve("docker-compose.yml");
19847
- const cwdEnv = path41.resolve(".env");
20078
+ const cwdCompose = path42.resolve("docker-compose.yml");
20079
+ const cwdEnv = path42.resolve(".env");
19848
20080
  return {
19849
20081
  composeFile: process.env.EXE_STACK_COMPOSE_FILE || (existsSync34(cwdCompose) ? cwdCompose : "/opt/exe-stack/docker-compose.yml"),
19850
20082
  envFile: process.env.EXE_STACK_ENV_FILE || (existsSync34(cwdEnv) ? cwdEnv : "/opt/exe-stack/.env"),
@@ -19858,7 +20090,7 @@ function defaultStackPaths() {
19858
20090
  function loadDefaultPublicKey() {
19859
20091
  if (process.env.EXE_STACK_PUBLIC_KEY) return process.env.EXE_STACK_PUBLIC_KEY;
19860
20092
  if (process.env.EXE_STACK_PUBLIC_KEY_FILE && existsSync34(process.env.EXE_STACK_PUBLIC_KEY_FILE)) {
19861
- return readFileSync28(process.env.EXE_STACK_PUBLIC_KEY_FILE, "utf8");
20093
+ return readFileSync29(process.env.EXE_STACK_PUBLIC_KEY_FILE, "utf8");
19862
20094
  }
19863
20095
  return void 0;
19864
20096
  }
@@ -19873,9 +20105,9 @@ var init_stack_update = __esm({
19873
20105
  // src/bin/stack-update.ts
19874
20106
  var stack_update_exports = {};
19875
20107
  __export(stack_update_exports, {
19876
- runStackUpdateCli: () => main6
20108
+ runStackUpdateCli: () => main7
19877
20109
  });
19878
- import { readFileSync as readFileSync29 } from "fs";
20110
+ import { readFileSync as readFileSync30 } from "fs";
19879
20111
  function parseArgs4(args2) {
19880
20112
  const defaults = defaultStackPaths();
19881
20113
  const opts = {
@@ -19907,8 +20139,8 @@ function parseArgs4(args2) {
19907
20139
  else if (arg === "--env-file") opts.envFile = next();
19908
20140
  else if (arg.startsWith("--env-file=")) opts.envFile = arg.split("=").slice(1).join("=");
19909
20141
  else if (arg === "--lock-file") opts.lockFile = next();
19910
- else if (arg === "--public-key") opts.manifestPublicKey = readFileSync29(next(), "utf8");
19911
- else if (arg.startsWith("--public-key=")) opts.manifestPublicKey = readFileSync29(arg.split("=").slice(1).join("="), "utf8");
20142
+ else if (arg === "--public-key") opts.manifestPublicKey = readFileSync30(next(), "utf8");
20143
+ else if (arg.startsWith("--public-key=")) opts.manifestPublicKey = readFileSync30(arg.split("=").slice(1).join("="), "utf8");
19912
20144
  else if (arg === "--auth-token") opts.manifestAuthToken = next();
19913
20145
  else if (arg.startsWith("--auth-token=")) opts.manifestAuthToken = arg.split("=").slice(1).join("=");
19914
20146
  else if (arg === "--auth-token-env") opts.manifestAuthToken = process.env[next()] ?? "";
@@ -19999,7 +20231,7 @@ function printBreaking(changes) {
19999
20231
  if (c.expectedDowntimeMinutes) console.log(` Expected downtime: ${c.expectedDowntimeMinutes} minutes`);
20000
20232
  }
20001
20233
  }
20002
- async function main6() {
20234
+ async function main7() {
20003
20235
  const opts = parseArgs4(process.argv.slice(2));
20004
20236
  if (opts.rollback) {
20005
20237
  if (!opts.yes) {
@@ -20011,11 +20243,11 @@ async function main6() {
20011
20243
  return;
20012
20244
  }
20013
20245
  const manifest = await loadStackManifest(opts.manifestRef, void 0, opts.manifestPublicKey, opts.manifestAuthToken);
20014
- const envRaw = readFileSync29(opts.envFile, "utf8");
20246
+ const envRaw = readFileSync30(opts.envFile, "utf8");
20015
20247
  const plan = createStackUpdatePlan(manifest, envRaw, opts.targetVersion);
20016
20248
  assertDeploymentScopeAllowed(plan, opts.deploymentPersona);
20017
20249
  const plannedEnvRaw = patchEnv(envRaw, Object.fromEntries(plan.changes.map((c) => [c.key, c.after])));
20018
- assertProductionDeployGate(plan, plannedEnvRaw, readFileSync29(opts.composeFile, "utf8"), {
20250
+ assertProductionDeployGate(plan, plannedEnvRaw, readFileSync30(opts.composeFile, "utf8"), {
20019
20251
  breakGlassReason: opts.breakGlassReason,
20020
20252
  breakGlassAuditFile: opts.breakGlassAuditFile,
20021
20253
  envFile: opts.envFile
@@ -20044,7 +20276,7 @@ var init_stack_update2 = __esm({
20044
20276
  init_is_main();
20045
20277
  init_stack_update();
20046
20278
  if (isMainModule(import.meta.url)) {
20047
- main6().catch((err) => {
20279
+ main7().catch((err) => {
20048
20280
  console.error(err instanceof Error ? err.message : String(err));
20049
20281
  process.exit(1);
20050
20282
  });
@@ -20216,7 +20448,7 @@ var init_registry_proxy = __esm({
20216
20448
  // src/bin/registry-proxy.ts
20217
20449
  var registry_proxy_exports = {};
20218
20450
  __export(registry_proxy_exports, {
20219
- main: () => main7
20451
+ main: () => main8
20220
20452
  });
20221
20453
  function printHelp2() {
20222
20454
  console.log(`exe-os registry-proxy \u2014 authenticated pull-through proxy for AskExe customer images
@@ -20235,7 +20467,7 @@ Docker image shape for clients:
20235
20467
  registry.askexe.com/askexe/exe-crm:v0.9.3
20236
20468
  `);
20237
20469
  }
20238
- async function main7(args2 = process.argv.slice(2)) {
20470
+ async function main8(args2 = process.argv.slice(2)) {
20239
20471
  if (args2.includes("--help") || args2.includes("-h")) {
20240
20472
  printHelp2();
20241
20473
  return;
@@ -20248,7 +20480,7 @@ var init_registry_proxy2 = __esm({
20248
20480
  init_is_main();
20249
20481
  init_registry_proxy();
20250
20482
  if (isMainModule(import.meta.url)) {
20251
- main7().catch((err) => {
20483
+ main8().catch((err) => {
20252
20484
  console.error(err instanceof Error ? err.message : String(err));
20253
20485
  process.exit(1);
20254
20486
  });
@@ -22567,17 +22799,17 @@ var init_sanitize_ansi = __esm({
22567
22799
  if (!hasAnsiControlCharacters(text)) {
22568
22800
  return text;
22569
22801
  }
22570
- let output = "";
22802
+ let output2 = "";
22571
22803
  for (const token of tokenizeAnsi(text)) {
22572
22804
  if (token.type === "text" || token.type === "osc") {
22573
- output += token.value;
22805
+ output2 += token.value;
22574
22806
  continue;
22575
22807
  }
22576
22808
  if (token.type === "csi" && token.finalCharacter === "m" && token.intermediateString === "" && sgrParametersRegex.test(token.parameterString)) {
22577
- output += token.value;
22809
+ output2 += token.value;
22578
22810
  }
22579
22811
  }
22580
- return output;
22812
+ return output2;
22581
22813
  };
22582
22814
  sanitize_ansi_default = sanitizeAnsi;
22583
22815
  }
@@ -23364,7 +23596,7 @@ var init_render_border = __esm({
23364
23596
  "src/tui/ink/render-border.js"() {
23365
23597
  "use strict";
23366
23598
  init_colorize();
23367
- renderBorder = (x, y, node, output) => {
23599
+ renderBorder = (x, y, node, output2) => {
23368
23600
  if (node.style.borderStyle) {
23369
23601
  const width = node.yogaNode.getComputedWidth();
23370
23602
  const height = node.yogaNode.getComputedHeight();
@@ -23407,18 +23639,18 @@ var init_render_border = __esm({
23407
23639
  }
23408
23640
  const offsetY = showTopBorder ? 1 : 0;
23409
23641
  if (topBorder) {
23410
- output.write(x, y, topBorder, { transformers: [] });
23642
+ output2.write(x, y, topBorder, { transformers: [] });
23411
23643
  }
23412
23644
  if (showLeftBorder) {
23413
- output.write(x, y + offsetY, leftBorder, { transformers: [] });
23645
+ output2.write(x, y + offsetY, leftBorder, { transformers: [] });
23414
23646
  }
23415
23647
  if (showRightBorder) {
23416
- output.write(x + width - 1, y + offsetY, rightBorder, {
23648
+ output2.write(x + width - 1, y + offsetY, rightBorder, {
23417
23649
  transformers: []
23418
23650
  });
23419
23651
  }
23420
23652
  if (bottomBorder) {
23421
- output.write(x, y + height - 1, bottomBorder, { transformers: [] });
23653
+ output2.write(x, y + height - 1, bottomBorder, { transformers: [] });
23422
23654
  }
23423
23655
  }
23424
23656
  };
@@ -23432,7 +23664,7 @@ var init_render_background = __esm({
23432
23664
  "src/tui/ink/render-background.js"() {
23433
23665
  "use strict";
23434
23666
  init_colorize();
23435
- renderBackground = (x, y, node, output) => {
23667
+ renderBackground = (x, y, node, output2) => {
23436
23668
  if (!node.style.backgroundColor) {
23437
23669
  return;
23438
23670
  }
@@ -23449,7 +23681,7 @@ var init_render_background = __esm({
23449
23681
  }
23450
23682
  const backgroundLine = colorize_default(" ".repeat(contentWidth), node.style.backgroundColor, "background");
23451
23683
  for (let row = 0; row < contentHeight; row++) {
23452
- output.write(x + leftBorderWidth, y + topBorderHeight + row, backgroundLine, { transformers: [] });
23684
+ output2.write(x + leftBorderWidth, y + topBorderHeight + row, backgroundLine, { transformers: [] });
23453
23685
  }
23454
23686
  };
23455
23687
  render_background_default = renderBackground;
@@ -23485,13 +23717,13 @@ var init_render_node_to_output = __esm({
23485
23717
  if (node.yogaNode?.getDisplay() === src_default.DISPLAY_NONE) {
23486
23718
  return "";
23487
23719
  }
23488
- let output = "";
23720
+ let output2 = "";
23489
23721
  if (node.nodeName === "ink-text") {
23490
- output = squash_text_nodes_default(node);
23722
+ output2 = squash_text_nodes_default(node);
23491
23723
  } else if (node.nodeName === "ink-box" || node.nodeName === "ink-root") {
23492
23724
  const separator = node.style.flexDirection === "row" || node.style.flexDirection === "row-reverse" ? " " : "\n";
23493
23725
  const childNodes = node.style.flexDirection === "row-reverse" || node.style.flexDirection === "column-reverse" ? [...node.childNodes].reverse() : [...node.childNodes];
23494
- output = childNodes.map((childNode) => {
23726
+ output2 = childNodes.map((childNode) => {
23495
23727
  const screenReaderOutput = renderNodeToScreenReaderOutput(childNode, {
23496
23728
  parentRole: node.internal_accessibility?.role,
23497
23729
  skipStaticElements: options.skipStaticElements
@@ -23505,16 +23737,16 @@ var init_render_node_to_output = __esm({
23505
23737
  const stateKeys = Object.keys(state);
23506
23738
  const stateDescription = stateKeys.filter((key) => state[key]).join(", ");
23507
23739
  if (stateDescription) {
23508
- output = `(${stateDescription}) ${output}`;
23740
+ output2 = `(${stateDescription}) ${output2}`;
23509
23741
  }
23510
23742
  }
23511
23743
  if (role && role !== options.parentRole) {
23512
- output = `${role}: ${output}`;
23744
+ output2 = `${role}: ${output2}`;
23513
23745
  }
23514
23746
  }
23515
- return output;
23747
+ return output2;
23516
23748
  };
23517
- renderNodeToOutput = (node, output, options) => {
23749
+ renderNodeToOutput = (node, output2, options) => {
23518
23750
  const { offsetX = 0, offsetY = 0, transformers = [], skipStaticElements } = options;
23519
23751
  if (skipStaticElements && node.internal_static) {
23520
23752
  return;
@@ -23540,14 +23772,14 @@ var init_render_node_to_output = __esm({
23540
23772
  text = wrap_text_default(text, maxWidth, textWrap);
23541
23773
  }
23542
23774
  text = applyPaddingToText(node, text);
23543
- output.write(x, y, text, { transformers: newTransformers });
23775
+ output2.write(x, y, text, { transformers: newTransformers });
23544
23776
  }
23545
23777
  return;
23546
23778
  }
23547
23779
  let clipped = false;
23548
23780
  if (node.nodeName === "ink-box") {
23549
- render_background_default(x, y, node, output);
23550
- render_border_default(x, y, node, output);
23781
+ render_background_default(x, y, node, output2);
23782
+ render_border_default(x, y, node, output2);
23551
23783
  const clipHorizontally = node.style.overflowX === "hidden" || node.style.overflow === "hidden";
23552
23784
  const clipVertically = node.style.overflowY === "hidden" || node.style.overflow === "hidden";
23553
23785
  if (clipHorizontally || clipVertically) {
@@ -23555,13 +23787,13 @@ var init_render_node_to_output = __esm({
23555
23787
  const x2 = clipHorizontally ? x + yogaNode.getComputedWidth() - yogaNode.getComputedBorder(src_default.EDGE_RIGHT) : void 0;
23556
23788
  const y1 = clipVertically ? y + yogaNode.getComputedBorder(src_default.EDGE_TOP) : void 0;
23557
23789
  const y2 = clipVertically ? y + yogaNode.getComputedHeight() - yogaNode.getComputedBorder(src_default.EDGE_BOTTOM) : void 0;
23558
- output.clip({ x1, x2, y1, y2 });
23790
+ output2.clip({ x1, x2, y1, y2 });
23559
23791
  clipped = true;
23560
23792
  }
23561
23793
  }
23562
23794
  if (node.nodeName === "ink-root" || node.nodeName === "ink-box") {
23563
23795
  for (const childNode of node.childNodes) {
23564
- renderNodeToOutput(childNode, output, {
23796
+ renderNodeToOutput(childNode, output2, {
23565
23797
  offsetX: x,
23566
23798
  offsetY: y,
23567
23799
  transformers: newTransformers,
@@ -23569,7 +23801,7 @@ var init_render_node_to_output = __esm({
23569
23801
  });
23570
23802
  }
23571
23803
  if (clipped) {
23572
- output.unclip();
23804
+ output2.unclip();
23573
23805
  }
23574
23806
  }
23575
23807
  }
@@ -23654,7 +23886,7 @@ var init_output = __esm({
23654
23886
  });
23655
23887
  }
23656
23888
  get() {
23657
- const output = [];
23889
+ const output2 = [];
23658
23890
  for (let y = 0; y < this.height; y++) {
23659
23891
  const row = [];
23660
23892
  for (let x = 0; x < this.width; x++) {
@@ -23665,7 +23897,7 @@ var init_output = __esm({
23665
23897
  styles: []
23666
23898
  });
23667
23899
  }
23668
- output.push(row);
23900
+ output2.push(row);
23669
23901
  }
23670
23902
  const clips = [];
23671
23903
  for (const operation of this.operations) {
@@ -23718,7 +23950,7 @@ var init_output = __esm({
23718
23950
  }
23719
23951
  let offsetY = 0;
23720
23952
  for (let [index, line] of lines.entries()) {
23721
- const currentLine = output[y + offsetY];
23953
+ const currentLine = output2[y + offsetY];
23722
23954
  if (!currentLine) {
23723
23955
  continue;
23724
23956
  }
@@ -23746,13 +23978,13 @@ var init_output = __esm({
23746
23978
  }
23747
23979
  }
23748
23980
  }
23749
- const generatedOutput = output.map((line) => {
23981
+ const generatedOutput = output2.map((line) => {
23750
23982
  const lineWithoutEmptyItems = line.filter((item) => item !== void 0);
23751
23983
  return styledCharsToString(lineWithoutEmptyItems).trimEnd();
23752
23984
  }).join("\n");
23753
23985
  return {
23754
23986
  output: generatedOutput,
23755
- height: output.length
23987
+ height: output2.length
23756
23988
  };
23757
23989
  }
23758
23990
  };
@@ -23769,10 +24001,10 @@ var init_renderer = __esm({
23769
24001
  renderer = (node, isScreenReaderEnabled) => {
23770
24002
  if (node.yogaNode) {
23771
24003
  if (isScreenReaderEnabled) {
23772
- const output2 = renderNodeToScreenReaderOutput(node, {
24004
+ const output3 = renderNodeToScreenReaderOutput(node, {
23773
24005
  skipStaticElements: true
23774
24006
  });
23775
- const outputHeight2 = output2 === "" ? 0 : output2.split("\n").length;
24007
+ const outputHeight2 = output3 === "" ? 0 : output3.split("\n").length;
23776
24008
  let staticOutput2 = "";
23777
24009
  if (node.staticNode) {
23778
24010
  staticOutput2 = renderNodeToScreenReaderOutput(node.staticNode, {
@@ -23780,17 +24012,17 @@ var init_renderer = __esm({
23780
24012
  });
23781
24013
  }
23782
24014
  return {
23783
- output: output2,
24015
+ output: output3,
23784
24016
  outputHeight: outputHeight2,
23785
24017
  staticOutput: staticOutput2 ? `${staticOutput2}
23786
24018
  ` : ""
23787
24019
  };
23788
24020
  }
23789
- const output = new Output({
24021
+ const output2 = new Output({
23790
24022
  width: node.yogaNode.getComputedWidth(),
23791
24023
  height: node.yogaNode.getComputedHeight()
23792
24024
  });
23793
- render_node_to_output_default(node, output, {
24025
+ render_node_to_output_default(node, output2, {
23794
24026
  skipStaticElements: true
23795
24027
  });
23796
24028
  let staticOutput;
@@ -23803,7 +24035,7 @@ var init_renderer = __esm({
23803
24035
  skipStaticElements: false
23804
24036
  });
23805
24037
  }
23806
- const { output: generatedOutput, height: outputHeight } = output.get();
24038
+ const { output: generatedOutput, height: outputHeight } = output2.get();
23807
24039
  return {
23808
24040
  output: generatedOutput,
23809
24041
  outputHeight,
@@ -24614,8 +24846,8 @@ var init_ErrorOverview = __esm({
24614
24846
  "use strict";
24615
24847
  init_Box();
24616
24848
  init_Text();
24617
- cleanupPath = (path55) => {
24618
- return path55?.replace(`file://${cwd()}/`, "");
24849
+ cleanupPath = (path56) => {
24850
+ return path56?.replace(`file://${cwd()}/`, "");
24619
24851
  };
24620
24852
  stackUtils = new StackUtils({
24621
24853
  cwd: cwd(),
@@ -25236,13 +25468,13 @@ var init_ink = __esm({
25236
25468
  incremental: options.incrementalRendering
25237
25469
  });
25238
25470
  this.cursorPosition = void 0;
25239
- this.throttledLog = unthrottled ? this.log : throttle((output) => {
25240
- const shouldWrite = this.log.willRender(output);
25471
+ this.throttledLog = unthrottled ? this.log : throttle((output2) => {
25472
+ const shouldWrite = this.log.willRender(output2);
25241
25473
  const sync = shouldSynchronize(this.options.stdout);
25242
25474
  if (sync && shouldWrite) {
25243
25475
  this.options.stdout.write(bsu);
25244
25476
  }
25245
- this.log(output);
25477
+ this.log(output2);
25246
25478
  if (sync && shouldWrite) {
25247
25479
  this.options.stdout.write(esu);
25248
25480
  }
@@ -25333,22 +25565,22 @@ var init_ink = __esm({
25333
25565
  return;
25334
25566
  }
25335
25567
  const startTime = performance.now();
25336
- const { output, outputHeight, staticOutput } = renderer_default(this.rootNode, this.isScreenReaderEnabled);
25568
+ const { output: output2, outputHeight, staticOutput } = renderer_default(this.rootNode, this.isScreenReaderEnabled);
25337
25569
  this.options.onRender?.({ renderTime: performance.now() - startTime });
25338
25570
  const hasStaticOutput = staticOutput && staticOutput !== "\n";
25339
25571
  if (this.options.debug) {
25340
25572
  if (hasStaticOutput) {
25341
25573
  this.fullStaticOutput += staticOutput;
25342
25574
  }
25343
- this.options.stdout.write(this.fullStaticOutput + output);
25575
+ this.options.stdout.write(this.fullStaticOutput + output2);
25344
25576
  return;
25345
25577
  }
25346
25578
  if (isInCi2) {
25347
25579
  if (hasStaticOutput) {
25348
25580
  this.options.stdout.write(staticOutput);
25349
25581
  }
25350
- this.lastOutput = output;
25351
- this.lastOutputToRender = output + "\n";
25582
+ this.lastOutput = output2;
25583
+ this.lastOutputToRender = output2 + "\n";
25352
25584
  this.lastOutputHeight = outputHeight;
25353
25585
  return;
25354
25586
  }
@@ -25362,14 +25594,14 @@ var init_ink = __esm({
25362
25594
  this.options.stdout.write(erase + staticOutput);
25363
25595
  this.lastOutputHeight = 0;
25364
25596
  }
25365
- if (output === this.lastOutput && !hasStaticOutput) {
25597
+ if (output2 === this.lastOutput && !hasStaticOutput) {
25366
25598
  if (sync) {
25367
25599
  this.options.stdout.write(esu);
25368
25600
  }
25369
25601
  return;
25370
25602
  }
25371
25603
  const terminalWidth = this.getTerminalWidth();
25372
- const wrappedOutput = wrapAnsi2(output, terminalWidth, {
25604
+ const wrappedOutput = wrapAnsi2(output2, terminalWidth, {
25373
25605
  trim: false,
25374
25606
  hard: true
25375
25607
  });
@@ -25379,7 +25611,7 @@ var init_ink = __esm({
25379
25611
  const erase = this.lastOutputHeight > 0 ? ansiEscapes3.eraseLines(this.lastOutputHeight) : "";
25380
25612
  this.options.stdout.write(erase + wrappedOutput);
25381
25613
  }
25382
- this.lastOutput = output;
25614
+ this.lastOutput = output2;
25383
25615
  this.lastOutputToRender = wrappedOutput;
25384
25616
  this.lastOutputHeight = wrappedOutput === "" ? 0 : wrappedOutput.split("\n").length;
25385
25617
  if (sync) {
@@ -25391,14 +25623,14 @@ var init_ink = __esm({
25391
25623
  this.fullStaticOutput += staticOutput;
25392
25624
  }
25393
25625
  const isFullscreen = this.options.stdout.isTTY && outputHeight >= this.options.stdout.rows;
25394
- const outputToRender = isFullscreen ? output : output + "\n";
25626
+ const outputToRender = isFullscreen ? output2 : output2 + "\n";
25395
25627
  if (this.lastOutputHeight >= this.options.stdout.rows) {
25396
25628
  const sync = shouldSynchronize(this.options.stdout);
25397
25629
  if (sync) {
25398
25630
  this.options.stdout.write(bsu);
25399
25631
  }
25400
- this.options.stdout.write(ansiEscapes3.clearTerminal + this.fullStaticOutput + output);
25401
- this.lastOutput = output;
25632
+ this.options.stdout.write(ansiEscapes3.clearTerminal + this.fullStaticOutput + output2);
25633
+ this.lastOutput = output2;
25402
25634
  this.lastOutputToRender = outputToRender;
25403
25635
  this.lastOutputHeight = outputHeight;
25404
25636
  this.log.sync(outputToRender);
@@ -25418,10 +25650,10 @@ var init_ink = __esm({
25418
25650
  if (sync) {
25419
25651
  this.options.stdout.write(esu);
25420
25652
  }
25421
- } else if (output !== this.lastOutput || this.log.isCursorDirty()) {
25653
+ } else if (output2 !== this.lastOutput || this.log.isCursorDirty()) {
25422
25654
  this.throttledLog(outputToRender);
25423
25655
  }
25424
- this.lastOutput = output;
25656
+ this.lastOutput = output2;
25425
25657
  this.lastOutputToRender = outputToRender;
25426
25658
  this.lastOutputHeight = outputHeight;
25427
25659
  };
@@ -28760,7 +28992,7 @@ var init_anthropic = __esm({
28760
28992
 
28761
28993
  // src/lib/providers/openai-compat.ts
28762
28994
  import OpenAI from "openai";
28763
- import { randomUUID as randomUUID5 } from "crypto";
28995
+ import { randomUUID as randomUUID6 } from "crypto";
28764
28996
  var OpenAICompatProvider;
28765
28997
  var init_openai_compat = __esm({
28766
28998
  "src/lib/providers/openai-compat.ts"() {
@@ -28877,7 +29109,7 @@ var init_openai_compat = __esm({
28877
29109
  }
28878
29110
  content.push({
28879
29111
  type: "tool_use",
28880
- id: call.id ?? randomUUID5(),
29112
+ id: call.id ?? randomUUID6(),
28881
29113
  name: fn.name,
28882
29114
  input
28883
29115
  });
@@ -29078,10 +29310,10 @@ var init_hooks = __esm({
29078
29310
  });
29079
29311
 
29080
29312
  // src/runtime/safety-checks.ts
29081
- import path42 from "path";
29313
+ import path43 from "path";
29082
29314
  import os21 from "os";
29083
29315
  function checkPathSafety(filePath) {
29084
- const resolved = path42.resolve(filePath);
29316
+ const resolved = path43.resolve(filePath);
29085
29317
  for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
29086
29318
  const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
29087
29319
  if (matches) {
@@ -29091,7 +29323,7 @@ function checkPathSafety(filePath) {
29091
29323
  return { safe: true, bypassImmune: true };
29092
29324
  }
29093
29325
  function checkReadPathSafety(filePath) {
29094
- const resolved = path42.resolve(filePath);
29326
+ const resolved = path43.resolve(filePath);
29095
29327
  const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
29096
29328
  (p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
29097
29329
  );
@@ -29117,11 +29349,11 @@ var init_safety_checks = __esm({
29117
29349
  reason: "Git config can set hooks and command execution"
29118
29350
  },
29119
29351
  {
29120
- pattern: (p) => p.startsWith(path42.join(HOME, ".claude")),
29352
+ pattern: (p) => p.startsWith(path43.join(HOME, ".claude")),
29121
29353
  reason: "Claude configuration files are protected"
29122
29354
  },
29123
29355
  {
29124
- pattern: (p) => p.startsWith(path42.join(HOME, ".exe-os")),
29356
+ pattern: (p) => p.startsWith(path43.join(HOME, ".exe-os")),
29125
29357
  reason: "exe-os configuration files are protected"
29126
29358
  },
29127
29359
  {
@@ -29138,7 +29370,7 @@ var init_safety_checks = __esm({
29138
29370
  },
29139
29371
  {
29140
29372
  pattern: (p) => {
29141
- const name = path42.basename(p);
29373
+ const name = path43.basename(p);
29142
29374
  return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
29143
29375
  },
29144
29376
  reason: "Shell configuration files can execute arbitrary code on login"
@@ -29165,7 +29397,7 @@ __export(file_read_exports, {
29165
29397
  FileReadTool: () => FileReadTool
29166
29398
  });
29167
29399
  import fs3 from "fs/promises";
29168
- import path43 from "path";
29400
+ import path44 from "path";
29169
29401
  import { z } from "zod";
29170
29402
  function isBinary(buf) {
29171
29403
  for (let i = 0; i < buf.length; i++) {
@@ -29201,7 +29433,7 @@ var init_file_read = __esm({
29201
29433
  return { behavior: "allow" };
29202
29434
  },
29203
29435
  async call(input, context) {
29204
- const filePath = path43.isAbsolute(input.file_path) ? input.file_path : path43.resolve(context.cwd, input.file_path);
29436
+ const filePath = path44.isAbsolute(input.file_path) ? input.file_path : path44.resolve(context.cwd, input.file_path);
29205
29437
  let stat2;
29206
29438
  try {
29207
29439
  stat2 = await fs3.stat(filePath);
@@ -29241,7 +29473,7 @@ __export(glob_exports, {
29241
29473
  GlobTool: () => GlobTool
29242
29474
  });
29243
29475
  import fs4 from "fs/promises";
29244
- import path44 from "path";
29476
+ import path45 from "path";
29245
29477
  import { z as z2 } from "zod";
29246
29478
  async function walkDir(dir, maxDepth = 10) {
29247
29479
  const results = [];
@@ -29257,7 +29489,7 @@ async function walkDir(dir, maxDepth = 10) {
29257
29489
  if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
29258
29490
  continue;
29259
29491
  }
29260
- const fullPath = path44.join(current, entry.name);
29492
+ const fullPath = path45.join(current, entry.name);
29261
29493
  if (entry.isDirectory()) {
29262
29494
  await walk(fullPath, depth + 1);
29263
29495
  } else {
@@ -29291,11 +29523,11 @@ var init_glob = __esm({
29291
29523
  inputSchema: inputSchema2,
29292
29524
  isReadOnly: true,
29293
29525
  async call(input, context) {
29294
- const baseDir = input.path ? path44.isAbsolute(input.path) ? input.path : path44.resolve(context.cwd, input.path) : context.cwd;
29526
+ const baseDir = input.path ? path45.isAbsolute(input.path) ? input.path : path45.resolve(context.cwd, input.path) : context.cwd;
29295
29527
  try {
29296
29528
  const entries = await walkDir(baseDir);
29297
29529
  const matched = entries.filter(
29298
- (e) => simpleGlobMatch(path44.relative(baseDir, e.path), input.pattern)
29530
+ (e) => simpleGlobMatch(path45.relative(baseDir, e.path), input.pattern)
29299
29531
  );
29300
29532
  matched.sort((a, b) => b.mtime - a.mtime);
29301
29533
  if (matched.length === 0) {
@@ -29321,7 +29553,7 @@ __export(grep_exports, {
29321
29553
  });
29322
29554
  import { spawn as spawn2 } from "child_process";
29323
29555
  import fs5 from "fs/promises";
29324
- import path45 from "path";
29556
+ import path46 from "path";
29325
29557
  import { z as z3 } from "zod";
29326
29558
  function runRipgrep(input, searchPath, context) {
29327
29559
  return new Promise((resolve, reject) => {
@@ -29349,8 +29581,8 @@ function runRipgrep(input, searchPath, context) {
29349
29581
  context.abortSignal.addEventListener("abort", onAbort, { once: true });
29350
29582
  child.on("close", (code) => {
29351
29583
  context.abortSignal.removeEventListener("abort", onAbort);
29352
- const output = Buffer.concat(chunks).toString("utf-8").trim();
29353
- if (code === 1 && !output) {
29584
+ const output2 = Buffer.concat(chunks).toString("utf-8").trim();
29585
+ if (code === 1 && !output2) {
29354
29586
  resolve({ content: "No matches found." });
29355
29587
  return;
29356
29588
  }
@@ -29358,7 +29590,7 @@ function runRipgrep(input, searchPath, context) {
29358
29590
  reject(new Error("ripgrep error"));
29359
29591
  return;
29360
29592
  }
29361
- resolve({ content: output || "No matches found." });
29593
+ resolve({ content: output2 || "No matches found." });
29362
29594
  });
29363
29595
  child.on("error", () => reject(new Error("rg not found")));
29364
29596
  });
@@ -29375,7 +29607,7 @@ async function nodeGrep(input, searchPath) {
29375
29607
  }
29376
29608
  for (const entry of entries) {
29377
29609
  if (entry.name === "node_modules" || entry.name === ".git") continue;
29378
- const fullPath = path45.join(dir, entry.name);
29610
+ const fullPath = path46.join(dir, entry.name);
29379
29611
  if (entry.isDirectory()) {
29380
29612
  await walk(fullPath);
29381
29613
  } else {
@@ -29421,7 +29653,7 @@ var init_grep = __esm({
29421
29653
  inputSchema: inputSchema3,
29422
29654
  isReadOnly: true,
29423
29655
  async call(input, context) {
29424
- const searchPath = input.path ? path45.isAbsolute(input.path) ? input.path : path45.resolve(context.cwd, input.path) : context.cwd;
29656
+ const searchPath = input.path ? path46.isAbsolute(input.path) ? input.path : path46.resolve(context.cwd, input.path) : context.cwd;
29425
29657
  try {
29426
29658
  const result = await runRipgrep(input, searchPath, context);
29427
29659
  return result;
@@ -29446,7 +29678,7 @@ __export(file_write_exports, {
29446
29678
  FileWriteTool: () => FileWriteTool
29447
29679
  });
29448
29680
  import fs6 from "fs/promises";
29449
- import path46 from "path";
29681
+ import path47 from "path";
29450
29682
  import { z as z4 } from "zod";
29451
29683
  var inputSchema4, FileWriteTool;
29452
29684
  var init_file_write = __esm({
@@ -29474,8 +29706,8 @@ var init_file_write = __esm({
29474
29706
  return { behavior: "allow" };
29475
29707
  },
29476
29708
  async call(input, context) {
29477
- const filePath = path46.isAbsolute(input.file_path) ? input.file_path : path46.resolve(context.cwd, input.file_path);
29478
- const dir = path46.dirname(filePath);
29709
+ const filePath = path47.isAbsolute(input.file_path) ? input.file_path : path47.resolve(context.cwd, input.file_path);
29710
+ const dir = path47.dirname(filePath);
29479
29711
  await fs6.mkdir(dir, { recursive: true });
29480
29712
  await fs6.writeFile(filePath, input.content, "utf-8");
29481
29713
  return {
@@ -29493,7 +29725,7 @@ __export(file_edit_exports, {
29493
29725
  FileEditTool: () => FileEditTool
29494
29726
  });
29495
29727
  import fs7 from "fs/promises";
29496
- import path47 from "path";
29728
+ import path48 from "path";
29497
29729
  import { z as z5 } from "zod";
29498
29730
  function countOccurrences(haystack, needle) {
29499
29731
  let count = 0;
@@ -29534,7 +29766,7 @@ var init_file_edit = __esm({
29534
29766
  return { behavior: "allow" };
29535
29767
  },
29536
29768
  async call(input, context) {
29537
- const filePath = path47.isAbsolute(input.file_path) ? input.file_path : path47.resolve(context.cwd, input.file_path);
29769
+ const filePath = path48.isAbsolute(input.file_path) ? input.file_path : path48.resolve(context.cwd, input.file_path);
29538
29770
  let content;
29539
29771
  try {
29540
29772
  content = await fs7.readFile(filePath, "utf-8");
@@ -29757,8 +29989,8 @@ var init_bash = __esm({
29757
29989
  return;
29758
29990
  }
29759
29991
  if (code !== 0) {
29760
- const output = stderr || stdout || `Exit code ${code}`;
29761
- resolve({ content: output, isError: true });
29992
+ const output2 = stderr || stdout || `Exit code ${code}`;
29993
+ resolve({ content: output2, isError: true });
29762
29994
  return;
29763
29995
  }
29764
29996
  resolve({ content: stdout || "(no output)" });
@@ -29776,7 +30008,7 @@ var init_bash = __esm({
29776
30008
  // src/tui/views/CommandCenter.tsx
29777
30009
  import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
29778
30010
  import TextInput from "ink-text-input";
29779
- import path48 from "path";
30011
+ import path49 from "path";
29780
30012
  import { homedir as homedir6 } from "os";
29781
30013
  import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
29782
30014
  function CommandCenterView({
@@ -29811,7 +30043,7 @@ function CommandCenterView({
29811
30043
  const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
29812
30044
  const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
29813
30045
  const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
29814
- const { readFileSync: readFileSync36, existsSync: existsSync41 } = await import("fs");
30046
+ const { readFileSync: readFileSync37, existsSync: existsSync41 } = await import("fs");
29815
30047
  const { join } = await import("path");
29816
30048
  const { homedir: homedir8 } = await import("os");
29817
30049
  const configPath = join(homedir8(), ".exe-os", "config.json");
@@ -29819,7 +30051,7 @@ function CommandCenterView({
29819
30051
  let providerConfigs = {};
29820
30052
  if (existsSync41(configPath)) {
29821
30053
  try {
29822
- const raw = JSON.parse(readFileSync36(configPath, "utf8"));
30054
+ const raw = JSON.parse(readFileSync37(configPath, "utf8"));
29823
30055
  if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
29824
30056
  if (raw.providers && typeof raw.providers === "object") {
29825
30057
  providerConfigs = raw.providers;
@@ -29880,7 +30112,7 @@ function CommandCenterView({
29880
30112
  const markerDir = join(homedir8(), ".exe-os", "session-cache");
29881
30113
  const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
29882
30114
  for (const f of agentFiles) {
29883
- const data = JSON.parse(readFileSync36(join(markerDir, f), "utf8"));
30115
+ const data = JSON.parse(readFileSync37(join(markerDir, f), "utf8"));
29884
30116
  if (data.agentRole) {
29885
30117
  agentRole = data.agentRole;
29886
30118
  break;
@@ -30025,7 +30257,7 @@ function CommandCenterView({
30025
30257
  const demoEntries = DEMO_PROJECTS.map((p) => ({
30026
30258
  projectName: p.projectName,
30027
30259
  exeSession: p.exeSession,
30028
- projectDir: path48.join(homedir6(), p.projectName),
30260
+ projectDir: path49.join(homedir6(), p.projectName),
30029
30261
  employeeCount: p.employees.length,
30030
30262
  activeCount: p.employees.filter((e) => e.status === "active").length,
30031
30263
  memoryCount: p.employees.length * 4e3,
@@ -30401,11 +30633,11 @@ function TmuxPane({ sessionName, employeeName, employeeRole, projectName, onDeta
30401
30633
  const capture = () => {
30402
30634
  try {
30403
30635
  const { execSync: execSync18 } = __require("child_process");
30404
- const output = execSync18(
30636
+ const output2 = execSync18(
30405
30637
  `tmux capture-pane -t ${JSON.stringify(sessionName)} -p -e 2>/dev/null | tail -${CAPTURE_LINES}`,
30406
30638
  { encoding: "utf8", timeout: 3e3 }
30407
30639
  );
30408
- setLines(output.split("\n"));
30640
+ setLines(output2.split("\n"));
30409
30641
  setAlive(true);
30410
30642
  } catch {
30411
30643
  setAlive(false);
@@ -30506,7 +30738,7 @@ var init_TmuxPane = __esm({
30506
30738
  });
30507
30739
 
30508
30740
  // src/lib/task-router.ts
30509
- import { randomUUID as randomUUID6 } from "crypto";
30741
+ import { randomUUID as randomUUID7 } from "crypto";
30510
30742
  function resolveBloomRouting(complexity, config = DEFAULT_BLOOM_CONFIG) {
30511
30743
  const tier = config.complexityToTier[complexity];
30512
30744
  const rule = config.tierRules[tier];
@@ -31029,7 +31261,7 @@ var init_useOrchestrator = __esm({
31029
31261
 
31030
31262
  // src/tui/views/Sessions.tsx
31031
31263
  import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
31032
- import path49 from "path";
31264
+ import path50 from "path";
31033
31265
  import { homedir as homedir7 } from "os";
31034
31266
  import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
31035
31267
  function isCoordinatorEntry(entry) {
@@ -31067,7 +31299,7 @@ function SessionsView({
31067
31299
  if (demo) {
31068
31300
  setProjects(DEMO_PROJECTS.map((p) => ({
31069
31301
  ...p,
31070
- projectDir: path49.join(homedir7(), p.projectName),
31302
+ projectDir: path50.join(homedir7(), p.projectName),
31071
31303
  employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
31072
31304
  })));
31073
31305
  return;
@@ -32282,12 +32514,12 @@ async function loadGatewayConfig() {
32282
32514
  state.running = false;
32283
32515
  }
32284
32516
  try {
32285
- const { existsSync: existsSync41, readFileSync: readFileSync36 } = await import("fs");
32517
+ const { existsSync: existsSync41, readFileSync: readFileSync37 } = await import("fs");
32286
32518
  const { join } = await import("path");
32287
32519
  const home = process.env.HOME ?? "";
32288
32520
  const configPath = join(home, ".exe-os", "gateway.json");
32289
32521
  if (existsSync41(configPath)) {
32290
- const raw = JSON.parse(readFileSync36(configPath, "utf8"));
32522
+ const raw = JSON.parse(readFileSync37(configPath, "utf8"));
32291
32523
  state.port = raw.port ?? 3100;
32292
32524
  state.gatewayUrl = raw.gatewayUrl ?? "";
32293
32525
  if (raw.adapters) {
@@ -32885,12 +33117,12 @@ function TeamView({ onBack, onViewSessions }) {
32885
33117
  setMembers(teamData);
32886
33118
  setDbError(null);
32887
33119
  try {
32888
- const { existsSync: existsSync41, readFileSync: readFileSync36 } = await import("fs");
33120
+ const { existsSync: existsSync41, readFileSync: readFileSync37 } = await import("fs");
32889
33121
  const { join } = await import("path");
32890
33122
  const home = process.env.HOME ?? "";
32891
33123
  const gatewayConfig = join(home, ".exe-os", "gateway.json");
32892
33124
  if (existsSync41(gatewayConfig)) {
32893
- const raw = JSON.parse(readFileSync36(gatewayConfig, "utf8"));
33125
+ const raw = JSON.parse(readFileSync37(gatewayConfig, "utf8"));
32894
33126
  if (raw.agents && raw.agents.length > 0) {
32895
33127
  setExternals(raw.agents.map((a) => ({
32896
33128
  name: a.name,
@@ -33070,8 +33302,8 @@ __export(wiki_client_exports, {
33070
33302
  listDocuments: () => listDocuments,
33071
33303
  listWorkspaces: () => listWorkspaces
33072
33304
  });
33073
- async function wikiFetch(config, path55, method = "GET", body) {
33074
- const url = `${config.baseUrl}/api/v1${path55}`;
33305
+ async function wikiFetch(config, path56, method = "GET", body) {
33306
+ const url = `${config.baseUrl}/api/v1${path56}`;
33075
33307
  const headers = {
33076
33308
  Authorization: `Bearer ${config.apiKey}`,
33077
33309
  "Content-Type": "application/json"
@@ -33104,7 +33336,7 @@ async function wikiFetch(config, path55, method = "GET", body) {
33104
33336
  }
33105
33337
  }
33106
33338
  if (!response.ok) {
33107
- throw new Error(`Wiki API ${method} ${path55}: ${response.status} ${response.statusText}`);
33339
+ throw new Error(`Wiki API ${method} ${path56}: ${response.status} ${response.statusText}`);
33108
33340
  }
33109
33341
  return response.json();
33110
33342
  } finally {
@@ -33721,17 +33953,17 @@ function SettingsView({ onBack }) {
33721
33953
  }
33722
33954
  let version = "unknown";
33723
33955
  try {
33724
- const { readFileSync: readFileSync36 } = await import("fs");
33956
+ const { readFileSync: readFileSync37 } = await import("fs");
33725
33957
  const { createRequire: createRequire3 } = await import("module");
33726
33958
  const require2 = createRequire3(import.meta.url);
33727
33959
  const pkgPath = require2.resolve("@askexenow/exe-os/package.json");
33728
- const pkg = JSON.parse(readFileSync36(pkgPath, "utf8"));
33960
+ const pkg = JSON.parse(readFileSync37(pkgPath, "utf8"));
33729
33961
  version = pkg.version;
33730
33962
  } catch {
33731
33963
  try {
33732
- const { readFileSync: readFileSync36 } = await import("fs");
33964
+ const { readFileSync: readFileSync37 } = await import("fs");
33733
33965
  const { join: joinPath } = await import("path");
33734
- const pkg = JSON.parse(readFileSync36(joinPath(process.cwd(), "package.json"), "utf8"));
33966
+ const pkg = JSON.parse(readFileSync37(joinPath(process.cwd(), "package.json"), "utf8"));
33735
33967
  version = pkg.version;
33736
33968
  } catch {
33737
33969
  }
@@ -34588,24 +34820,24 @@ __export(code_context_index_exports, {
34588
34820
  traceCodeSymbol: () => traceCodeSymbol
34589
34821
  });
34590
34822
  import crypto14 from "crypto";
34591
- import path50 from "path";
34592
- import { existsSync as existsSync36, mkdirSync as mkdirSync24, readFileSync as readFileSync31, readdirSync as readdirSync11, statSync as statSync7, writeFileSync as writeFileSync25 } from "fs";
34823
+ import path51 from "path";
34824
+ import { existsSync as existsSync36, mkdirSync as mkdirSync25, readFileSync as readFileSync32, readdirSync as readdirSync11, statSync as statSync7, writeFileSync as writeFileSync26 } from "fs";
34593
34825
  import { spawnSync } from "child_process";
34594
34826
  function normalizeProjectRoot(projectRoot) {
34595
- return path50.resolve(projectRoot || process.cwd());
34827
+ return path51.resolve(projectRoot || process.cwd());
34596
34828
  }
34597
34829
  function hashText(text) {
34598
34830
  return crypto14.createHash("sha256").update(text).digest("hex");
34599
34831
  }
34600
34832
  function indexDir() {
34601
- const dir = path50.join(EXE_AI_DIR, "code-context");
34602
- mkdirSync24(dir, { recursive: true });
34833
+ const dir = path51.join(EXE_AI_DIR, "code-context");
34834
+ mkdirSync25(dir, { recursive: true });
34603
34835
  return dir;
34604
34836
  }
34605
34837
  function getCodeContextIndexPath(projectRoot) {
34606
34838
  const root = normalizeProjectRoot(projectRoot);
34607
34839
  const rootHash = hashText(root).slice(0, 16);
34608
- return path50.join(indexDir(), `${rootHash}.json`);
34840
+ return path51.join(indexDir(), `${rootHash}.json`);
34609
34841
  }
34610
34842
  function currentBranch(projectRoot) {
34611
34843
  const result = spawnSync("git", ["branch", "--show-current"], { cwd: projectRoot, encoding: "utf8", timeout: 2e3 });
@@ -34618,8 +34850,8 @@ function shouldIgnore(relPath) {
34618
34850
  }
34619
34851
  function listRecursive(projectRoot, dir = projectRoot, out = []) {
34620
34852
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
34621
- const abs = path50.join(dir, entry.name);
34622
- const rel = path50.relative(projectRoot, abs).replaceAll(path50.sep, "/");
34853
+ const abs = path51.join(dir, entry.name);
34854
+ const rel = path51.relative(projectRoot, abs).replaceAll(path51.sep, "/");
34623
34855
  if (shouldIgnore(rel)) continue;
34624
34856
  if (entry.isDirectory()) listRecursive(projectRoot, abs, out);
34625
34857
  else if (entry.isFile()) out.push(rel);
@@ -34635,7 +34867,7 @@ function listCodeFiles(projectRoot, maxFiles) {
34635
34867
  const rg = spawnSync("rg", ["--files"], { cwd: projectRoot, encoding: "utf8", timeout: 5e3, maxBuffer: 1024 * 1024 * 16 });
34636
34868
  files = rg.status === 0 && rg.stdout.trim() ? rg.stdout.split("\n").map((s) => s.trim()).filter(Boolean) : listRecursive(projectRoot);
34637
34869
  }
34638
- return files.map((file) => file.replaceAll(path50.sep, "/")).filter((file) => isChunkable(file) && !shouldIgnore(file)).slice(0, maxFiles).sort();
34870
+ return files.map((file) => file.replaceAll(path51.sep, "/")).filter((file) => isChunkable(file) && !shouldIgnore(file)).slice(0, maxFiles).sort();
34639
34871
  }
34640
34872
  function parseImportPaths(importText) {
34641
34873
  const paths = [];
@@ -34648,13 +34880,13 @@ function parseImportPaths(importText) {
34648
34880
  }
34649
34881
  function resolveImport(fromFile, importPath, allFiles) {
34650
34882
  if (!importPath.startsWith(".")) return null;
34651
- const base = path50.posix.normalize(path50.posix.join(path50.posix.dirname(fromFile.replaceAll(path50.sep, "/")), importPath));
34883
+ const base = path51.posix.normalize(path51.posix.join(path51.posix.dirname(fromFile.replaceAll(path51.sep, "/")), importPath));
34652
34884
  const withoutKnownExt = base.replace(/\.(?:[a-z0-9]+)$/i, "");
34653
34885
  const candidates = [base];
34654
34886
  for (const ext of ["ts", "tsx", "js", "jsx", "py", "rs", "go", "java", "cs", "cpp", "c", "rb", "php", "swift", "kt", "scala", "sql", "md", "json", "yaml", "yml"]) {
34655
34887
  candidates.push(`${withoutKnownExt}.${ext}`, `${base}.${ext}`);
34656
34888
  }
34657
- for (const indexName of ["index.ts", "index.tsx", "index.js", "mod.rs", "__init__.py"]) candidates.push(path50.posix.join(base, indexName));
34889
+ for (const indexName of ["index.ts", "index.tsx", "index.js", "mod.rs", "__init__.py"]) candidates.push(path51.posix.join(base, indexName));
34658
34890
  return candidates.find((candidate) => allFiles.has(candidate)) ?? null;
34659
34891
  }
34660
34892
  function symbolId(filePath, chunk) {
@@ -34664,7 +34896,7 @@ function loadIndex(projectRoot) {
34664
34896
  const file = getCodeContextIndexPath(projectRoot);
34665
34897
  if (!existsSync36(file)) return null;
34666
34898
  try {
34667
- const parsed = JSON.parse(readFileSync31(file, "utf8"));
34899
+ const parsed = JSON.parse(readFileSync32(file, "utf8"));
34668
34900
  if (parsed.version !== INDEX_VERSION || parsed.projectRoot !== projectRoot) return null;
34669
34901
  return parsed;
34670
34902
  } catch {
@@ -34672,10 +34904,10 @@ function loadIndex(projectRoot) {
34672
34904
  }
34673
34905
  }
34674
34906
  function saveIndex(index) {
34675
- writeFileSync25(getCodeContextIndexPath(index.projectRoot), JSON.stringify(index, null, 2));
34907
+ writeFileSync26(getCodeContextIndexPath(index.projectRoot), JSON.stringify(index, null, 2));
34676
34908
  }
34677
34909
  function buildFileRecord(projectRoot, relPath, allFiles, previous) {
34678
- const absPath = path50.join(projectRoot, relPath);
34910
+ const absPath = path51.join(projectRoot, relPath);
34679
34911
  let stat2;
34680
34912
  try {
34681
34913
  stat2 = statSync7(absPath);
@@ -34685,7 +34917,7 @@ function buildFileRecord(projectRoot, relPath, allFiles, previous) {
34685
34917
  if (!stat2.isFile()) return { record: null, reused: false };
34686
34918
  const language = languageForFile(relPath);
34687
34919
  if (!language || !isChunkable(relPath)) return { record: null, reused: false };
34688
- const source = readFileSync31(absPath, "utf8");
34920
+ const source = readFileSync32(absPath, "utf8");
34689
34921
  const hash = hashText(source);
34690
34922
  if (previous && previous.hash === hash && previous.mtimeMs === stat2.mtimeMs && previous.size === stat2.size && previous.language === language) {
34691
34923
  return { record: previous, reused: true };
@@ -34713,13 +34945,13 @@ function buildCodeContextIndex(options = {}) {
34713
34945
  const branch = currentBranch(projectRoot);
34714
34946
  const previous = options.force ? null : loadIndex(projectRoot);
34715
34947
  const files = listCodeFiles(projectRoot, maxFiles);
34716
- const allFiles = new Set(files.map((file) => file.replaceAll(path50.sep, "/")));
34948
+ const allFiles = new Set(files.map((file) => file.replaceAll(path51.sep, "/")));
34717
34949
  const fileRecords = {};
34718
34950
  let rebuiltFiles = 0;
34719
34951
  let reusedFiles = 0;
34720
34952
  let skippedFiles = 0;
34721
34953
  for (const rel of files) {
34722
- const normalized = rel.replaceAll(path50.sep, "/");
34954
+ const normalized = rel.replaceAll(path51.sep, "/");
34723
34955
  const { record, reused } = buildFileRecord(projectRoot, normalized, allFiles, previous?.files[normalized]);
34724
34956
  if (record) {
34725
34957
  fileRecords[normalized] = record;
@@ -34748,11 +34980,11 @@ function loadOrBuildCodeContextIndex(options = {}) {
34748
34980
  if (loaded) {
34749
34981
  const currentFiles = listCodeFiles(projectRoot, options.maxFiles ?? DEFAULT_MAX_FILES);
34750
34982
  const unchanged = currentFiles.every((rel) => {
34751
- const normalized = rel.replaceAll(path50.sep, "/");
34983
+ const normalized = rel.replaceAll(path51.sep, "/");
34752
34984
  const existing = loaded.files[normalized];
34753
34985
  if (!existing) return false;
34754
34986
  try {
34755
- const stat2 = statSync7(path50.join(projectRoot, normalized));
34987
+ const stat2 = statSync7(path51.join(projectRoot, normalized));
34756
34988
  return stat2.mtimeMs === existing.mtimeMs && stat2.size === existing.size;
34757
34989
  } catch {
34758
34990
  return false;
@@ -34805,9 +35037,9 @@ function globToRegex(pattern) {
34805
35037
  }
34806
35038
  function matchesPath(filePath, patterns) {
34807
35039
  if (!patterns || patterns.length === 0) return true;
34808
- const normalized = filePath.replaceAll(path50.sep, "/");
35040
+ const normalized = filePath.replaceAll(path51.sep, "/");
34809
35041
  return patterns.some((pattern) => {
34810
- const p = pattern.replaceAll(path50.sep, "/").replace(/^\.\//, "");
35042
+ const p = pattern.replaceAll(path51.sep, "/").replace(/^\.\//, "");
34811
35043
  return normalized === p || normalized.startsWith(`${p}/`) || normalized.endsWith(p) || globToRegex(p).test(normalized);
34812
35044
  });
34813
35045
  }
@@ -34925,7 +35157,7 @@ function traceCodeSymbol(symbolName, options = {}) {
34925
35157
  }
34926
35158
  function resolveTargetFile(index, input) {
34927
35159
  if (input.filePath) {
34928
- const normalized = input.filePath.replaceAll(path50.sep, "/").replace(/^\.\//, "");
35160
+ const normalized = input.filePath.replaceAll(path51.sep, "/").replace(/^\.\//, "");
34929
35161
  if (index.files[normalized]) return { filePath: normalized, target: normalized };
34930
35162
  const suffix = Object.keys(index.files).find((file) => file.endsWith(normalized));
34931
35163
  if (suffix) return { filePath: suffix, target: input.filePath };
@@ -34955,7 +35187,7 @@ function analyzeBlastRadius(input) {
34955
35187
  }
34956
35188
  }
34957
35189
  }
34958
- const targetBase = path50.basename(target.filePath).replace(/\.[^.]+$/, "").toLowerCase();
35190
+ const targetBase = path51.basename(target.filePath).replace(/\.[^.]+$/, "").toLowerCase();
34959
35191
  const symbolLower = input.symbol?.toLowerCase();
34960
35192
  const tests = Object.keys(index.files).filter((file) => {
34961
35193
  const lower = file.toLowerCase();
@@ -35188,13 +35420,13 @@ __export(installer_exports2, {
35188
35420
  verifyOpenCodeHooks: () => verifyOpenCodeHooks
35189
35421
  });
35190
35422
  import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
35191
- import { existsSync as existsSync37, readFileSync as readFileSync32 } from "fs";
35192
- import path51 from "path";
35423
+ import { existsSync as existsSync37, readFileSync as readFileSync33 } from "fs";
35424
+ import path52 from "path";
35193
35425
  import os22 from "os";
35194
35426
  async function registerOpenCodeMcp(packageRoot, homeDir = os22.homedir()) {
35195
35427
  void packageRoot;
35196
- const configDir = path51.join(homeDir, ".config", "opencode");
35197
- const configPath = path51.join(configDir, "opencode.json");
35428
+ const configDir = path52.join(homeDir, ".config", "opencode");
35429
+ const configPath = path52.join(configDir, "opencode.json");
35198
35430
  await mkdir8(configDir, { recursive: true });
35199
35431
  let config = {};
35200
35432
  if (existsSync37(configPath)) {
@@ -35225,8 +35457,8 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os22.homedir()) {
35225
35457
  return true;
35226
35458
  }
35227
35459
  async function installOpenCodePlugin(packageRoot, homeDir = os22.homedir()) {
35228
- const pluginDir = path51.join(homeDir, ".config", "opencode", "plugins");
35229
- const pluginPath = path51.join(pluginDir, "exe-os.mjs");
35460
+ const pluginDir = path52.join(homeDir, ".config", "opencode", "plugins");
35461
+ const pluginPath = path52.join(pluginDir, "exe-os.mjs");
35230
35462
  await mkdir8(pluginDir, { recursive: true });
35231
35463
  const pluginContent = PLUGIN_TEMPLATE.replace(
35232
35464
  /__PACKAGE_ROOT__/g,
@@ -35242,18 +35474,18 @@ async function installOpenCodePlugin(packageRoot, homeDir = os22.homedir()) {
35242
35474
  return true;
35243
35475
  }
35244
35476
  function verifyOpenCodeHooks(homeDir = os22.homedir()) {
35245
- const configPath = path51.join(homeDir, ".config", "opencode", "opencode.json");
35246
- const pluginPath = path51.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
35477
+ const configPath = path52.join(homeDir, ".config", "opencode", "opencode.json");
35478
+ const pluginPath = path52.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
35247
35479
  if (!existsSync37(configPath)) return false;
35248
35480
  try {
35249
- const config = JSON.parse(readFileSync32(configPath, "utf-8"));
35481
+ const config = JSON.parse(readFileSync33(configPath, "utf-8"));
35250
35482
  if (!config.mcp?.["exe-os"]?.enabled) return false;
35251
35483
  } catch {
35252
35484
  return false;
35253
35485
  }
35254
35486
  if (!existsSync37(pluginPath)) return false;
35255
35487
  try {
35256
- const plugin = readFileSync32(pluginPath, "utf-8");
35488
+ const plugin = readFileSync33(pluginPath, "utf-8");
35257
35489
  if (!plugin.includes(EXE_HOOK_FILES.postToolCombined)) return false;
35258
35490
  if (textHasLegacySplitPostToolHook(plugin)) return false;
35259
35491
  } catch {
@@ -35295,14 +35527,14 @@ __export(installer_exports3, {
35295
35527
  verifyCodexHooks: () => verifyCodexHooks
35296
35528
  });
35297
35529
  import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
35298
- import { existsSync as existsSync38, readFileSync as readFileSync33 } from "fs";
35299
- import path52 from "path";
35530
+ import { existsSync as existsSync38, readFileSync as readFileSync34 } from "fs";
35531
+ import path53 from "path";
35300
35532
  import os23 from "os";
35301
35533
  async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35302
- const codexDir = path52.join(homeDir, ".codex");
35303
- const hooksPath = path52.join(codexDir, "hooks.json");
35304
- const logsDir = path52.join(homeDir, ".exe-os", "logs");
35305
- const hookLogPath = path52.join(logsDir, "hooks.log");
35534
+ const codexDir = path53.join(homeDir, ".codex");
35535
+ const hooksPath = path53.join(codexDir, "hooks.json");
35536
+ const logsDir = path53.join(homeDir, ".exe-os", "logs");
35537
+ const hookLogPath = path53.join(logsDir, "hooks.log");
35306
35538
  const logSuffix = ` 2>> "${hookLogPath}"`;
35307
35539
  await mkdir9(codexDir, { recursive: true });
35308
35540
  await mkdir9(logsDir, { recursive: true });
@@ -35327,7 +35559,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35327
35559
  // Combined hook: runs ingest + error-recall in one Node process.
35328
35560
  // Eliminates a cold-start cycle per tool call (~3-6s savings on Codex).
35329
35561
  type: "command",
35330
- command: `node "${path52.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
35562
+ command: `node "${path53.join(packageRoot, "dist", "hooks", "post-tool-combined.js")}"${logSuffix}`
35331
35563
  }
35332
35564
  ]
35333
35565
  },
@@ -35341,7 +35573,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35341
35573
  // Single hook: prompt-submit handles memory retrieval + entity boost.
35342
35574
  // exe-heartbeat-hook is CC-specific (intercom) — omitted on Codex.
35343
35575
  type: "command",
35344
- command: `node "${path52.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
35576
+ command: `node "${path53.join(packageRoot, "dist", "hooks", "prompt-submit.js")}"${logSuffix}`
35345
35577
  }
35346
35578
  ]
35347
35579
  },
@@ -35353,7 +35585,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35353
35585
  hooks: [
35354
35586
  {
35355
35587
  type: "command",
35356
- command: `node "${path52.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
35588
+ command: `node "${path53.join(packageRoot, "dist", "hooks", "stop.js")}"${logSuffix}`
35357
35589
  }
35358
35590
  ]
35359
35591
  },
@@ -35366,7 +35598,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35366
35598
  hooks: [
35367
35599
  {
35368
35600
  type: "command",
35369
- command: `node "${path52.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
35601
+ command: `node "${path53.join(packageRoot, "dist", "hooks", "pre-tool-use.js")}"${logSuffix}`
35370
35602
  }
35371
35603
  ]
35372
35604
  },
@@ -35415,10 +35647,10 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
35415
35647
  return { added, skipped };
35416
35648
  }
35417
35649
  function verifyCodexHooks(homeDir = os23.homedir()) {
35418
- const hooksPath = path52.join(homeDir, ".codex", "hooks.json");
35650
+ const hooksPath = path53.join(homeDir, ".codex", "hooks.json");
35419
35651
  if (!existsSync38(hooksPath)) return false;
35420
35652
  try {
35421
- const hooksJson = JSON.parse(readFileSync33(hooksPath, "utf-8"));
35653
+ const hooksJson = JSON.parse(readFileSync34(hooksPath, "utf-8"));
35422
35654
  if (!hooksJson.hooks) return false;
35423
35655
  const required = ["PostToolUse", "UserPromptSubmit", "Stop", "PreToolUse"];
35424
35656
  for (const event of required) {
@@ -35450,8 +35682,8 @@ function verifyCodexHooks(homeDir = os23.homedir()) {
35450
35682
  async function installCodexStatusLine(homeDir = os23.homedir()) {
35451
35683
  const prefs = loadPreferences(homeDir);
35452
35684
  if (prefs.codexStatusLine === false) return "opted-out";
35453
- const codexDir = path52.join(homeDir, ".codex");
35454
- const configPath = path52.join(codexDir, "config.toml");
35685
+ const codexDir = path53.join(homeDir, ".codex");
35686
+ const configPath = path53.join(codexDir, "config.toml");
35455
35687
  await mkdir9(codexDir, { recursive: true });
35456
35688
  let content = "";
35457
35689
  if (existsSync38(configPath)) {
@@ -35506,8 +35738,8 @@ ${line}
35506
35738
  return { content: next, changed: next !== sectionContent };
35507
35739
  }
35508
35740
  async function registerCodexMcpServer(packageRoot, homeDir = os23.homedir()) {
35509
- const codexDir = path52.join(homeDir, ".codex");
35510
- const configPath = path52.join(codexDir, "config.toml");
35741
+ const codexDir = path53.join(homeDir, ".codex");
35742
+ const configPath = path53.join(codexDir, "config.toml");
35511
35743
  void packageRoot;
35512
35744
  await mkdir9(codexDir, { recursive: true });
35513
35745
  let content = "";
@@ -35536,8 +35768,8 @@ async function registerCodexMcpServer(packageRoot, homeDir = os23.homedir()) {
35536
35768
  return "registered";
35537
35769
  }
35538
35770
  async function ensureCodexHooksFeature(homeDir = os23.homedir()) {
35539
- const configPath = path52.join(homeDir, ".codex", "config.toml");
35540
- await mkdir9(path52.join(homeDir, ".codex"), { recursive: true });
35771
+ const configPath = path53.join(homeDir, ".codex", "config.toml");
35772
+ await mkdir9(path53.join(homeDir, ".codex"), { recursive: true });
35541
35773
  let content = "";
35542
35774
  if (existsSync38(configPath)) {
35543
35775
  content = await readFile8(configPath, "utf-8");
@@ -35614,32 +35846,32 @@ __export(mcp_diagnostics_exports, {
35614
35846
  diagnoseClaudeMcpConfig: () => diagnoseClaudeMcpConfig,
35615
35847
  formatMcpDiagnosticReport: () => formatMcpDiagnosticReport
35616
35848
  });
35617
- import { existsSync as existsSync39, readFileSync as readFileSync34 } from "fs";
35618
- import path53 from "path";
35849
+ import { existsSync as existsSync39, readFileSync as readFileSync35 } from "fs";
35850
+ import path54 from "path";
35619
35851
  import os24 from "os";
35620
35852
  function readJson(filePath) {
35621
35853
  if (!existsSync39(filePath)) return null;
35622
35854
  try {
35623
- return JSON.parse(readFileSync34(filePath, "utf8"));
35855
+ return JSON.parse(readFileSync35(filePath, "utf8"));
35624
35856
  } catch {
35625
35857
  return null;
35626
35858
  }
35627
35859
  }
35628
35860
  function pathApplies2(projectPath, cwd2) {
35629
- const project = path53.resolve(projectPath);
35630
- const current = path53.resolve(cwd2);
35631
- return current === project || current.startsWith(project + path53.sep);
35861
+ const project = path54.resolve(projectPath);
35862
+ const current = path54.resolve(cwd2);
35863
+ return current === project || current.startsWith(project + path54.sep);
35632
35864
  }
35633
35865
  function findAncestorMcpJsons2(cwd2, homeDir) {
35634
35866
  const files = [];
35635
- let dir = path53.resolve(cwd2);
35636
- const root = path53.parse(dir).root;
35637
- const stop = path53.resolve(homeDir);
35867
+ let dir = path54.resolve(cwd2);
35868
+ const root = path54.parse(dir).root;
35869
+ const stop = path54.resolve(homeDir);
35638
35870
  while (dir !== root) {
35639
- const candidate = path53.join(dir, ".mcp.json");
35871
+ const candidate = path54.join(dir, ".mcp.json");
35640
35872
  if (existsSync39(candidate)) files.push(candidate);
35641
35873
  if (dir === stop) break;
35642
- dir = path53.dirname(dir);
35874
+ dir = path54.dirname(dir);
35643
35875
  }
35644
35876
  return files;
35645
35877
  }
@@ -35656,8 +35888,8 @@ function serverAllowedByPermissions(serverName, prefixes) {
35656
35888
  return prefixes.has(serverName) || prefixes.has(serverName.replace(/-/g, "_"));
35657
35889
  }
35658
35890
  function diagnoseClaudeMcpConfig(homeDir = os24.homedir(), cwd2 = process.cwd(), env = process.env) {
35659
- const claudeJsonPath = path53.join(homeDir, ".claude.json");
35660
- const settingsPath = path53.join(homeDir, ".claude", "settings.json");
35891
+ const claudeJsonPath = path54.join(homeDir, ".claude.json");
35892
+ const settingsPath = path54.join(homeDir, ".claude", "settings.json");
35661
35893
  const claudeJson = readJson(claudeJsonPath);
35662
35894
  const settings = readJson(settingsPath);
35663
35895
  const issues = [];
@@ -35777,7 +36009,7 @@ function diagnoseClaudeMcpConfig(homeDir = os24.homedir(), cwd2 = process.cwd(),
35777
36009
  });
35778
36010
  }
35779
36011
  return {
35780
- cwd: path53.resolve(cwd2),
36012
+ cwd: path54.resolve(cwd2),
35781
36013
  globalServers,
35782
36014
  projectServers: projectServers.sort((a, b) => a.name.localeCompare(b.name)),
35783
36015
  mcpJsonServers: mcpJsonServers.sort((a, b) => a.name.localeCompare(b.name)),
@@ -35814,14 +36046,14 @@ var init_mcp_diagnostics = __esm({
35814
36046
  });
35815
36047
 
35816
36048
  // src/bin/cli.ts
35817
- import { existsSync as existsSync40, readFileSync as readFileSync35, writeFileSync as writeFileSync26, readdirSync as readdirSync12, rmSync as rmSync2 } from "fs";
35818
- import path54 from "path";
36049
+ import { existsSync as existsSync40, readFileSync as readFileSync36, writeFileSync as writeFileSync27, readdirSync as readdirSync12, rmSync as rmSync2 } from "fs";
36050
+ import path55 from "path";
35819
36051
  import os25 from "os";
35820
36052
  var args = process.argv.slice(2);
35821
36053
  if (args.includes("--version") || args.includes("-v")) {
35822
36054
  try {
35823
- const pkgPath = path54.join(path54.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
35824
- const pkg = JSON.parse(readFileSync35(pkgPath, "utf8"));
36055
+ const pkgPath = path55.join(path55.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
36056
+ const pkg = JSON.parse(readFileSync36(pkgPath, "utf8"));
35825
36057
  console.log(pkg.version);
35826
36058
  } catch {
35827
36059
  console.log("unknown");
@@ -35943,6 +36175,9 @@ if (args.includes("--global")) {
35943
36175
  const { main: runCloud } = await Promise.resolve().then(() => (init_exe_cloud(), exe_cloud_exports));
35944
36176
  await runCloud();
35945
36177
  }
36178
+ } else if (args[0] === "support") {
36179
+ const { main: runSupport } = await Promise.resolve().then(() => (init_exe_support(), exe_support_exports));
36180
+ await runSupport(args.slice(1));
35946
36181
  } else if (args[0] === "bulk-sync-postgres") {
35947
36182
  const { main: runBulkSyncPostgres } = await Promise.resolve().then(() => (init_bulk_sync_postgres(), bulk_sync_postgres_exports));
35948
36183
  await runBulkSyncPostgres();
@@ -36046,11 +36281,11 @@ ID: ${result.id}`);
36046
36281
  });
36047
36282
  await init_App2().then(() => App_exports);
36048
36283
  } else {
36049
- const claudeDir = path54.join(os25.homedir(), ".claude");
36050
- const settingsPath = path54.join(claudeDir, "settings.json");
36284
+ const claudeDir = path55.join(os25.homedir(), ".claude");
36285
+ const settingsPath = path55.join(claudeDir, "settings.json");
36051
36286
  const hasClaudeCode = existsSync40(settingsPath) && (() => {
36052
36287
  try {
36053
- const raw = readFileSync35(settingsPath, "utf8");
36288
+ const raw = readFileSync36(settingsPath, "utf8");
36054
36289
  return raw.includes("exe-os") || raw.includes("exe-mem");
36055
36290
  } catch {
36056
36291
  return false;
@@ -36060,9 +36295,9 @@ ID: ${result.id}`);
36060
36295
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
36061
36296
  let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
36062
36297
  try {
36063
- const rosterPath = path54.join(os25.homedir(), ".exe-os", "exe-employees.json");
36298
+ const rosterPath = path55.join(os25.homedir(), ".exe-os", "exe-employees.json");
36064
36299
  if (existsSync40(rosterPath)) {
36065
- const roster = JSON.parse(readFileSync35(rosterPath, "utf8"));
36300
+ const roster = JSON.parse(readFileSync36(rosterPath, "utf8"));
36066
36301
  const coo = roster.find((e) => e.role === "COO");
36067
36302
  if (coo) cooName = coo.name;
36068
36303
  }
@@ -36215,14 +36450,14 @@ async function runCodexInstall() {
36215
36450
  }
36216
36451
  async function runClaudeCheck() {
36217
36452
  const { detectMcpNameCollisions: detectMcpNameCollisions2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
36218
- const claudeDir = path54.join(os25.homedir(), ".claude");
36219
- const settingsPath = path54.join(claudeDir, "settings.json");
36220
- const claudeJsonPath = path54.join(os25.homedir(), ".claude.json");
36453
+ const claudeDir = path55.join(os25.homedir(), ".claude");
36454
+ const settingsPath = path55.join(claudeDir, "settings.json");
36455
+ const claudeJsonPath = path55.join(os25.homedir(), ".claude.json");
36221
36456
  let ok = true;
36222
36457
  if (existsSync40(settingsPath)) {
36223
36458
  let settings;
36224
36459
  try {
36225
- settings = JSON.parse(readFileSync35(settingsPath, "utf8"));
36460
+ settings = JSON.parse(readFileSync36(settingsPath, "utf8"));
36226
36461
  } catch {
36227
36462
  console.log("\x1B[31m\u2717\x1B[0m settings.json is malformed (invalid JSON)");
36228
36463
  ok = false;
@@ -36251,7 +36486,7 @@ async function runClaudeCheck() {
36251
36486
  if (existsSync40(claudeJsonPath)) {
36252
36487
  let claudeJson;
36253
36488
  try {
36254
- claudeJson = JSON.parse(readFileSync35(claudeJsonPath, "utf8"));
36489
+ claudeJson = JSON.parse(readFileSync36(claudeJsonPath, "utf8"));
36255
36490
  } catch {
36256
36491
  console.log("\x1B[31m\u2717\x1B[0m claude.json is malformed (invalid JSON)");
36257
36492
  ok = false;
@@ -36284,7 +36519,7 @@ async function runClaudeCheck() {
36284
36519
  } else {
36285
36520
  console.log("\x1B[32m\u2713\x1B[0m No .mcp.json/project MCP name collisions detected");
36286
36521
  }
36287
- const skillsDir = path54.join(claudeDir, "skills");
36522
+ const skillsDir = path55.join(claudeDir, "skills");
36288
36523
  if (existsSync40(skillsDir)) {
36289
36524
  console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
36290
36525
  } else {
@@ -36309,16 +36544,16 @@ async function runClaudeUninstall(flags = []) {
36309
36544
  const dryRun = flags.includes("--dry-run");
36310
36545
  const purge = flags.includes("--purge");
36311
36546
  const homeDir = os25.homedir();
36312
- const claudeDir = path54.join(homeDir, ".claude");
36313
- const settingsPath = path54.join(claudeDir, "settings.json");
36314
- const claudeJsonPath = path54.join(homeDir, ".claude.json");
36315
- const exeOsDir = path54.join(homeDir, ".exe-os");
36547
+ const claudeDir = path55.join(homeDir, ".claude");
36548
+ const settingsPath = path55.join(claudeDir, "settings.json");
36549
+ const claudeJsonPath = path55.join(homeDir, ".claude.json");
36550
+ const exeOsDir = path55.join(homeDir, ".exe-os");
36316
36551
  let removed = 0;
36317
36552
  const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
36318
36553
  let settings = {};
36319
36554
  if (existsSync40(settingsPath)) {
36320
36555
  try {
36321
- settings = JSON.parse(readFileSync35(settingsPath, "utf8"));
36556
+ settings = JSON.parse(readFileSync36(settingsPath, "utf8"));
36322
36557
  } catch {
36323
36558
  console.error("Your ~/.claude/settings.json appears malformed.");
36324
36559
  if (purge) {
@@ -36356,7 +36591,7 @@ async function runClaudeUninstall(flags = []) {
36356
36591
  permCount = before - settings.permissions.allow.length;
36357
36592
  }
36358
36593
  if (!dryRun) {
36359
- writeFileSync26(settingsPath, JSON.stringify(settings, null, 2) + "\n");
36594
+ writeFileSync27(settingsPath, JSON.stringify(settings, null, 2) + "\n");
36360
36595
  }
36361
36596
  log("\u2713 Removed exe-os hooks from settings.json");
36362
36597
  if (permCount > 0) log(`\u2713 Removed ${permCount} MCP permission entries`);
@@ -36364,7 +36599,7 @@ async function runClaudeUninstall(flags = []) {
36364
36599
  }
36365
36600
  }
36366
36601
  if (existsSync40(claudeJsonPath)) {
36367
- const raw = readFileSync35(claudeJsonPath, "utf8");
36602
+ const raw = readFileSync36(claudeJsonPath, "utf8");
36368
36603
  if (raw.length > 1e6) {
36369
36604
  console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
36370
36605
  } else {
@@ -36385,7 +36620,7 @@ async function runClaudeUninstall(flags = []) {
36385
36620
  }
36386
36621
  if (removedMcp) {
36387
36622
  if (!dryRun) {
36388
- writeFileSync26(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
36623
+ writeFileSync27(claudeJsonPath, JSON.stringify(claudeJson, null, 2) + "\n");
36389
36624
  }
36390
36625
  log("\u2713 Removed exe-os MCP server from claude.json");
36391
36626
  removed++;
@@ -36393,14 +36628,14 @@ async function runClaudeUninstall(flags = []) {
36393
36628
  }
36394
36629
  }
36395
36630
  }
36396
- const skillsDir = path54.join(claudeDir, "skills");
36631
+ const skillsDir = path55.join(claudeDir, "skills");
36397
36632
  if (existsSync40(skillsDir)) {
36398
36633
  let skillCount = 0;
36399
36634
  try {
36400
36635
  const entries = readdirSync12(skillsDir);
36401
36636
  for (const entry of entries) {
36402
36637
  if (entry.startsWith("exe")) {
36403
- const fullPath = path54.join(skillsDir, entry);
36638
+ const fullPath = path55.join(skillsDir, entry);
36404
36639
  if (!dryRun) rmSync2(fullPath, { recursive: true, force: true });
36405
36640
  skillCount++;
36406
36641
  }
@@ -36412,30 +36647,30 @@ async function runClaudeUninstall(flags = []) {
36412
36647
  removed++;
36413
36648
  }
36414
36649
  }
36415
- const claudeMdPath = path54.join(claudeDir, "CLAUDE.md");
36650
+ const claudeMdPath = path55.join(claudeDir, "CLAUDE.md");
36416
36651
  if (existsSync40(claudeMdPath)) {
36417
- const content = readFileSync35(claudeMdPath, "utf8");
36652
+ const content = readFileSync36(claudeMdPath, "utf8");
36418
36653
  const startMarker = "<!-- exe-os:orchestration-start -->";
36419
36654
  const endMarker = "<!-- exe-os:orchestration-end -->";
36420
36655
  const startIdx = content.indexOf(startMarker);
36421
36656
  const endIdx = content.indexOf(endMarker);
36422
36657
  if (startIdx !== -1 && endIdx !== -1) {
36423
36658
  const cleaned = (content.slice(0, startIdx) + content.slice(endIdx + endMarker.length)).replace(/\n{3,}/g, "\n\n").trim() + "\n";
36424
- if (!dryRun) writeFileSync26(claudeMdPath, cleaned);
36659
+ if (!dryRun) writeFileSync27(claudeMdPath, cleaned);
36425
36660
  log("\u2713 Removed orchestration block from CLAUDE.md");
36426
36661
  removed++;
36427
36662
  }
36428
36663
  }
36429
- const agentsDir = path54.join(claudeDir, "agents");
36664
+ const agentsDir = path55.join(claudeDir, "agents");
36430
36665
  if (existsSync40(agentsDir)) {
36431
36666
  let agentCount = 0;
36432
36667
  try {
36433
36668
  const entries = readdirSync12(agentsDir).filter((f) => f.endsWith(".md"));
36434
36669
  let knownNames = /* @__PURE__ */ new Set();
36435
- const rosterPath = path54.join(exeOsDir, "exe-employees.json");
36670
+ const rosterPath = path55.join(exeOsDir, "exe-employees.json");
36436
36671
  if (existsSync40(rosterPath)) {
36437
36672
  try {
36438
- const roster = JSON.parse(readFileSync35(rosterPath, "utf8"));
36673
+ const roster = JSON.parse(readFileSync36(rosterPath, "utf8"));
36439
36674
  knownNames = new Set(roster.map((e) => e.name));
36440
36675
  } catch {
36441
36676
  }
@@ -36443,7 +36678,7 @@ async function runClaudeUninstall(flags = []) {
36443
36678
  for (const entry of entries) {
36444
36679
  const name = entry.replace(/\.md$/, "");
36445
36680
  if (knownNames.has(name)) {
36446
- if (!dryRun) rmSync2(path54.join(agentsDir, entry), { force: true });
36681
+ if (!dryRun) rmSync2(path55.join(agentsDir, entry), { force: true });
36447
36682
  agentCount++;
36448
36683
  }
36449
36684
  }
@@ -36454,16 +36689,16 @@ async function runClaudeUninstall(flags = []) {
36454
36689
  removed++;
36455
36690
  }
36456
36691
  }
36457
- const projectsDir = path54.join(claudeDir, "projects");
36692
+ const projectsDir = path55.join(claudeDir, "projects");
36458
36693
  if (existsSync40(projectsDir)) {
36459
36694
  let projectCount = 0;
36460
36695
  try {
36461
36696
  const projects = readdirSync12(projectsDir);
36462
36697
  for (const proj of projects) {
36463
- const projSettings = path54.join(projectsDir, proj, "settings.json");
36698
+ const projSettings = path55.join(projectsDir, proj, "settings.json");
36464
36699
  if (!existsSync40(projSettings)) continue;
36465
36700
  try {
36466
- const pSettings = JSON.parse(readFileSync35(projSettings, "utf8"));
36701
+ const pSettings = JSON.parse(readFileSync36(projSettings, "utf8"));
36467
36702
  let changed = false;
36468
36703
  if (Array.isArray(pSettings.permissions?.allow)) {
36469
36704
  const before = pSettings.permissions.allow.length;
@@ -36473,7 +36708,7 @@ async function runClaudeUninstall(flags = []) {
36473
36708
  if (pSettings.permissions.allow.length < before) changed = true;
36474
36709
  }
36475
36710
  if (changed && !dryRun) {
36476
- writeFileSync26(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
36711
+ writeFileSync27(projSettings, JSON.stringify(pSettings, null, 2) + "\n");
36477
36712
  }
36478
36713
  if (changed) projectCount++;
36479
36714
  } catch {
@@ -36497,17 +36732,17 @@ async function runClaudeUninstall(flags = []) {
36497
36732
  };
36498
36733
  const exeBinPath = findExeBin3();
36499
36734
  if (!exeBinPath) throw new Error("exe-os not found in PATH");
36500
- const binDir = path54.dirname(exeBinPath);
36735
+ const binDir = path55.dirname(exeBinPath);
36501
36736
  let symlinkCount = 0;
36502
- const rosterPath = path54.join(exeOsDir, "exe-employees.json");
36737
+ const rosterPath = path55.join(exeOsDir, "exe-employees.json");
36503
36738
  if (existsSync40(rosterPath)) {
36504
- const roster = JSON.parse(readFileSync35(rosterPath, "utf8"));
36739
+ const roster = JSON.parse(readFileSync36(rosterPath, "utf8"));
36505
36740
  const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
36506
36741
  const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME2;
36507
36742
  for (const emp of roster) {
36508
36743
  if (emp.name === coordinatorName) continue;
36509
36744
  for (const suffix of ["", "-opencode"]) {
36510
- const linkPath = path54.join(binDir, `${emp.name}${suffix}`);
36745
+ const linkPath = path55.join(binDir, `${emp.name}${suffix}`);
36511
36746
  if (existsSync40(linkPath)) {
36512
36747
  if (!dryRun) rmSync2(linkPath, { force: true });
36513
36748
  symlinkCount++;
@@ -36546,7 +36781,7 @@ async function checkForUpdateOnBoot() {
36546
36781
  const config = await loadConfig2();
36547
36782
  if (!config.autoUpdate.checkOnBoot) return;
36548
36783
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
36549
- const packageRoot = path54.resolve(
36784
+ const packageRoot = path55.resolve(
36550
36785
  new URL("../..", import.meta.url).pathname
36551
36786
  );
36552
36787
  const result = checkForUpdate2(packageRoot);
@@ -36607,7 +36842,7 @@ async function runActivate(key) {
36607
36842
  const idTemplate = getIdentityTemplate(identityKey);
36608
36843
  if (idTemplate) {
36609
36844
  const idPath = identityPath2(name);
36610
- const dir = path54.dirname(idPath);
36845
+ const dir = path55.dirname(idPath);
36611
36846
  if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
36612
36847
  fs8.writeFileSync(idPath, idTemplate.replace(/^agent_id: \w+/m, `agent_id: ${name}`), "utf-8");
36613
36848
  }