@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
|
@@ -1621,8 +1621,8 @@ function findPackageRoot() {
|
|
|
1621
1621
|
function getAvailableMemoryGB() {
|
|
1622
1622
|
if (process.platform === "darwin") {
|
|
1623
1623
|
try {
|
|
1624
|
-
const { execSync:
|
|
1625
|
-
const vmstat =
|
|
1624
|
+
const { execSync: execSync11 } = __require("child_process");
|
|
1625
|
+
const vmstat = execSync11("vm_stat", { encoding: "utf8" });
|
|
1626
1626
|
const pageSize = 16384;
|
|
1627
1627
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1628
1628
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -6722,6 +6722,7 @@ var init_task_scope = __esm({
|
|
|
6722
6722
|
// src/lib/keychain.ts
|
|
6723
6723
|
import { readFile as readFile4, writeFile as writeFile5, unlink, mkdir as mkdir4, chmod as chmod2 } from "fs/promises";
|
|
6724
6724
|
import { existsSync as existsSync16 } from "fs";
|
|
6725
|
+
import { execSync as execSync8 } from "child_process";
|
|
6725
6726
|
import path20 from "path";
|
|
6726
6727
|
import os12 from "os";
|
|
6727
6728
|
function getKeyDir() {
|
|
@@ -6730,6 +6731,59 @@ function getKeyDir() {
|
|
|
6730
6731
|
function getKeyPath() {
|
|
6731
6732
|
return path20.join(getKeyDir(), "master.key");
|
|
6732
6733
|
}
|
|
6734
|
+
function macKeychainGet() {
|
|
6735
|
+
if (process.platform !== "darwin") return null;
|
|
6736
|
+
try {
|
|
6737
|
+
return execSync8(
|
|
6738
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
6739
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
6740
|
+
).trim();
|
|
6741
|
+
} catch {
|
|
6742
|
+
return null;
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
function macKeychainSet(value) {
|
|
6746
|
+
if (process.platform !== "darwin") return false;
|
|
6747
|
+
try {
|
|
6748
|
+
try {
|
|
6749
|
+
execSync8(
|
|
6750
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
6751
|
+
{ timeout: 5e3 }
|
|
6752
|
+
);
|
|
6753
|
+
} catch {
|
|
6754
|
+
}
|
|
6755
|
+
execSync8(
|
|
6756
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
6757
|
+
{ timeout: 5e3 }
|
|
6758
|
+
);
|
|
6759
|
+
return true;
|
|
6760
|
+
} catch {
|
|
6761
|
+
return false;
|
|
6762
|
+
}
|
|
6763
|
+
}
|
|
6764
|
+
function linuxSecretGet() {
|
|
6765
|
+
if (process.platform !== "linux") return null;
|
|
6766
|
+
try {
|
|
6767
|
+
return execSync8(
|
|
6768
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
6769
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
6770
|
+
).trim();
|
|
6771
|
+
} catch {
|
|
6772
|
+
return null;
|
|
6773
|
+
}
|
|
6774
|
+
}
|
|
6775
|
+
function linuxSecretSet(value) {
|
|
6776
|
+
if (process.platform !== "linux") return false;
|
|
6777
|
+
try {
|
|
6778
|
+
execSync8(
|
|
6779
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
6780
|
+
{ timeout: 5e3 }
|
|
6781
|
+
);
|
|
6782
|
+
return true;
|
|
6783
|
+
} catch {
|
|
6784
|
+
return false;
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6733
6787
|
async function tryKeytar() {
|
|
6734
6788
|
try {
|
|
6735
6789
|
return await import("keytar");
|
|
@@ -6737,13 +6791,63 @@ async function tryKeytar() {
|
|
|
6737
6791
|
return null;
|
|
6738
6792
|
}
|
|
6739
6793
|
}
|
|
6794
|
+
function deriveMachineKey() {
|
|
6795
|
+
try {
|
|
6796
|
+
const crypto7 = __require("crypto");
|
|
6797
|
+
const material = [
|
|
6798
|
+
os12.hostname(),
|
|
6799
|
+
os12.userInfo().username,
|
|
6800
|
+
os12.arch(),
|
|
6801
|
+
os12.platform(),
|
|
6802
|
+
// Machine ID on Linux (stable across reboots)
|
|
6803
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
6804
|
+
].join("|");
|
|
6805
|
+
return crypto7.createHash("sha256").update(material).digest();
|
|
6806
|
+
} catch {
|
|
6807
|
+
return null;
|
|
6808
|
+
}
|
|
6809
|
+
}
|
|
6810
|
+
function readMachineId() {
|
|
6811
|
+
try {
|
|
6812
|
+
const { readFileSync: readFileSync16 } = __require("fs");
|
|
6813
|
+
return readFileSync16("/etc/machine-id", "utf-8").trim();
|
|
6814
|
+
} catch {
|
|
6815
|
+
return "";
|
|
6816
|
+
}
|
|
6817
|
+
}
|
|
6818
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
6819
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
6820
|
+
try {
|
|
6821
|
+
const crypto7 = __require("crypto");
|
|
6822
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
6823
|
+
if (parts.length !== 3) return null;
|
|
6824
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
6825
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
6826
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
6827
|
+
const decipher = crypto7.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
6828
|
+
decipher.setAuthTag(authTag);
|
|
6829
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
6830
|
+
decrypted += decipher.final("utf-8");
|
|
6831
|
+
return decrypted;
|
|
6832
|
+
} catch {
|
|
6833
|
+
return null;
|
|
6834
|
+
}
|
|
6835
|
+
}
|
|
6740
6836
|
async function getMasterKey() {
|
|
6837
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
6838
|
+
if (nativeValue) {
|
|
6839
|
+
return Buffer.from(nativeValue, "base64");
|
|
6840
|
+
}
|
|
6741
6841
|
const keytar = await tryKeytar();
|
|
6742
6842
|
if (keytar) {
|
|
6743
6843
|
try {
|
|
6744
|
-
const
|
|
6745
|
-
if (
|
|
6746
|
-
|
|
6844
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
6845
|
+
if (keytarValue) {
|
|
6846
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
6847
|
+
if (migrated) {
|
|
6848
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
6849
|
+
}
|
|
6850
|
+
return Buffer.from(keytarValue, "base64");
|
|
6747
6851
|
}
|
|
6748
6852
|
} catch {
|
|
6749
6853
|
}
|
|
@@ -6757,8 +6861,31 @@ async function getMasterKey() {
|
|
|
6757
6861
|
return null;
|
|
6758
6862
|
}
|
|
6759
6863
|
try {
|
|
6760
|
-
const content = await readFile4(keyPath, "utf-8");
|
|
6761
|
-
|
|
6864
|
+
const content = (await readFile4(keyPath, "utf-8")).trim();
|
|
6865
|
+
let b64Value;
|
|
6866
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
6867
|
+
const machineKey = deriveMachineKey();
|
|
6868
|
+
if (!machineKey) {
|
|
6869
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
6870
|
+
return null;
|
|
6871
|
+
}
|
|
6872
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
6873
|
+
if (!decrypted) {
|
|
6874
|
+
process.stderr.write(
|
|
6875
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
6876
|
+
);
|
|
6877
|
+
return null;
|
|
6878
|
+
}
|
|
6879
|
+
b64Value = decrypted;
|
|
6880
|
+
} else {
|
|
6881
|
+
b64Value = content;
|
|
6882
|
+
}
|
|
6883
|
+
const key = Buffer.from(b64Value, "base64");
|
|
6884
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
6885
|
+
if (migrated) {
|
|
6886
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
6887
|
+
}
|
|
6888
|
+
return key;
|
|
6762
6889
|
} catch (err) {
|
|
6763
6890
|
process.stderr.write(
|
|
6764
6891
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -6767,12 +6894,13 @@ async function getMasterKey() {
|
|
|
6767
6894
|
return null;
|
|
6768
6895
|
}
|
|
6769
6896
|
}
|
|
6770
|
-
var SERVICE, ACCOUNT;
|
|
6897
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
6771
6898
|
var init_keychain = __esm({
|
|
6772
6899
|
"src/lib/keychain.ts"() {
|
|
6773
6900
|
"use strict";
|
|
6774
6901
|
SERVICE = "exe-mem";
|
|
6775
6902
|
ACCOUNT = "master-key";
|
|
6903
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
6776
6904
|
}
|
|
6777
6905
|
});
|
|
6778
6906
|
|
|
@@ -8099,11 +8227,11 @@ __export(git_staleness_exports, {
|
|
|
8099
8227
|
detectStaleFiles: () => detectStaleFiles,
|
|
8100
8228
|
recordFileRead: () => recordFileRead
|
|
8101
8229
|
});
|
|
8102
|
-
import { execSync as
|
|
8230
|
+
import { execSync as execSync9 } from "child_process";
|
|
8103
8231
|
import path23 from "path";
|
|
8104
8232
|
function getHeadCommit(cwd) {
|
|
8105
8233
|
try {
|
|
8106
|
-
return
|
|
8234
|
+
return execSync9("git rev-parse --short HEAD", {
|
|
8107
8235
|
cwd,
|
|
8108
8236
|
timeout: GIT_TIMEOUT_MS,
|
|
8109
8237
|
encoding: "utf-8"
|
|
@@ -8166,7 +8294,7 @@ async function detectStaleFiles(agentId, cwd) {
|
|
|
8166
8294
|
const readAt = String(record.read_at ?? "");
|
|
8167
8295
|
if (!filePath || !readAt) continue;
|
|
8168
8296
|
try {
|
|
8169
|
-
const gitSummary =
|
|
8297
|
+
const gitSummary = execSync9(
|
|
8170
8298
|
`git log -1 --oneline --after=${JSON.stringify(readAt)} --format="%h %an: %s" -- ${JSON.stringify(filePath)}`,
|
|
8171
8299
|
{
|
|
8172
8300
|
cwd,
|
|
@@ -8210,7 +8338,7 @@ __export(git_task_sweep_exports, {
|
|
|
8210
8338
|
matchScore: () => matchScore,
|
|
8211
8339
|
sweepTasks: () => sweepTasks
|
|
8212
8340
|
});
|
|
8213
|
-
import { execSync as
|
|
8341
|
+
import { execSync as execSync10 } from "child_process";
|
|
8214
8342
|
function extractKeywords(text) {
|
|
8215
8343
|
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, " ").split(/\s+/).filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
|
|
8216
8344
|
}
|
|
@@ -8239,7 +8367,7 @@ function matchScore(task, commitMessage, changedFiles) {
|
|
|
8239
8367
|
function getRecentCommits(limit = DEFAULT_COMMIT_LIMIT) {
|
|
8240
8368
|
try {
|
|
8241
8369
|
const SEPARATOR = "<<SEP>>";
|
|
8242
|
-
const output =
|
|
8370
|
+
const output = execSync10(
|
|
8243
8371
|
`git log --format="%h${SEPARATOR}%s${SEPARATOR}%aI" --name-only -n ${limit} -z`,
|
|
8244
8372
|
{ encoding: "utf8", timeout: 1e4 }
|
|
8245
8373
|
);
|
|
@@ -1439,8 +1439,8 @@ function findPackageRoot() {
|
|
|
1439
1439
|
function getAvailableMemoryGB() {
|
|
1440
1440
|
if (process.platform === "darwin") {
|
|
1441
1441
|
try {
|
|
1442
|
-
const { execSync:
|
|
1443
|
-
const vmstat =
|
|
1442
|
+
const { execSync: execSync10 } = __require("child_process");
|
|
1443
|
+
const vmstat = execSync10("vm_stat", { encoding: "utf8" });
|
|
1444
1444
|
const pageSize = 16384;
|
|
1445
1445
|
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1446
1446
|
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
@@ -3179,6 +3179,7 @@ var init_database = __esm({
|
|
|
3179
3179
|
// src/lib/keychain.ts
|
|
3180
3180
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3181
3181
|
import { existsSync as existsSync7 } from "fs";
|
|
3182
|
+
import { execSync as execSync2 } from "child_process";
|
|
3182
3183
|
import path7 from "path";
|
|
3183
3184
|
import os5 from "os";
|
|
3184
3185
|
function getKeyDir() {
|
|
@@ -3187,6 +3188,59 @@ function getKeyDir() {
|
|
|
3187
3188
|
function getKeyPath() {
|
|
3188
3189
|
return path7.join(getKeyDir(), "master.key");
|
|
3189
3190
|
}
|
|
3191
|
+
function macKeychainGet() {
|
|
3192
|
+
if (process.platform !== "darwin") return null;
|
|
3193
|
+
try {
|
|
3194
|
+
return execSync2(
|
|
3195
|
+
`security find-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w 2>/dev/null`,
|
|
3196
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
3197
|
+
).trim();
|
|
3198
|
+
} catch {
|
|
3199
|
+
return null;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
function macKeychainSet(value) {
|
|
3203
|
+
if (process.platform !== "darwin") return false;
|
|
3204
|
+
try {
|
|
3205
|
+
try {
|
|
3206
|
+
execSync2(
|
|
3207
|
+
`security delete-generic-password -s "${SERVICE}" -a "${ACCOUNT}" 2>/dev/null`,
|
|
3208
|
+
{ timeout: 5e3 }
|
|
3209
|
+
);
|
|
3210
|
+
} catch {
|
|
3211
|
+
}
|
|
3212
|
+
execSync2(
|
|
3213
|
+
`security add-generic-password -s "${SERVICE}" -a "${ACCOUNT}" -w "${value}"`,
|
|
3214
|
+
{ timeout: 5e3 }
|
|
3215
|
+
);
|
|
3216
|
+
return true;
|
|
3217
|
+
} catch {
|
|
3218
|
+
return false;
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
function linuxSecretGet() {
|
|
3222
|
+
if (process.platform !== "linux") return null;
|
|
3223
|
+
try {
|
|
3224
|
+
return execSync2(
|
|
3225
|
+
`secret-tool lookup service "${SERVICE}" account "${ACCOUNT}" 2>/dev/null`,
|
|
3226
|
+
{ encoding: "utf-8", timeout: 5e3 }
|
|
3227
|
+
).trim();
|
|
3228
|
+
} catch {
|
|
3229
|
+
return null;
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
function linuxSecretSet(value) {
|
|
3233
|
+
if (process.platform !== "linux") return false;
|
|
3234
|
+
try {
|
|
3235
|
+
execSync2(
|
|
3236
|
+
`echo -n "${value}" | secret-tool store --label="exe-os master key" service "${SERVICE}" account "${ACCOUNT}"`,
|
|
3237
|
+
{ timeout: 5e3 }
|
|
3238
|
+
);
|
|
3239
|
+
return true;
|
|
3240
|
+
} catch {
|
|
3241
|
+
return false;
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3190
3244
|
async function tryKeytar() {
|
|
3191
3245
|
try {
|
|
3192
3246
|
return await import("keytar");
|
|
@@ -3194,13 +3248,63 @@ async function tryKeytar() {
|
|
|
3194
3248
|
return null;
|
|
3195
3249
|
}
|
|
3196
3250
|
}
|
|
3251
|
+
function deriveMachineKey() {
|
|
3252
|
+
try {
|
|
3253
|
+
const crypto3 = __require("crypto");
|
|
3254
|
+
const material = [
|
|
3255
|
+
os5.hostname(),
|
|
3256
|
+
os5.userInfo().username,
|
|
3257
|
+
os5.arch(),
|
|
3258
|
+
os5.platform(),
|
|
3259
|
+
// Machine ID on Linux (stable across reboots)
|
|
3260
|
+
process.platform === "linux" ? readMachineId() : ""
|
|
3261
|
+
].join("|");
|
|
3262
|
+
return crypto3.createHash("sha256").update(material).digest();
|
|
3263
|
+
} catch {
|
|
3264
|
+
return null;
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
function readMachineId() {
|
|
3268
|
+
try {
|
|
3269
|
+
const { readFileSync: readFileSync13 } = __require("fs");
|
|
3270
|
+
return readFileSync13("/etc/machine-id", "utf-8").trim();
|
|
3271
|
+
} catch {
|
|
3272
|
+
return "";
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
function decryptWithMachineKey(encrypted, machineKey) {
|
|
3276
|
+
if (!encrypted.startsWith(ENCRYPTED_PREFIX)) return null;
|
|
3277
|
+
try {
|
|
3278
|
+
const crypto3 = __require("crypto");
|
|
3279
|
+
const parts = encrypted.slice(ENCRYPTED_PREFIX.length).split(":");
|
|
3280
|
+
if (parts.length !== 3) return null;
|
|
3281
|
+
const [ivB64, tagB64, cipherB64] = parts;
|
|
3282
|
+
const iv = Buffer.from(ivB64, "base64");
|
|
3283
|
+
const authTag = Buffer.from(tagB64, "base64");
|
|
3284
|
+
const decipher = crypto3.createDecipheriv("aes-256-gcm", machineKey, iv);
|
|
3285
|
+
decipher.setAuthTag(authTag);
|
|
3286
|
+
let decrypted = decipher.update(cipherB64, "base64", "utf-8");
|
|
3287
|
+
decrypted += decipher.final("utf-8");
|
|
3288
|
+
return decrypted;
|
|
3289
|
+
} catch {
|
|
3290
|
+
return null;
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3197
3293
|
async function getMasterKey() {
|
|
3294
|
+
const nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
3295
|
+
if (nativeValue) {
|
|
3296
|
+
return Buffer.from(nativeValue, "base64");
|
|
3297
|
+
}
|
|
3198
3298
|
const keytar = await tryKeytar();
|
|
3199
3299
|
if (keytar) {
|
|
3200
3300
|
try {
|
|
3201
|
-
const
|
|
3202
|
-
if (
|
|
3203
|
-
|
|
3301
|
+
const keytarValue = await keytar.getPassword(SERVICE, ACCOUNT);
|
|
3302
|
+
if (keytarValue) {
|
|
3303
|
+
const migrated = macKeychainSet(keytarValue) || linuxSecretSet(keytarValue);
|
|
3304
|
+
if (migrated) {
|
|
3305
|
+
process.stderr.write("[keychain] Migrated key from keytar to native keychain.\n");
|
|
3306
|
+
}
|
|
3307
|
+
return Buffer.from(keytarValue, "base64");
|
|
3204
3308
|
}
|
|
3205
3309
|
} catch {
|
|
3206
3310
|
}
|
|
@@ -3214,8 +3318,31 @@ async function getMasterKey() {
|
|
|
3214
3318
|
return null;
|
|
3215
3319
|
}
|
|
3216
3320
|
try {
|
|
3217
|
-
const content = await readFile3(keyPath, "utf-8");
|
|
3218
|
-
|
|
3321
|
+
const content = (await readFile3(keyPath, "utf-8")).trim();
|
|
3322
|
+
let b64Value;
|
|
3323
|
+
if (content.startsWith(ENCRYPTED_PREFIX)) {
|
|
3324
|
+
const machineKey = deriveMachineKey();
|
|
3325
|
+
if (!machineKey) {
|
|
3326
|
+
process.stderr.write("[keychain] Cannot derive machine key to decrypt stored key.\n");
|
|
3327
|
+
return null;
|
|
3328
|
+
}
|
|
3329
|
+
const decrypted = decryptWithMachineKey(content, machineKey);
|
|
3330
|
+
if (!decrypted) {
|
|
3331
|
+
process.stderr.write(
|
|
3332
|
+
"[keychain] Key decryption failed \u2014 machine may have changed.\n Use your 24-word recovery phrase: exe-os link import\n"
|
|
3333
|
+
);
|
|
3334
|
+
return null;
|
|
3335
|
+
}
|
|
3336
|
+
b64Value = decrypted;
|
|
3337
|
+
} else {
|
|
3338
|
+
b64Value = content;
|
|
3339
|
+
}
|
|
3340
|
+
const key = Buffer.from(b64Value, "base64");
|
|
3341
|
+
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
3342
|
+
if (migrated) {
|
|
3343
|
+
process.stderr.write("[keychain] Migrated key from file to native keychain.\n");
|
|
3344
|
+
}
|
|
3345
|
+
return key;
|
|
3219
3346
|
} catch (err) {
|
|
3220
3347
|
process.stderr.write(
|
|
3221
3348
|
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -3224,12 +3351,13 @@ async function getMasterKey() {
|
|
|
3224
3351
|
return null;
|
|
3225
3352
|
}
|
|
3226
3353
|
}
|
|
3227
|
-
var SERVICE, ACCOUNT;
|
|
3354
|
+
var SERVICE, ACCOUNT, ENCRYPTED_PREFIX;
|
|
3228
3355
|
var init_keychain = __esm({
|
|
3229
3356
|
"src/lib/keychain.ts"() {
|
|
3230
3357
|
"use strict";
|
|
3231
3358
|
SERVICE = "exe-mem";
|
|
3232
3359
|
ACCOUNT = "master-key";
|
|
3360
|
+
ENCRYPTED_PREFIX = "enc:";
|
|
3233
3361
|
}
|
|
3234
3362
|
});
|
|
3235
3363
|
|
|
@@ -4752,7 +4880,7 @@ __export(project_name_exports, {
|
|
|
4752
4880
|
_resetCache: () => _resetCache,
|
|
4753
4881
|
getProjectName: () => getProjectName
|
|
4754
4882
|
});
|
|
4755
|
-
import { execSync as
|
|
4883
|
+
import { execSync as execSync3 } from "child_process";
|
|
4756
4884
|
import path10 from "path";
|
|
4757
4885
|
function getProjectName(cwd) {
|
|
4758
4886
|
const dir = cwd ?? process.cwd();
|
|
@@ -4760,7 +4888,7 @@ function getProjectName(cwd) {
|
|
|
4760
4888
|
try {
|
|
4761
4889
|
let repoRoot;
|
|
4762
4890
|
try {
|
|
4763
|
-
const gitCommonDir =
|
|
4891
|
+
const gitCommonDir = execSync3("git rev-parse --path-format=absolute --git-common-dir", {
|
|
4764
4892
|
cwd: dir,
|
|
4765
4893
|
encoding: "utf8",
|
|
4766
4894
|
timeout: 2e3,
|
|
@@ -4768,7 +4896,7 @@ function getProjectName(cwd) {
|
|
|
4768
4896
|
}).trim();
|
|
4769
4897
|
repoRoot = path10.dirname(gitCommonDir);
|
|
4770
4898
|
} catch {
|
|
4771
|
-
repoRoot =
|
|
4899
|
+
repoRoot = execSync3("git rev-parse --show-toplevel", {
|
|
4772
4900
|
cwd: dir,
|
|
4773
4901
|
encoding: "utf8",
|
|
4774
4902
|
timeout: 2e3,
|
|
@@ -4802,14 +4930,14 @@ var file_grep_exports = {};
|
|
|
4802
4930
|
__export(file_grep_exports, {
|
|
4803
4931
|
grepProjectFiles: () => grepProjectFiles
|
|
4804
4932
|
});
|
|
4805
|
-
import { execSync as
|
|
4933
|
+
import { execSync as execSync4 } from "child_process";
|
|
4806
4934
|
import { readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync10 } from "fs";
|
|
4807
4935
|
import path11 from "path";
|
|
4808
4936
|
import crypto2 from "crypto";
|
|
4809
4937
|
function hasRipgrep() {
|
|
4810
4938
|
if (_hasRg === null) {
|
|
4811
4939
|
try {
|
|
4812
|
-
|
|
4940
|
+
execSync4("rg --version", { stdio: "ignore", timeout: 2e3 });
|
|
4813
4941
|
_hasRg = true;
|
|
4814
4942
|
} catch {
|
|
4815
4943
|
_hasRg = false;
|
|
@@ -4875,7 +5003,7 @@ function grepWithRipgrep(pattern, projectRoot, patterns) {
|
|
|
4875
5003
|
const globs = (patterns ?? DEFAULT_PATTERNS).map((p) => `--glob '${p}'`).join(" ");
|
|
4876
5004
|
const excludes = EXCLUDE_DIRS.map((d) => `--glob '!${d}'`).join(" ");
|
|
4877
5005
|
const cmd = `rg -i -c --hidden --no-config --no-ignore '${pattern.replace(/'/g, "\\'")}' . ${globs} ${excludes} --max-filesize ${MAX_FILE_SIZE} 2>/dev/null || true`;
|
|
4878
|
-
const output =
|
|
5006
|
+
const output = execSync4(cmd, {
|
|
4879
5007
|
cwd: projectRoot,
|
|
4880
5008
|
encoding: "utf8",
|
|
4881
5009
|
timeout: 3e3,
|
|
@@ -4890,12 +5018,12 @@ function grepWithRipgrep(pattern, projectRoot, patterns) {
|
|
|
4890
5018
|
const matchCount = parseInt(line.slice(colonIdx + 1));
|
|
4891
5019
|
if (isNaN(matchCount) || matchCount === 0) continue;
|
|
4892
5020
|
try {
|
|
4893
|
-
const firstMatch =
|
|
5021
|
+
const firstMatch = execSync4(
|
|
4894
5022
|
`rg -i -n --hidden '${pattern.replace(/'/g, "\\'")}' '${filePath}' --max-count 1 2>/dev/null | head -1`,
|
|
4895
5023
|
{ cwd: projectRoot, encoding: "utf8", timeout: 1e3 }
|
|
4896
5024
|
).trim();
|
|
4897
5025
|
const lineNum = parseInt(firstMatch.split(":")[0] ?? "1");
|
|
4898
|
-
const totalLines =
|
|
5026
|
+
const totalLines = execSync4(`wc -l < '${filePath}'`, {
|
|
4899
5027
|
cwd: projectRoot,
|
|
4900
5028
|
encoding: "utf8",
|
|
4901
5029
|
timeout: 1e3
|
|
@@ -5524,10 +5652,17 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5524
5652
|
if (ENTITY_BOOST_WEIGHT === 0 || results.length === 0) {
|
|
5525
5653
|
return emptyResult;
|
|
5526
5654
|
}
|
|
5527
|
-
|
|
5655
|
+
const debugStart = process.env.EXE_DEBUG_HOOKS ? performance.now() : 0;
|
|
5656
|
+
const debugEnd = () => {
|
|
5657
|
+
if (!process.env.EXE_DEBUG_HOOKS) return;
|
|
5658
|
+
process.stderr.write(
|
|
5659
|
+
`[entity-boost] ${(performance.now() - debugStart).toFixed(3)}ms
|
|
5660
|
+
`
|
|
5661
|
+
);
|
|
5662
|
+
};
|
|
5528
5663
|
const entities = await matchEntities(query, client);
|
|
5529
5664
|
if (entities.length === 0) {
|
|
5530
|
-
|
|
5665
|
+
debugEnd();
|
|
5531
5666
|
return emptyResult;
|
|
5532
5667
|
}
|
|
5533
5668
|
const boostMap = /* @__PURE__ */ new Map();
|
|
@@ -5549,7 +5684,7 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5549
5684
|
await traverseAndScore(entities, client, boostMap, resultIds, graphContextMap);
|
|
5550
5685
|
await applyHyperedgeBoost(entities, client, boostMap, resultIds);
|
|
5551
5686
|
if (boostMap.size === 0) {
|
|
5552
|
-
|
|
5687
|
+
debugEnd();
|
|
5553
5688
|
return emptyResult;
|
|
5554
5689
|
}
|
|
5555
5690
|
const scored = results.map((r, i) => ({
|
|
@@ -5560,7 +5695,7 @@ async function applyEntityBoost(results, query, client) {
|
|
|
5560
5695
|
scored.sort(
|
|
5561
5696
|
(a, b) => b.baseScore + b.entityBoost - (a.baseScore + a.entityBoost)
|
|
5562
5697
|
);
|
|
5563
|
-
|
|
5698
|
+
debugEnd();
|
|
5564
5699
|
return {
|
|
5565
5700
|
results: scored.map((s) => s.record),
|
|
5566
5701
|
graphContext: graphContextMap
|
|
@@ -6205,7 +6340,7 @@ var init_hybrid_search = __esm({
|
|
|
6205
6340
|
});
|
|
6206
6341
|
|
|
6207
6342
|
// src/lib/session-key.ts
|
|
6208
|
-
import { execSync as
|
|
6343
|
+
import { execSync as execSync5 } from "child_process";
|
|
6209
6344
|
function normalizeCommand(command) {
|
|
6210
6345
|
const trimmed = command.trim().toLowerCase();
|
|
6211
6346
|
const parts = trimmed.split(/[\\/]/);
|
|
@@ -6224,7 +6359,7 @@ function resolveRuntimeProcess() {
|
|
|
6224
6359
|
let pid = process.ppid;
|
|
6225
6360
|
for (let i = 0; i < 10; i++) {
|
|
6226
6361
|
try {
|
|
6227
|
-
const info =
|
|
6362
|
+
const info = execSync5(`ps -p ${pid} -o ppid=,comm=`, {
|
|
6228
6363
|
encoding: "utf8",
|
|
6229
6364
|
timeout: 2e3
|
|
6230
6365
|
}).trim();
|
|
@@ -6274,7 +6409,7 @@ var init_session_key = __esm({
|
|
|
6274
6409
|
|
|
6275
6410
|
// src/lib/active-agent.ts
|
|
6276
6411
|
import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, unlinkSync as unlinkSync3, readdirSync as readdirSync3 } from "fs";
|
|
6277
|
-
import { execSync as
|
|
6412
|
+
import { execSync as execSync6 } from "child_process";
|
|
6278
6413
|
import path12 from "path";
|
|
6279
6414
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
6280
6415
|
if (candidate === baseName) return true;
|
|
@@ -6366,7 +6501,7 @@ function getActiveAgent() {
|
|
|
6366
6501
|
} catch {
|
|
6367
6502
|
}
|
|
6368
6503
|
try {
|
|
6369
|
-
const sessionName =
|
|
6504
|
+
const sessionName = execSync6(
|
|
6370
6505
|
"tmux display-message -p '#{session_name}' 2>/dev/null",
|
|
6371
6506
|
{ encoding: "utf8", timeout: 2e3 }
|
|
6372
6507
|
).trim();
|
|
@@ -6584,7 +6719,7 @@ var init_transport = __esm({
|
|
|
6584
6719
|
});
|
|
6585
6720
|
|
|
6586
6721
|
// src/lib/cc-agent-support.ts
|
|
6587
|
-
import { execSync as
|
|
6722
|
+
import { execSync as execSync7 } from "child_process";
|
|
6588
6723
|
var init_cc_agent_support = __esm({
|
|
6589
6724
|
"src/lib/cc-agent-support.ts"() {
|
|
6590
6725
|
"use strict";
|
|
@@ -6843,7 +6978,7 @@ var catchup_brief_exports = {};
|
|
|
6843
6978
|
__export(catchup_brief_exports, {
|
|
6844
6979
|
buildCatchupBrief: () => buildCatchupBrief
|
|
6845
6980
|
});
|
|
6846
|
-
import { execSync as
|
|
6981
|
+
import { execSync as execSync8 } from "child_process";
|
|
6847
6982
|
function clipText(text, maxChars) {
|
|
6848
6983
|
if (text.length <= maxChars) return text;
|
|
6849
6984
|
if (maxChars <= 1) return "\u2026";
|
|
@@ -6889,7 +7024,7 @@ ${clipText(checkpoint.raw_text, MAX_CHECKPOINT_CHARS)}`
|
|
|
6889
7024
|
} catch {
|
|
6890
7025
|
}
|
|
6891
7026
|
try {
|
|
6892
|
-
const gitLog =
|
|
7027
|
+
const gitLog = execSync8(
|
|
6893
7028
|
`git log --oneline --since=${JSON.stringify(lastTimestamp)} --format="%h %an: %s" | head -10`,
|
|
6894
7029
|
{ cwd, timeout: 3e3, encoding: "utf-8" }
|
|
6895
7030
|
).trim();
|
|
@@ -6967,11 +7102,11 @@ __export(git_staleness_exports, {
|
|
|
6967
7102
|
detectStaleFiles: () => detectStaleFiles,
|
|
6968
7103
|
recordFileRead: () => recordFileRead
|
|
6969
7104
|
});
|
|
6970
|
-
import { execSync as
|
|
7105
|
+
import { execSync as execSync9 } from "child_process";
|
|
6971
7106
|
import path18 from "path";
|
|
6972
7107
|
function getHeadCommit(cwd) {
|
|
6973
7108
|
try {
|
|
6974
|
-
return
|
|
7109
|
+
return execSync9("git rev-parse --short HEAD", {
|
|
6975
7110
|
cwd,
|
|
6976
7111
|
timeout: GIT_TIMEOUT_MS,
|
|
6977
7112
|
encoding: "utf-8"
|
|
@@ -7034,7 +7169,7 @@ async function detectStaleFiles(agentId, cwd) {
|
|
|
7034
7169
|
const readAt = String(record.read_at ?? "");
|
|
7035
7170
|
if (!filePath || !readAt) continue;
|
|
7036
7171
|
try {
|
|
7037
|
-
const gitSummary =
|
|
7172
|
+
const gitSummary = execSync9(
|
|
7038
7173
|
`git log -1 --oneline --after=${JSON.stringify(readAt)} --format="%h %an: %s" -- ${JSON.stringify(filePath)}`,
|
|
7039
7174
|
{
|
|
7040
7175
|
cwd,
|