@askexenow/exe-os 0.9.113 → 0.9.114

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 (79) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +24 -12
  2. package/dist/bin/agentic-reflection-backfill.js +24 -12
  3. package/dist/bin/agentic-semantic-label.js +24 -12
  4. package/dist/bin/backfill-conversations.js +24 -12
  5. package/dist/bin/backfill-responses.js +24 -12
  6. package/dist/bin/backfill-vectors.js +24 -12
  7. package/dist/bin/bulk-sync-postgres.js +24 -12
  8. package/dist/bin/cleanup-stale-review-tasks.js +24 -12
  9. package/dist/bin/cli.js +96 -22
  10. package/dist/bin/exe-agent.js +27 -0
  11. package/dist/bin/exe-assign.js +24 -12
  12. package/dist/bin/exe-boot.js +44 -15
  13. package/dist/bin/exe-call.js +8 -0
  14. package/dist/bin/exe-cloud.js +34 -11
  15. package/dist/bin/exe-dispatch.js +34 -16
  16. package/dist/bin/exe-doctor.js +24 -12
  17. package/dist/bin/exe-export-behaviors.js +24 -12
  18. package/dist/bin/exe-forget.js +24 -12
  19. package/dist/bin/exe-gateway.js +33 -15
  20. package/dist/bin/exe-heartbeat.js +24 -12
  21. package/dist/bin/exe-kill.js +24 -12
  22. package/dist/bin/exe-launch-agent.js +103 -17
  23. package/dist/bin/exe-new-employee.js +9 -1
  24. package/dist/bin/exe-pending-messages.js +24 -12
  25. package/dist/bin/exe-pending-notifications.js +24 -12
  26. package/dist/bin/exe-pending-reviews.js +24 -12
  27. package/dist/bin/exe-rename.js +24 -12
  28. package/dist/bin/exe-review.js +24 -12
  29. package/dist/bin/exe-search.js +24 -12
  30. package/dist/bin/exe-session-cleanup.js +33 -15
  31. package/dist/bin/exe-start-codex.js +33 -13
  32. package/dist/bin/exe-start-opencode.js +33 -13
  33. package/dist/bin/exe-status.js +24 -12
  34. package/dist/bin/exe-team.js +24 -12
  35. package/dist/bin/git-sweep.js +34 -16
  36. package/dist/bin/graph-backfill.js +24 -12
  37. package/dist/bin/graph-export.js +24 -12
  38. package/dist/bin/install.js +9 -1
  39. package/dist/bin/intercom-check.js +33 -15
  40. package/dist/bin/scan-tasks.js +34 -16
  41. package/dist/bin/setup.js +60 -11
  42. package/dist/bin/shard-migrate.js +24 -12
  43. package/dist/gateway/index.js +33 -15
  44. package/dist/hooks/bug-report-worker.js +33 -15
  45. package/dist/hooks/codex-stop-task-finalizer.js +32 -12
  46. package/dist/hooks/commit-complete.js +34 -16
  47. package/dist/hooks/error-recall.js +24 -12
  48. package/dist/hooks/ingest.js +33 -15
  49. package/dist/hooks/instructions-loaded.js +24 -12
  50. package/dist/hooks/notification.js +24 -12
  51. package/dist/hooks/post-compact.js +24 -12
  52. package/dist/hooks/post-tool-combined.js +24 -12
  53. package/dist/hooks/pre-compact.js +34 -16
  54. package/dist/hooks/pre-tool-use.js +58 -11
  55. package/dist/hooks/prompt-submit.js +33 -15
  56. package/dist/hooks/session-end.js +34 -16
  57. package/dist/hooks/session-start.js +32 -12
  58. package/dist/hooks/stop.js +24 -12
  59. package/dist/hooks/subagent-stop.js +24 -12
  60. package/dist/hooks/summary-worker.js +34 -11
  61. package/dist/index.js +60 -15
  62. package/dist/lib/agent-config.js +8 -0
  63. package/dist/lib/cloud-sync.js +34 -11
  64. package/dist/lib/consolidation.js +9 -1
  65. package/dist/lib/employees.js +8 -0
  66. package/dist/lib/exe-daemon.js +174 -17
  67. package/dist/lib/hybrid-search.js +24 -12
  68. package/dist/lib/keychain.js +24 -12
  69. package/dist/lib/schedules.js +24 -12
  70. package/dist/lib/skill-learning.js +8 -0
  71. package/dist/lib/store.js +24 -12
  72. package/dist/lib/tasks.js +10 -4
  73. package/dist/lib/tmux-routing.js +10 -4
  74. package/dist/mcp/server.js +44 -15
  75. package/dist/mcp/tools/create-task.js +10 -4
  76. package/dist/mcp/tools/update-task.js +10 -4
  77. package/dist/runtime/index.js +60 -15
  78. package/dist/tui/App.js +61 -16
  79. package/package.json +1 -1
@@ -4385,7 +4385,7 @@ init_memory();
4385
4385
  init_database();
4386
4386
 
4387
4387
  // src/lib/keychain.ts
4388
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4388
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4389
4389
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4390
4390
  import { execSync as execSync3 } from "child_process";
4391
4391
  import path6 from "path";
@@ -4424,12 +4424,14 @@ function linuxSecretAvailable() {
4424
4424
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4425
4425
  if (process.platform !== "linux") return false;
4426
4426
  try {
4427
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4428
4427
  const st = statSync3(keyPath);
4429
4428
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4429
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4430
4430
  if (uid === 0) return true;
4431
4431
  const exeOsDir = process.env.EXE_OS_DIR;
4432
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4432
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4433
+ if (!linuxSecretAvailable()) return true;
4434
+ return false;
4433
4435
  } catch {
4434
4436
  return false;
4435
4437
  }
@@ -4580,15 +4582,25 @@ async function writeMachineBoundFileFallback(b64) {
4580
4582
  await mkdir3(dir, { recursive: true });
4581
4583
  const keyPath = getKeyPath();
4582
4584
  const machineKey = deriveMachineKey();
4583
- if (machineKey) {
4584
- const encrypted = encryptWithMachineKey(b64, machineKey);
4585
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4586
- await chmod2(keyPath, 384);
4587
- return "encrypted";
4588
- }
4589
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4590
- await chmod2(keyPath, 384);
4591
- return "plaintext";
4585
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4586
+ const result = machineKey ? "encrypted" : "plaintext";
4587
+ const tmpPath = keyPath + ".tmp";
4588
+ try {
4589
+ if (existsSync7(keyPath)) {
4590
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4591
+ });
4592
+ }
4593
+ await writeFile3(tmpPath, content, "utf-8");
4594
+ await chmod2(tmpPath, 384);
4595
+ await rename(tmpPath, keyPath);
4596
+ } catch (err) {
4597
+ try {
4598
+ await unlink(tmpPath);
4599
+ } catch {
4600
+ }
4601
+ throw err;
4602
+ }
4603
+ return result;
4592
4604
  }
4593
4605
  async function getMasterKey() {
4594
4606
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3958,7 +3958,7 @@ init_memory();
3958
3958
  init_database();
3959
3959
 
3960
3960
  // src/lib/keychain.ts
3961
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3961
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3962
3962
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3963
3963
  import { execSync as execSync3 } from "child_process";
3964
3964
  import path6 from "path";
@@ -3997,12 +3997,14 @@ function linuxSecretAvailable() {
3997
3997
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3998
3998
  if (process.platform !== "linux") return false;
3999
3999
  try {
4000
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4001
4000
  const st = statSync3(keyPath);
4002
4001
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4002
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4003
4003
  if (uid === 0) return true;
4004
4004
  const exeOsDir = process.env.EXE_OS_DIR;
4005
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4005
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4006
+ if (!linuxSecretAvailable()) return true;
4007
+ return false;
4006
4008
  } catch {
4007
4009
  return false;
4008
4010
  }
@@ -4153,15 +4155,25 @@ async function writeMachineBoundFileFallback(b64) {
4153
4155
  await mkdir3(dir, { recursive: true });
4154
4156
  const keyPath = getKeyPath();
4155
4157
  const machineKey = deriveMachineKey();
4156
- if (machineKey) {
4157
- const encrypted = encryptWithMachineKey(b64, machineKey);
4158
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4159
- await chmod2(keyPath, 384);
4160
- return "encrypted";
4161
- }
4162
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4163
- await chmod2(keyPath, 384);
4164
- return "plaintext";
4158
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4159
+ const result = machineKey ? "encrypted" : "plaintext";
4160
+ const tmpPath = keyPath + ".tmp";
4161
+ try {
4162
+ if (existsSync7(keyPath)) {
4163
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4164
+ });
4165
+ }
4166
+ await writeFile3(tmpPath, content, "utf-8");
4167
+ await chmod2(tmpPath, 384);
4168
+ await rename(tmpPath, keyPath);
4169
+ } catch (err) {
4170
+ try {
4171
+ await unlink(tmpPath);
4172
+ } catch {
4173
+ }
4174
+ throw err;
4175
+ }
4176
+ return result;
4165
4177
  }
4166
4178
  async function getMasterKey() {
4167
4179
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -4082,7 +4082,7 @@ init_memory();
4082
4082
  init_database();
4083
4083
 
4084
4084
  // src/lib/keychain.ts
4085
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4085
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4086
4086
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4087
4087
  import { execSync as execSync3 } from "child_process";
4088
4088
  import path6 from "path";
@@ -4121,12 +4121,14 @@ function linuxSecretAvailable() {
4121
4121
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4122
4122
  if (process.platform !== "linux") return false;
4123
4123
  try {
4124
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4125
4124
  const st = statSync3(keyPath);
4126
4125
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4126
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4127
4127
  if (uid === 0) return true;
4128
4128
  const exeOsDir = process.env.EXE_OS_DIR;
4129
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4129
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4130
+ if (!linuxSecretAvailable()) return true;
4131
+ return false;
4130
4132
  } catch {
4131
4133
  return false;
4132
4134
  }
@@ -4277,15 +4279,25 @@ async function writeMachineBoundFileFallback(b64) {
4277
4279
  await mkdir3(dir, { recursive: true });
4278
4280
  const keyPath = getKeyPath();
4279
4281
  const machineKey = deriveMachineKey();
4280
- if (machineKey) {
4281
- const encrypted = encryptWithMachineKey(b64, machineKey);
4282
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4283
- await chmod2(keyPath, 384);
4284
- return "encrypted";
4285
- }
4286
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4287
- await chmod2(keyPath, 384);
4288
- return "plaintext";
4282
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4283
+ const result = machineKey ? "encrypted" : "plaintext";
4284
+ const tmpPath = keyPath + ".tmp";
4285
+ try {
4286
+ if (existsSync7(keyPath)) {
4287
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4288
+ });
4289
+ }
4290
+ await writeFile3(tmpPath, content, "utf-8");
4291
+ await chmod2(tmpPath, 384);
4292
+ await rename(tmpPath, keyPath);
4293
+ } catch (err) {
4294
+ try {
4295
+ await unlink(tmpPath);
4296
+ } catch {
4297
+ }
4298
+ throw err;
4299
+ }
4300
+ return result;
4289
4301
  }
4290
4302
  async function getMasterKey() {
4291
4303
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -4534,7 +4534,7 @@ init_memory();
4534
4534
  init_database();
4535
4535
 
4536
4536
  // src/lib/keychain.ts
4537
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4537
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4538
4538
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4539
4539
  import { execSync as execSync3 } from "child_process";
4540
4540
  import path6 from "path";
@@ -4573,12 +4573,14 @@ function linuxSecretAvailable() {
4573
4573
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4574
4574
  if (process.platform !== "linux") return false;
4575
4575
  try {
4576
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4577
4576
  const st = statSync3(keyPath);
4578
4577
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4578
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4579
4579
  if (uid === 0) return true;
4580
4580
  const exeOsDir = process.env.EXE_OS_DIR;
4581
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4581
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4582
+ if (!linuxSecretAvailable()) return true;
4583
+ return false;
4582
4584
  } catch {
4583
4585
  return false;
4584
4586
  }
@@ -4729,15 +4731,25 @@ async function writeMachineBoundFileFallback(b64) {
4729
4731
  await mkdir3(dir, { recursive: true });
4730
4732
  const keyPath = getKeyPath();
4731
4733
  const machineKey = deriveMachineKey();
4732
- if (machineKey) {
4733
- const encrypted = encryptWithMachineKey(b64, machineKey);
4734
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4735
- await chmod2(keyPath, 384);
4736
- return "encrypted";
4737
- }
4738
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4739
- await chmod2(keyPath, 384);
4740
- return "plaintext";
4734
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4735
+ const result = machineKey ? "encrypted" : "plaintext";
4736
+ const tmpPath = keyPath + ".tmp";
4737
+ try {
4738
+ if (existsSync7(keyPath)) {
4739
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4740
+ });
4741
+ }
4742
+ await writeFile3(tmpPath, content, "utf-8");
4743
+ await chmod2(tmpPath, 384);
4744
+ await rename(tmpPath, keyPath);
4745
+ } catch (err) {
4746
+ try {
4747
+ await unlink(tmpPath);
4748
+ } catch {
4749
+ }
4750
+ throw err;
4751
+ }
4752
+ return result;
4741
4753
  }
4742
4754
  async function getMasterKey() {
4743
4755
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -4533,7 +4533,7 @@ init_memory();
4533
4533
  init_database();
4534
4534
 
4535
4535
  // src/lib/keychain.ts
4536
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4536
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4537
4537
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4538
4538
  import { execSync as execSync3 } from "child_process";
4539
4539
  import path6 from "path";
@@ -4572,12 +4572,14 @@ function linuxSecretAvailable() {
4572
4572
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4573
4573
  if (process.platform !== "linux") return false;
4574
4574
  try {
4575
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4576
4575
  const st = statSync3(keyPath);
4577
4576
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4577
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4578
4578
  if (uid === 0) return true;
4579
4579
  const exeOsDir = process.env.EXE_OS_DIR;
4580
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4580
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4581
+ if (!linuxSecretAvailable()) return true;
4582
+ return false;
4581
4583
  } catch {
4582
4584
  return false;
4583
4585
  }
@@ -4728,15 +4730,25 @@ async function writeMachineBoundFileFallback(b64) {
4728
4730
  await mkdir3(dir, { recursive: true });
4729
4731
  const keyPath = getKeyPath();
4730
4732
  const machineKey = deriveMachineKey();
4731
- if (machineKey) {
4732
- const encrypted = encryptWithMachineKey(b64, machineKey);
4733
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4734
- await chmod2(keyPath, 384);
4735
- return "encrypted";
4736
- }
4737
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4738
- await chmod2(keyPath, 384);
4739
- return "plaintext";
4733
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4734
+ const result = machineKey ? "encrypted" : "plaintext";
4735
+ const tmpPath = keyPath + ".tmp";
4736
+ try {
4737
+ if (existsSync7(keyPath)) {
4738
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4739
+ });
4740
+ }
4741
+ await writeFile3(tmpPath, content, "utf-8");
4742
+ await chmod2(tmpPath, 384);
4743
+ await rename(tmpPath, keyPath);
4744
+ } catch (err) {
4745
+ try {
4746
+ await unlink(tmpPath);
4747
+ } catch {
4748
+ }
4749
+ throw err;
4750
+ }
4751
+ return result;
4740
4752
  }
4741
4753
  async function getMasterKey() {
4742
4754
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -4080,7 +4080,7 @@ init_memory();
4080
4080
  init_database();
4081
4081
 
4082
4082
  // src/lib/keychain.ts
4083
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
4083
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
4084
4084
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
4085
4085
  import { execSync as execSync3 } from "child_process";
4086
4086
  import path6 from "path";
@@ -4119,12 +4119,14 @@ function linuxSecretAvailable() {
4119
4119
  function isRootOnlyTrustedServerKeyFile(keyPath) {
4120
4120
  if (process.platform !== "linux") return false;
4121
4121
  try {
4122
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4123
4122
  const st = statSync3(keyPath);
4124
4123
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
4124
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
4125
4125
  if (uid === 0) return true;
4126
4126
  const exeOsDir = process.env.EXE_OS_DIR;
4127
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
4127
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
4128
+ if (!linuxSecretAvailable()) return true;
4129
+ return false;
4128
4130
  } catch {
4129
4131
  return false;
4130
4132
  }
@@ -4275,15 +4277,25 @@ async function writeMachineBoundFileFallback(b64) {
4275
4277
  await mkdir3(dir, { recursive: true });
4276
4278
  const keyPath = getKeyPath();
4277
4279
  const machineKey = deriveMachineKey();
4278
- if (machineKey) {
4279
- const encrypted = encryptWithMachineKey(b64, machineKey);
4280
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
4281
- await chmod2(keyPath, 384);
4282
- return "encrypted";
4283
- }
4284
- await writeFile3(keyPath, b64 + "\n", "utf-8");
4285
- await chmod2(keyPath, 384);
4286
- return "plaintext";
4280
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
4281
+ const result = machineKey ? "encrypted" : "plaintext";
4282
+ const tmpPath = keyPath + ".tmp";
4283
+ try {
4284
+ if (existsSync7(keyPath)) {
4285
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
4286
+ });
4287
+ }
4288
+ await writeFile3(tmpPath, content, "utf-8");
4289
+ await chmod2(tmpPath, 384);
4290
+ await rename(tmpPath, keyPath);
4291
+ } catch (err) {
4292
+ try {
4293
+ await unlink(tmpPath);
4294
+ } catch {
4295
+ }
4296
+ throw err;
4297
+ }
4298
+ return result;
4287
4299
  }
4288
4300
  async function getMasterKey() {
4289
4301
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3101,7 +3101,7 @@ var init_database = __esm({
3101
3101
  });
3102
3102
 
3103
3103
  // src/lib/keychain.ts
3104
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3104
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3105
3105
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3106
3106
  import { execSync as execSync3 } from "child_process";
3107
3107
  import path6 from "path";
@@ -3136,12 +3136,14 @@ function linuxSecretAvailable() {
3136
3136
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3137
3137
  if (process.platform !== "linux") return false;
3138
3138
  try {
3139
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3140
3139
  const st = statSync3(keyPath);
3141
3140
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3141
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3142
3142
  if (uid === 0) return true;
3143
3143
  const exeOsDir = process.env.EXE_OS_DIR;
3144
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
3144
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
3145
+ if (!linuxSecretAvailable()) return true;
3146
+ return false;
3145
3147
  } catch {
3146
3148
  return false;
3147
3149
  }
@@ -3291,15 +3293,25 @@ async function writeMachineBoundFileFallback(b64) {
3291
3293
  await mkdir3(dir, { recursive: true });
3292
3294
  const keyPath = getKeyPath();
3293
3295
  const machineKey = deriveMachineKey();
3294
- if (machineKey) {
3295
- const encrypted = encryptWithMachineKey(b64, machineKey);
3296
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3297
- await chmod2(keyPath, 384);
3298
- return "encrypted";
3299
- }
3300
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3301
- await chmod2(keyPath, 384);
3302
- return "plaintext";
3296
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3297
+ const result = machineKey ? "encrypted" : "plaintext";
3298
+ const tmpPath = keyPath + ".tmp";
3299
+ try {
3300
+ if (existsSync7(keyPath)) {
3301
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3302
+ });
3303
+ }
3304
+ await writeFile3(tmpPath, content, "utf-8");
3305
+ await chmod2(tmpPath, 384);
3306
+ await rename(tmpPath, keyPath);
3307
+ } catch (err) {
3308
+ try {
3309
+ await unlink(tmpPath);
3310
+ } catch {
3311
+ }
3312
+ throw err;
3313
+ }
3314
+ return result;
3303
3315
  }
3304
3316
  async function getMasterKey() {
3305
3317
  let nativeValue = macKeychainGet() ?? linuxSecretGet();
@@ -3327,7 +3327,7 @@ var init_database = __esm({
3327
3327
  });
3328
3328
 
3329
3329
  // src/lib/keychain.ts
3330
- import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
3330
+ import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
3331
3331
  import { existsSync as existsSync7, statSync as statSync3 } from "fs";
3332
3332
  import { execSync as execSync3 } from "child_process";
3333
3333
  import path6 from "path";
@@ -3362,12 +3362,14 @@ function linuxSecretAvailable() {
3362
3362
  function isRootOnlyTrustedServerKeyFile(keyPath) {
3363
3363
  if (process.platform !== "linux") return false;
3364
3364
  try {
3365
- const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3366
3365
  const st = statSync3(keyPath);
3367
3366
  if (!st.isFile() || (st.mode & 63) !== 0) return false;
3367
+ const uid = typeof os5.userInfo().uid === "number" ? os5.userInfo().uid : -1;
3368
3368
  if (uid === 0) return true;
3369
3369
  const exeOsDir = process.env.EXE_OS_DIR;
3370
- return Boolean(exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep));
3370
+ if (exeOsDir && path6.resolve(keyPath).startsWith(path6.resolve(exeOsDir) + path6.sep)) return true;
3371
+ if (!linuxSecretAvailable()) return true;
3372
+ return false;
3371
3373
  } catch {
3372
3374
  return false;
3373
3375
  }
@@ -3517,15 +3519,25 @@ async function writeMachineBoundFileFallback(b64) {
3517
3519
  await mkdir3(dir, { recursive: true });
3518
3520
  const keyPath = getKeyPath();
3519
3521
  const machineKey = deriveMachineKey();
3520
- if (machineKey) {
3521
- const encrypted = encryptWithMachineKey(b64, machineKey);
3522
- await writeFile3(keyPath, encrypted + "\n", "utf-8");
3523
- await chmod2(keyPath, 384);
3524
- return "encrypted";
3525
- }
3526
- await writeFile3(keyPath, b64 + "\n", "utf-8");
3527
- await chmod2(keyPath, 384);
3528
- return "plaintext";
3522
+ const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
3523
+ const result = machineKey ? "encrypted" : "plaintext";
3524
+ const tmpPath = keyPath + ".tmp";
3525
+ try {
3526
+ if (existsSync7(keyPath)) {
3527
+ await copyFile(keyPath, keyPath + ".bak").catch(() => {
3528
+ });
3529
+ }
3530
+ await writeFile3(tmpPath, content, "utf-8");
3531
+ await chmod2(tmpPath, 384);
3532
+ await rename(tmpPath, keyPath);
3533
+ } catch (err) {
3534
+ try {
3535
+ await unlink(tmpPath);
3536
+ } catch {
3537
+ }
3538
+ throw err;
3539
+ }
3540
+ return result;
3529
3541
  }
3530
3542
  async function getMasterKey() {
3531
3543
  let nativeValue = macKeychainGet() ?? linuxSecretGet();