@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
package/dist/index.js CHANGED
@@ -1856,7 +1856,7 @@ var init_daemon_auth = __esm({
1856
1856
  // src/lib/exe-daemon-client.ts
1857
1857
  import net from "net";
1858
1858
  import os7 from "os";
1859
- import { spawn } from "child_process";
1859
+ import { spawn, execSync as execSync5 } from "child_process";
1860
1860
  import { randomUUID as randomUUID2 } from "crypto";
1861
1861
  import { existsSync as existsSync8, unlinkSync as unlinkSync2, readFileSync as readFileSync7, openSync, closeSync, statSync } from "fs";
1862
1862
  import path9 from "path";
@@ -1886,6 +1886,14 @@ function handleData(chunk) {
1886
1886
  }
1887
1887
  }
1888
1888
  }
1889
+ function isZombie(pid) {
1890
+ try {
1891
+ const state = execSync5(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
1892
+ return state.startsWith("Z");
1893
+ } catch {
1894
+ return false;
1895
+ }
1896
+ }
1889
1897
  function cleanupStaleFiles() {
1890
1898
  if (existsSync8(PID_PATH)) {
1891
1899
  try {
@@ -1893,7 +1901,11 @@ function cleanupStaleFiles() {
1893
1901
  if (pid > 0) {
1894
1902
  try {
1895
1903
  process.kill(pid, 0);
1896
- return;
1904
+ if (!isZombie(pid)) {
1905
+ return;
1906
+ }
1907
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
1908
+ `);
1897
1909
  } catch {
1898
1910
  }
1899
1911
  }
@@ -1921,8 +1933,8 @@ function findPackageRoot() {
1921
1933
  function getAvailableMemoryGB() {
1922
1934
  if (process.platform === "darwin") {
1923
1935
  try {
1924
- const { execSync: execSync9 } = __require("child_process");
1925
- const vmstat = execSync9("vm_stat", { encoding: "utf8" });
1936
+ const { execSync: execSync10 } = __require("child_process");
1937
+ const vmstat = execSync10("vm_stat", { encoding: "utf8" });
1926
1938
  const pageSize = 16384;
1927
1939
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
1928
1940
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -3857,6 +3869,12 @@ async function disposeDatabase() {
3857
3869
  clearInterval(_walCheckpointTimer);
3858
3870
  _walCheckpointTimer = null;
3859
3871
  }
3872
+ if (_client) {
3873
+ try {
3874
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
3875
+ } catch {
3876
+ }
3877
+ }
3860
3878
  if (_daemonClient) {
3861
3879
  _daemonClient.close();
3862
3880
  _daemonClient = null;
@@ -4244,7 +4262,7 @@ var init_state_bus = __esm({
4244
4262
  });
4245
4263
 
4246
4264
  // src/lib/project-name.ts
4247
- import { execSync as execSync5 } from "child_process";
4265
+ import { execSync as execSync6 } from "child_process";
4248
4266
  import path14 from "path";
4249
4267
  function getProjectName(cwd) {
4250
4268
  const dir = cwd ?? process.cwd();
@@ -4252,7 +4270,7 @@ function getProjectName(cwd) {
4252
4270
  try {
4253
4271
  let repoRoot;
4254
4272
  try {
4255
- const gitCommonDir = execSync5("git rev-parse --path-format=absolute --git-common-dir", {
4273
+ const gitCommonDir = execSync6("git rev-parse --path-format=absolute --git-common-dir", {
4256
4274
  cwd: dir,
4257
4275
  encoding: "utf8",
4258
4276
  timeout: 2e3,
@@ -4260,7 +4278,7 @@ function getProjectName(cwd) {
4260
4278
  }).trim();
4261
4279
  repoRoot = path14.dirname(gitCommonDir);
4262
4280
  } catch {
4263
- repoRoot = execSync5("git rev-parse --show-toplevel", {
4281
+ repoRoot = execSync6("git rev-parse --show-toplevel", {
4264
4282
  cwd: dir,
4265
4283
  encoding: "utf8",
4266
4284
  timeout: 2e3,
@@ -4351,7 +4369,7 @@ var init_session_scope = __esm({
4351
4369
  import crypto4 from "crypto";
4352
4370
  import path15 from "path";
4353
4371
  import os11 from "os";
4354
- import { execSync as execSync6 } from "child_process";
4372
+ import { execSync as execSync7 } from "child_process";
4355
4373
  import { mkdir as mkdir3, writeFile as writeFile3, appendFile } from "fs/promises";
4356
4374
  import { existsSync as existsSync13, readFileSync as readFileSync11 } from "fs";
4357
4375
  async function writeCheckpoint(input) {
@@ -4696,14 +4714,14 @@ function isTmuxSessionAlive(identifier) {
4696
4714
  if (!identifier || identifier === "unknown") return true;
4697
4715
  try {
4698
4716
  if (identifier.startsWith("%")) {
4699
- const output = execSync6("tmux list-panes -a -F '#{pane_id}'", {
4717
+ const output = execSync7("tmux list-panes -a -F '#{pane_id}'", {
4700
4718
  timeout: 2e3,
4701
4719
  encoding: "utf8",
4702
4720
  stdio: ["pipe", "pipe", "pipe"]
4703
4721
  });
4704
4722
  return output.split("\n").some((l) => l.trim() === identifier);
4705
4723
  } else {
4706
- execSync6(`tmux has-session -t ${JSON.stringify(identifier)}`, {
4724
+ execSync7(`tmux has-session -t ${JSON.stringify(identifier)}`, {
4707
4725
  timeout: 2e3,
4708
4726
  stdio: ["pipe", "pipe", "pipe"]
4709
4727
  });
@@ -4712,7 +4730,7 @@ function isTmuxSessionAlive(identifier) {
4712
4730
  } catch {
4713
4731
  if (identifier.startsWith("%")) return true;
4714
4732
  try {
4715
- execSync6("tmux list-sessions", {
4733
+ execSync7("tmux list-sessions", {
4716
4734
  timeout: 2e3,
4717
4735
  stdio: ["pipe", "pipe", "pipe"]
4718
4736
  });
@@ -4727,12 +4745,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
4727
4745
  if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
4728
4746
  try {
4729
4747
  const since = new Date(taskCreatedAt).toISOString();
4730
- const branch = execSync6(
4748
+ const branch = execSync7(
4731
4749
  "git rev-parse --abbrev-ref HEAD 2>/dev/null",
4732
4750
  { encoding: "utf8", timeout: 3e3 }
4733
4751
  ).trim();
4734
4752
  const branchArg = branch && branch !== "HEAD" ? branch : "";
4735
- const commitCount = execSync6(
4753
+ const commitCount = execSync7(
4736
4754
  `git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
4737
4755
  { encoding: "utf8", timeout: 5e3 }
4738
4756
  ).trim();
@@ -6402,7 +6420,7 @@ __export(tmux_routing_exports, {
6402
6420
  spawnEmployee: () => spawnEmployee,
6403
6421
  verifyPaneAtCapacity: () => verifyPaneAtCapacity
6404
6422
  });
6405
- import { execFileSync as execFileSync2, execSync as execSync7 } from "child_process";
6423
+ import { execFileSync as execFileSync2, execSync as execSync8 } from "child_process";
6406
6424
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, existsSync as existsSync15, appendFileSync, readdirSync as readdirSync3 } from "fs";
6407
6425
  import path19 from "path";
6408
6426
  import os12 from "os";
@@ -7123,7 +7141,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
7123
7141
  let booted = false;
7124
7142
  for (let i = 0; i < 30; i++) {
7125
7143
  try {
7126
- execSync7("sleep 0.5");
7144
+ execSync8("sleep 0.5");
7127
7145
  } catch {
7128
7146
  }
7129
7147
  try {
@@ -7202,7 +7220,7 @@ var init_tmux_routing = __esm({
7202
7220
  // src/lib/keychain.ts
7203
7221
  import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
7204
7222
  import { existsSync as existsSync16, statSync as statSync2 } from "fs";
7205
- import { execSync as execSync8 } from "child_process";
7223
+ import { execSync as execSync9 } from "child_process";
7206
7224
  import path20 from "path";
7207
7225
  import os13 from "os";
7208
7226
  function getKeyDir() {
@@ -7219,13 +7237,13 @@ function linuxSecretAvailable() {
7219
7237
  if (process.platform !== "linux") return false;
7220
7238
  if (linuxSecretAvailability !== null) return linuxSecretAvailability;
7221
7239
  try {
7222
- execSync8("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
7240
+ execSync9("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
7223
7241
  } catch {
7224
7242
  linuxSecretAvailability = false;
7225
7243
  return false;
7226
7244
  }
7227
7245
  try {
7228
- execSync8("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
7246
+ execSync9("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
7229
7247
  linuxSecretAvailability = true;
7230
7248
  } catch {
7231
7249
  linuxSecretAvailability = false;
@@ -7249,7 +7267,7 @@ function macKeychainGet(service = SERVICE) {
7249
7267
  if (!nativeKeychainAllowed()) return null;
7250
7268
  if (process.platform !== "darwin") return null;
7251
7269
  try {
7252
- return execSync8(
7270
+ return execSync9(
7253
7271
  `security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
7254
7272
  { encoding: "utf-8", timeout: 5e3 }
7255
7273
  ).trim();
@@ -7262,13 +7280,13 @@ function macKeychainSet(value, service = SERVICE) {
7262
7280
  if (process.platform !== "darwin") return false;
7263
7281
  try {
7264
7282
  try {
7265
- execSync8(
7283
+ execSync9(
7266
7284
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
7267
7285
  { timeout: 5e3 }
7268
7286
  );
7269
7287
  } catch {
7270
7288
  }
7271
- execSync8(
7289
+ execSync9(
7272
7290
  `security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
7273
7291
  { timeout: 5e3 }
7274
7292
  );
@@ -7281,7 +7299,7 @@ function macKeychainDelete(service = SERVICE) {
7281
7299
  if (!nativeKeychainAllowed()) return false;
7282
7300
  if (process.platform !== "darwin") return false;
7283
7301
  try {
7284
- execSync8(
7302
+ execSync9(
7285
7303
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
7286
7304
  { timeout: 5e3 }
7287
7305
  );
@@ -7293,7 +7311,7 @@ function macKeychainDelete(service = SERVICE) {
7293
7311
  function linuxSecretGet(service = SERVICE) {
7294
7312
  if (!linuxSecretAvailable()) return null;
7295
7313
  try {
7296
- return execSync8(
7314
+ return execSync9(
7297
7315
  `secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7298
7316
  { encoding: "utf-8", timeout: 5e3 }
7299
7317
  ).trim();
@@ -7304,7 +7322,7 @@ function linuxSecretGet(service = SERVICE) {
7304
7322
  function linuxSecretSet(value, service = SERVICE) {
7305
7323
  if (!linuxSecretAvailable()) return false;
7306
7324
  try {
7307
- execSync8(
7325
+ execSync9(
7308
7326
  `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7309
7327
  { timeout: 5e3 }
7310
7328
  );
@@ -7317,7 +7335,7 @@ function linuxSecretDelete(service = SERVICE) {
7317
7335
  if (!nativeKeychainAllowed()) return false;
7318
7336
  if (process.platform !== "linux") return false;
7319
7337
  try {
7320
- execSync8(
7338
+ execSync9(
7321
7339
  `secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
7322
7340
  { timeout: 5e3 }
7323
7341
  );
@@ -919,7 +919,7 @@ var init_daemon_auth = __esm({
919
919
  // src/lib/exe-daemon-client.ts
920
920
  import net from "net";
921
921
  import os4 from "os";
922
- import { spawn } from "child_process";
922
+ import { spawn, execSync as execSync2 } from "child_process";
923
923
  import { randomUUID } from "crypto";
924
924
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
925
925
  import path5 from "path";
@@ -949,6 +949,14 @@ function handleData(chunk) {
949
949
  }
950
950
  }
951
951
  }
952
+ function isZombie(pid) {
953
+ try {
954
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
955
+ return state.startsWith("Z");
956
+ } catch {
957
+ return false;
958
+ }
959
+ }
952
960
  function cleanupStaleFiles() {
953
961
  if (existsSync5(PID_PATH)) {
954
962
  try {
@@ -956,7 +964,11 @@ function cleanupStaleFiles() {
956
964
  if (pid > 0) {
957
965
  try {
958
966
  process.kill(pid, 0);
959
- return;
967
+ if (!isZombie(pid)) {
968
+ return;
969
+ }
970
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
971
+ `);
960
972
  } catch {
961
973
  }
962
974
  }
@@ -984,8 +996,8 @@ function findPackageRoot() {
984
996
  function getAvailableMemoryGB() {
985
997
  if (process.platform === "darwin") {
986
998
  try {
987
- const { execSync: execSync3 } = __require("child_process");
988
- const vmstat = execSync3("vm_stat", { encoding: "utf8" });
999
+ const { execSync: execSync4 } = __require("child_process");
1000
+ const vmstat = execSync4("vm_stat", { encoding: "utf8" });
989
1001
  const pageSize = 16384;
990
1002
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
991
1003
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -2771,6 +2783,12 @@ async function disposeDatabase() {
2771
2783
  clearInterval(_walCheckpointTimer);
2772
2784
  _walCheckpointTimer = null;
2773
2785
  }
2786
+ if (_client) {
2787
+ try {
2788
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2789
+ } catch {
2790
+ }
2791
+ }
2774
2792
  if (_daemonClient) {
2775
2793
  _daemonClient.close();
2776
2794
  _daemonClient = null;
@@ -3042,7 +3060,7 @@ __export(keychain_exports, {
3042
3060
  });
3043
3061
  import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3044
3062
  import { existsSync as existsSync8, statSync as statSync2 } from "fs";
3045
- import { execSync as execSync2 } from "child_process";
3063
+ import { execSync as execSync3 } from "child_process";
3046
3064
  import path8 from "path";
3047
3065
  import os6 from "os";
3048
3066
  function getKeyDir() {
@@ -3059,13 +3077,13 @@ function linuxSecretAvailable() {
3059
3077
  if (process.platform !== "linux") return false;
3060
3078
  if (linuxSecretAvailability !== null) return linuxSecretAvailability;
3061
3079
  try {
3062
- execSync2("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3080
+ execSync3("command -v secret-tool >/dev/null 2>&1", { timeout: 1e3 });
3063
3081
  } catch {
3064
3082
  linuxSecretAvailability = false;
3065
3083
  return false;
3066
3084
  }
3067
3085
  try {
3068
- execSync2("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3086
+ execSync3("secret-tool search --all exe-os probe >/dev/null 2>&1", { timeout: 1e3 });
3069
3087
  linuxSecretAvailability = true;
3070
3088
  } catch {
3071
3089
  linuxSecretAvailability = false;
@@ -3089,7 +3107,7 @@ function macKeychainGet(service = SERVICE) {
3089
3107
  if (!nativeKeychainAllowed()) return null;
3090
3108
  if (process.platform !== "darwin") return null;
3091
3109
  try {
3092
- return execSync2(
3110
+ return execSync3(
3093
3111
  `security find-generic-password -s "${service}" -a "${ACCOUNT}" -w 2>/dev/null`,
3094
3112
  { encoding: "utf-8", timeout: 5e3 }
3095
3113
  ).trim();
@@ -3102,13 +3120,13 @@ function macKeychainSet(value, service = SERVICE) {
3102
3120
  if (process.platform !== "darwin") return false;
3103
3121
  try {
3104
3122
  try {
3105
- execSync2(
3123
+ execSync3(
3106
3124
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3107
3125
  { timeout: 5e3 }
3108
3126
  );
3109
3127
  } catch {
3110
3128
  }
3111
- execSync2(
3129
+ execSync3(
3112
3130
  `security add-generic-password -s "${service}" -a "${ACCOUNT}" -w "${value}"`,
3113
3131
  { timeout: 5e3 }
3114
3132
  );
@@ -3121,7 +3139,7 @@ function macKeychainDelete(service = SERVICE) {
3121
3139
  if (!nativeKeychainAllowed()) return false;
3122
3140
  if (process.platform !== "darwin") return false;
3123
3141
  try {
3124
- execSync2(
3142
+ execSync3(
3125
3143
  `security delete-generic-password -s "${service}" -a "${ACCOUNT}" 2>/dev/null`,
3126
3144
  { timeout: 5e3 }
3127
3145
  );
@@ -3133,7 +3151,7 @@ function macKeychainDelete(service = SERVICE) {
3133
3151
  function linuxSecretGet(service = SERVICE) {
3134
3152
  if (!linuxSecretAvailable()) return null;
3135
3153
  try {
3136
- return execSync2(
3154
+ return execSync3(
3137
3155
  `secret-tool lookup service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3138
3156
  { encoding: "utf-8", timeout: 5e3 }
3139
3157
  ).trim();
@@ -3144,7 +3162,7 @@ function linuxSecretGet(service = SERVICE) {
3144
3162
  function linuxSecretSet(value, service = SERVICE) {
3145
3163
  if (!linuxSecretAvailable()) return false;
3146
3164
  try {
3147
- execSync2(
3165
+ execSync3(
3148
3166
  `echo -n "${value}" | secret-tool store --label="exe-os master key" service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3149
3167
  { timeout: 5e3 }
3150
3168
  );
@@ -3157,7 +3175,7 @@ function linuxSecretDelete(service = SERVICE) {
3157
3175
  if (!nativeKeychainAllowed()) return false;
3158
3176
  if (process.platform !== "linux") return false;
3159
3177
  try {
3160
- execSync2(
3178
+ execSync3(
3161
3179
  `secret-tool clear service "${service}" account "${ACCOUNT}" 2>/dev/null`,
3162
3180
  { timeout: 5e3 }
3163
3181
  );
@@ -178,7 +178,7 @@ var init_daemon_auth = __esm({
178
178
  // src/lib/exe-daemon-client.ts
179
179
  import net from "net";
180
180
  import os4 from "os";
181
- import { spawn } from "child_process";
181
+ import { spawn, execSync as execSync2 } from "child_process";
182
182
  import { randomUUID } from "crypto";
183
183
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
184
184
  import path5 from "path";
@@ -208,6 +208,14 @@ function handleData(chunk) {
208
208
  }
209
209
  }
210
210
  }
211
+ function isZombie(pid) {
212
+ try {
213
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
214
+ return state.startsWith("Z");
215
+ } catch {
216
+ return false;
217
+ }
218
+ }
211
219
  function cleanupStaleFiles() {
212
220
  if (existsSync5(PID_PATH)) {
213
221
  try {
@@ -215,7 +223,11 @@ function cleanupStaleFiles() {
215
223
  if (pid > 0) {
216
224
  try {
217
225
  process.kill(pid, 0);
218
- return;
226
+ if (!isZombie(pid)) {
227
+ return;
228
+ }
229
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
230
+ `);
219
231
  } catch {
220
232
  }
221
233
  }
@@ -243,8 +255,8 @@ function findPackageRoot() {
243
255
  function getAvailableMemoryGB() {
244
256
  if (process.platform === "darwin") {
245
257
  try {
246
- const { execSync: execSync2 } = __require("child_process");
247
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
258
+ const { execSync: execSync3 } = __require("child_process");
259
+ const vmstat = execSync3("vm_stat", { encoding: "utf8" });
248
260
  const pageSize = 16384;
249
261
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
250
262
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -2688,6 +2700,12 @@ async function disposeDatabase() {
2688
2700
  clearInterval(_walCheckpointTimer);
2689
2701
  _walCheckpointTimer = null;
2690
2702
  }
2703
+ if (_client) {
2704
+ try {
2705
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2706
+ } catch {
2707
+ }
2708
+ }
2691
2709
  if (_daemonClient) {
2692
2710
  _daemonClient.close();
2693
2711
  _daemonClient = null;
@@ -8,7 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
  // src/lib/exe-daemon-client.ts
9
9
  import net from "net";
10
10
  import os2 from "os";
11
- import { spawn } from "child_process";
11
+ import { spawn, execSync } from "child_process";
12
12
  import { randomUUID } from "crypto";
13
13
  import { existsSync as existsSync4, unlinkSync, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
14
14
  import path3 from "path";
@@ -194,6 +194,14 @@ function handleData(chunk) {
194
194
  }
195
195
  }
196
196
  }
197
+ function isZombie(pid) {
198
+ try {
199
+ const state = execSync(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
200
+ return state.startsWith("Z");
201
+ } catch {
202
+ return false;
203
+ }
204
+ }
197
205
  function cleanupStaleFiles() {
198
206
  if (existsSync4(PID_PATH)) {
199
207
  try {
@@ -201,7 +209,11 @@ function cleanupStaleFiles() {
201
209
  if (pid > 0) {
202
210
  try {
203
211
  process.kill(pid, 0);
204
- return;
212
+ if (!isZombie(pid)) {
213
+ return;
214
+ }
215
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
216
+ `);
205
217
  } catch {
206
218
  }
207
219
  }
@@ -229,8 +241,8 @@ function findPackageRoot() {
229
241
  function getAvailableMemoryGB() {
230
242
  if (process.platform === "darwin") {
231
243
  try {
232
- const { execSync } = __require("child_process");
233
- const vmstat = execSync("vm_stat", { encoding: "utf8" });
244
+ const { execSync: execSync2 } = __require("child_process");
245
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
234
246
  const pageSize = 16384;
235
247
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
236
248
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
package/dist/lib/db.js CHANGED
@@ -178,7 +178,7 @@ var init_daemon_auth = __esm({
178
178
  // src/lib/exe-daemon-client.ts
179
179
  import net from "net";
180
180
  import os4 from "os";
181
- import { spawn } from "child_process";
181
+ import { spawn, execSync as execSync2 } from "child_process";
182
182
  import { randomUUID } from "crypto";
183
183
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
184
184
  import path5 from "path";
@@ -208,6 +208,14 @@ function handleData(chunk) {
208
208
  }
209
209
  }
210
210
  }
211
+ function isZombie(pid) {
212
+ try {
213
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
214
+ return state.startsWith("Z");
215
+ } catch {
216
+ return false;
217
+ }
218
+ }
211
219
  function cleanupStaleFiles() {
212
220
  if (existsSync5(PID_PATH)) {
213
221
  try {
@@ -215,7 +223,11 @@ function cleanupStaleFiles() {
215
223
  if (pid > 0) {
216
224
  try {
217
225
  process.kill(pid, 0);
218
- return;
226
+ if (!isZombie(pid)) {
227
+ return;
228
+ }
229
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
230
+ `);
219
231
  } catch {
220
232
  }
221
233
  }
@@ -243,8 +255,8 @@ function findPackageRoot() {
243
255
  function getAvailableMemoryGB() {
244
256
  if (process.platform === "darwin") {
245
257
  try {
246
- const { execSync: execSync2 } = __require("child_process");
247
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
258
+ const { execSync: execSync3 } = __require("child_process");
259
+ const vmstat = execSync3("vm_stat", { encoding: "utf8" });
248
260
  const pageSize = 16384;
249
261
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
250
262
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -2688,6 +2700,12 @@ async function disposeDatabase() {
2688
2700
  clearInterval(_walCheckpointTimer);
2689
2701
  _walCheckpointTimer = null;
2690
2702
  }
2703
+ if (_client) {
2704
+ try {
2705
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2706
+ } catch {
2707
+ }
2708
+ }
2691
2709
  if (_daemonClient) {
2692
2710
  _daemonClient.close();
2693
2711
  _daemonClient = null;
@@ -864,7 +864,7 @@ var init_daemon_auth = __esm({
864
864
  // src/lib/exe-daemon-client.ts
865
865
  import net from "net";
866
866
  import os4 from "os";
867
- import { spawn } from "child_process";
867
+ import { spawn, execSync as execSync2 } from "child_process";
868
868
  import { randomUUID } from "crypto";
869
869
  import { existsSync as existsSync5, unlinkSync as unlinkSync2, readFileSync as readFileSync4, openSync, closeSync, statSync } from "fs";
870
870
  import path5 from "path";
@@ -894,6 +894,14 @@ function handleData(chunk) {
894
894
  }
895
895
  }
896
896
  }
897
+ function isZombie(pid) {
898
+ try {
899
+ const state = execSync2(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
900
+ return state.startsWith("Z");
901
+ } catch {
902
+ return false;
903
+ }
904
+ }
897
905
  function cleanupStaleFiles() {
898
906
  if (existsSync5(PID_PATH)) {
899
907
  try {
@@ -901,7 +909,11 @@ function cleanupStaleFiles() {
901
909
  if (pid > 0) {
902
910
  try {
903
911
  process.kill(pid, 0);
904
- return;
912
+ if (!isZombie(pid)) {
913
+ return;
914
+ }
915
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
916
+ `);
905
917
  } catch {
906
918
  }
907
919
  }
@@ -929,8 +941,8 @@ function findPackageRoot() {
929
941
  function getAvailableMemoryGB() {
930
942
  if (process.platform === "darwin") {
931
943
  try {
932
- const { execSync: execSync2 } = __require("child_process");
933
- const vmstat = execSync2("vm_stat", { encoding: "utf8" });
944
+ const { execSync: execSync3 } = __require("child_process");
945
+ const vmstat = execSync3("vm_stat", { encoding: "utf8" });
934
946
  const pageSize = 16384;
935
947
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
936
948
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
@@ -2716,6 +2728,12 @@ async function disposeDatabase() {
2716
2728
  clearInterval(_walCheckpointTimer);
2717
2729
  _walCheckpointTimer = null;
2718
2730
  }
2731
+ if (_client) {
2732
+ try {
2733
+ await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
2734
+ } catch {
2735
+ }
2736
+ }
2719
2737
  if (_daemonClient) {
2720
2738
  _daemonClient.close();
2721
2739
  _daemonClient = null;
@@ -326,7 +326,7 @@ var EMBEDDING_DIM = 1024;
326
326
  init_config();
327
327
  import net from "net";
328
328
  import os2 from "os";
329
- import { spawn } from "child_process";
329
+ import { spawn, execSync } from "child_process";
330
330
  import { randomUUID } from "crypto";
331
331
  import { existsSync as existsSync4, unlinkSync, readFileSync as readFileSync3, openSync, closeSync, statSync } from "fs";
332
332
  import path3 from "path";
@@ -407,6 +407,14 @@ function handleData(chunk) {
407
407
  }
408
408
  }
409
409
  }
410
+ function isZombie(pid) {
411
+ try {
412
+ const state = execSync(`ps -p ${pid} -o state=`, { encoding: "utf8", timeout: 2e3 }).trim();
413
+ return state.startsWith("Z");
414
+ } catch {
415
+ return false;
416
+ }
417
+ }
410
418
  function cleanupStaleFiles() {
411
419
  if (existsSync4(PID_PATH)) {
412
420
  try {
@@ -414,7 +422,11 @@ function cleanupStaleFiles() {
414
422
  if (pid > 0) {
415
423
  try {
416
424
  process.kill(pid, 0);
417
- return;
425
+ if (!isZombie(pid)) {
426
+ return;
427
+ }
428
+ process.stderr.write(`[exed-client] PID ${pid} is a zombie \u2014 cleaning up stale files
429
+ `);
418
430
  } catch {
419
431
  }
420
432
  }
@@ -442,8 +454,8 @@ function findPackageRoot() {
442
454
  function getAvailableMemoryGB() {
443
455
  if (process.platform === "darwin") {
444
456
  try {
445
- const { execSync } = __require("child_process");
446
- const vmstat = execSync("vm_stat", { encoding: "utf8" });
457
+ const { execSync: execSync2 } = __require("child_process");
458
+ const vmstat = execSync2("vm_stat", { encoding: "utf8" });
447
459
  const pageSize = 16384;
448
460
  const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
449
461
  const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;