@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
|
@@ -1070,8 +1070,8 @@ function findPackageRoot() {
|
|
|
1070
1070
|
function getAvailableMemoryGB() {
|
|
1071
1071
|
if (process.platform === "darwin") {
|
|
1072
1072
|
try {
|
|
1073
|
-
const { execSync:
|
|
1074
|
-
const vmstat =
|
|
1073
|
+
const { execSync: execSync5 } = __require("child_process");
|
|
1074
|
+
const vmstat = execSync5("vm_stat", { encoding: "utf8" });
|
|
1075
1075
|
const pageSize = 16384;
|
|
1076
1076
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1077
1077
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -2810,6 +2810,7 @@ var init_database = __esm({
|
|
|
2810
2810
|
// src/lib/keychain.ts
|
|
2811
2811
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
2812
2812
|
import { existsSync as existsSync6 } from "fs";
|
|
2813
|
+
import { execSync as execSync2 } from "child_process";
|
|
2813
2814
|
import path6 from "path";
|
|
2814
2815
|
import os5 from "os";
|
|
2815
2816
|
function getKeyDir() {
|
|
@@ -2818,6 +2819,59 @@ function getKeyDir() {
|
|
|
2818
2819
|
function getKeyPath() {
|
|
2819
2820
|
return path6.join(getKeyDir(), "master.key");
|
|
2820
2821
|
}
|
|
2822
|
+
function macKeychainGet() {
|
|
2823
|
+
if (process.platform !== "darwin") return null;
|
|
2824
|
+
try {
|
|
2825
|
+
return execSync2(
|
|
2826
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
2827
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
2828
|
+
).trim();
|
|
2829
|
+
} catch {
|
|
2830
|
+
return null;
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
function macKeychainSet(value) {
|
|
2834
|
+
if (process.platform !== "darwin") return false;
|
|
2835
|
+
try {
|
|
2836
|
+
try {
|
|
2837
|
+
execSync2(
|
|
2838
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
2839
|
+
{ timeout: 5e3 }
|
|
2840
|
+
);
|
|
2841
|
+
} catch {
|
|
2842
|
+
}
|
|
2843
|
+
execSync2(
|
|
2844
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
2845
|
+
{ timeout: 5e3 }
|
|
2846
|
+
);
|
|
2847
|
+
return true;
|
|
2848
|
+
} catch {
|
|
2849
|
+
return false;
|
|
2850
|
+
}
|
|
2851
|
+
}
|
|
2852
|
+
function linuxSecretGet() {
|
|
2853
|
+
if (process.platform !== "linux") return null;
|
|
2854
|
+
try {
|
|
2855
|
+
return execSync2(
|
|
2856
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
2857
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
2858
|
+
).trim();
|
|
2859
|
+
} catch {
|
|
2860
|
+
return null;
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
function linuxSecretSet(value) {
|
|
2864
|
+
if (process.platform !== "linux") return false;
|
|
2865
|
+
try {
|
|
2866
|
+
execSync2(
|
|
2867
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
2868
|
+
{ timeout: 5e3 }
|
|
2869
|
+
);
|
|
2870
|
+
return true;
|
|
2871
|
+
} catch {
|
|
2872
|
+
return false;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2821
2875
|
async function tryKeytar() {
|
|
2822
2876
|
try {
|
|
2823
2877
|
return await import("keytar");
|
|
@@ -2825,13 +2879,63 @@ async function tryKeytar() {
|
|
|
2825
2879
|
return null;
|
|
2826
2880
|
}
|
|
2827
2881
|
}
|
|
2882
|
+
function deriveMachineKey() {
|
|
2883
|
+
try {
|
|
2884
|
+
const crypto3 = __require("crypto");
|
|
2885
|
+
const material = [
|
|
2886
|
+
os5.hostname(),
|
|
2887
|
+
os5.userInfo().username,
|
|
2888
|
+
os5.arch(),
|
|
2889
|
+
os5.platform(),
|
|
2890
|
+
// Machine ID on Linux (stable across reboots)
|
|
2891
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
2892
|
+
].join("|");
|
|
2893
|
+
return crypto3.createHash("sha256").update(material).digest();
|
|
2894
|
+
} catch {
|
|
2895
|
+
return null;
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
function readMachineId() {
|
|
2899
|
+
try {
|
|
2900
|
+
const { readFileSync: readFileSync12 } = __require("fs");
|
|
2901
|
+
return readFileSync12("/etc/machine-id", "utf-8").trim();
|
|
2902
|
+
} catch {
|
|
2903
|
+
return "";
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
2907
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
2908
|
+
try {
|
|
2909
|
+
const crypto3 = __require("crypto");
|
|
2910
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
2911
|
+
if (parts.length !== 3) return null;
|
|
2912
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
2913
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
2914
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
2915
|
+
const decipher = crypto3.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
2916
|
+
decipher.setAuthTag(authTag);
|
|
2917
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
2918
|
+
decrypted += decipher.final("utf-8");
|
|
2919
|
+
return decrypted;
|
|
2920
|
+
} catch {
|
|
2921
|
+
return null;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2828
2924
|
async function getMasterKey() {
|
|
2925
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
2926
|
+
if (nativeValue) {
|
|
2927
|
+
return Buffer.from(nativeValue, "base64");
|
|
2928
|
+
}
|
|
2829
2929
|
const keytar = await tryKeytar();
|
|
2830
2930
|
if (keytar) {
|
|
2831
2931
|
try {
|
|
2832
|
-
const
|
|
2833
|
-
if (
|
|
2834
|
-
|
|
2932
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
2933
|
+
if (keytarValue) {
|
|
2934
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
2935
|
+
if (migrated) {
|
|
2936
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
2937
|
+
}
|
|
2938
|
+
return Buffer.from(keytarValue, "base64");
|
|
2835
2939
|
}
|
|
2836
2940
|
} catch {
|
|
2837
2941
|
}
|
|
@@ -2845,8 +2949,31 @@ async function getMasterKey() {
|
|
|
2845
2949
|
return null;
|
|
2846
2950
|
}
|
|
2847
2951
|
try {
|
|
2848
|
-
const content = await readFile3(keyPath, "utf-8");
|
|
2849
|
-
|
|
2952
|
+
const content = (await readFile3(keyPath, "utf-8")).trim();
|
|
2953
|
+
let b64Value;
|
|
2954
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
2955
|
+
const machineKey = deriveMachineKey();
|
|
2956
|
+
if (!machineKey) {
|
|
2957
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
2958
|
+
return null;
|
|
2959
|
+
}
|
|
2960
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
2961
|
+
if (!decrypted) {
|
|
2962
|
+
process.stderr.write(
|
|
2963
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
2964
|
+
);
|
|
2965
|
+
return null;
|
|
2966
|
+
}
|
|
2967
|
+
b64Value = decrypted;
|
|
2968
|
+
} else {
|
|
2969
|
+
b64Value = content;
|
|
2970
|
+
}
|
|
2971
|
+
const key = Buffer.from(b64Value, "base64");
|
|
2972
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
2973
|
+
if (migrated) {
|
|
2974
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
2975
|
+
}
|
|
2976
|
+
return key;
|
|
2850
2977
|
} catch (err) {
|
|
2851
2978
|
process.stderr.write(
|
|
2852
2979
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -2855,12 +2982,13 @@ async function getMasterKey() {
|
|
|
2855
2982
|
return null;
|
|
2856
2983
|
}
|
|
2857
2984
|
}
|
|
2858
|
-
var SERVICE, ACCOUNT;
|
|
2985
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
2859
2986
|
var init_keychain = __esm({
|
|
2860
2987
|
"src/lib/keychain.ts"() {
|
|
2861
2988
|
"use strict";
|
|
2862
2989
|
SERVICE = "exe-mem";
|
|
2863
2990
|
ACCOUNT = "master-key";
|
|
2991
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
2864
2992
|
}
|
|
2865
2993
|
});
|
|
2866
2994
|
|
|
@@ -4103,7 +4231,7 @@ var init_session_registry = __esm({
|
|
|
4103
4231
|
});
|
|
4104
4232
|
|
|
4105
4233
|
// src/lib/session-key.ts
|
|
4106
|
-
import { execSync as
|
|
4234
|
+
import { execSync as execSync3 } from "child_process";
|
|
4107
4235
|
function normalizeCommand(command) {
|
|
4108
4236
|
const trimmed = command.trim().toLowerCase();
|
|
4109
4237
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -4122,7 +4250,7 @@ function resolveRuntimeProcess() {
|
|
|
4122
4250
|
let pid = process.ppid;
|
|
4123
4251
|
for (let i = 0; i < 10; i++) {
|
|
4124
4252
|
try {
|
|
4125
|
-
const info =
|
|
4253
|
+
const info = execSync3(`ps -p ${pid} -o ppid=,comm=`, {
|
|
4126
4254
|
encoding: "utf8",
|
|
4127
4255
|
timeout: 2e3
|
|
4128
4256
|
}).trim();
|
|
@@ -4288,7 +4416,7 @@ var init_transport = __esm({
|
|
|
4288
4416
|
});
|
|
4289
4417
|
|
|
4290
4418
|
// src/lib/cc-agent-support.ts
|
|
4291
|
-
import { execSync as
|
|
4419
|
+
import { execSync as execSync4 } from "child_process";
|
|
4292
4420
|
var init_cc_agent_support = __esm({
|
|
4293
4421
|
"src/lib/cc-agent-support.ts"() {
|
|
4294
4422
|
"use strict";
|
|
@@ -4689,8 +4817,8 @@ function hashOutput(text) {
|
|
|
4689
4817
|
async function queryPendingReviews() {
|
|
4690
4818
|
let sessionScope;
|
|
4691
4819
|
try {
|
|
4692
|
-
const { execSync:
|
|
4693
|
-
const tmuxSession =
|
|
4820
|
+
const { execSync: execSync5 } = await import("child_process");
|
|
4821
|
+
const tmuxSession = execSync5("tmux display-message -p '#{session_name}'", { encoding: "utf8", timeout: 2e3 }).trim();
|
|
4694
4822
|
if (isExeSession(tmuxSession)) sessionScope = tmuxSession;
|
|
4695
4823
|
} catch {
|
|
4696
4824
|
}
|
package/dist/bin/exe-kill.js
CHANGED
|
@@ -1040,8 +1040,8 @@ function findPackageRoot() {
|
|
|
1040
1040
|
function getAvailableMemoryGB() {
|
|
1041
1041
|
if (process.platform === "darwin") {
|
|
1042
1042
|
try {
|
|
1043
|
-
const { execSync:
|
|
1044
|
-
const vmstat =
|
|
1043
|
+
const { execSync: execSync4 } = __require("child_process");
|
|
1044
|
+
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
1045
1045
|
const pageSize = 16384;
|
|
1046
1046
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1047
1047
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -2780,6 +2780,7 @@ var init_database = __esm({
|
|
|
2780
2780
|
// src/lib/keychain.ts
|
|
2781
2781
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
2782
2782
|
import { existsSync as existsSync6 } from "fs";
|
|
2783
|
+
import { execSync as execSync2 } from "child_process";
|
|
2783
2784
|
import path6 from "path";
|
|
2784
2785
|
import os5 from "os";
|
|
2785
2786
|
function getKeyDir() {
|
|
@@ -2788,6 +2789,59 @@ function getKeyDir() {
|
|
|
2788
2789
|
function getKeyPath() {
|
|
2789
2790
|
return path6.join(getKeyDir(), "master.key");
|
|
2790
2791
|
}
|
|
2792
|
+
function macKeychainGet() {
|
|
2793
|
+
if (process.platform !== "darwin") return null;
|
|
2794
|
+
try {
|
|
2795
|
+
return execSync2(
|
|
2796
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
2797
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
2798
|
+
).trim();
|
|
2799
|
+
} catch {
|
|
2800
|
+
return null;
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
function macKeychainSet(value) {
|
|
2804
|
+
if (process.platform !== "darwin") return false;
|
|
2805
|
+
try {
|
|
2806
|
+
try {
|
|
2807
|
+
execSync2(
|
|
2808
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
2809
|
+
{ timeout: 5e3 }
|
|
2810
|
+
);
|
|
2811
|
+
} catch {
|
|
2812
|
+
}
|
|
2813
|
+
execSync2(
|
|
2814
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
2815
|
+
{ timeout: 5e3 }
|
|
2816
|
+
);
|
|
2817
|
+
return true;
|
|
2818
|
+
} catch {
|
|
2819
|
+
return false;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
function linuxSecretGet() {
|
|
2823
|
+
if (process.platform !== "linux") return null;
|
|
2824
|
+
try {
|
|
2825
|
+
return execSync2(
|
|
2826
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
2827
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
2828
|
+
).trim();
|
|
2829
|
+
} catch {
|
|
2830
|
+
return null;
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
function linuxSecretSet(value) {
|
|
2834
|
+
if (process.platform !== "linux") return false;
|
|
2835
|
+
try {
|
|
2836
|
+
execSync2(
|
|
2837
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
2838
|
+
{ timeout: 5e3 }
|
|
2839
|
+
);
|
|
2840
|
+
return true;
|
|
2841
|
+
} catch {
|
|
2842
|
+
return false;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2791
2845
|
async function tryKeytar() {
|
|
2792
2846
|
try {
|
|
2793
2847
|
return await import("keytar");
|
|
@@ -2795,13 +2849,63 @@ async function tryKeytar() {
|
|
|
2795
2849
|
return null;
|
|
2796
2850
|
}
|
|
2797
2851
|
}
|
|
2852
|
+
function deriveMachineKey() {
|
|
2853
|
+
try {
|
|
2854
|
+
const crypto3 = __require("crypto");
|
|
2855
|
+
const material = [
|
|
2856
|
+
os5.hostname(),
|
|
2857
|
+
os5.userInfo().username,
|
|
2858
|
+
os5.arch(),
|
|
2859
|
+
os5.platform(),
|
|
2860
|
+
// Machine ID on Linux (stable across reboots)
|
|
2861
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
2862
|
+
].join("|");
|
|
2863
|
+
return crypto3.createHash("sha256").update(material).digest();
|
|
2864
|
+
} catch {
|
|
2865
|
+
return null;
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
function readMachineId() {
|
|
2869
|
+
try {
|
|
2870
|
+
const { readFileSync: readFileSync6 } = __require("fs");
|
|
2871
|
+
return readFileSync6("/etc/machine-id", "utf-8").trim();
|
|
2872
|
+
} catch {
|
|
2873
|
+
return "";
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
2877
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
2878
|
+
try {
|
|
2879
|
+
const crypto3 = __require("crypto");
|
|
2880
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
2881
|
+
if (parts.length !== 3) return null;
|
|
2882
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
2883
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
2884
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
2885
|
+
const decipher = crypto3.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
2886
|
+
decipher.setAuthTag(authTag);
|
|
2887
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
2888
|
+
decrypted += decipher.final("utf-8");
|
|
2889
|
+
return decrypted;
|
|
2890
|
+
} catch {
|
|
2891
|
+
return null;
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2798
2894
|
async function getMasterKey() {
|
|
2895
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
2896
|
+
if (nativeValue) {
|
|
2897
|
+
return Buffer.from(nativeValue, "base64");
|
|
2898
|
+
}
|
|
2799
2899
|
const keytar = await tryKeytar();
|
|
2800
2900
|
if (keytar) {
|
|
2801
2901
|
try {
|
|
2802
|
-
const
|
|
2803
|
-
if (
|
|
2804
|
-
|
|
2902
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
2903
|
+
if (keytarValue) {
|
|
2904
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
2905
|
+
if (migrated) {
|
|
2906
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
2907
|
+
}
|
|
2908
|
+
return Buffer.from(keytarValue, "base64");
|
|
2805
2909
|
}
|
|
2806
2910
|
} catch {
|
|
2807
2911
|
}
|
|
@@ -2815,8 +2919,31 @@ async function getMasterKey() {
|
|
|
2815
2919
|
return null;
|
|
2816
2920
|
}
|
|
2817
2921
|
try {
|
|
2818
|
-
const content = await readFile3(keyPath, "utf-8");
|
|
2819
|
-
|
|
2922
|
+
const content = (await readFile3(keyPath, "utf-8")).trim();
|
|
2923
|
+
let b64Value;
|
|
2924
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
2925
|
+
const machineKey = deriveMachineKey();
|
|
2926
|
+
if (!machineKey) {
|
|
2927
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
2928
|
+
return null;
|
|
2929
|
+
}
|
|
2930
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
2931
|
+
if (!decrypted) {
|
|
2932
|
+
process.stderr.write(
|
|
2933
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
2934
|
+
);
|
|
2935
|
+
return null;
|
|
2936
|
+
}
|
|
2937
|
+
b64Value = decrypted;
|
|
2938
|
+
} else {
|
|
2939
|
+
b64Value = content;
|
|
2940
|
+
}
|
|
2941
|
+
const key = Buffer.from(b64Value, "base64");
|
|
2942
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
2943
|
+
if (migrated) {
|
|
2944
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
2945
|
+
}
|
|
2946
|
+
return key;
|
|
2820
2947
|
} catch (err) {
|
|
2821
2948
|
process.stderr.write(
|
|
2822
2949
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -2825,12 +2952,13 @@ async function getMasterKey() {
|
|
|
2825
2952
|
return null;
|
|
2826
2953
|
}
|
|
2827
2954
|
}
|
|
2828
|
-
var SERVICE, ACCOUNT;
|
|
2955
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
2829
2956
|
var init_keychain = __esm({
|
|
2830
2957
|
"src/lib/keychain.ts"() {
|
|
2831
2958
|
"use strict";
|
|
2832
2959
|
SERVICE = "exe-mem";
|
|
2833
2960
|
ACCOUNT = "master-key";
|
|
2961
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
2834
2962
|
}
|
|
2835
2963
|
});
|
|
2836
2964
|
|
|
@@ -4063,7 +4191,7 @@ var init_store = __esm({
|
|
|
4063
4191
|
|
|
4064
4192
|
// src/bin/exe-kill.ts
|
|
4065
4193
|
init_store();
|
|
4066
|
-
import { execSync as
|
|
4194
|
+
import { execSync as execSync3 } from "child_process";
|
|
4067
4195
|
|
|
4068
4196
|
// src/bin/fast-db-init.ts
|
|
4069
4197
|
async function fastDbInit() {
|
|
@@ -4175,7 +4303,7 @@ function listSessions() {
|
|
|
4175
4303
|
var MANUAL_KILL_REASON = "manual";
|
|
4176
4304
|
function listLiveSessions() {
|
|
4177
4305
|
try {
|
|
4178
|
-
const out =
|
|
4306
|
+
const out = execSync3("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
4179
4307
|
encoding: "utf8",
|
|
4180
4308
|
timeout: 3e3
|
|
4181
4309
|
});
|
|
@@ -4186,7 +4314,7 @@ function listLiveSessions() {
|
|
|
4186
4314
|
}
|
|
4187
4315
|
function currentExeSession() {
|
|
4188
4316
|
try {
|
|
4189
|
-
return
|
|
4317
|
+
return execSync3("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
4190
4318
|
encoding: "utf8",
|
|
4191
4319
|
timeout: 3e3
|
|
4192
4320
|
}).trim() || null;
|
|
@@ -4209,7 +4337,7 @@ function resolveAgentId(sessionName, fallbackName) {
|
|
|
4209
4337
|
return entry?.agentId ?? fallbackName;
|
|
4210
4338
|
}
|
|
4211
4339
|
function killTmuxSession(sessionName) {
|
|
4212
|
-
|
|
4340
|
+
execSync3(
|
|
4213
4341
|
`tmux kill-session -t ${JSON.stringify(sessionName)} 2>/dev/null`,
|
|
4214
4342
|
{ stdio: "ignore" }
|
|
4215
4343
|
);
|