@askexenow/exe-os 0.9.84 → 0.9.86

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 (82) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +32 -14
  2. package/dist/bin/agentic-reflection-backfill.js +32 -14
  3. package/dist/bin/agentic-semantic-label.js +32 -14
  4. package/dist/bin/backfill-conversations.js +32 -14
  5. package/dist/bin/backfill-responses.js +32 -14
  6. package/dist/bin/backfill-vectors.js +32 -14
  7. package/dist/bin/bulk-sync-postgres.js +32 -14
  8. package/dist/bin/cleanup-stale-review-tasks.js +35 -17
  9. package/dist/bin/cli.js +224 -86
  10. package/dist/bin/exe-assign.js +32 -14
  11. package/dist/bin/exe-boot.js +57 -39
  12. package/dist/bin/exe-cloud.js +22 -4
  13. package/dist/bin/exe-dispatch.js +43 -25
  14. package/dist/bin/exe-doctor.js +22 -4
  15. package/dist/bin/exe-export-behaviors.js +32 -14
  16. package/dist/bin/exe-forget.js +32 -14
  17. package/dist/bin/exe-gateway.js +47 -29
  18. package/dist/bin/exe-heartbeat.js +37 -19
  19. package/dist/bin/exe-kill.js +36 -18
  20. package/dist/bin/exe-launch-agent.js +170 -79
  21. package/dist/bin/exe-new-employee.js +32 -0
  22. package/dist/bin/exe-pending-messages.js +35 -17
  23. package/dist/bin/exe-pending-notifications.js +35 -17
  24. package/dist/bin/exe-pending-reviews.js +37 -19
  25. package/dist/bin/exe-rename.js +34 -16
  26. package/dist/bin/exe-review.js +32 -14
  27. package/dist/bin/exe-search.js +40 -22
  28. package/dist/bin/exe-session-cleanup.js +67 -44
  29. package/dist/bin/exe-start-codex.js +39 -21
  30. package/dist/bin/exe-start-opencode.js +37 -19
  31. package/dist/bin/exe-status.js +44 -26
  32. package/dist/bin/exe-team.js +32 -14
  33. package/dist/bin/git-sweep.js +45 -27
  34. package/dist/bin/graph-backfill.js +32 -14
  35. package/dist/bin/graph-export.js +32 -14
  36. package/dist/bin/install.js +32 -0
  37. package/dist/bin/intercom-check.js +49 -31
  38. package/dist/bin/scan-tasks.js +45 -27
  39. package/dist/bin/setup.js +29 -11
  40. package/dist/bin/shard-migrate.js +32 -14
  41. package/dist/bin/stack-update.js +95 -7
  42. package/dist/bin/update.js +1 -1
  43. package/dist/gateway/index.js +47 -29
  44. package/dist/hooks/bug-report-worker.js +47 -29
  45. package/dist/hooks/codex-stop-task-finalizer.js +41 -23
  46. package/dist/hooks/commit-complete.js +46 -28
  47. package/dist/hooks/error-recall.js +44 -26
  48. package/dist/hooks/ingest-worker.js +4 -4
  49. package/dist/hooks/ingest.js +38 -20
  50. package/dist/hooks/instructions-loaded.js +32 -14
  51. package/dist/hooks/notification.js +32 -14
  52. package/dist/hooks/post-compact.js +32 -14
  53. package/dist/hooks/post-tool-combined.js +45 -27
  54. package/dist/hooks/pre-compact.js +43 -25
  55. package/dist/hooks/pre-tool-use.js +40 -22
  56. package/dist/hooks/prompt-submit.js +60 -42
  57. package/dist/hooks/session-end.js +48 -30
  58. package/dist/hooks/session-start.js +50 -32
  59. package/dist/hooks/stop.js +35 -17
  60. package/dist/hooks/subagent-stop.js +32 -14
  61. package/dist/hooks/summary-worker.js +37 -19
  62. package/dist/index.js +43 -25
  63. package/dist/lib/cloud-sync.js +32 -14
  64. package/dist/lib/database.js +22 -4
  65. package/dist/lib/db-daemon-client.js +16 -4
  66. package/dist/lib/db.js +22 -4
  67. package/dist/lib/device-registry.js +22 -4
  68. package/dist/lib/embedder.js +16 -4
  69. package/dist/lib/exe-daemon-client.js +16 -4
  70. package/dist/lib/exe-daemon.js +165 -66
  71. package/dist/lib/hybrid-search.js +40 -22
  72. package/dist/lib/schedules.js +35 -17
  73. package/dist/lib/skill-learning.js +16 -4
  74. package/dist/lib/store.js +32 -14
  75. package/dist/lib/tasks.js +16 -4
  76. package/dist/lib/tmux-routing.js +18 -6
  77. package/dist/mcp/server.js +142 -60
  78. package/dist/mcp/tools/create-task.js +18 -6
  79. package/dist/mcp/tools/update-task.js +18 -6
  80. package/dist/runtime/index.js +43 -25
  81. package/dist/tui/App.js +73 -55
  82. package/package.json +1 -1
@@ -1581,7 +1581,7 @@ __export(exe_daemon_client_exports, {
1581
1581
  });
1582
1582
  import net from "net";
1583
1583
  import os6 from "os";
1584
- import { spawn } from "child_process";
1584
+ import { spawn, execSync as execSync4 } from "child_process";
1585
1585
  import { randomUUID } from "crypto";
1586
1586
  import { existsSync as existsSync8, unlinkSync as unlinkSync2, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
1587
1587
  import path8 from "path";
@@ -1611,6 +1611,14 @@ function handleData(chunk) {
1611
1611
  }
1612
1612
  }
1613
1613
  }
1614
+ function isZombie(pid) {
1615
+ try {
1616
+ const state = execSync4(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
1617
+ return state.startsWith("Z");
1618
+ } catch {
1619
+ return false;
1620
+ }
1621
+ }
1614
1622
  function cleanupStaleFiles() {
1615
1623
  if (existsSync8(PID_PATH)) {
1616
1624
  try {
@@ -1618,7 +1626,11 @@ function cleanupStaleFiles() {
1618
1626
  if (pid > 0) {
1619
1627
  try {
1620
1628
  process.kill(pid, 0);
1621
- return;
1629
+ if (!isZombie(pid)) {
1630
+ return;
1631
+ }
1632
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
1633
+ `);
1622
1634
  } catch {
1623
1635
  }
1624
1636
  }
@@ -1646,8 +1658,8 @@ function findPackageRoot() {
1646
1658
  function getAvailableMemoryGB() {
1647
1659
  if (process.platform === "darwin") {
1648
1660
  try {
1649
- const { execSync: execSync8 } = __require("child_process");
1650
- const vmstat = execSync8("vm_stat", { encoding: "utf8" });
1661
+ const { execSync: execSync9 } = __require("child_process");
1662
+ const vmstat = execSync9("vm_stat", { encoding: "utf8" });
1651
1663
  const pageSize = 16384;
1652
1664
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1653
1665
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -3637,6 +3649,12 @@ async function disposeDatabase() {
3637
3649
  clearInterval(_walCheckpointTimer);
3638
3650
  _walCheckpointTimer = null;
3639
3651
  }
3652
+ if (_client) {
3653
+ try {
3654
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
3655
+ } catch {
3656
+ }
3657
+ }
3640
3658
  if (_daemonClient) {
3641
3659
  _daemonClient.close();
3642
3660
  _daemonClient = null;
@@ -4018,7 +4036,7 @@ var init_state_bus = __esm({
4018
4036
  });
4019
4037
 
4020
4038
  // src/lib/project-name.ts
4021
- import { execSync as execSync4 } from "child_process";
4039
+ import { execSync as execSync5 } from "child_process";
4022
4040
  import path13 from "path";
4023
4041
  function getProjectName(cwd) {
4024
4042
  const dir = cwd ?? process.cwd();
@@ -4026,7 +4044,7 @@ function getProjectName(cwd) {
4026
4044
  try {
4027
4045
  let repoRoot;
4028
4046
  try {
4029
- const gitCommonDir = execSync4("git rev-parse --path-format=absolute --git-common-dir", {
4047
+ const gitCommonDir = execSync5("git rev-parse --path-format=absolute --git-common-dir", {
4030
4048
  cwd: dir,
4031
4049
  encoding: "utf8",
4032
4050
  timeout: 2e3,
@@ -4034,7 +4052,7 @@ function getProjectName(cwd) {
4034
4052
  }).trim();
4035
4053
  repoRoot = path13.dirname(gitCommonDir);
4036
4054
  } catch {
4037
- repoRoot = execSync4("git rev-parse --show-toplevel", {
4055
+ repoRoot = execSync5("git rev-parse --show-toplevel", {
4038
4056
  cwd: dir,
4039
4057
  encoding: "utf8",
4040
4058
  timeout: 2e3,
@@ -4125,7 +4143,7 @@ var init_session_scope = __esm({
4125
4143
  import crypto4 from "crypto";
4126
4144
  import path14 from "path";
4127
4145
  import os10 from "os";
4128
- import { execSync as execSync5 } from "child_process";
4146
+ import { execSync as execSync6 } from "child_process";
4129
4147
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
4130
4148
  import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
4131
4149
  async function writeCheckpoint(input) {
@@ -4470,14 +4488,14 @@ function isTmuxSessionAlive(identifier) {
4470
4488
  if (!identifier || identifier === "unknown") return true;
4471
4489
  try {
4472
4490
  if (identifier.startsWith("%")) {
4473
- const output = execSync5("tmux list-panes -a -F '#{pane_id}'", {
4491
+ const output = execSync6("tmux list-panes -a -F '#{pane_id}'", {
4474
4492
  timeout: 2e3,
4475
4493
  encoding: "utf8",
4476
4494
  stdio: ["pipe", "pipe", "pipe"]
4477
4495
  });
4478
4496
  return output.split("\n").some((l) => l.trim() === identifier);
4479
4497
  } else {
4480
- execSync5(`tmux has-session -t ${JSON.stringify(identifier)}`, {
4498
+ execSync6(`tmux has-session -t ${JSON.stringify(identifier)}`, {
4481
4499
  timeout: 2e3,
4482
4500
  stdio: ["pipe", "pipe", "pipe"]
4483
4501
  });
@@ -4486,7 +4504,7 @@ function isTmuxSessionAlive(identifier) {
4486
4504
  } catch {
4487
4505
  if (identifier.startsWith("%")) return true;
4488
4506
  try {
4489
- execSync5("tmux list-sessions", {
4507
+ execSync6("tmux list-sessions", {
4490
4508
  timeout: 2e3,
4491
4509
  stdio: ["pipe", "pipe", "pipe"]
4492
4510
  });
@@ -4501,12 +4519,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
4501
4519
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
4502
4520
  try {
4503
4521
  const since = new Date(taskCreatedAt).toISOString();
4504
- const branch = execSync5(
4522
+ const branch = execSync6(
4505
4523
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
4506
4524
  { encoding: "utf8", timeout: 3e3 }
4507
4525
  ).trim();
4508
4526
  const branchArg = branch && branch !== "HEAD" ? branch : "";
4509
- const commitCount = execSync5(
4527
+ const commitCount = execSync6(
4510
4528
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
4511
4529
  { encoding: "utf8", timeout: 5e3 }
4512
4530
  ).trim();
@@ -6105,7 +6123,7 @@ __export(tmux_routing_exports, {
6105
6123
  spawnEmployee: () => spawnEmployee,
6106
6124
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
6107
6125
  });
6108
- import { execFileSync as execFileSync2, execSync as execSync6 } from "child_process";
6126
+ import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
6109
6127
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync15, appendFileSync, readdirSync as readdirSync3 } from "fs";
6110
6128
  import path18 from "path";
6111
6129
  import os11 from "os";
@@ -6826,7 +6844,7 @@ function spawnEmployee(employeeName2, exeSession2, projectDir2, opts) {
6826
6844
  let booted = false;
6827
6845
  for (let i = 0; i < 30; i++) {
6828
6846
  try {
6829
- execSync6("sleep 0.5");
6847
+ execSync7("sleep 0.5");
6830
6848
  } catch {
6831
6849
  }
6832
6850
  try {
@@ -6905,7 +6923,7 @@ var init_tmux_routing = __esm({
6905
6923
  // src/lib/keychain.ts
6906
6924
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
6907
6925
  import { existsSync as existsSync16, statSync as statSync2 } from "fs";
6908
- import { execSync as execSync7 } from "child_process";
6926
+ import { execSync as execSync8 } from "child_process";
6909
6927
  import path19 from "path";
6910
6928
  import os12 from "os";
6911
6929
  function getKeyDir() {
@@ -6922,13 +6940,13 @@ function linuxSecretAvailable() {
6922
6940
  if (process.platform !== "linux") return false;
6923
6941
  if (linuxSecretAvailability !== null) return linuxSecretAvailability;
6924
6942
  try {
6925
- execSync7("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
6943
+ execSync8("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
6926
6944
  } catch {
6927
6945
  linuxSecretAvailability = false;
6928
6946
  return false;
6929
6947
  }
6930
6948
  try {
6931
- execSync7("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
6949
+ execSync8("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
6932
6950
  linuxSecretAvailability = true;
6933
6951
  } catch {
6934
6952
  linuxSecretAvailability = false;
@@ -6952,7 +6970,7 @@ function macKeychainGet(service = SERVICE) {
6952
6970
  if (!nativeKeychainAllowed()) return null;
6953
6971
  if (process.platform !== "darwin") return null;
6954
6972
  try {
6955
- return execSync7(
6973
+ return execSync8(
6956
6974
  `security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
6957
6975
  { encoding: "utf-8", timeout: 5e3 }
6958
6976
  ).trim();
@@ -6965,13 +6983,13 @@ function macKeychainSet(value, service = SERVICE) {
6965
6983
  if (process.platform !== "darwin") return false;
6966
6984
  try {
6967
6985
  try {
6968
- execSync7(
6986
+ execSync8(
6969
6987
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
6970
6988
  { timeout: 5e3 }
6971
6989
  );
6972
6990
  } catch {
6973
6991
  }
6974
- execSync7(
6992
+ execSync8(
6975
6993
  `security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
6976
6994
  { timeout: 5e3 }
6977
6995
  );
@@ -6984,7 +7002,7 @@ function macKeychainDelete(service = SERVICE) {
6984
7002
  if (!nativeKeychainAllowed()) return false;
6985
7003
  if (process.platform !== "darwin") return false;
6986
7004
  try {
6987
- execSync7(
7005
+ execSync8(
6988
7006
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
6989
7007
  { timeout: 5e3 }
6990
7008
  );
@@ -6996,7 +7014,7 @@ function macKeychainDelete(service = SERVICE) {
6996
7014
  function linuxSecretGet(service = SERVICE) {
6997
7015
  if (!linuxSecretAvailable()) return null;
6998
7016
  try {
6999
- return execSync7(
7017
+ return execSync8(
7000
7018
  `secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7001
7019
  { encoding: "utf-8", timeout: 5e3 }
7002
7020
  ).trim();
@@ -7007,7 +7025,7 @@ function linuxSecretGet(service = SERVICE) {
7007
7025
  function linuxSecretSet(value, service = SERVICE) {
7008
7026
  if (!linuxSecretAvailable()) return false;
7009
7027
  try {
7010
- execSync7(
7028
+ execSync8(
7011
7029
  `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7012
7030
  { timeout: 5e3 }
7013
7031
  );
@@ -7020,7 +7038,7 @@ function linuxSecretDelete(service = SERVICE) {
7020
7038
  if (!nativeKeychainAllowed()) return false;
7021
7039
  if (process.platform !== "linux") return false;
7022
7040
  try {
7023
- execSync7(
7041
+ execSync8(
7024
7042
  `secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7025
7043
  { timeout: 5e3 }
7026
7044
  );
@@ -2035,7 +2035,7 @@ __export(exe_daemon_client_exports, {
2035
2035
  });
2036
2036
  import net from "net";
2037
2037
  import os5 from "os";
2038
- import { spawn } from "child_process";
2038
+ import { spawn, execSync as execSync3 } from "child_process";
2039
2039
  import { randomUUID } from "crypto";
2040
2040
  import { existsSync as existsSync9, unlinkSync as unlinkSync3, readFileSync as readFileSync5, openSync, closeSync, statSync as statSync3 } from "fs";
2041
2041
  import path9 from "path";
@@ -2065,6 +2065,14 @@ function handleData(chunk) {
2065
2065
  }
2066
2066
  }
2067
2067
  }
2068
+ function isZombie(pid) {
2069
+ try {
2070
+ const state = execSync3(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
2071
+ return state.startsWith("Z");
2072
+ } catch {
2073
+ return false;
2074
+ }
2075
+ }
2068
2076
  function cleanupStaleFiles() {
2069
2077
  if (existsSync9(PID_PATH)) {
2070
2078
  try {
@@ -2072,7 +2080,11 @@ function cleanupStaleFiles() {
2072
2080
  if (pid > 0) {
2073
2081
  try {
2074
2082
  process.kill(pid, 0);
2075
- return;
2083
+ if (!isZombie(pid)) {
2084
+ return;
2085
+ }
2086
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
2087
+ `);
2076
2088
  } catch {
2077
2089
  }
2078
2090
  }
@@ -2100,8 +2112,8 @@ function findPackageRoot() {
2100
2112
  function getAvailableMemoryGB() {
2101
2113
  if (process.platform === "darwin") {
2102
2114
  try {
2103
- const { execSync: execSync3 } = __require("child_process");
2104
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
2115
+ const { execSync: execSync4 } = __require("child_process");
2116
+ const vmstat = execSync4("vm_stat", { encoding: "utf8" });
2105
2117
  const pageSize = 16384;
2106
2118
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
2107
2119
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -4091,6 +4103,12 @@ async function disposeDatabase() {
4091
4103
  clearInterval(_walCheckpointTimer);
4092
4104
  _walCheckpointTimer = null;
4093
4105
  }
4106
+ if (_client) {
4107
+ try {
4108
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
4109
+ } catch {
4110
+ }
4111
+ }
4094
4112
  if (_daemonClient) {
4095
4113
  _daemonClient.close();
4096
4114
  _daemonClient = null;
@@ -1068,7 +1068,7 @@ __export(exe_daemon_client_exports, {
1068
1068
  });
1069
1069
  import net from "net";
1070
1070
  import os4 from "os";
1071
- import { spawn } from "child_process";
1071
+ import { spawn, execSync as execSync2 } from "child_process";
1072
1072
  import { randomUUID } from "crypto";
1073
1073
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
1074
1074
  import path5 from "path";
@@ -1098,6 +1098,14 @@ function handleData(chunk) {
1098
1098
  }
1099
1099
  }
1100
1100
  }
1101
+ function isZombie(pid) {
1102
+ try {
1103
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
1104
+ return state.startsWith("Z");
1105
+ } catch {
1106
+ return false;
1107
+ }
1108
+ }
1101
1109
  function cleanupStaleFiles() {
1102
1110
  if (existsSync5(PID_PATH)) {
1103
1111
  try {
@@ -1105,7 +1113,11 @@ function cleanupStaleFiles() {
1105
1113
  if (pid > 0) {
1106
1114
  try {
1107
1115
  process.kill(pid, 0);
1108
- return;
1116
+ if (!isZombie(pid)) {
1117
+ return;
1118
+ }
1119
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
1120
+ `);
1109
1121
  } catch {
1110
1122
  }
1111
1123
  }
@@ -1133,8 +1145,8 @@ function findPackageRoot() {
1133
1145
  function getAvailableMemoryGB() {
1134
1146
  if (process.platform === "darwin") {
1135
1147
  try {
1136
- const { execSync: execSync3 } = __require("child_process");
1137
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
1148
+ const { execSync: execSync4 } = __require("child_process");
1149
+ const vmstat = execSync4("vm_stat", { encoding: "utf8" });
1138
1150
  const pageSize = 16384;
1139
1151
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1140
1152
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -3124,6 +3136,12 @@ async function disposeDatabase() {
3124
3136
  clearInterval(_walCheckpointTimer);
3125
3137
  _walCheckpointTimer = null;
3126
3138
  }
3139
+ if (_client) {
3140
+ try {
3141
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
3142
+ } catch {
3143
+ }
3144
+ }
3127
3145
  if (_daemonClient) {
3128
3146
  _daemonClient.close();
3129
3147
  _daemonClient = null;
@@ -3160,7 +3178,7 @@ var init_database = __esm({
3160
3178
  // src/lib/keychain.ts
3161
3179
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3162
3180
  import { existsSync as existsSync6, statSync as statSync2 } from "fs";
3163
- import { execSync as execSync2 } from "child_process";
3181
+ import { execSync as execSync3 } from "child_process";
3164
3182
  import path6 from "path";
3165
3183
  import os5 from "os";
3166
3184
  function getKeyDir() {
@@ -3177,13 +3195,13 @@ function linuxSecretAvailable() {
3177
3195
  if (process.platform !== "linux") return false;
3178
3196
  if (linuxSecretAvailability !== null) return linuxSecretAvailability;
3179
3197
  try {
3180
- execSync2("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3198
+ execSync3("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3181
3199
  } catch {
3182
3200
  linuxSecretAvailability = false;
3183
3201
  return false;
3184
3202
  }
3185
3203
  try {
3186
- execSync2("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3204
+ execSync3("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3187
3205
  linuxSecretAvailability = true;
3188
3206
  } catch {
3189
3207
  linuxSecretAvailability = false;
@@ -3207,7 +3225,7 @@ function macKeychainGet(service = SERVICE) {
3207
3225
  if (!nativeKeychainAllowed()) return null;
3208
3226
  if (process.platform !== "darwin") return null;
3209
3227
  try {
3210
- return execSync2(
3228
+ return execSync3(
3211
3229
  `security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
3212
3230
  { encoding: "utf-8", timeout: 5e3 }
3213
3231
  ).trim();
@@ -3220,13 +3238,13 @@ function macKeychainSet(value, service = SERVICE) {
3220
3238
  if (process.platform !== "darwin") return false;
3221
3239
  try {
3222
3240
  try {
3223
- execSync2(
3241
+ execSync3(
3224
3242
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3225
3243
  { timeout: 5e3 }
3226
3244
  );
3227
3245
  } catch {
3228
3246
  }
3229
- execSync2(
3247
+ execSync3(
3230
3248
  `security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
3231
3249
  { timeout: 5e3 }
3232
3250
  );
@@ -3239,7 +3257,7 @@ function macKeychainDelete(service = SERVICE) {
3239
3257
  if (!nativeKeychainAllowed()) return false;
3240
3258
  if (process.platform !== "darwin") return false;
3241
3259
  try {
3242
- execSync2(
3260
+ execSync3(
3243
3261
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3244
3262
  { timeout: 5e3 }
3245
3263
  );
@@ -3251,7 +3269,7 @@ function macKeychainDelete(service = SERVICE) {
3251
3269
  function linuxSecretGet(service = SERVICE) {
3252
3270
  if (!linuxSecretAvailable()) return null;
3253
3271
  try {
3254
- return execSync2(
3272
+ return execSync3(
3255
3273
  `secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3256
3274
  { encoding: "utf-8", timeout: 5e3 }
3257
3275
  ).trim();
@@ -3262,7 +3280,7 @@ function linuxSecretGet(service = SERVICE) {
3262
3280
  function linuxSecretSet(value, service = SERVICE) {
3263
3281
  if (!linuxSecretAvailable()) return false;
3264
3282
  try {
3265
- execSync2(
3283
+ execSync3(
3266
3284
  `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3267
3285
  { timeout: 5e3 }
3268
3286
  );
@@ -3275,7 +3293,7 @@ function linuxSecretDelete(service = SERVICE) {
3275
3293
  if (!nativeKeychainAllowed()) return false;
3276
3294
  if (process.platform !== "linux") return false;
3277
3295
  try {
3278
- execSync2(
3296
+ execSync3(
3279
3297
  `secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3280
3298
  { timeout: 5e3 }
3281
3299
  );
@@ -992,7 +992,7 @@ __export(exe_daemon_client_exports, {
992
992
  });
993
993
  import net from "net";
994
994
  import os4 from "os";
995
- import { spawn } from "child_process";
995
+ import { spawn, execSync as execSync2 } from "child_process";
996
996
  import { randomUUID } from "crypto";
997
997
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
998
998
  import path5 from "path";
@@ -1022,6 +1022,14 @@ function handleData(chunk) {
1022
1022
  }
1023
1023
  }
1024
1024
  }
1025
+ function isZombie(pid) {
1026
+ try {
1027
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
1028
+ return state.startsWith("Z");
1029
+ } catch {
1030
+ return false;
1031
+ }
1032
+ }
1025
1033
  function cleanupStaleFiles() {
1026
1034
  if (existsSync5(PID_PATH)) {
1027
1035
  try {
@@ -1029,7 +1037,11 @@ function cleanupStaleFiles() {
1029
1037
  if (pid > 0) {
1030
1038
  try {
1031
1039
  process.kill(pid, 0);
1032
- return;
1040
+ if (!isZombie(pid)) {
1041
+ return;
1042
+ }
1043
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
1044
+ `);
1033
1045
  } catch {
1034
1046
  }
1035
1047
  }
@@ -1057,8 +1069,8 @@ function findPackageRoot() {
1057
1069
  function getAvailableMemoryGB() {
1058
1070
  if (process.platform === "darwin") {
1059
1071
  try {
1060
- const { execSync: execSync3 } = __require("child_process");
1061
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
1072
+ const { execSync: execSync4 } = __require("child_process");
1073
+ const vmstat = execSync4("vm_stat", { encoding: "utf8" });
1062
1074
  const pageSize = 16384;
1063
1075
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1064
1076
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -3048,6 +3060,12 @@ async function disposeDatabase() {
3048
3060
  clearInterval(_walCheckpointTimer);
3049
3061
  _walCheckpointTimer = null;
3050
3062
  }
3063
+ if (_client) {
3064
+ try {
3065
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
3066
+ } catch {
3067
+ }
3068
+ }
3051
3069
  if (_daemonClient) {
3052
3070
  _daemonClient.close();
3053
3071
  _daemonClient = null;
@@ -3084,7 +3102,7 @@ var init_database = __esm({
3084
3102
  // src/lib/keychain.ts
3085
3103
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3086
3104
  import { existsSync as existsSync6, statSync as statSync2 } from "fs";
3087
- import { execSync as execSync2 } from "child_process";
3105
+ import { execSync as execSync3 } from "child_process";
3088
3106
  import path6 from "path";
3089
3107
  import os5 from "os";
3090
3108
  function getKeyDir() {
@@ -3101,13 +3119,13 @@ function linuxSecretAvailable() {
3101
3119
  if (process.platform !== "linux") return false;
3102
3120
  if (linuxSecretAvailability !== null) return linuxSecretAvailability;
3103
3121
  try {
3104
- execSync2("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3122
+ execSync3("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3105
3123
  } catch {
3106
3124
  linuxSecretAvailability = false;
3107
3125
  return false;
3108
3126
  }
3109
3127
  try {
3110
- execSync2("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3128
+ execSync3("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3111
3129
  linuxSecretAvailability = true;
3112
3130
  } catch {
3113
3131
  linuxSecretAvailability = false;
@@ -3131,7 +3149,7 @@ function macKeychainGet(service = SERVICE) {
3131
3149
  if (!nativeKeychainAllowed()) return null;
3132
3150
  if (process.platform !== "darwin") return null;
3133
3151
  try {
3134
- return execSync2(
3152
+ return execSync3(
3135
3153
  `security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
3136
3154
  { encoding: "utf-8", timeout: 5e3 }
3137
3155
  ).trim();
@@ -3144,13 +3162,13 @@ function macKeychainSet(value, service = SERVICE) {
3144
3162
  if (process.platform !== "darwin") return false;
3145
3163
  try {
3146
3164
  try {
3147
- execSync2(
3165
+ execSync3(
3148
3166
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3149
3167
  { timeout: 5e3 }
3150
3168
  );
3151
3169
  } catch {
3152
3170
  }
3153
- execSync2(
3171
+ execSync3(
3154
3172
  `security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
3155
3173
  { timeout: 5e3 }
3156
3174
  );
@@ -3163,7 +3181,7 @@ function macKeychainDelete(service = SERVICE) {
3163
3181
  if (!nativeKeychainAllowed()) return false;
3164
3182
  if (process.platform !== "darwin") return false;
3165
3183
  try {
3166
- execSync2(
3184
+ execSync3(
3167
3185
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3168
3186
  { timeout: 5e3 }
3169
3187
  );
@@ -3175,7 +3193,7 @@ function macKeychainDelete(service = SERVICE) {
3175
3193
  function linuxSecretGet(service = SERVICE) {
3176
3194
  if (!linuxSecretAvailable()) return null;
3177
3195
  try {
3178
- return execSync2(
3196
+ return execSync3(
3179
3197
  `secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3180
3198
  { encoding: "utf-8", timeout: 5e3 }
3181
3199
  ).trim();
@@ -3186,7 +3204,7 @@ function linuxSecretGet(service = SERVICE) {
3186
3204
  function linuxSecretSet(value, service = SERVICE) {
3187
3205
  if (!linuxSecretAvailable()) return false;
3188
3206
  try {
3189
- execSync2(
3207
+ execSync3(
3190
3208
  `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3191
3209
  { timeout: 5e3 }
3192
3210
  );
@@ -3199,7 +3217,7 @@ function linuxSecretDelete(service = SERVICE) {
3199
3217
  if (!nativeKeychainAllowed()) return false;
3200
3218
  if (process.platform !== "linux") return false;
3201
3219
  try {
3202
- execSync2(
3220
+ execSync3(
3203
3221
  `secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3204
3222
  { timeout: 5e3 }
3205
3223
  );