@askexenow/exe-os 0.9.70 → 0.9.71

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 (69) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +27 -0
  2. package/dist/bin/agentic-reflection-backfill.js +27 -0
  3. package/dist/bin/agentic-semantic-label.js +27 -0
  4. package/dist/bin/backfill-conversations.js +27 -0
  5. package/dist/bin/backfill-responses.js +27 -0
  6. package/dist/bin/backfill-vectors.js +27 -0
  7. package/dist/bin/bulk-sync-postgres.js +27 -0
  8. package/dist/bin/cleanup-stale-review-tasks.js +27 -0
  9. package/dist/bin/cli.js +27 -0
  10. package/dist/bin/exe-assign.js +27 -0
  11. package/dist/bin/exe-boot.js +27 -0
  12. package/dist/bin/exe-cloud.js +27 -0
  13. package/dist/bin/exe-dispatch.js +27 -0
  14. package/dist/bin/exe-doctor.js +27 -0
  15. package/dist/bin/exe-export-behaviors.js +27 -0
  16. package/dist/bin/exe-forget.js +27 -0
  17. package/dist/bin/exe-gateway.js +27 -0
  18. package/dist/bin/exe-heartbeat.js +27 -0
  19. package/dist/bin/exe-kill.js +27 -0
  20. package/dist/bin/exe-launch-agent.js +27 -0
  21. package/dist/bin/exe-pending-messages.js +27 -0
  22. package/dist/bin/exe-pending-notifications.js +27 -0
  23. package/dist/bin/exe-pending-reviews.js +27 -0
  24. package/dist/bin/exe-rename.js +27 -0
  25. package/dist/bin/exe-review.js +27 -0
  26. package/dist/bin/exe-search.js +27 -0
  27. package/dist/bin/exe-session-cleanup.js +27 -0
  28. package/dist/bin/exe-start-codex.js +27 -0
  29. package/dist/bin/exe-start-opencode.js +27 -0
  30. package/dist/bin/exe-status.js +27 -0
  31. package/dist/bin/exe-team.js +27 -0
  32. package/dist/bin/git-sweep.js +27 -0
  33. package/dist/bin/graph-backfill.js +27 -0
  34. package/dist/bin/graph-export.js +27 -0
  35. package/dist/bin/intercom-check.js +27 -0
  36. package/dist/bin/scan-tasks.js +27 -0
  37. package/dist/bin/setup.js +27 -0
  38. package/dist/bin/shard-migrate.js +27 -0
  39. package/dist/gateway/index.js +27 -0
  40. package/dist/hooks/bug-report-worker.js +27 -0
  41. package/dist/hooks/codex-stop-task-finalizer.js +27 -0
  42. package/dist/hooks/commit-complete.js +27 -0
  43. package/dist/hooks/error-recall.js +27 -0
  44. package/dist/hooks/ingest.js +27 -0
  45. package/dist/hooks/instructions-loaded.js +27 -0
  46. package/dist/hooks/notification.js +27 -0
  47. package/dist/hooks/post-compact.js +27 -0
  48. package/dist/hooks/post-tool-combined.js +692 -17
  49. package/dist/hooks/pre-compact.js +27 -0
  50. package/dist/hooks/pre-tool-use.js +27 -0
  51. package/dist/hooks/prompt-submit.js +308 -0
  52. package/dist/hooks/session-end.js +27 -0
  53. package/dist/hooks/session-start.js +27 -0
  54. package/dist/hooks/stop.js +273 -12
  55. package/dist/hooks/subagent-stop.js +27 -0
  56. package/dist/hooks/summary-worker.js +27 -0
  57. package/dist/index.js +27 -0
  58. package/dist/lib/cloud-sync.js +27 -0
  59. package/dist/lib/database.js +27 -0
  60. package/dist/lib/db.js +27 -0
  61. package/dist/lib/device-registry.js +27 -0
  62. package/dist/lib/exe-daemon.js +260 -28
  63. package/dist/lib/hybrid-search.js +27 -0
  64. package/dist/lib/schedules.js +27 -0
  65. package/dist/lib/store.js +27 -0
  66. package/dist/mcp/server.js +246 -25
  67. package/dist/runtime/index.js +27 -0
  68. package/dist/tui/App.js +27 -0
  69. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
2
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
3
5
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
6
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
7
  }) : x)(function(x) {
@@ -13,6 +15,15 @@ var __export = (target, all) => {
13
15
  for (var name in all)
14
16
  __defProp(target, name, { get: all[name], enumerable: true });
15
17
  };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
27
 
17
28
  // src/lib/secure-files.ts
18
29
  import { chmodSync, existsSync, mkdirSync } from "fs";
@@ -1218,6 +1229,17 @@ var init_daemon_auth = __esm({
1218
1229
  });
1219
1230
 
1220
1231
  // src/lib/exe-daemon-client.ts
1232
+ var exe_daemon_client_exports = {};
1233
+ __export(exe_daemon_client_exports, {
1234
+ connectEmbedDaemon: () => connectEmbedDaemon,
1235
+ disconnectClient: () => disconnectClient,
1236
+ embedBatchViaClient: () => embedBatchViaClient,
1237
+ embedViaClient: () => embedViaClient,
1238
+ isClientConnected: () => isClientConnected,
1239
+ pingDaemon: () => pingDaemon,
1240
+ sendDaemonRequest: () => sendDaemonRequest,
1241
+ sendIngestRequest: () => sendIngestRequest
1242
+ });
1221
1243
  import net from "net";
1222
1244
  import os4 from "os";
1223
1245
  import { spawn } from "child_process";
@@ -1285,8 +1307,8 @@ function findPackageRoot() {
1285
1307
  function getAvailableMemoryGB() {
1286
1308
  if (process.platform === "darwin") {
1287
1309
  try {
1288
- const { execSync: execSync7 } = __require("child_process");
1289
- const vmstat = execSync7("vm_stat", { encoding: "utf8" });
1310
+ const { execSync: execSync8 } = __require("child_process");
1311
+ const vmstat = execSync8("vm_stat", { encoding: "utf8" });
1290
1312
  const pageSize = 16384;
1291
1313
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1292
1314
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -1606,6 +1628,15 @@ async function embedViaClient(text, priority = "high") {
1606
1628
  );
1607
1629
  return !result.error && result.vectors?.[0] ? result.vectors[0] : null;
1608
1630
  }
1631
+ async function embedBatchViaClient(texts, priority = "high") {
1632
+ if (!_connected && !await connectEmbedDaemon()) return null;
1633
+ _requestCount++;
1634
+ const result = await retryThenRestart(
1635
+ () => sendRequest(texts, priority),
1636
+ "Batch embed"
1637
+ );
1638
+ return !result.error && result.vectors ? result.vectors : null;
1639
+ }
1609
1640
  function disconnectClient() {
1610
1641
  if (_socket) {
1611
1642
  _socket.destroy();
@@ -1622,6 +1653,17 @@ function disconnectClient() {
1622
1653
  function isClientConnected() {
1623
1654
  return _connected;
1624
1655
  }
1656
+ function sendIngestRequest(payload) {
1657
+ if (!_socket || !_connected) return false;
1658
+ try {
1659
+ const id = randomUUID();
1660
+ const token = process.env[DAEMON_TOKEN_ENV] ?? readDaemonToken();
1661
+ _socket.write(JSON.stringify({ id, token, type: "ingest", ...payload }) + "\n");
1662
+ return true;
1663
+ } catch {
1664
+ return false;
1665
+ }
1666
+ }
1625
1667
  var SOCKET_PATH, PID_PATH, SPAWN_LOCK_PATH, SPAWN_LOCK_STALE_MS, CONNECT_TIMEOUT_MS, REQUEST_TIMEOUT_MS, DAEMON_TOKEN_ENV, _socket, _connected, _buffer, _requestCount, _consecutiveFailures, HEALTH_CHECK_INTERVAL, MAX_RETRIES_BEFORE_RESTART, RETRY_DELAYS_MS, MIN_DAEMON_AGE_MS, _pending, MAX_BUFFER;
1626
1668
  var init_exe_daemon_client = __esm({
1627
1669
  "src/lib/exe-daemon-client.ts"() {
@@ -1650,6 +1692,15 @@ var init_exe_daemon_client = __esm({
1650
1692
  });
1651
1693
 
1652
1694
  // src/lib/daemon-protocol.ts
1695
+ var daemon_protocol_exports = {};
1696
+ __export(daemon_protocol_exports, {
1697
+ deserializeArgs: () => deserializeArgs,
1698
+ deserializeResultSet: () => deserializeResultSet,
1699
+ deserializeValue: () => deserializeValue,
1700
+ serializeArgs: () => serializeArgs,
1701
+ serializeResultSet: () => serializeResultSet,
1702
+ serializeValue: () => serializeValue
1703
+ });
1653
1704
  function serializeValue(v) {
1654
1705
  if (v === null || v === void 0) return null;
1655
1706
  if (typeof v === "bigint") return Number(v);
@@ -1674,6 +1725,32 @@ function deserializeValue(v) {
1674
1725
  }
1675
1726
  return v;
1676
1727
  }
1728
+ function serializeArgs(args) {
1729
+ return args.map(serializeValue);
1730
+ }
1731
+ function deserializeArgs(args) {
1732
+ return args.map(deserializeValue);
1733
+ }
1734
+ function serializeResultSet(rs) {
1735
+ const rows = [];
1736
+ for (const row of rs.rows) {
1737
+ const obj = {};
1738
+ for (let i = 0; i < rs.columns.length; i++) {
1739
+ const col = rs.columns[i];
1740
+ if (col !== void 0) {
1741
+ obj[col] = serializeValue(row[i]);
1742
+ }
1743
+ }
1744
+ rows.push(obj);
1745
+ }
1746
+ return {
1747
+ columns: [...rs.columns],
1748
+ columnTypes: [...rs.columnTypes ?? []],
1749
+ rows,
1750
+ rowsAffected: typeof rs.rowsAffected === "bigint" ? Number(rs.rowsAffected) : rs.rowsAffected ?? 0,
1751
+ lastInsertRowid: rs.lastInsertRowid != null ? typeof rs.lastInsertRowid === "bigint" ? Number(rs.lastInsertRowid) : rs.lastInsertRowid : null
1752
+ };
1753
+ }
1677
1754
  function deserializeResultSet(srs) {
1678
1755
  const rows = srs.rows.map((obj) => {
1679
1756
  const values = srs.columns.map(
@@ -2613,6 +2690,33 @@ async function ensureSchema() {
2613
2690
  CREATE INDEX IF NOT EXISTS idx_chat_history_session
2614
2691
  ON chat_history(session_id, id);
2615
2692
  `);
2693
+ await client.executeMultiple(`
2694
+ CREATE TABLE IF NOT EXISTS session_events (
2695
+ id TEXT PRIMARY KEY,
2696
+ agent_id TEXT NOT NULL,
2697
+ agent_role TEXT NOT NULL,
2698
+ session_id TEXT NOT NULL,
2699
+ session_scope TEXT,
2700
+ project_name TEXT NOT NULL,
2701
+ event_index INTEGER NOT NULL,
2702
+ event_type TEXT NOT NULL,
2703
+ tool_name TEXT,
2704
+ tool_use_id TEXT,
2705
+ content TEXT NOT NULL,
2706
+ payload_json TEXT,
2707
+ has_error INTEGER NOT NULL DEFAULT 0,
2708
+ created_at TEXT NOT NULL
2709
+ );
2710
+
2711
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
2712
+ ON session_events(agent_id, created_at DESC);
2713
+
2714
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
2715
+ ON session_events(session_id, event_index);
2716
+
2717
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
2718
+ ON session_events(session_scope, agent_id, created_at DESC);
2719
+ `);
2616
2720
  await client.executeMultiple(`
2617
2721
  CREATE TABLE IF NOT EXISTS workspaces (
2618
2722
  id TEXT PRIMARY KEY,
@@ -3380,8 +3484,8 @@ function deriveMachineKey() {
3380
3484
  }
3381
3485
  function readMachineId() {
3382
3486
  try {
3383
- const { readFileSync: readFileSync8 } = __require("fs");
3384
- return readFileSync8("/etc/machine-id", "utf-8").trim();
3487
+ const { readFileSync: readFileSync13 } = __require("fs");
3488
+ return readFileSync13("/etc/machine-id", "utf-8").trim();
3385
3489
  } catch {
3386
3490
  return "";
3387
3491
  }
@@ -5776,10 +5880,10 @@ async function disposeEmbedder() {
5776
5880
  async function embedDirect(text) {
5777
5881
  const llamaCpp = await import("node-llama-cpp");
5778
5882
  const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
5779
- const { existsSync: existsSync11 } = await import("fs");
5780
- const path13 = await import("path");
5781
- const modelPath = path13.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
5782
- if (!existsSync11(modelPath)) {
5883
+ const { existsSync: existsSync17 } = await import("fs");
5884
+ const path20 = await import("path");
5885
+ const modelPath = path20.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
5886
+ if (!existsSync17(modelPath)) {
5783
5887
  throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
5784
5888
  }
5785
5889
  const llama = await llamaCpp.getLlama();
@@ -6870,10 +6974,10 @@ async function hybridSearch(queryText, agentId, options) {
6870
6974
  };
6871
6975
  try {
6872
6976
  const fs = await import("fs");
6873
- const path13 = await import("path");
6874
- const os6 = await import("os");
6875
- const logPath = path13.join(os6.homedir(), ".exe-os", "search-quality.jsonl");
6876
- fs.mkdirSync(path13.dirname(logPath), { recursive: true });
6977
+ const path20 = await import("path");
6978
+ const os11 = await import("os");
6979
+ const logPath = path20.join(os11.homedir(), ".exe-os", "search-quality.jsonl");
6980
+ fs.mkdirSync(path20.dirname(logPath), { recursive: true });
6877
6981
  fs.appendFileSync(logPath, JSON.stringify(logEntry) + "\n");
6878
6982
  } catch {
6879
6983
  }
@@ -7407,8 +7511,8 @@ function findContainingChunk(filePath, snippet) {
7407
7511
  try {
7408
7512
  const ext = filePath.split(".").pop()?.toLowerCase();
7409
7513
  if (ext !== "ts" && ext !== "tsx" && ext !== "js" && ext !== "jsx") return "";
7410
- const { readFileSync: readFileSync8 } = __require("fs");
7411
- const source = readFileSync8(filePath, "utf8");
7514
+ const { readFileSync: readFileSync13 } = __require("fs");
7515
+ const source = readFileSync13(filePath, "utf8");
7412
7516
  const lines = source.split("\n");
7413
7517
  const lowerSnippet = snippet.toLowerCase().slice(0, 80);
7414
7518
  let matchLine = -1;
@@ -7474,9 +7578,9 @@ function extractBash(input2, response) {
7474
7578
  }
7475
7579
  function extractGrep(input2, response) {
7476
7580
  const pattern = String(input2.pattern ?? "");
7477
- const path13 = input2.path ? String(input2.path) : "";
7581
+ const path20 = input2.path ? String(input2.path) : "";
7478
7582
  const output = String(response.text ?? response.content ?? JSON.stringify(response).slice(0, MAX_OUTPUT));
7479
- return `Searched for "${pattern}"${path13 ? ` in ${path13}` : ""}
7583
+ return `Searched for "${pattern}"${path20 ? ` in ${path20}` : ""}
7480
7584
  ${output.slice(0, MAX_OUTPUT)}`;
7481
7585
  }
7482
7586
  function extractGlob(input2, response) {
@@ -7881,6 +7985,551 @@ var init_active_agent2 = __esm({
7881
7985
  }
7882
7986
  });
7883
7987
 
7988
+ // src/bin/fast-db-init.ts
7989
+ var fast_db_init_exports = {};
7990
+ __export(fast_db_init_exports, {
7991
+ fastDbInit: () => fastDbInit
7992
+ });
7993
+ async function fastDbInit() {
7994
+ const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
7995
+ if (isInitialized2()) {
7996
+ return getClient2();
7997
+ }
7998
+ try {
7999
+ const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
8000
+ const { deserializeResultSet: deserializeResultSet2 } = await Promise.resolve().then(() => (init_daemon_protocol(), daemon_protocol_exports));
8001
+ await connectEmbedDaemon2();
8002
+ if (isClientConnected2()) {
8003
+ const daemonClient = {
8004
+ async execute(stmt) {
8005
+ const sql = typeof stmt === "string" ? stmt : stmt.sql;
8006
+ const args = typeof stmt === "string" ? [] : Array.isArray(stmt.args) ? stmt.args : [];
8007
+ const resp = await sendDaemonRequest2({ type: "db-execute", sql, args });
8008
+ if (resp.error) throw new Error(String(resp.error));
8009
+ if (resp.db) return deserializeResultSet2(resp.db);
8010
+ throw new Error("Unexpected daemon response");
8011
+ },
8012
+ async batch(stmts, mode) {
8013
+ const statements = stmts.map((s) => {
8014
+ const sql = typeof s === "string" ? s : s.sql;
8015
+ const args = typeof s === "string" ? [] : Array.isArray(s.args) ? s.args : [];
8016
+ return { sql, args };
8017
+ });
8018
+ const resp = await sendDaemonRequest2({ type: "db-batch", statements, mode: mode ?? "deferred" });
8019
+ if (resp.error) throw new Error(String(resp.error));
8020
+ const batchResults = resp["db-batch"];
8021
+ if (batchResults) return batchResults.map(deserializeResultSet2);
8022
+ throw new Error("Unexpected daemon batch response");
8023
+ },
8024
+ async transaction(_mode) {
8025
+ throw new Error("Transactions not supported via daemon socket");
8026
+ },
8027
+ async executeMultiple(_sql) {
8028
+ throw new Error("executeMultiple not supported via daemon socket");
8029
+ },
8030
+ async migrate(_stmts) {
8031
+ throw new Error("migrate not supported via daemon socket");
8032
+ },
8033
+ sync() {
8034
+ return Promise.resolve(void 0);
8035
+ },
8036
+ close() {
8037
+ },
8038
+ get closed() {
8039
+ return false;
8040
+ },
8041
+ get protocol() {
8042
+ return "file";
8043
+ }
8044
+ };
8045
+ setExternalClient2(daemonClient);
8046
+ return daemonClient;
8047
+ }
8048
+ } catch {
8049
+ }
8050
+ const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
8051
+ await initStore2({ lightweight: true });
8052
+ return getClient2();
8053
+ }
8054
+ var init_fast_db_init = __esm({
8055
+ "src/bin/fast-db-init.ts"() {
8056
+ "use strict";
8057
+ }
8058
+ });
8059
+
8060
+ // src/lib/session-registry.ts
8061
+ import path13 from "path";
8062
+ import os6 from "os";
8063
+ var REGISTRY_PATH;
8064
+ var init_session_registry = __esm({
8065
+ "src/lib/session-registry.ts"() {
8066
+ "use strict";
8067
+ REGISTRY_PATH = path13.join(os6.homedir(), ".exe-os", "session-registry.json");
8068
+ }
8069
+ });
8070
+
8071
+ // src/lib/tmux-transport.ts
8072
+ var tmux_transport_exports = {};
8073
+ __export(tmux_transport_exports, {
8074
+ TmuxTransport: () => TmuxTransport
8075
+ });
8076
+ import { execFileSync } from "child_process";
8077
+ var QUIET, TmuxTransport;
8078
+ var init_tmux_transport = __esm({
8079
+ "src/lib/tmux-transport.ts"() {
8080
+ "use strict";
8081
+ QUIET = {
8082
+ encoding: "utf8",
8083
+ stdio: ["pipe", "pipe", "pipe"]
8084
+ };
8085
+ TmuxTransport = class {
8086
+ getMySession() {
8087
+ try {
8088
+ return execFileSync("tmux", ["display-message", "-p", "#{session_name}"], QUIET).trim() || null;
8089
+ } catch {
8090
+ return null;
8091
+ }
8092
+ }
8093
+ listSessions() {
8094
+ try {
8095
+ return execFileSync("tmux", ["list-sessions", "-F", "#{session_name}"], QUIET).trim().split("\n").filter(Boolean);
8096
+ } catch {
8097
+ return [];
8098
+ }
8099
+ }
8100
+ isAlive(target) {
8101
+ try {
8102
+ const sessions = this.listSessions();
8103
+ if (!sessions.includes(target)) return false;
8104
+ const paneStatus = execFileSync(
8105
+ "tmux",
8106
+ ["list-panes", "-t", target, "-F", "#{pane_dead}"],
8107
+ QUIET
8108
+ ).trim();
8109
+ return paneStatus !== "1";
8110
+ } catch {
8111
+ return false;
8112
+ }
8113
+ }
8114
+ sendKeys(target, keys) {
8115
+ execFileSync("tmux", ["send-keys", "-t", target, keys, "Enter"], QUIET);
8116
+ }
8117
+ /**
8118
+ * Send text as literal characters, then submit with Enter as a separate call.
8119
+ * Fixes Codex intercom bug: long text + Enter in one send-keys blast causes
8120
+ * Codex to drop the Enter. Splitting them ensures the text renders before
8121
+ * the submit keystroke arrives.
8122
+ */
8123
+ sendKeysLiteral(target, text) {
8124
+ execFileSync("tmux", ["send-keys", "-t", target, "-l", text], QUIET);
8125
+ execFileSync("tmux", ["send-keys", "-t", target, "Enter"], QUIET);
8126
+ }
8127
+ capturePane(target, lines) {
8128
+ const args = ["capture-pane", "-t", target, "-p"];
8129
+ if (lines) args.push("-S", `-${lines}`);
8130
+ return execFileSync("tmux", args, { ...QUIET, timeout: 3e3 });
8131
+ }
8132
+ isPaneInCopyMode(target) {
8133
+ try {
8134
+ const result = execFileSync(
8135
+ "tmux",
8136
+ ["display-message", "-p", "-t", target, "#{pane_in_mode}"],
8137
+ { ...QUIET, timeout: 3e3 }
8138
+ ).trim();
8139
+ return result === "1";
8140
+ } catch {
8141
+ return false;
8142
+ }
8143
+ }
8144
+ spawn(name, config) {
8145
+ try {
8146
+ const args = ["new-session", "-d", "-s", name];
8147
+ if (config.cwd) args.push("-c", config.cwd);
8148
+ args.push(config.command);
8149
+ execFileSync("tmux", args);
8150
+ return { sessionName: name };
8151
+ } catch (e) {
8152
+ return { sessionName: name, error: `spawn failed: ${e}` };
8153
+ }
8154
+ }
8155
+ kill(target) {
8156
+ try {
8157
+ execFileSync("tmux", ["kill-session", "-t", target], QUIET);
8158
+ } catch {
8159
+ }
8160
+ }
8161
+ pipeLog(target, logFile) {
8162
+ try {
8163
+ const safePath = logFile.replace(/'/g, "'\\''");
8164
+ execFileSync("tmux", ["pipe-pane", "-t", target, `cat >> '${safePath}'`], QUIET);
8165
+ } catch {
8166
+ }
8167
+ }
8168
+ };
8169
+ }
8170
+ });
8171
+
8172
+ // src/lib/transport.ts
8173
+ function getTransport() {
8174
+ if (!_transport) {
8175
+ const { TmuxTransport: TmuxTransport2 } = (init_tmux_transport(), __toCommonJS(tmux_transport_exports));
8176
+ _transport = new TmuxTransport2();
8177
+ }
8178
+ return _transport;
8179
+ }
8180
+ var _transport;
8181
+ var init_transport = __esm({
8182
+ "src/lib/transport.ts"() {
8183
+ "use strict";
8184
+ _transport = null;
8185
+ }
8186
+ });
8187
+
8188
+ // src/lib/cc-agent-support.ts
8189
+ import { execSync as execSync7 } from "child_process";
8190
+ var init_cc_agent_support = __esm({
8191
+ "src/lib/cc-agent-support.ts"() {
8192
+ "use strict";
8193
+ }
8194
+ });
8195
+
8196
+ // src/lib/provider-table.ts
8197
+ var init_provider_table = __esm({
8198
+ "src/lib/provider-table.ts"() {
8199
+ "use strict";
8200
+ }
8201
+ });
8202
+
8203
+ // src/lib/runtime-table.ts
8204
+ var RUNTIME_TABLE;
8205
+ var init_runtime_table = __esm({
8206
+ "src/lib/runtime-table.ts"() {
8207
+ "use strict";
8208
+ RUNTIME_TABLE = {
8209
+ codex: {
8210
+ binary: "codex",
8211
+ launchMode: "interactive",
8212
+ autoApproveFlag: "--dangerously-bypass-approvals-and-sandbox",
8213
+ inlineFlag: "--no-alt-screen",
8214
+ apiKeyEnv: "OPENAI_API_KEY",
8215
+ defaultModel: "gpt-5.5"
8216
+ },
8217
+ opencode: {
8218
+ binary: "opencode",
8219
+ launchMode: "exec",
8220
+ autoApproveFlag: "--dangerously-skip-permissions",
8221
+ inlineFlag: "",
8222
+ apiKeyEnv: "ANTHROPIC_API_KEY",
8223
+ defaultModel: "anthropic/claude-sonnet-4-6"
8224
+ }
8225
+ };
8226
+ }
8227
+ });
8228
+
8229
+ // src/lib/agent-config.ts
8230
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync11 } from "fs";
8231
+ import path14 from "path";
8232
+ var AGENT_CONFIG_PATH, DEFAULT_MODELS;
8233
+ var init_agent_config = __esm({
8234
+ "src/lib/agent-config.ts"() {
8235
+ "use strict";
8236
+ init_config();
8237
+ init_runtime_table();
8238
+ init_secure_files();
8239
+ AGENT_CONFIG_PATH = path14.join(EXE_AI_DIR, "agent-config.json");
8240
+ DEFAULT_MODELS = {
8241
+ claude: "claude-opus-4.6",
8242
+ codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
8243
+ opencode: RUNTIME_TABLE.opencode?.defaultModel ?? "anthropic/claude-sonnet-4-6"
8244
+ };
8245
+ }
8246
+ });
8247
+
8248
+ // src/lib/intercom-queue.ts
8249
+ import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, renameSync as renameSync5, existsSync as existsSync12, mkdirSync as mkdirSync4 } from "fs";
8250
+ import path15 from "path";
8251
+ import os7 from "os";
8252
+ var QUEUE_PATH2, TTL_MS2, INTERCOM_LOG;
8253
+ var init_intercom_queue = __esm({
8254
+ "src/lib/intercom-queue.ts"() {
8255
+ "use strict";
8256
+ QUEUE_PATH2 = path15.join(os7.homedir(), ".exe-os", "intercom-queue.json");
8257
+ TTL_MS2 = 60 * 60 * 1e3;
8258
+ INTERCOM_LOG = path15.join(os7.homedir(), ".exe-os", "intercom.log");
8259
+ }
8260
+ });
8261
+
8262
+ // src/lib/license.ts
8263
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, existsSync as existsSync13, mkdirSync as mkdirSync5 } from "fs";
8264
+ import { randomUUID as randomUUID3 } from "crypto";
8265
+ import { createRequire as createRequire2 } from "module";
8266
+ import { pathToFileURL as pathToFileURL2 } from "url";
8267
+ import os8 from "os";
8268
+ import path16 from "path";
8269
+ import { jwtVerify, importSPKI } from "jose";
8270
+ var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
8271
+ var init_license = __esm({
8272
+ "src/lib/license.ts"() {
8273
+ "use strict";
8274
+ init_config();
8275
+ LICENSE_PATH = path16.join(EXE_AI_DIR, "license.key");
8276
+ CACHE_PATH = path16.join(EXE_AI_DIR, "license-cache.json");
8277
+ DEVICE_ID_PATH = path16.join(EXE_AI_DIR, "device-id");
8278
+ }
8279
+ });
8280
+
8281
+ // src/lib/plan-limits.ts
8282
+ import { readFileSync as readFileSync11, existsSync as existsSync14 } from "fs";
8283
+ import path17 from "path";
8284
+ var CACHE_PATH2;
8285
+ var init_plan_limits = __esm({
8286
+ "src/lib/plan-limits.ts"() {
8287
+ "use strict";
8288
+ init_database();
8289
+ init_employees();
8290
+ init_license();
8291
+ init_config();
8292
+ CACHE_PATH2 = path17.join(EXE_AI_DIR, "license-cache.json");
8293
+ }
8294
+ });
8295
+
8296
+ // src/lib/agent-symlinks.ts
8297
+ import os9 from "os";
8298
+ import path18 from "path";
8299
+ import {
8300
+ existsSync as existsSync15,
8301
+ lstatSync,
8302
+ mkdirSync as mkdirSync6,
8303
+ readlinkSync as readlinkSync2,
8304
+ symlinkSync as symlinkSync2
8305
+ } from "fs";
8306
+ var init_agent_symlinks = __esm({
8307
+ "src/lib/agent-symlinks.ts"() {
8308
+ "use strict";
8309
+ init_employees();
8310
+ }
8311
+ });
8312
+
8313
+ // src/lib/tmux-routing.ts
8314
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, existsSync as existsSync16, appendFileSync as appendFileSync2, readdirSync as readdirSync4 } from "fs";
8315
+ import path19 from "path";
8316
+ import os10 from "os";
8317
+ import { fileURLToPath as fileURLToPath2 } from "url";
8318
+ function getMySession() {
8319
+ return getTransport().getMySession();
8320
+ }
8321
+ function extractRootExe(name) {
8322
+ if (!name) return null;
8323
+ if (!name.includes("-")) return name;
8324
+ const parts = name.split("-").filter(Boolean);
8325
+ return parts.length > 0 ? parts[parts.length - 1] : null;
8326
+ }
8327
+ function getParentExe(sessionKey) {
8328
+ try {
8329
+ const data = JSON.parse(readFileSync12(path19.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
8330
+ return data.parentExe || null;
8331
+ } catch {
8332
+ return null;
8333
+ }
8334
+ }
8335
+ function resolveExeSession() {
8336
+ const mySession = getMySession();
8337
+ if (!mySession) return null;
8338
+ const fromSessionName = extractRootExe(mySession);
8339
+ try {
8340
+ const key = getSessionKey();
8341
+ const parentExe = getParentExe(key);
8342
+ if (parentExe) {
8343
+ const fromCache = extractRootExe(parentExe) ?? parentExe;
8344
+ if (fromSessionName && fromCache !== fromSessionName) {
8345
+ process.stderr.write(
8346
+ `[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
8347
+ `
8348
+ );
8349
+ return fromSessionName;
8350
+ }
8351
+ return fromCache;
8352
+ }
8353
+ } catch {
8354
+ }
8355
+ return fromSessionName ?? mySession;
8356
+ }
8357
+ var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
8358
+ var init_tmux_routing = __esm({
8359
+ "src/lib/tmux-routing.ts"() {
8360
+ "use strict";
8361
+ init_session_registry();
8362
+ init_session_key();
8363
+ init_transport();
8364
+ init_cc_agent_support();
8365
+ init_mcp_prefix();
8366
+ init_provider_table();
8367
+ init_agent_config();
8368
+ init_runtime_table();
8369
+ init_intercom_queue();
8370
+ init_plan_limits();
8371
+ init_employees();
8372
+ init_agent_symlinks();
8373
+ SPAWN_LOCK_DIR = path19.join(os10.homedir(), ".exe-os", "spawn-locks");
8374
+ SESSION_CACHE = path19.join(os10.homedir(), ".exe-os", "session-cache");
8375
+ INTERCOM_LOG2 = path19.join(os10.homedir(), ".exe-os", "intercom.log");
8376
+ DEBOUNCE_FILE = path19.join(SESSION_CACHE, "intercom-debounce.json");
8377
+ DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
8378
+ }
8379
+ });
8380
+
8381
+ // src/lib/task-scope.ts
8382
+ function getCurrentSessionScope() {
8383
+ try {
8384
+ return resolveExeSession();
8385
+ } catch {
8386
+ return null;
8387
+ }
8388
+ }
8389
+ function strictSessionScopeFilter(sessionScope, tableAlias) {
8390
+ const scope = sessionScope !== void 0 ? sessionScope : getCurrentSessionScope();
8391
+ if (!scope) return { sql: "", args: [] };
8392
+ const col = tableAlias ? `${tableAlias}.session_scope` : "session_scope";
8393
+ return {
8394
+ sql: ` AND ${col} = ?`,
8395
+ args: [scope]
8396
+ };
8397
+ }
8398
+ var init_task_scope = __esm({
8399
+ "src/lib/task-scope.ts"() {
8400
+ "use strict";
8401
+ init_tmux_routing();
8402
+ }
8403
+ });
8404
+
8405
+ // src/lib/session-events.ts
8406
+ var session_events_exports = {};
8407
+ __export(session_events_exports, {
8408
+ ensureSessionEventsTable: () => ensureSessionEventsTable,
8409
+ listRecentSessionEvents: () => listRecentSessionEvents,
8410
+ recordSessionEvent: () => recordSessionEvent
8411
+ });
8412
+ import { randomUUID as randomUUID4 } from "crypto";
8413
+ async function ensureSessionEventsTable(client) {
8414
+ await client.execute(`
8415
+ CREATE TABLE IF NOT EXISTS session_events (
8416
+ id TEXT PRIMARY KEY,
8417
+ agent_id TEXT NOT NULL,
8418
+ agent_role TEXT NOT NULL,
8419
+ session_id TEXT NOT NULL,
8420
+ session_scope TEXT,
8421
+ project_name TEXT NOT NULL,
8422
+ event_index INTEGER NOT NULL,
8423
+ event_type TEXT NOT NULL,
8424
+ tool_name TEXT,
8425
+ tool_use_id TEXT,
8426
+ content TEXT NOT NULL,
8427
+ payload_json TEXT,
8428
+ has_error INTEGER NOT NULL DEFAULT 0,
8429
+ created_at TEXT NOT NULL
8430
+ )
8431
+ `);
8432
+ await client.execute(`
8433
+ CREATE INDEX IF NOT EXISTS idx_session_events_agent_time
8434
+ ON session_events(agent_id, created_at DESC)
8435
+ `);
8436
+ await client.execute(`
8437
+ CREATE INDEX IF NOT EXISTS idx_session_events_session_index
8438
+ ON session_events(session_id, event_index)
8439
+ `);
8440
+ await client.execute(`
8441
+ CREATE INDEX IF NOT EXISTS idx_session_events_scope_agent_time
8442
+ ON session_events(session_scope, agent_id, created_at DESC)
8443
+ `);
8444
+ }
8445
+ async function recordSessionEvent(client, input2) {
8446
+ if (!input2.content || input2.content.trim().length === 0) return;
8447
+ await ensureSessionEventsTable(client);
8448
+ const maxResult = await client.execute({
8449
+ sql: "SELECT COALESCE(MAX(event_index), 0) AS max_index FROM session_events WHERE session_id = ?",
8450
+ args: [input2.sessionId]
8451
+ });
8452
+ const currentMax = Number(maxResult.rows[0]?.max_index ?? 0);
8453
+ const eventIndex = Number.isFinite(currentMax) ? currentMax + 1 : 1;
8454
+ await client.execute({
8455
+ sql: `INSERT INTO session_events (
8456
+ id, agent_id, agent_role, session_id, session_scope, project_name,
8457
+ event_index, event_type, tool_name, tool_use_id, content,
8458
+ payload_json, has_error, created_at
8459
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8460
+ args: [
8461
+ randomUUID4(),
8462
+ input2.agentId,
8463
+ input2.agentRole,
8464
+ input2.sessionId,
8465
+ input2.sessionScope ?? getCurrentSessionScope(),
8466
+ input2.projectName ?? getProjectName(input2.cwd),
8467
+ eventIndex,
8468
+ input2.eventType,
8469
+ input2.toolName ?? null,
8470
+ input2.toolUseId ?? null,
8471
+ input2.content,
8472
+ input2.payloadJson ?? null,
8473
+ input2.hasError ? 1 : 0,
8474
+ input2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
8475
+ ]
8476
+ });
8477
+ }
8478
+ async function listRecentSessionEvents(client, options) {
8479
+ await ensureSessionEventsTable(client);
8480
+ const conditions = ["agent_id = ?"];
8481
+ const args = [options.agentId];
8482
+ if (options.sessionId) {
8483
+ conditions.push("session_id = ?");
8484
+ args.push(options.sessionId);
8485
+ }
8486
+ if (options.eventType) {
8487
+ conditions.push("event_type = ?");
8488
+ args.push(options.eventType);
8489
+ }
8490
+ if (options.projectName && options.projectName !== "all") {
8491
+ conditions.push("project_name = ?");
8492
+ args.push(options.projectName);
8493
+ }
8494
+ const scope = strictSessionScopeFilter(options.sessionScope);
8495
+ const where = `WHERE ${conditions.join(" AND ")}${scope.sql}`;
8496
+ args.push(...scope.args);
8497
+ args.push(Math.min(Math.max(options.limit ?? 20, 1), 100));
8498
+ const result = await client.execute({
8499
+ sql: `SELECT id, agent_id, agent_role, session_id, session_scope,
8500
+ project_name, event_index, event_type, tool_name, tool_use_id,
8501
+ content, payload_json, has_error, created_at
8502
+ FROM session_events
8503
+ ${where}
8504
+ ORDER BY created_at DESC, event_index DESC
8505
+ LIMIT ?`,
8506
+ args
8507
+ });
8508
+ return result.rows.map((row) => ({
8509
+ id: String(row.id),
8510
+ agentId: String(row.agent_id),
8511
+ agentRole: String(row.agent_role),
8512
+ sessionId: String(row.session_id),
8513
+ sessionScope: row.session_scope == null ? null : String(row.session_scope),
8514
+ projectName: String(row.project_name),
8515
+ eventIndex: Number(row.event_index),
8516
+ eventType: String(row.event_type),
8517
+ toolName: row.tool_name == null ? null : String(row.tool_name),
8518
+ toolUseId: row.tool_use_id == null ? null : String(row.tool_use_id),
8519
+ content: String(row.content),
8520
+ payloadJson: row.payload_json == null ? null : String(row.payload_json),
8521
+ hasError: Number(row.has_error) === 1,
8522
+ createdAt: String(row.created_at)
8523
+ }));
8524
+ }
8525
+ var init_session_events = __esm({
8526
+ "src/lib/session-events.ts"() {
8527
+ "use strict";
8528
+ init_task_scope();
8529
+ init_project_name();
8530
+ }
8531
+ });
8532
+
7884
8533
  // src/adapters/claude/hooks/post-tool-combined.ts
7885
8534
  if (!process.env.AGENT_ID) {
7886
8535
  process.env.AGENT_ID = "default";
@@ -7930,7 +8579,33 @@ ${context}`
7930
8579
  const { writeMemoryViaDaemon: writeMemoryViaDaemon2 } = await Promise.resolve().then(() => (init_memory_queue_client(), memory_queue_client_exports));
7931
8580
  const { buildPostToolMemoryEntry: buildPostToolMemoryEntry2 } = await Promise.resolve().then(() => (init_post_tool_memory(), post_tool_memory_exports));
7932
8581
  const { getActiveAgent: getActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent2(), active_agent_exports));
7933
- const entry = buildPostToolMemoryEntry2(data, getActiveAgent2());
8582
+ const { detectError: detectError2 } = await Promise.resolve().then(() => (init_error_detector(), error_detector_exports));
8583
+ const agent = getActiveAgent2();
8584
+ try {
8585
+ const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
8586
+ const { recordSessionEvent: recordSessionEvent2 } = await Promise.resolve().then(() => (init_session_events(), session_events_exports));
8587
+ const client = await fastDbInit2();
8588
+ const toolName = String(data.tool_name ?? "unknown");
8589
+ const toolInput = JSON.stringify(data.tool_input ?? {});
8590
+ const toolResponse = JSON.stringify(data.tool_response ?? data.tool_result ?? {});
8591
+ await recordSessionEvent2(client, {
8592
+ agentId: agent.agentId,
8593
+ agentRole: agent.agentRole,
8594
+ sessionId: String(data.session_id ?? "unknown"),
8595
+ eventType: "tool_call",
8596
+ toolName,
8597
+ toolUseId: data.tool_use_id ? String(data.tool_use_id) : null,
8598
+ content: `${toolName}
8599
+ input: ${toolInput.slice(0, 8e3)}
8600
+ result: ${toolResponse.slice(0, 8e3)}`,
8601
+ payloadJson: JSON.stringify(data).slice(0, 3e4),
8602
+ hasError: detectError2(data),
8603
+ cwd: typeof data.cwd === "string" ? data.cwd : process.cwd(),
8604
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
8605
+ });
8606
+ } catch {
8607
+ }
8608
+ const entry = buildPostToolMemoryEntry2(data, agent);
7934
8609
  if (entry) await writeMemoryViaDaemon2(entry);
7935
8610
  } catch {
7936
8611
  }