@askexenow/exe-os 0.9.30 → 0.9.32
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.
- package/dist/bin/backfill-conversations.js +135 -7
- package/dist/bin/backfill-responses.js +135 -7
- package/dist/bin/backfill-vectors.js +135 -7
- package/dist/bin/cleanup-stale-review-tasks.js +139 -11
- package/dist/bin/cli.js +812 -486
- package/dist/bin/exe-assign.js +135 -7
- package/dist/bin/exe-boot.js +422 -113
- package/dist/bin/exe-cloud.js +160 -9
- package/dist/bin/exe-dispatch.js +136 -8
- package/dist/bin/exe-doctor.js +255 -13
- package/dist/bin/exe-export-behaviors.js +136 -8
- package/dist/bin/exe-forget.js +136 -8
- package/dist/bin/exe-gateway.js +171 -24
- package/dist/bin/exe-heartbeat.js +141 -13
- package/dist/bin/exe-kill.js +140 -12
- package/dist/bin/exe-launch-agent.js +143 -15
- package/dist/bin/exe-link.js +357 -48
- package/dist/bin/exe-pending-messages.js +136 -8
- package/dist/bin/exe-pending-notifications.js +136 -8
- package/dist/bin/exe-pending-reviews.js +138 -10
- package/dist/bin/exe-review.js +136 -8
- package/dist/bin/exe-search.js +155 -20
- package/dist/bin/exe-session-cleanup.js +166 -38
- package/dist/bin/exe-start-codex.js +142 -14
- package/dist/bin/exe-start-opencode.js +140 -12
- package/dist/bin/exe-status.js +148 -20
- package/dist/bin/exe-team.js +136 -8
- package/dist/bin/git-sweep.js +138 -10
- package/dist/bin/graph-backfill.js +135 -7
- package/dist/bin/graph-export.js +136 -8
- package/dist/bin/intercom-check.js +153 -25
- package/dist/bin/scan-tasks.js +138 -10
- package/dist/bin/setup.js +447 -121
- package/dist/bin/shard-migrate.js +135 -7
- package/dist/gateway/index.js +151 -23
- package/dist/hooks/bug-report-worker.js +151 -23
- package/dist/hooks/codex-stop-task-finalizer.js +145 -17
- package/dist/hooks/commit-complete.js +138 -10
- package/dist/hooks/error-recall.js +159 -24
- package/dist/hooks/ingest.js +142 -14
- package/dist/hooks/instructions-loaded.js +136 -8
- package/dist/hooks/notification.js +136 -8
- package/dist/hooks/post-compact.js +136 -8
- package/dist/hooks/post-tool-combined.js +159 -24
- package/dist/hooks/pre-compact.js +136 -8
- package/dist/hooks/pre-tool-use.js +144 -16
- package/dist/hooks/prompt-submit.js +195 -55
- package/dist/hooks/session-end.js +141 -13
- package/dist/hooks/session-start.js +165 -30
- package/dist/hooks/stop.js +136 -8
- package/dist/hooks/subagent-stop.js +136 -8
- package/dist/hooks/summary-worker.js +374 -65
- package/dist/index.js +136 -8
- package/dist/lib/cloud-sync.js +355 -46
- package/dist/lib/consolidation.js +1 -0
- package/dist/lib/exe-daemon.js +469 -127
- package/dist/lib/hybrid-search.js +155 -20
- package/dist/lib/keychain.js +191 -7
- package/dist/lib/schedules.js +138 -10
- package/dist/lib/store.js +135 -7
- package/dist/mcp/server.js +706 -213
- package/dist/runtime/index.js +136 -8
- package/dist/tui/App.js +208 -31
- package/package.json +1 -1
package/dist/bin/exe-cloud.js
CHANGED
|
@@ -18,6 +18,7 @@ var __export = (target, all) => {
|
|
|
18
18
|
// src/lib/keychain.ts
|
|
19
19
|
import { readFile, writeFile, unlink, mkdir, chmod } from "fs/promises";
|
|
20
20
|
import { existsSync } from "fs";
|
|
21
|
+
import { execSync } from "child_process";
|
|
21
22
|
import path from "path";
|
|
22
23
|
import os from "os";
|
|
23
24
|
function getKeyDir() {
|
|
@@ -26,6 +27,59 @@ function getKeyDir() {
|
|
|
26
27
|
function getKeyPath() {
|
|
27
28
|
return path.join(getKeyDir(), "master.key");
|
|
28
29
|
}
|
|
30
|
+
function macKeychainGet() {
|
|
31
|
+
if (process.platform !== "darwin") return null;
|
|
32
|
+
try {
|
|
33
|
+
return execSync(
|
|
34
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
35
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
36
|
+
).trim();
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function macKeychainSet(value) {
|
|
42
|
+
if (process.platform !== "darwin") return false;
|
|
43
|
+
try {
|
|
44
|
+
try {
|
|
45
|
+
execSync(
|
|
46
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
47
|
+
{ timeout: 5e3 }
|
|
48
|
+
);
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
execSync(
|
|
52
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
53
|
+
{ timeout: 5e3 }
|
|
54
|
+
);
|
|
55
|
+
return true;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function linuxSecretGet() {
|
|
61
|
+
if (process.platform !== "linux") return null;
|
|
62
|
+
try {
|
|
63
|
+
return execSync(
|
|
64
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
65
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
66
|
+
).trim();
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function linuxSecretSet(value) {
|
|
72
|
+
if (process.platform !== "linux") return false;
|
|
73
|
+
try {
|
|
74
|
+
execSync(
|
|
75
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
76
|
+
{ timeout: 5e3 }
|
|
77
|
+
);
|
|
78
|
+
return true;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
29
83
|
async function tryKeytar() {
|
|
30
84
|
try {
|
|
31
85
|
return await import("keytar");
|
|
@@ -33,13 +87,72 @@ async function tryKeytar() {
|
|
|
33
87
|
return null;
|
|
34
88
|
}
|
|
35
89
|
}
|
|
90
|
+
function deriveMachineKey() {
|
|
91
|
+
try {
|
|
92
|
+
const crypto4 = __require("crypto");
|
|
93
|
+
const material = [
|
|
94
|
+
os.hostname(),
|
|
95
|
+
os.userInfo().username,
|
|
96
|
+
os.arch(),
|
|
97
|
+
os.platform(),
|
|
98
|
+
// Machine ID on Linux (stable across reboots)
|
|
99
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
100
|
+
].join("|");
|
|
101
|
+
return crypto4.createHash("sha256").update(material).digest();
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function readMachineId() {
|
|
107
|
+
try {
|
|
108
|
+
const { readFileSync: readFileSync6 } = __require("fs");
|
|
109
|
+
return readFileSync6("/etc/machine-id", "utf-8").trim();
|
|
110
|
+
} catch {
|
|
111
|
+
return "";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function encryptWithMachineKey(plaintext, machineKey) {
|
|
115
|
+
const crypto4 = __require("crypto");
|
|
116
|
+
const iv = crypto4.randomBytes(12);
|
|
117
|
+
const cipher = crypto4.createCipheriv("aes-256-gcm", machineKey, iv);
|
|
118
|
+
let encrypted = cipher.update(plaintext, "utf-8", "base64");
|
|
119
|
+
encrypted += cipher.final("base64");
|
|
120
|
+
const authTag = cipher.getAuthTag().toString("base64");
|
|
121
|
+
return `${ENCRYPTED_PREFIX}${iv.toString("base64")}:${authTag}:${encrypted}`;
|
|
122
|
+
}
|
|
123
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
124
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
125
|
+
try {
|
|
126
|
+
const crypto4 = __require("crypto");
|
|
127
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
128
|
+
if (parts.length !== 3) return null;
|
|
129
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
130
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
131
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
132
|
+
const decipher = crypto4.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
133
|
+
decipher.setAuthTag(authTag);
|
|
134
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
135
|
+
decrypted += decipher.final("utf-8");
|
|
136
|
+
return decrypted;
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
36
141
|
async function getMasterKey() {
|
|
142
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
143
|
+
if (nativeValue) {
|
|
144
|
+
return Buffer.from(nativeValue, "base64");
|
|
145
|
+
}
|
|
37
146
|
const keytar = await tryKeytar();
|
|
38
147
|
if (keytar) {
|
|
39
148
|
try {
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
149
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
150
|
+
if (keytarValue) {
|
|
151
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
152
|
+
if (migrated) {
|
|
153
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
154
|
+
}
|
|
155
|
+
return Buffer.from(keytarValue, "base64");
|
|
43
156
|
}
|
|
44
157
|
} catch {
|
|
45
158
|
}
|
|
@@ -53,8 +166,31 @@ async function getMasterKey() {
|
|
|
53
166
|
return null;
|
|
54
167
|
}
|
|
55
168
|
try {
|
|
56
|
-
const content = await readFile(keyPath, "utf-8");
|
|
57
|
-
|
|
169
|
+
const content = (await readFile(keyPath, "utf-8")).trim();
|
|
170
|
+
let b64Value;
|
|
171
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
172
|
+
const machineKey = deriveMachineKey();
|
|
173
|
+
if (!machineKey) {
|
|
174
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
178
|
+
if (!decrypted) {
|
|
179
|
+
process.stderr.write(
|
|
180
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
181
|
+
);
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
b64Value = decrypted;
|
|
185
|
+
} else {
|
|
186
|
+
b64Value = content;
|
|
187
|
+
}
|
|
188
|
+
const key = Buffer.from(b64Value, "base64");
|
|
189
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
190
|
+
if (migrated) {
|
|
191
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
192
|
+
}
|
|
193
|
+
return key;
|
|
58
194
|
} catch (err) {
|
|
59
195
|
process.stderr.write(
|
|
60
196
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -65,6 +201,9 @@ async function getMasterKey() {
|
|
|
65
201
|
}
|
|
66
202
|
async function setMasterKey(key) {
|
|
67
203
|
const b64 = key.toString("base64");
|
|
204
|
+
if (macKeychainSet(b64) || linuxSecretSet(b64)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
68
207
|
const keytar = await tryKeytar();
|
|
69
208
|
if (keytar) {
|
|
70
209
|
try {
|
|
@@ -76,8 +215,19 @@ async function setMasterKey(key) {
|
|
|
76
215
|
const dir = getKeyDir();
|
|
77
216
|
await mkdir(dir, { recursive: true });
|
|
78
217
|
const keyPath = getKeyPath();
|
|
79
|
-
|
|
80
|
-
|
|
218
|
+
const machineKey = deriveMachineKey();
|
|
219
|
+
if (machineKey) {
|
|
220
|
+
const encrypted = encryptWithMachineKey(b64, machineKey);
|
|
221
|
+
await writeFile(keyPath, encrypted + "\n", "utf-8");
|
|
222
|
+
await chmod(keyPath, 384);
|
|
223
|
+
process.stderr.write("[keychain] Key stored encrypted (machine-bound).\n");
|
|
224
|
+
} else {
|
|
225
|
+
await writeFile(keyPath, b64 + "\n", "utf-8");
|
|
226
|
+
await chmod(keyPath, 384);
|
|
227
|
+
process.stderr.write(
|
|
228
|
+
"[keychain] WARNING: Key stored in plaintext file \u2014 no OS keychain available.\n"
|
|
229
|
+
);
|
|
230
|
+
}
|
|
81
231
|
}
|
|
82
232
|
async function loadBip39() {
|
|
83
233
|
try {
|
|
@@ -108,12 +258,13 @@ async function importMnemonic(mnemonic) {
|
|
|
108
258
|
const entropy = mnemonicToEntropy(trimmed);
|
|
109
259
|
return Buffer.from(entropy, "hex");
|
|
110
260
|
}
|
|
111
|
-
var SERVICE, ACCOUNT;
|
|
261
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
112
262
|
var init_keychain = __esm({
|
|
113
263
|
"src/lib/keychain.ts"() {
|
|
114
264
|
"use strict";
|
|
115
265
|
SERVICE = "exe-mem";
|
|
116
266
|
ACCOUNT = "master-key";
|
|
267
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
117
268
|
}
|
|
118
269
|
});
|
|
119
270
|
|
|
@@ -344,7 +495,7 @@ var init_db_retry = __esm({
|
|
|
344
495
|
// src/lib/employees.ts
|
|
345
496
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
346
497
|
import { existsSync as existsSync4, symlinkSync, readlinkSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync, writeFileSync } from "fs";
|
|
347
|
-
import { execSync } from "child_process";
|
|
498
|
+
import { execSync as execSync2 } from "child_process";
|
|
348
499
|
import path3 from "path";
|
|
349
500
|
import os3 from "os";
|
|
350
501
|
var EMPLOYEES_PATH, IDENTITY_DIR;
|
package/dist/bin/exe-dispatch.js
CHANGED
|
@@ -1619,8 +1619,8 @@ function findPackageRoot() {
|
|
|
1619
1619
|
function getAvailableMemoryGB() {
|
|
1620
1620
|
if (process.platform === "darwin") {
|
|
1621
1621
|
try {
|
|
1622
|
-
const { execSync:
|
|
1623
|
-
const vmstat =
|
|
1622
|
+
const { execSync: execSync8 } = __require("child_process");
|
|
1623
|
+
const vmstat = execSync8("vm_stat", { encoding: "utf8" });
|
|
1624
1624
|
const pageSize = 16384;
|
|
1625
1625
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1626
1626
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -6514,6 +6514,7 @@ var init_tmux_routing = __esm({
|
|
|
6514
6514
|
// src/lib/keychain.ts
|
|
6515
6515
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
6516
6516
|
import { existsSync as existsSync15 } from "fs";
|
|
6517
|
+
import { execSync as execSync7 } from "child_process";
|
|
6517
6518
|
import path18 from "path";
|
|
6518
6519
|
import os11 from "os";
|
|
6519
6520
|
function getKeyDir() {
|
|
@@ -6522,6 +6523,59 @@ function getKeyDir() {
|
|
|
6522
6523
|
function getKeyPath() {
|
|
6523
6524
|
return path18.join(getKeyDir(), "master.key");
|
|
6524
6525
|
}
|
|
6526
|
+
function macKeychainGet() {
|
|
6527
|
+
if (process.platform !== "darwin") return null;
|
|
6528
|
+
try {
|
|
6529
|
+
return execSync7(
|
|
6530
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
6531
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
6532
|
+
).trim();
|
|
6533
|
+
} catch {
|
|
6534
|
+
return null;
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
6537
|
+
function macKeychainSet(value) {
|
|
6538
|
+
if (process.platform !== "darwin") return false;
|
|
6539
|
+
try {
|
|
6540
|
+
try {
|
|
6541
|
+
execSync7(
|
|
6542
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
6543
|
+
{ timeout: 5e3 }
|
|
6544
|
+
);
|
|
6545
|
+
} catch {
|
|
6546
|
+
}
|
|
6547
|
+
execSync7(
|
|
6548
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
6549
|
+
{ timeout: 5e3 }
|
|
6550
|
+
);
|
|
6551
|
+
return true;
|
|
6552
|
+
} catch {
|
|
6553
|
+
return false;
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
function linuxSecretGet() {
|
|
6557
|
+
if (process.platform !== "linux") return null;
|
|
6558
|
+
try {
|
|
6559
|
+
return execSync7(
|
|
6560
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
6561
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
6562
|
+
).trim();
|
|
6563
|
+
} catch {
|
|
6564
|
+
return null;
|
|
6565
|
+
}
|
|
6566
|
+
}
|
|
6567
|
+
function linuxSecretSet(value) {
|
|
6568
|
+
if (process.platform !== "linux") return false;
|
|
6569
|
+
try {
|
|
6570
|
+
execSync7(
|
|
6571
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
6572
|
+
{ timeout: 5e3 }
|
|
6573
|
+
);
|
|
6574
|
+
return true;
|
|
6575
|
+
} catch {
|
|
6576
|
+
return false;
|
|
6577
|
+
}
|
|
6578
|
+
}
|
|
6525
6579
|
async function tryKeytar() {
|
|
6526
6580
|
try {
|
|
6527
6581
|
return await import("keytar");
|
|
@@ -6529,13 +6583,63 @@ async function tryKeytar() {
|
|
|
6529
6583
|
return null;
|
|
6530
6584
|
}
|
|
6531
6585
|
}
|
|
6586
|
+
function deriveMachineKey() {
|
|
6587
|
+
try {
|
|
6588
|
+
const crypto7 = __require("crypto");
|
|
6589
|
+
const material = [
|
|
6590
|
+
os11.hostname(),
|
|
6591
|
+
os11.userInfo().username,
|
|
6592
|
+
os11.arch(),
|
|
6593
|
+
os11.platform(),
|
|
6594
|
+
// Machine ID on Linux (stable across reboots)
|
|
6595
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
6596
|
+
].join("|");
|
|
6597
|
+
return crypto7.createHash("sha256").update(material).digest();
|
|
6598
|
+
} catch {
|
|
6599
|
+
return null;
|
|
6600
|
+
}
|
|
6601
|
+
}
|
|
6602
|
+
function readMachineId() {
|
|
6603
|
+
try {
|
|
6604
|
+
const { readFileSync: readFileSync13 } = __require("fs");
|
|
6605
|
+
return readFileSync13("/etc/machine-id", "utf-8").trim();
|
|
6606
|
+
} catch {
|
|
6607
|
+
return "";
|
|
6608
|
+
}
|
|
6609
|
+
}
|
|
6610
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
6611
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
6612
|
+
try {
|
|
6613
|
+
const crypto7 = __require("crypto");
|
|
6614
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
6615
|
+
if (parts.length !== 3) return null;
|
|
6616
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
6617
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
6618
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
6619
|
+
const decipher = crypto7.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
6620
|
+
decipher.setAuthTag(authTag);
|
|
6621
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
6622
|
+
decrypted += decipher.final("utf-8");
|
|
6623
|
+
return decrypted;
|
|
6624
|
+
} catch {
|
|
6625
|
+
return null;
|
|
6626
|
+
}
|
|
6627
|
+
}
|
|
6532
6628
|
async function getMasterKey() {
|
|
6629
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
6630
|
+
if (nativeValue) {
|
|
6631
|
+
return Buffer.from(nativeValue, "base64");
|
|
6632
|
+
}
|
|
6533
6633
|
const keytar = await tryKeytar();
|
|
6534
6634
|
if (keytar) {
|
|
6535
6635
|
try {
|
|
6536
|
-
const
|
|
6537
|
-
if (
|
|
6538
|
-
|
|
6636
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
6637
|
+
if (keytarValue) {
|
|
6638
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
6639
|
+
if (migrated) {
|
|
6640
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
6641
|
+
}
|
|
6642
|
+
return Buffer.from(keytarValue, "base64");
|
|
6539
6643
|
}
|
|
6540
6644
|
} catch {
|
|
6541
6645
|
}
|
|
@@ -6549,8 +6653,31 @@ async function getMasterKey() {
|
|
|
6549
6653
|
return null;
|
|
6550
6654
|
}
|
|
6551
6655
|
try {
|
|
6552
|
-
const content = await readFile4(keyPath, "utf-8");
|
|
6553
|
-
|
|
6656
|
+
const content = (await readFile4(keyPath, "utf-8")).trim();
|
|
6657
|
+
let b64Value;
|
|
6658
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
6659
|
+
const machineKey = deriveMachineKey();
|
|
6660
|
+
if (!machineKey) {
|
|
6661
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
6662
|
+
return null;
|
|
6663
|
+
}
|
|
6664
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
6665
|
+
if (!decrypted) {
|
|
6666
|
+
process.stderr.write(
|
|
6667
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
6668
|
+
);
|
|
6669
|
+
return null;
|
|
6670
|
+
}
|
|
6671
|
+
b64Value = decrypted;
|
|
6672
|
+
} else {
|
|
6673
|
+
b64Value = content;
|
|
6674
|
+
}
|
|
6675
|
+
const key = Buffer.from(b64Value, "base64");
|
|
6676
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
6677
|
+
if (migrated) {
|
|
6678
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
6679
|
+
}
|
|
6680
|
+
return key;
|
|
6554
6681
|
} catch (err) {
|
|
6555
6682
|
process.stderr.write(
|
|
6556
6683
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -6559,12 +6686,13 @@ async function getMasterKey() {
|
|
|
6559
6686
|
return null;
|
|
6560
6687
|
}
|
|
6561
6688
|
}
|
|
6562
|
-
var SERVICE, ACCOUNT;
|
|
6689
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
6563
6690
|
var init_keychain = __esm({
|
|
6564
6691
|
"src/lib/keychain.ts"() {
|
|
6565
6692
|
"use strict";
|
|
6566
6693
|
SERVICE = "exe-mem";
|
|
6567
6694
|
ACCOUNT = "master-key";
|
|
6695
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
6568
6696
|
}
|
|
6569
6697
|
});
|
|
6570
6698
|
|