@askexenow/exe-os 0.9.97 → 0.9.99
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/agentic-ontology-backfill.js +7 -29
- package/dist/bin/agentic-reflection-backfill.js +7 -29
- package/dist/bin/agentic-semantic-label.js +7 -29
- package/dist/bin/backfill-conversations.js +7 -29
- package/dist/bin/backfill-responses.js +7 -29
- package/dist/bin/backfill-vectors.js +7 -29
- package/dist/bin/bulk-sync-postgres.js +7 -29
- package/dist/bin/cleanup-stale-review-tasks.js +7 -29
- package/dist/bin/cli.js +11 -33
- package/dist/bin/exe-agent.js +7 -0
- package/dist/bin/exe-assign.js +7 -29
- package/dist/bin/exe-boot.js +7 -29
- package/dist/bin/exe-call.js +7 -0
- package/dist/bin/exe-cloud.js +7 -29
- package/dist/bin/exe-dispatch.js +7 -29
- package/dist/bin/exe-doctor.js +7 -29
- package/dist/bin/exe-export-behaviors.js +7 -29
- package/dist/bin/exe-forget.js +7 -29
- package/dist/bin/exe-gateway.js +7 -29
- package/dist/bin/exe-heartbeat.js +7 -29
- package/dist/bin/exe-kill.js +7 -29
- package/dist/bin/exe-launch-agent.js +7 -29
- package/dist/bin/exe-new-employee.js +7 -0
- package/dist/bin/exe-pending-messages.js +7 -29
- package/dist/bin/exe-pending-notifications.js +7 -29
- package/dist/bin/exe-pending-reviews.js +7 -29
- package/dist/bin/exe-rename.js +7 -29
- package/dist/bin/exe-review.js +7 -29
- package/dist/bin/exe-search.js +7 -29
- package/dist/bin/exe-session-cleanup.js +7 -29
- package/dist/bin/exe-start-codex.js +7 -29
- package/dist/bin/exe-start-opencode.js +7 -29
- package/dist/bin/exe-status.js +7 -29
- package/dist/bin/exe-team.js +7 -29
- package/dist/bin/git-sweep.js +7 -29
- package/dist/bin/graph-backfill.js +7 -29
- package/dist/bin/graph-export.js +7 -29
- package/dist/bin/intercom-check.js +7 -29
- package/dist/bin/scan-tasks.js +7 -29
- package/dist/bin/setup.js +11 -33
- package/dist/bin/shard-migrate.js +7 -29
- package/dist/gateway/index.js +7 -29
- package/dist/hooks/bug-report-worker.js +7 -29
- package/dist/hooks/codex-stop-task-finalizer.js +7 -29
- package/dist/hooks/commit-complete.js +7 -29
- package/dist/hooks/error-recall.js +7 -29
- package/dist/hooks/ingest.js +7 -29
- package/dist/hooks/instructions-loaded.js +7 -29
- package/dist/hooks/notification.js +7 -29
- package/dist/hooks/post-compact.js +7 -29
- package/dist/hooks/post-tool-combined.js +7 -29
- package/dist/hooks/pre-compact.js +7 -29
- package/dist/hooks/pre-tool-use.js +7 -29
- package/dist/hooks/prompt-submit.js +7 -29
- package/dist/hooks/session-end.js +7 -29
- package/dist/hooks/session-start.js +7 -29
- package/dist/hooks/stop.js +7 -29
- package/dist/hooks/subagent-stop.js +7 -29
- package/dist/hooks/summary-worker.js +7 -29
- package/dist/index.js +7 -29
- package/dist/lib/cloud-sync.js +0 -29
- package/dist/lib/database.js +0 -35
- package/dist/lib/db-daemon-client.js +0 -36
- package/dist/lib/db.js +0 -35
- package/dist/lib/device-registry.js +0 -35
- package/dist/lib/embedder.js +0 -35
- package/dist/lib/employee-templates.js +7 -0
- package/dist/lib/exe-daemon-client.js +0 -36
- package/dist/lib/exe-daemon.js +7 -29
- package/dist/lib/hybrid-search.js +7 -29
- package/dist/lib/schedules.js +7 -29
- package/dist/lib/skill-learning.js +0 -35
- package/dist/lib/store.js +7 -29
- package/dist/lib/tasks.js +0 -29
- package/dist/lib/tmux-routing.js +0 -29
- package/dist/mcp/server.js +7 -29
- package/dist/mcp/tools/create-task.js +0 -29
- package/dist/mcp/tools/update-task.js +0 -29
- package/dist/runtime/index.js +7 -29
- package/dist/tui/App.js +7 -29
- package/package.json +1 -1
|
@@ -1055,40 +1055,11 @@ function findPackageRoot() {
|
|
|
1055
1055
|
}
|
|
1056
1056
|
return null;
|
|
1057
1057
|
}
|
|
1058
|
-
function getAvailableMemoryGB() {
|
|
1059
|
-
if (process.platform === "darwin") {
|
|
1060
|
-
try {
|
|
1061
|
-
const { execSync: execSync4 } = __require("child_process");
|
|
1062
|
-
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
1063
|
-
const pageSize = 16384;
|
|
1064
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1065
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1066
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1067
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1068
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1069
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1070
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1071
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1072
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1073
|
-
} catch {
|
|
1074
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1078
|
-
}
|
|
1079
1058
|
function spawnDaemon() {
|
|
1080
|
-
const freeGB = getAvailableMemoryGB();
|
|
1081
1059
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1082
1060
|
if (totalGB <= 8) {
|
|
1083
1061
|
process.stderr.write(
|
|
1084
1062
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1085
|
-
`
|
|
1086
|
-
);
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1090
|
-
process.stderr.write(
|
|
1091
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1092
1063
|
`
|
|
1093
1064
|
);
|
|
1094
1065
|
return;
|
|
@@ -3545,6 +3516,13 @@ var init_platform_procedures = __esm({
|
|
|
3545
3516
|
priority: "p0",
|
|
3546
3517
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
3547
3518
|
},
|
|
3519
|
+
// --- Encryption key + cloud sync ---
|
|
3520
|
+
{
|
|
3521
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
3522
|
+
domain: "security",
|
|
3523
|
+
priority: "p0",
|
|
3524
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
3525
|
+
},
|
|
3548
3526
|
// --- MCP is the ONLY data interface ---
|
|
3549
3527
|
{
|
|
3550
3528
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
package/dist/bin/graph-export.js
CHANGED
|
@@ -1066,40 +1066,11 @@ function findPackageRoot() {
|
|
|
1066
1066
|
}
|
|
1067
1067
|
return null;
|
|
1068
1068
|
}
|
|
1069
|
-
function getAvailableMemoryGB() {
|
|
1070
|
-
if (process.platform === "darwin") {
|
|
1071
|
-
try {
|
|
1072
|
-
const { execSync: execSync4 } = __require("child_process");
|
|
1073
|
-
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
1074
|
-
const pageSize = 16384;
|
|
1075
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1076
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1077
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1078
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1079
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1080
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1081
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1082
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1083
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1084
|
-
} catch {
|
|
1085
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1089
|
-
}
|
|
1090
1069
|
function spawnDaemon() {
|
|
1091
|
-
const freeGB = getAvailableMemoryGB();
|
|
1092
1070
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1093
1071
|
if (totalGB <= 8) {
|
|
1094
1072
|
process.stderr.write(
|
|
1095
1073
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1096
|
-
`
|
|
1097
|
-
);
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1101
|
-
process.stderr.write(
|
|
1102
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1103
1074
|
`
|
|
1104
1075
|
);
|
|
1105
1076
|
return;
|
|
@@ -4317,6 +4288,13 @@ var init_platform_procedures = __esm({
|
|
|
4317
4288
|
priority: "p0",
|
|
4318
4289
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4319
4290
|
},
|
|
4291
|
+
// --- Encryption key + cloud sync ---
|
|
4292
|
+
{
|
|
4293
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4294
|
+
domain: "security",
|
|
4295
|
+
priority: "p0",
|
|
4296
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4297
|
+
},
|
|
4320
4298
|
// --- MCP is the ONLY data interface ---
|
|
4321
4299
|
{
|
|
4322
4300
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -1175,40 +1175,11 @@ function findPackageRoot() {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
return null;
|
|
1177
1177
|
}
|
|
1178
|
-
function getAvailableMemoryGB() {
|
|
1179
|
-
if (process.platform === "darwin") {
|
|
1180
|
-
try {
|
|
1181
|
-
const { execSync: execSync9 } = __require("child_process");
|
|
1182
|
-
const vmstat = execSync9("vm_stat", { encoding: "utf8" });
|
|
1183
|
-
const pageSize = 16384;
|
|
1184
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1185
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1186
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1187
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1188
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1189
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1190
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1191
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1192
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1193
|
-
} catch {
|
|
1194
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1198
|
-
}
|
|
1199
1178
|
function spawnDaemon() {
|
|
1200
|
-
const freeGB = getAvailableMemoryGB();
|
|
1201
1179
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1202
1180
|
if (totalGB <= 8) {
|
|
1203
1181
|
process.stderr.write(
|
|
1204
1182
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1205
|
-
`
|
|
1206
|
-
);
|
|
1207
|
-
return;
|
|
1208
|
-
}
|
|
1209
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1210
|
-
process.stderr.write(
|
|
1211
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1212
1183
|
`
|
|
1213
1184
|
);
|
|
1214
1185
|
return;
|
|
@@ -4426,6 +4397,13 @@ var init_platform_procedures = __esm({
|
|
|
4426
4397
|
priority: "p0",
|
|
4427
4398
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4428
4399
|
},
|
|
4400
|
+
// --- Encryption key + cloud sync ---
|
|
4401
|
+
{
|
|
4402
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4403
|
+
domain: "security",
|
|
4404
|
+
priority: "p0",
|
|
4405
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4406
|
+
},
|
|
4429
4407
|
// --- MCP is the ONLY data interface ---
|
|
4430
4408
|
{
|
|
4431
4409
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
package/dist/bin/scan-tasks.js
CHANGED
|
@@ -1667,40 +1667,11 @@ function findPackageRoot() {
|
|
|
1667
1667
|
}
|
|
1668
1668
|
return null;
|
|
1669
1669
|
}
|
|
1670
|
-
function getAvailableMemoryGB() {
|
|
1671
|
-
if (process.platform === "darwin") {
|
|
1672
|
-
try {
|
|
1673
|
-
const { execSync: execSync9 } = __require("child_process");
|
|
1674
|
-
const vmstat = execSync9("vm_stat", { encoding: "utf8" });
|
|
1675
|
-
const pageSize = 16384;
|
|
1676
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1677
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1678
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1679
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1680
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1681
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1682
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1683
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1684
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1685
|
-
} catch {
|
|
1686
|
-
return os6.freemem() / (1024 * 1024 * 1024);
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
return os6.freemem() / (1024 * 1024 * 1024);
|
|
1690
|
-
}
|
|
1691
1670
|
function spawnDaemon() {
|
|
1692
|
-
const freeGB = getAvailableMemoryGB();
|
|
1693
1671
|
const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
|
|
1694
1672
|
if (totalGB <= 8) {
|
|
1695
1673
|
process.stderr.write(
|
|
1696
1674
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1697
|
-
`
|
|
1698
|
-
);
|
|
1699
|
-
return;
|
|
1700
|
-
}
|
|
1701
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1702
|
-
process.stderr.write(
|
|
1703
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1704
1675
|
`
|
|
1705
1676
|
);
|
|
1706
1677
|
return;
|
|
@@ -8156,6 +8127,13 @@ var init_platform_procedures = __esm({
|
|
|
8156
8127
|
priority: "p0",
|
|
8157
8128
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
8158
8129
|
},
|
|
8130
|
+
// --- Encryption key + cloud sync ---
|
|
8131
|
+
{
|
|
8132
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
8133
|
+
domain: "security",
|
|
8134
|
+
priority: "p0",
|
|
8135
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
8136
|
+
},
|
|
8159
8137
|
// --- MCP is the ONLY data interface ---
|
|
8160
8138
|
{
|
|
8161
8139
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
package/dist/bin/setup.js
CHANGED
|
@@ -920,40 +920,11 @@ function findPackageRoot() {
|
|
|
920
920
|
}
|
|
921
921
|
return null;
|
|
922
922
|
}
|
|
923
|
-
function getAvailableMemoryGB() {
|
|
924
|
-
if (process.platform === "darwin") {
|
|
925
|
-
try {
|
|
926
|
-
const { execSync: execSync5 } = __require("child_process");
|
|
927
|
-
const vmstat = execSync5("vm_stat", { encoding: "utf8" });
|
|
928
|
-
const pageSize = 16384;
|
|
929
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
930
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
931
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
932
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
933
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
934
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
935
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
936
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
937
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
938
|
-
} catch {
|
|
939
|
-
return os3.freemem() / (1024 * 1024 * 1024);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
return os3.freemem() / (1024 * 1024 * 1024);
|
|
943
|
-
}
|
|
944
923
|
function spawnDaemon() {
|
|
945
|
-
const freeGB = getAvailableMemoryGB();
|
|
946
924
|
const totalGB = os3.totalmem() / (1024 * 1024 * 1024);
|
|
947
925
|
if (totalGB <= 8) {
|
|
948
926
|
process.stderr.write(
|
|
949
927
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
950
|
-
`
|
|
951
|
-
);
|
|
952
|
-
return;
|
|
953
|
-
}
|
|
954
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
955
|
-
process.stderr.write(
|
|
956
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
957
928
|
`
|
|
958
929
|
);
|
|
959
930
|
return;
|
|
@@ -6727,6 +6698,13 @@ var init_platform_procedures = __esm({
|
|
|
6727
6698
|
priority: "p0",
|
|
6728
6699
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
6729
6700
|
},
|
|
6701
|
+
// --- Encryption key + cloud sync ---
|
|
6702
|
+
{
|
|
6703
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
6704
|
+
domain: "security",
|
|
6705
|
+
priority: "p0",
|
|
6706
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
6707
|
+
},
|
|
6730
6708
|
// --- MCP is the ONLY data interface ---
|
|
6731
6709
|
{
|
|
6732
6710
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -8452,7 +8430,7 @@ function ask(rl, prompt) {
|
|
|
8452
8430
|
doAsk();
|
|
8453
8431
|
});
|
|
8454
8432
|
}
|
|
8455
|
-
function
|
|
8433
|
+
function getAvailableMemoryGB() {
|
|
8456
8434
|
if (process.platform === "darwin") {
|
|
8457
8435
|
try {
|
|
8458
8436
|
const { execSync: execSync5 } = __require("child_process");
|
|
@@ -8476,11 +8454,11 @@ function getTotalMemoryGB() {
|
|
|
8476
8454
|
return os8.totalmem() / (1024 * 1024 * 1024);
|
|
8477
8455
|
}
|
|
8478
8456
|
function isLowMemory() {
|
|
8479
|
-
return
|
|
8457
|
+
return getAvailableMemoryGB() < 2;
|
|
8480
8458
|
}
|
|
8481
8459
|
async function validateModel(log) {
|
|
8482
8460
|
const totalGB = getTotalMemoryGB();
|
|
8483
|
-
const freeGB =
|
|
8461
|
+
const freeGB = getAvailableMemoryGB();
|
|
8484
8462
|
if (totalGB <= 8 || isLowMemory()) {
|
|
8485
8463
|
log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
|
|
8486
8464
|
log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
|
|
@@ -8725,7 +8703,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
8725
8703
|
skipModel2 = true;
|
|
8726
8704
|
}
|
|
8727
8705
|
if (!skipModel2) {
|
|
8728
|
-
const freeGB =
|
|
8706
|
+
const freeGB = getAvailableMemoryGB();
|
|
8729
8707
|
if (freeGB < 2) {
|
|
8730
8708
|
log(`\u26A0 Low memory detected: ${freeGB.toFixed(1)}GB free of ${totalGB.toFixed(0)}GB total`);
|
|
8731
8709
|
log(" Close other applications (browser, Slack, etc.) before continuing.");
|
|
@@ -1055,40 +1055,11 @@ function findPackageRoot() {
|
|
|
1055
1055
|
}
|
|
1056
1056
|
return null;
|
|
1057
1057
|
}
|
|
1058
|
-
function getAvailableMemoryGB() {
|
|
1059
|
-
if (process.platform === "darwin") {
|
|
1060
|
-
try {
|
|
1061
|
-
const { execSync: execSync4 } = __require("child_process");
|
|
1062
|
-
const vmstat = execSync4("vm_stat", { encoding: "utf8" });
|
|
1063
|
-
const pageSize = 16384;
|
|
1064
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1065
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1066
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1067
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1068
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1069
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1070
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1071
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1072
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1073
|
-
} catch {
|
|
1074
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1078
|
-
}
|
|
1079
1058
|
function spawnDaemon() {
|
|
1080
|
-
const freeGB = getAvailableMemoryGB();
|
|
1081
1059
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1082
1060
|
if (totalGB <= 8) {
|
|
1083
1061
|
process.stderr.write(
|
|
1084
1062
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1085
|
-
`
|
|
1086
|
-
);
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1090
|
-
process.stderr.write(
|
|
1091
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1092
1063
|
`
|
|
1093
1064
|
);
|
|
1094
1065
|
return;
|
|
@@ -3545,6 +3516,13 @@ var init_platform_procedures = __esm({
|
|
|
3545
3516
|
priority: "p0",
|
|
3546
3517
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
3547
3518
|
},
|
|
3519
|
+
// --- Encryption key + cloud sync ---
|
|
3520
|
+
{
|
|
3521
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
3522
|
+
domain: "security",
|
|
3523
|
+
priority: "p0",
|
|
3524
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
3525
|
+
},
|
|
3548
3526
|
// --- MCP is the ONLY data interface ---
|
|
3549
3527
|
{
|
|
3550
3528
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
package/dist/gateway/index.js
CHANGED
|
@@ -1776,40 +1776,11 @@ function findPackageRoot() {
|
|
|
1776
1776
|
}
|
|
1777
1777
|
return null;
|
|
1778
1778
|
}
|
|
1779
|
-
function getAvailableMemoryGB() {
|
|
1780
|
-
if (process.platform === "darwin") {
|
|
1781
|
-
try {
|
|
1782
|
-
const { execSync: execSync9 } = __require("child_process");
|
|
1783
|
-
const vmstat = execSync9("vm_stat", { encoding: "utf8" });
|
|
1784
|
-
const pageSize = 16384;
|
|
1785
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1786
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1787
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1788
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1789
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1790
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1791
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1792
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1793
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1794
|
-
} catch {
|
|
1795
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1799
|
-
}
|
|
1800
1779
|
function spawnDaemon() {
|
|
1801
|
-
const freeGB = getAvailableMemoryGB();
|
|
1802
1780
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1803
1781
|
if (totalGB <= 8) {
|
|
1804
1782
|
process.stderr.write(
|
|
1805
1783
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1806
|
-
`
|
|
1807
|
-
);
|
|
1808
|
-
return;
|
|
1809
|
-
}
|
|
1810
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1811
|
-
process.stderr.write(
|
|
1812
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1813
1784
|
`
|
|
1814
1785
|
);
|
|
1815
1786
|
return;
|
|
@@ -4985,6 +4956,13 @@ var init_platform_procedures = __esm({
|
|
|
4985
4956
|
priority: "p0",
|
|
4986
4957
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4987
4958
|
},
|
|
4959
|
+
// --- Encryption key + cloud sync ---
|
|
4960
|
+
{
|
|
4961
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4962
|
+
domain: "security",
|
|
4963
|
+
priority: "p0",
|
|
4964
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4965
|
+
},
|
|
4988
4966
|
// --- MCP is the ONLY data interface ---
|
|
4989
4967
|
{
|
|
4990
4968
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -1476,40 +1476,11 @@ function findPackageRoot() {
|
|
|
1476
1476
|
}
|
|
1477
1477
|
return null;
|
|
1478
1478
|
}
|
|
1479
|
-
function getAvailableMemoryGB() {
|
|
1480
|
-
if (process.platform === "darwin") {
|
|
1481
|
-
try {
|
|
1482
|
-
const { execSync: execSync9 } = __require("child_process");
|
|
1483
|
-
const vmstat = execSync9("vm_stat", { encoding: "utf8" });
|
|
1484
|
-
const pageSize = 16384;
|
|
1485
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1486
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1487
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1488
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1489
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1490
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1491
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1492
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1493
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1494
|
-
} catch {
|
|
1495
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1499
|
-
}
|
|
1500
1479
|
function spawnDaemon() {
|
|
1501
|
-
const freeGB = getAvailableMemoryGB();
|
|
1502
1480
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1503
1481
|
if (totalGB <= 8) {
|
|
1504
1482
|
process.stderr.write(
|
|
1505
1483
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1506
|
-
`
|
|
1507
|
-
);
|
|
1508
|
-
return;
|
|
1509
|
-
}
|
|
1510
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1511
|
-
process.stderr.write(
|
|
1512
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1513
1484
|
`
|
|
1514
1485
|
);
|
|
1515
1486
|
return;
|
|
@@ -4727,6 +4698,13 @@ var init_platform_procedures = __esm({
|
|
|
4727
4698
|
priority: "p0",
|
|
4728
4699
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4729
4700
|
},
|
|
4701
|
+
// --- Encryption key + cloud sync ---
|
|
4702
|
+
{
|
|
4703
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4704
|
+
domain: "security",
|
|
4705
|
+
priority: "p0",
|
|
4706
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4707
|
+
},
|
|
4730
4708
|
// --- MCP is the ONLY data interface ---
|
|
4731
4709
|
{
|
|
4732
4710
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -1159,40 +1159,11 @@ function findPackageRoot() {
|
|
|
1159
1159
|
}
|
|
1160
1160
|
return null;
|
|
1161
1161
|
}
|
|
1162
|
-
function getAvailableMemoryGB() {
|
|
1163
|
-
if (process.platform === "darwin") {
|
|
1164
|
-
try {
|
|
1165
|
-
const { execSync: execSync7 } = __require("child_process");
|
|
1166
|
-
const vmstat = execSync7("vm_stat", { encoding: "utf8" });
|
|
1167
|
-
const pageSize = 16384;
|
|
1168
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1169
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1170
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1171
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1172
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1173
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1174
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1175
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1176
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1177
|
-
} catch {
|
|
1178
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1179
|
-
}
|
|
1180
|
-
}
|
|
1181
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1182
|
-
}
|
|
1183
1162
|
function spawnDaemon() {
|
|
1184
|
-
const freeGB = getAvailableMemoryGB();
|
|
1185
1163
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1186
1164
|
if (totalGB <= 8) {
|
|
1187
1165
|
process.stderr.write(
|
|
1188
1166
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1189
|
-
`
|
|
1190
|
-
);
|
|
1191
|
-
return;
|
|
1192
|
-
}
|
|
1193
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1194
|
-
process.stderr.write(
|
|
1195
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1196
1167
|
`
|
|
1197
1168
|
);
|
|
1198
1169
|
return;
|
|
@@ -4410,6 +4381,13 @@ var init_platform_procedures = __esm({
|
|
|
4410
4381
|
priority: "p0",
|
|
4411
4382
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4412
4383
|
},
|
|
4384
|
+
// --- Encryption key + cloud sync ---
|
|
4385
|
+
{
|
|
4386
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4387
|
+
domain: "security",
|
|
4388
|
+
priority: "p0",
|
|
4389
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4390
|
+
},
|
|
4413
4391
|
// --- MCP is the ONLY data interface ---
|
|
4414
4392
|
{
|
|
4415
4393
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -1654,40 +1654,11 @@ function findPackageRoot() {
|
|
|
1654
1654
|
}
|
|
1655
1655
|
return null;
|
|
1656
1656
|
}
|
|
1657
|
-
function getAvailableMemoryGB() {
|
|
1658
|
-
if (process.platform === "darwin") {
|
|
1659
|
-
try {
|
|
1660
|
-
const { execSync: execSync11 } = __require("child_process");
|
|
1661
|
-
const vmstat = execSync11("vm_stat", { encoding: "utf8" });
|
|
1662
|
-
const pageSize = 16384;
|
|
1663
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1664
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1665
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1666
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1667
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1668
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1669
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1670
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1671
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1672
|
-
} catch {
|
|
1673
|
-
return os6.freemem() / (1024 * 1024 * 1024);
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
return os6.freemem() / (1024 * 1024 * 1024);
|
|
1677
|
-
}
|
|
1678
1657
|
function spawnDaemon() {
|
|
1679
|
-
const freeGB = getAvailableMemoryGB();
|
|
1680
1658
|
const totalGB = os6.totalmem() / (1024 * 1024 * 1024);
|
|
1681
1659
|
if (totalGB <= 8) {
|
|
1682
1660
|
process.stderr.write(
|
|
1683
1661
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1684
|
-
`
|
|
1685
|
-
);
|
|
1686
|
-
return;
|
|
1687
|
-
}
|
|
1688
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1689
|
-
process.stderr.write(
|
|
1690
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1691
1662
|
`
|
|
1692
1663
|
);
|
|
1693
1664
|
return;
|
|
@@ -8150,6 +8121,13 @@ var init_platform_procedures = __esm({
|
|
|
8150
8121
|
priority: "p0",
|
|
8151
8122
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
8152
8123
|
},
|
|
8124
|
+
// --- Encryption key + cloud sync ---
|
|
8125
|
+
{
|
|
8126
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
8127
|
+
domain: "security",
|
|
8128
|
+
priority: "p0",
|
|
8129
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
8130
|
+
},
|
|
8153
8131
|
// --- MCP is the ONLY data interface ---
|
|
8154
8132
|
{
|
|
8155
8133
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|
|
@@ -1122,40 +1122,11 @@ function findPackageRoot() {
|
|
|
1122
1122
|
}
|
|
1123
1123
|
return null;
|
|
1124
1124
|
}
|
|
1125
|
-
function getAvailableMemoryGB() {
|
|
1126
|
-
if (process.platform === "darwin") {
|
|
1127
|
-
try {
|
|
1128
|
-
const { execSync: execSync8 } = __require("child_process");
|
|
1129
|
-
const vmstat = execSync8("vm_stat", { encoding: "utf8" });
|
|
1130
|
-
const pageSize = 16384;
|
|
1131
|
-
const pageSizeMatch = vmstat.match(/page size of (\d+) bytes/);
|
|
1132
|
-
const actualPageSize = pageSizeMatch ? parseInt(pageSizeMatch[1], 10) : pageSize;
|
|
1133
|
-
const free = vmstat.match(/Pages free:\s+(\d+)/);
|
|
1134
|
-
const inactive = vmstat.match(/Pages inactive:\s+(\d+)/);
|
|
1135
|
-
const speculative = vmstat.match(/Pages speculative:\s+(\d+)/);
|
|
1136
|
-
const freePages = free ? parseInt(free[1], 10) : 0;
|
|
1137
|
-
const inactivePages = inactive ? parseInt(inactive[1], 10) : 0;
|
|
1138
|
-
const speculativePages = speculative ? parseInt(speculative[1], 10) : 0;
|
|
1139
|
-
return (freePages + inactivePages + speculativePages) * actualPageSize / (1024 * 1024 * 1024);
|
|
1140
|
-
} catch {
|
|
1141
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
return os4.freemem() / (1024 * 1024 * 1024);
|
|
1145
|
-
}
|
|
1146
1125
|
function spawnDaemon() {
|
|
1147
|
-
const freeGB = getAvailableMemoryGB();
|
|
1148
1126
|
const totalGB = os4.totalmem() / (1024 * 1024 * 1024);
|
|
1149
1127
|
if (totalGB <= 8) {
|
|
1150
1128
|
process.stderr.write(
|
|
1151
1129
|
`[exed-client] SKIP: ${totalGB.toFixed(0)}GB system \u2014 embedding daemon disabled. Using keyword search only. Minimum 16GB recommended for vector search.
|
|
1152
|
-
`
|
|
1153
|
-
);
|
|
1154
|
-
return;
|
|
1155
|
-
}
|
|
1156
|
-
if (totalGB <= 16 && freeGB < 2) {
|
|
1157
|
-
process.stderr.write(
|
|
1158
|
-
`[exed-client] SKIP: low memory (${freeGB.toFixed(1)}GB available / ${totalGB.toFixed(0)}GB total). Embedding daemon not started \u2014 using keyword search only.
|
|
1159
1130
|
`
|
|
1160
1131
|
);
|
|
1161
1132
|
return;
|
|
@@ -4318,6 +4289,13 @@ var init_platform_procedures = __esm({
|
|
|
4318
4289
|
priority: "p0",
|
|
4319
4290
|
content: "Tasks live in the DB. Intercom (tmux send-keys) is fire-and-forget \u2014 it may fail, get garbled, or arrive mid-work. Never rely on intercom for task delivery. The UserPromptSubmit hook checks the DB for new tasks on every prompt. Your operating procedures step 7 says check for next work. The daemon nudges idle agents as a speedup. If you have no tasks, you found them all."
|
|
4320
4291
|
},
|
|
4292
|
+
// --- Encryption key + cloud sync ---
|
|
4293
|
+
{
|
|
4294
|
+
title: "Encryption key lives in Keychain, not on disk \u2014 never expose the recovery phrase",
|
|
4295
|
+
domain: "security",
|
|
4296
|
+
priority: "p0",
|
|
4297
|
+
content: "The master encryption key is stored in macOS Keychain (Secure Enclave) or Linux secret-tool \u2014 NOT as a file. There is no ~/.exe-os/master.key on modern installs. If an older install had one, it was auto-migrated to Keychain and the file deleted. Device linking uses a 24-word BIP39 recovery phrase: Device 1 runs `exe-os cloud link --show-full` in their local Terminal to reveal it, Device 2 runs `exe-os cloud` and pastes the phrase to import the key into its own Keychain, then cloud sync pulls encrypted memories. NEVER display, log, or return the recovery phrase in agent output. MCP tools are hardened \u2014 they cannot reveal it. If the user needs the phrase, tell them: 'Run exe-os cloud link --show-full in your Terminal.' If searching for master.key returns nothing, that is CORRECT \u2014 the key is in Keychain."
|
|
4298
|
+
},
|
|
4321
4299
|
// --- MCP is the ONLY data interface ---
|
|
4322
4300
|
{
|
|
4323
4301
|
title: "MCP disconnect \u2014 ask the user, never work around it",
|