@askexenow/exe-os 0.8.83 → 0.8.86
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 +746 -595
- package/dist/bin/backfill-responses.js +745 -594
- package/dist/bin/backfill-vectors.js +312 -226
- package/dist/bin/cleanup-stale-review-tasks.js +154 -21
- package/dist/bin/cli.js +14678 -12676
- package/dist/bin/exe-agent-config.js +242 -0
- package/dist/bin/exe-agent.js +100 -91
- package/dist/bin/exe-assign.js +1003 -854
- package/dist/bin/exe-boot.js +1420 -485
- package/dist/bin/exe-call.js +10 -0
- package/dist/bin/exe-cloud.js +29 -6
- package/dist/bin/exe-dispatch.js +572 -271
- package/dist/bin/exe-doctor.js +403 -6
- package/dist/bin/exe-export-behaviors.js +175 -72
- package/dist/bin/exe-forget.js +102 -3
- package/dist/bin/exe-gateway.js +796 -292
- package/dist/bin/exe-healthcheck.js +134 -1
- package/dist/bin/exe-heartbeat.js +172 -36
- package/dist/bin/exe-kill.js +175 -72
- package/dist/bin/exe-launch-agent.js +189 -76
- package/dist/bin/exe-link.js +927 -82
- package/dist/bin/exe-new-employee.js +60 -8
- package/dist/bin/exe-pending-messages.js +151 -19
- package/dist/bin/exe-pending-notifications.js +97 -2
- package/dist/bin/exe-pending-reviews.js +155 -22
- package/dist/bin/exe-rename.js +564 -23
- package/dist/bin/exe-review.js +231 -73
- package/dist/bin/exe-search.js +995 -228
- package/dist/bin/exe-session-cleanup.js +4930 -1664
- package/dist/bin/exe-settings.js +20 -5
- package/dist/bin/exe-start-codex.js +2598 -0
- package/dist/bin/exe-start.sh +15 -3
- package/dist/bin/exe-status.js +154 -21
- package/dist/bin/exe-team.js +97 -2
- package/dist/bin/git-sweep.js +1180 -363
- package/dist/bin/graph-backfill.js +175 -72
- package/dist/bin/graph-export.js +175 -72
- package/dist/bin/install.js +60 -7
- package/dist/bin/list-providers.js +1 -0
- package/dist/bin/scan-tasks.js +1185 -367
- package/dist/bin/setup.js +914 -270
- package/dist/bin/shard-migrate.js +175 -72
- package/dist/bin/update.js +1 -0
- package/dist/bin/wiki-sync.js +175 -72
- package/dist/gateway/index.js +792 -285
- package/dist/hooks/bug-report-worker.js +445 -135
- package/dist/hooks/commit-complete.js +1178 -361
- package/dist/hooks/error-recall.js +994 -228
- package/dist/hooks/ingest-worker.js +1799 -1234
- package/dist/hooks/ingest.js +3 -0
- package/dist/hooks/instructions-loaded.js +707 -97
- package/dist/hooks/notification.js +699 -89
- package/dist/hooks/post-compact.js +757 -109
- package/dist/hooks/pre-compact.js +1061 -244
- package/dist/hooks/pre-tool-use.js +787 -130
- package/dist/hooks/prompt-ingest-worker.js +242 -101
- package/dist/hooks/prompt-submit.js +1121 -299
- package/dist/hooks/response-ingest-worker.js +242 -101
- package/dist/hooks/session-end.js +4063 -397
- package/dist/hooks/session-start.js +1071 -254
- package/dist/hooks/stop.js +768 -120
- package/dist/hooks/subagent-stop.js +757 -109
- package/dist/hooks/summary-worker.js +1706 -1011
- package/dist/index.js +1821 -1098
- package/dist/lib/agent-config.js +167 -0
- package/dist/lib/cloud-sync.js +932 -88
- package/dist/lib/consolidation.js +2 -1
- package/dist/lib/database.js +642 -87
- package/dist/lib/db-daemon-client.js +503 -0
- package/dist/lib/device-registry.js +547 -7
- package/dist/lib/embedder.js +14 -28
- package/dist/lib/employee-templates.js +84 -74
- package/dist/lib/employees.js +9 -0
- package/dist/lib/exe-daemon-client.js +16 -29
- package/dist/lib/exe-daemon.js +2733 -1575
- package/dist/lib/hybrid-search.js +995 -228
- package/dist/lib/identity.js +87 -67
- package/dist/lib/keychain.js +9 -1
- package/dist/lib/messaging.js +103 -40
- package/dist/lib/reminders.js +91 -74
- package/dist/lib/runtime-table.js +16 -0
- package/dist/lib/schedules.js +96 -2
- package/dist/lib/session-wrappers.js +22 -0
- package/dist/lib/skill-learning.js +103 -85
- package/dist/lib/store.js +234 -73
- package/dist/lib/tasks.js +348 -134
- package/dist/lib/tmux-routing.js +422 -208
- package/dist/lib/token-spend.js +273 -0
- package/dist/lib/ws-client.js +11 -0
- package/dist/mcp/server.js +5742 -696
- package/dist/mcp/tools/complete-reminder.js +94 -77
- package/dist/mcp/tools/create-reminder.js +94 -77
- package/dist/mcp/tools/create-task.js +375 -152
- package/dist/mcp/tools/deactivate-behavior.js +95 -77
- package/dist/mcp/tools/list-reminders.js +94 -77
- package/dist/mcp/tools/list-tasks.js +99 -31
- package/dist/mcp/tools/send-message.js +108 -45
- package/dist/mcp/tools/update-task.js +162 -77
- package/dist/runtime/index.js +1075 -258
- package/dist/tui/App.js +1333 -506
- package/package.json +6 -1
- package/src/commands/exe/agent-config.md +27 -0
- package/src/commands/exe/cc-doctor.md +10 -0
|
@@ -11,6 +11,7 @@ import { realpathSync } from "fs";
|
|
|
11
11
|
import { fileURLToPath } from "url";
|
|
12
12
|
function isMainModule(importMetaUrl) {
|
|
13
13
|
if (process.argv[1] == null) return false;
|
|
14
|
+
if (process.argv[1].includes("mcp/server")) return false;
|
|
14
15
|
try {
|
|
15
16
|
const scriptPath = realpathSync(process.argv[1]);
|
|
16
17
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
@@ -177,13 +178,144 @@ function checkWorkerSpawning(pkgRoot) {
|
|
|
177
178
|
}
|
|
178
179
|
return results;
|
|
179
180
|
}
|
|
181
|
+
function checkClaudeCodeInstall() {
|
|
182
|
+
const results = [];
|
|
183
|
+
const execPath = process.env.CLAUDE_CODE_EXECPATH ?? "";
|
|
184
|
+
if (execPath.length > 0 && (execPath.includes("claude/versions/") || execPath.includes("claude.exe") || execPath.includes("claude-native"))) {
|
|
185
|
+
results.push({
|
|
186
|
+
name: "cc/execpath-clean",
|
|
187
|
+
pass: false,
|
|
188
|
+
detail: `CLAUDE_CODE_EXECPATH points to native binary: "${execPath}" \u2014 20K phantom billing risk. Unset it: unset CLAUDE_CODE_EXECPATH`
|
|
189
|
+
});
|
|
190
|
+
} else {
|
|
191
|
+
results.push({
|
|
192
|
+
name: "cc/execpath-clean",
|
|
193
|
+
pass: true,
|
|
194
|
+
detail: execPath ? `CLAUDE_CODE_EXECPATH=${execPath} (node runtime, OK)` : "CLAUDE_CODE_EXECPATH is unset"
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
try {
|
|
198
|
+
const claudePath = execSync("which claude 2>/dev/null || true", { encoding: "utf8", timeout: 5e3 }).trim();
|
|
199
|
+
if (!claudePath) {
|
|
200
|
+
results.push({
|
|
201
|
+
name: "cc/cli-binary",
|
|
202
|
+
pass: false,
|
|
203
|
+
detail: "claude not found in PATH"
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
let resolved = claudePath;
|
|
207
|
+
try {
|
|
208
|
+
resolved = execSync(`readlink -f "${claudePath}" 2>/dev/null || readlink "${claudePath}" 2>/dev/null || echo "${claudePath}"`, {
|
|
209
|
+
encoding: "utf8",
|
|
210
|
+
timeout: 5e3
|
|
211
|
+
}).trim();
|
|
212
|
+
} catch {
|
|
213
|
+
}
|
|
214
|
+
if (resolved.includes("bin/claude.exe") || resolved.includes("bin/claude-native")) {
|
|
215
|
+
results.push({
|
|
216
|
+
name: "cc/cli-binary",
|
|
217
|
+
pass: false,
|
|
218
|
+
detail: `claude resolves to native binary: ${resolved}. Should be cli.js. Run: npm install -g @anthropic-ai/claude-code@2.1.98`
|
|
219
|
+
});
|
|
220
|
+
} else {
|
|
221
|
+
results.push({
|
|
222
|
+
name: "cc/cli-binary",
|
|
223
|
+
pass: true,
|
|
224
|
+
detail: `claude resolves to: ${resolved}`
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} catch {
|
|
229
|
+
results.push({
|
|
230
|
+
name: "cc/cli-binary",
|
|
231
|
+
pass: false,
|
|
232
|
+
detail: "Failed to check claude binary path"
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
const versionsDir = path.join(
|
|
236
|
+
process.env.HOME ?? process.env.USERPROFILE ?? "",
|
|
237
|
+
".local",
|
|
238
|
+
"share",
|
|
239
|
+
"claude",
|
|
240
|
+
"versions"
|
|
241
|
+
);
|
|
242
|
+
if (existsSync(versionsDir)) {
|
|
243
|
+
try {
|
|
244
|
+
const entries = readdirSync(versionsDir);
|
|
245
|
+
if (entries.length > 0) {
|
|
246
|
+
results.push({
|
|
247
|
+
name: "cc/native-cache-clean",
|
|
248
|
+
pass: false,
|
|
249
|
+
detail: `${entries.length} cached native version(s) found in ${versionsDir}: ${entries.slice(0, 3).join(", ")}${entries.length > 3 ? "..." : ""}. Remove: rm -rf "${versionsDir}"`
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
results.push({
|
|
253
|
+
name: "cc/native-cache-clean",
|
|
254
|
+
pass: true,
|
|
255
|
+
detail: `${versionsDir} is empty`
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
results.push({
|
|
260
|
+
name: "cc/native-cache-clean",
|
|
261
|
+
pass: true,
|
|
262
|
+
detail: `${versionsDir} not readable (OK)`
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
results.push({
|
|
267
|
+
name: "cc/native-cache-clean",
|
|
268
|
+
pass: true,
|
|
269
|
+
detail: `${versionsDir} does not exist`
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
const disableOld = process.env.DISABLE_AUTOUPDATER === "1";
|
|
273
|
+
const disableNew = process.env.CLAUDE_CODE_AUTOUPDATER_DISABLED === "1";
|
|
274
|
+
if (!disableOld && !disableNew) {
|
|
275
|
+
results.push({
|
|
276
|
+
name: "cc/autoupdater-disabled",
|
|
277
|
+
pass: false,
|
|
278
|
+
detail: "Neither DISABLE_AUTOUPDATER=1 nor CLAUDE_CODE_AUTOUPDATER_DISABLED=1 is set. Auto-updater may install infected native binary. Export both in your shell profile."
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
const which = [
|
|
282
|
+
disableOld ? "DISABLE_AUTOUPDATER=1" : null,
|
|
283
|
+
disableNew ? "CLAUDE_CODE_AUTOUPDATER_DISABLED=1" : null
|
|
284
|
+
].filter(Boolean).join(" + ");
|
|
285
|
+
results.push({
|
|
286
|
+
name: "cc/autoupdater-disabled",
|
|
287
|
+
pass: true,
|
|
288
|
+
detail: `Auto-updater disabled via ${which}`
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const ccVersion = execSync("claude --version 2>/dev/null || echo unknown", {
|
|
293
|
+
encoding: "utf8",
|
|
294
|
+
timeout: 5e3
|
|
295
|
+
}).trim();
|
|
296
|
+
const versionMatch = ccVersion.match(/(\d+\.\d+\.\d+)/);
|
|
297
|
+
if (versionMatch) {
|
|
298
|
+
const ver = versionMatch[1];
|
|
299
|
+
const [, minor] = ver.split(".").map(Number);
|
|
300
|
+
const isRisky = minor !== void 0 && minor >= 1 && parseInt(ver.split(".")[2] ?? "0") >= 119;
|
|
301
|
+
results.push({
|
|
302
|
+
name: "cc/version",
|
|
303
|
+
pass: !isRisky,
|
|
304
|
+
detail: isRisky ? `CC version ${ver} \u2014 \u22652.1.119 ships native binary only. Pin: npm install -g @anthropic-ai/claude-code@2.1.98` : `CC version ${ver}`
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
} catch {
|
|
308
|
+
}
|
|
309
|
+
return results;
|
|
310
|
+
}
|
|
180
311
|
function runHealthCheck() {
|
|
181
312
|
const pkgRoot = findPackageRoot();
|
|
182
313
|
const results = [
|
|
183
314
|
...checkBuildIntegrity(pkgRoot),
|
|
184
315
|
...checkEmbedPipeline(pkgRoot),
|
|
185
316
|
...checkTaskSystem(pkgRoot),
|
|
186
|
-
...checkWorkerSpawning(pkgRoot)
|
|
317
|
+
...checkWorkerSpawning(pkgRoot),
|
|
318
|
+
...checkClaudeCodeInstall()
|
|
187
319
|
];
|
|
188
320
|
const passed = results.filter((r) => r.pass).length;
|
|
189
321
|
const failed = results.filter((r) => !r.pass).length;
|
|
@@ -203,5 +335,6 @@ if (isMainModule(import.meta.url)) {
|
|
|
203
335
|
process.exit(failed > 0 ? 1 : 0);
|
|
204
336
|
}
|
|
205
337
|
export {
|
|
338
|
+
checkClaudeCodeInstall,
|
|
206
339
|
runHealthCheck
|
|
207
340
|
};
|
|
@@ -335,6 +335,12 @@ function getClient() {
|
|
|
335
335
|
if (!_resilientClient) {
|
|
336
336
|
throw new Error("Database client not initialized. Call initDatabase() first.");
|
|
337
337
|
}
|
|
338
|
+
if (process.env.EXE_IS_DAEMON === "1") {
|
|
339
|
+
return _resilientClient;
|
|
340
|
+
}
|
|
341
|
+
if (_daemonClient && _daemonClient._isDaemonActive()) {
|
|
342
|
+
return _daemonClient;
|
|
343
|
+
}
|
|
338
344
|
return _resilientClient;
|
|
339
345
|
}
|
|
340
346
|
function getRawClient() {
|
|
@@ -823,6 +829,12 @@ async function ensureSchema() {
|
|
|
823
829
|
} catch {
|
|
824
830
|
}
|
|
825
831
|
}
|
|
832
|
+
try {
|
|
833
|
+
await client.execute(
|
|
834
|
+
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
835
|
+
);
|
|
836
|
+
} catch {
|
|
837
|
+
}
|
|
826
838
|
await client.executeMultiple(`
|
|
827
839
|
CREATE TABLE IF NOT EXISTS entities (
|
|
828
840
|
id TEXT PRIMARY KEY,
|
|
@@ -875,7 +887,30 @@ async function ensureSchema() {
|
|
|
875
887
|
entity_id TEXT NOT NULL,
|
|
876
888
|
PRIMARY KEY (hyperedge_id, entity_id)
|
|
877
889
|
);
|
|
890
|
+
|
|
891
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(
|
|
892
|
+
name,
|
|
893
|
+
content=entities,
|
|
894
|
+
content_rowid=rowid
|
|
895
|
+
);
|
|
896
|
+
|
|
897
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_ai AFTER INSERT ON entities BEGIN
|
|
898
|
+
INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
|
|
899
|
+
END;
|
|
900
|
+
|
|
901
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_ad AFTER DELETE ON entities BEGIN
|
|
902
|
+
INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
|
|
903
|
+
END;
|
|
904
|
+
|
|
905
|
+
CREATE TRIGGER IF NOT EXISTS entities_fts_au AFTER UPDATE ON entities BEGIN
|
|
906
|
+
INSERT INTO entities_fts(entities_fts, rowid, name) VALUES('delete', old.rowid, old.name);
|
|
907
|
+
INSERT INTO entities_fts(rowid, name) VALUES (new.rowid, new.name);
|
|
908
|
+
END;
|
|
878
909
|
`);
|
|
910
|
+
try {
|
|
911
|
+
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
912
|
+
} catch {
|
|
913
|
+
}
|
|
879
914
|
await client.executeMultiple(`
|
|
880
915
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
881
916
|
alias TEXT NOT NULL PRIMARY KEY,
|
|
@@ -1056,6 +1091,33 @@ async function ensureSchema() {
|
|
|
1056
1091
|
CREATE INDEX IF NOT EXISTS idx_conversations_channel
|
|
1057
1092
|
ON conversations(channel_id);
|
|
1058
1093
|
`);
|
|
1094
|
+
await client.executeMultiple(`
|
|
1095
|
+
CREATE TABLE IF NOT EXISTS session_agent_map (
|
|
1096
|
+
session_uuid TEXT PRIMARY KEY,
|
|
1097
|
+
agent_id TEXT NOT NULL,
|
|
1098
|
+
session_name TEXT,
|
|
1099
|
+
task_id TEXT,
|
|
1100
|
+
project_name TEXT,
|
|
1101
|
+
started_at TEXT NOT NULL
|
|
1102
|
+
);
|
|
1103
|
+
|
|
1104
|
+
CREATE INDEX IF NOT EXISTS idx_session_agent_map_agent
|
|
1105
|
+
ON session_agent_map(agent_id);
|
|
1106
|
+
`);
|
|
1107
|
+
try {
|
|
1108
|
+
const mapCount = await client.execute({ sql: `SELECT COUNT(*) as cnt FROM session_agent_map`, args: [] });
|
|
1109
|
+
if (Number(mapCount.rows[0]?.cnt ?? 0) === 0) {
|
|
1110
|
+
await client.execute({
|
|
1111
|
+
sql: `INSERT OR IGNORE INTO session_agent_map (session_uuid, agent_id, session_name, started_at)
|
|
1112
|
+
SELECT session_id, agent_id, '', MIN(timestamp)
|
|
1113
|
+
FROM memories
|
|
1114
|
+
WHERE session_id IS NOT NULL AND session_id != '' AND agent_id IS NOT NULL AND agent_id != ''
|
|
1115
|
+
GROUP BY session_id, agent_id`,
|
|
1116
|
+
args: []
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
} catch {
|
|
1120
|
+
}
|
|
1059
1121
|
try {
|
|
1060
1122
|
await client.execute({
|
|
1061
1123
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
@@ -1189,8 +1251,30 @@ async function ensureSchema() {
|
|
|
1189
1251
|
});
|
|
1190
1252
|
} catch {
|
|
1191
1253
|
}
|
|
1254
|
+
for (const col of [
|
|
1255
|
+
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
1256
|
+
"ALTER TABLE memories ADD COLUMN outcome TEXT",
|
|
1257
|
+
"ALTER TABLE memories ADD COLUMN domain TEXT",
|
|
1258
|
+
"ALTER TABLE memories ADD COLUMN referenced_entities TEXT",
|
|
1259
|
+
"ALTER TABLE memories ADD COLUMN retrieval_count INTEGER DEFAULT 0",
|
|
1260
|
+
"ALTER TABLE memories ADD COLUMN chain_position TEXT",
|
|
1261
|
+
"ALTER TABLE memories ADD COLUMN review_status TEXT",
|
|
1262
|
+
"ALTER TABLE memories ADD COLUMN context_window_pct INTEGER",
|
|
1263
|
+
"ALTER TABLE memories ADD COLUMN file_paths TEXT",
|
|
1264
|
+
"ALTER TABLE memories ADD COLUMN commit_hash TEXT",
|
|
1265
|
+
"ALTER TABLE memories ADD COLUMN duration_ms INTEGER",
|
|
1266
|
+
"ALTER TABLE memories ADD COLUMN token_cost REAL",
|
|
1267
|
+
"ALTER TABLE memories ADD COLUMN audience TEXT",
|
|
1268
|
+
"ALTER TABLE memories ADD COLUMN language_type TEXT",
|
|
1269
|
+
"ALTER TABLE memories ADD COLUMN parent_memory_id TEXT"
|
|
1270
|
+
]) {
|
|
1271
|
+
try {
|
|
1272
|
+
await client.execute(col);
|
|
1273
|
+
} catch {
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1192
1276
|
}
|
|
1193
|
-
var _client, _resilientClient, initTurso;
|
|
1277
|
+
var _client, _resilientClient, _daemonClient, initTurso;
|
|
1194
1278
|
var init_database = __esm({
|
|
1195
1279
|
"src/lib/database.ts"() {
|
|
1196
1280
|
"use strict";
|
|
@@ -1198,6 +1282,7 @@ var init_database = __esm({
|
|
|
1198
1282
|
init_employees();
|
|
1199
1283
|
_client = null;
|
|
1200
1284
|
_resilientClient = null;
|
|
1285
|
+
_daemonClient = null;
|
|
1201
1286
|
initTurso = initDatabase;
|
|
1202
1287
|
}
|
|
1203
1288
|
});
|
|
@@ -1883,39 +1968,75 @@ var init_provider_table = __esm({
|
|
|
1883
1968
|
}
|
|
1884
1969
|
});
|
|
1885
1970
|
|
|
1886
|
-
// src/lib/
|
|
1887
|
-
|
|
1971
|
+
// src/lib/runtime-table.ts
|
|
1972
|
+
var RUNTIME_TABLE;
|
|
1973
|
+
var init_runtime_table = __esm({
|
|
1974
|
+
"src/lib/runtime-table.ts"() {
|
|
1975
|
+
"use strict";
|
|
1976
|
+
RUNTIME_TABLE = {
|
|
1977
|
+
codex: {
|
|
1978
|
+
binary: "codex",
|
|
1979
|
+
launchMode: "exec",
|
|
1980
|
+
autoApproveFlag: "--full-auto",
|
|
1981
|
+
inlineFlag: "--no-alt-screen",
|
|
1982
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
1983
|
+
defaultModel: "gpt-5.4"
|
|
1984
|
+
}
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
|
|
1989
|
+
// src/lib/agent-config.ts
|
|
1990
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync2 } from "fs";
|
|
1888
1991
|
import path7 from "path";
|
|
1992
|
+
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
1993
|
+
var init_agent_config = __esm({
|
|
1994
|
+
"src/lib/agent-config.ts"() {
|
|
1995
|
+
"use strict";
|
|
1996
|
+
init_config();
|
|
1997
|
+
init_runtime_table();
|
|
1998
|
+
AGENT_CONFIG_PATH = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
1999
|
+
DEFAULT_MODELS = {
|
|
2000
|
+
claude: "claude-opus-4",
|
|
2001
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
2002
|
+
opencode: "minimax-m2.7"
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
});
|
|
2006
|
+
|
|
2007
|
+
// src/lib/intercom-queue.ts
|
|
2008
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync7, mkdirSync as mkdirSync3 } from "fs";
|
|
2009
|
+
import path8 from "path";
|
|
1889
2010
|
import os6 from "os";
|
|
1890
2011
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
1891
2012
|
var init_intercom_queue = __esm({
|
|
1892
2013
|
"src/lib/intercom-queue.ts"() {
|
|
1893
2014
|
"use strict";
|
|
1894
|
-
QUEUE_PATH =
|
|
2015
|
+
QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
1895
2016
|
TTL_MS = 60 * 60 * 1e3;
|
|
1896
|
-
INTERCOM_LOG =
|
|
2017
|
+
INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
1897
2018
|
}
|
|
1898
2019
|
});
|
|
1899
2020
|
|
|
1900
2021
|
// src/lib/license.ts
|
|
1901
|
-
import { readFileSync as
|
|
2022
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
1902
2023
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1903
|
-
import
|
|
2024
|
+
import path9 from "path";
|
|
1904
2025
|
import { jwtVerify, importSPKI } from "jose";
|
|
1905
2026
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
1906
2027
|
var init_license = __esm({
|
|
1907
2028
|
"src/lib/license.ts"() {
|
|
1908
2029
|
"use strict";
|
|
1909
2030
|
init_config();
|
|
1910
|
-
LICENSE_PATH =
|
|
1911
|
-
CACHE_PATH =
|
|
1912
|
-
DEVICE_ID_PATH =
|
|
2031
|
+
LICENSE_PATH = path9.join(EXE_AI_DIR, "license.key");
|
|
2032
|
+
CACHE_PATH = path9.join(EXE_AI_DIR, "license-cache.json");
|
|
2033
|
+
DEVICE_ID_PATH = path9.join(EXE_AI_DIR, "device-id");
|
|
1913
2034
|
}
|
|
1914
2035
|
});
|
|
1915
2036
|
|
|
1916
2037
|
// src/lib/plan-limits.ts
|
|
1917
|
-
import { readFileSync as
|
|
1918
|
-
import
|
|
2038
|
+
import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
|
|
2039
|
+
import path10 from "path";
|
|
1919
2040
|
var CACHE_PATH2;
|
|
1920
2041
|
var init_plan_limits = __esm({
|
|
1921
2042
|
"src/lib/plan-limits.ts"() {
|
|
@@ -1924,13 +2045,13 @@ var init_plan_limits = __esm({
|
|
|
1924
2045
|
init_employees();
|
|
1925
2046
|
init_license();
|
|
1926
2047
|
init_config();
|
|
1927
|
-
CACHE_PATH2 =
|
|
2048
|
+
CACHE_PATH2 = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
1928
2049
|
}
|
|
1929
2050
|
});
|
|
1930
2051
|
|
|
1931
2052
|
// src/lib/tmux-routing.ts
|
|
1932
|
-
import { readFileSync as
|
|
1933
|
-
import
|
|
2053
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
|
|
2054
|
+
import path11 from "path";
|
|
1934
2055
|
import os7 from "os";
|
|
1935
2056
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1936
2057
|
function getMySession() {
|
|
@@ -1944,7 +2065,7 @@ function extractRootExe(name) {
|
|
|
1944
2065
|
}
|
|
1945
2066
|
function getParentExe(sessionKey) {
|
|
1946
2067
|
try {
|
|
1947
|
-
const data = JSON.parse(
|
|
2068
|
+
const data = JSON.parse(readFileSync8(path11.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
1948
2069
|
return data.parentExe || null;
|
|
1949
2070
|
} catch {
|
|
1950
2071
|
return null;
|
|
@@ -1978,27 +2099,29 @@ var init_tmux_routing = __esm({
|
|
|
1978
2099
|
init_cc_agent_support();
|
|
1979
2100
|
init_mcp_prefix();
|
|
1980
2101
|
init_provider_table();
|
|
2102
|
+
init_agent_config();
|
|
2103
|
+
init_runtime_table();
|
|
1981
2104
|
init_intercom_queue();
|
|
1982
2105
|
init_plan_limits();
|
|
1983
2106
|
init_employees();
|
|
1984
|
-
SPAWN_LOCK_DIR =
|
|
1985
|
-
SESSION_CACHE =
|
|
1986
|
-
INTERCOM_LOG2 =
|
|
1987
|
-
DEBOUNCE_FILE =
|
|
2107
|
+
SPAWN_LOCK_DIR = path11.join(os7.homedir(), ".exe-os", "spawn-locks");
|
|
2108
|
+
SESSION_CACHE = path11.join(os7.homedir(), ".exe-os", "session-cache");
|
|
2109
|
+
INTERCOM_LOG2 = path11.join(os7.homedir(), ".exe-os", "intercom.log");
|
|
2110
|
+
DEBOUNCE_FILE = path11.join(SESSION_CACHE, "intercom-debounce.json");
|
|
1988
2111
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
1989
2112
|
}
|
|
1990
2113
|
});
|
|
1991
2114
|
|
|
1992
2115
|
// src/lib/tasks-review.ts
|
|
1993
|
-
import
|
|
1994
|
-
import { existsSync as
|
|
2116
|
+
import path12 from "path";
|
|
2117
|
+
import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
|
|
1995
2118
|
async function listPendingReviews(limit, sessionScope) {
|
|
1996
2119
|
const client = getClient();
|
|
1997
2120
|
if (sessionScope) {
|
|
1998
2121
|
const result2 = await client.execute({
|
|
1999
2122
|
sql: `SELECT title, assigned_to, project_name FROM tasks
|
|
2000
2123
|
WHERE status = 'needs_review'
|
|
2001
|
-
AND
|
|
2124
|
+
AND session_scope = ?
|
|
2002
2125
|
ORDER BY priority ASC, created_at DESC LIMIT ?`,
|
|
2003
2126
|
args: [sessionScope, limit]
|
|
2004
2127
|
});
|
|
@@ -2050,12 +2173,13 @@ var init_task_scope = __esm({
|
|
|
2050
2173
|
});
|
|
2051
2174
|
|
|
2052
2175
|
// src/bin/exe-heartbeat.ts
|
|
2053
|
-
import { createHash } from "crypto";
|
|
2054
|
-
import { readFileSync as
|
|
2176
|
+
import { createHash as createHash2 } from "crypto";
|
|
2177
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
|
|
2055
2178
|
import os8 from "os";
|
|
2056
|
-
import
|
|
2179
|
+
import path13 from "path";
|
|
2057
2180
|
|
|
2058
2181
|
// src/lib/store.ts
|
|
2182
|
+
import { createHash } from "crypto";
|
|
2059
2183
|
init_database();
|
|
2060
2184
|
|
|
2061
2185
|
// src/lib/keychain.ts
|
|
@@ -2091,12 +2215,20 @@ async function getMasterKey() {
|
|
|
2091
2215
|
}
|
|
2092
2216
|
const keyPath = getKeyPath();
|
|
2093
2217
|
if (!existsSync3(keyPath)) {
|
|
2218
|
+
process.stderr.write(
|
|
2219
|
+
`[keychain] Key not found at ${keyPath} (HOME=${os3.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
2220
|
+
`
|
|
2221
|
+
);
|
|
2094
2222
|
return null;
|
|
2095
2223
|
}
|
|
2096
2224
|
try {
|
|
2097
2225
|
const content = await readFile3(keyPath, "utf-8");
|
|
2098
2226
|
return Buffer.from(content.trim(), "base64");
|
|
2099
|
-
} catch {
|
|
2227
|
+
} catch (err) {
|
|
2228
|
+
process.stderr.write(
|
|
2229
|
+
`[keychain] Key read failed at ${keyPath}: ${err instanceof Error ? err.message : String(err)}
|
|
2230
|
+
`
|
|
2231
|
+
);
|
|
2100
2232
|
return null;
|
|
2101
2233
|
}
|
|
2102
2234
|
}
|
|
@@ -2189,6 +2321,7 @@ import { realpathSync } from "fs";
|
|
|
2189
2321
|
import { fileURLToPath } from "url";
|
|
2190
2322
|
function isMainModule(importMetaUrl) {
|
|
2191
2323
|
if (process.argv[1] == null) return false;
|
|
2324
|
+
if (process.argv[1].includes("mcp/server")) return false;
|
|
2192
2325
|
try {
|
|
2193
2326
|
const scriptPath = realpathSync(process.argv[1]);
|
|
2194
2327
|
const modulePath = realpathSync(fileURLToPath(importMetaUrl));
|
|
@@ -2214,18 +2347,18 @@ var MESSAGE_PREVIEW_CHARS = 80;
|
|
|
2214
2347
|
var MARKER_FILENAME = "exe-heartbeat-marker.json";
|
|
2215
2348
|
var SESSION_CACHE_SUBDIR = "session-cache";
|
|
2216
2349
|
function resolveExeOsDir() {
|
|
2217
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
2350
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path13.join(os8.homedir(), ".exe-os");
|
|
2218
2351
|
}
|
|
2219
2352
|
function getMarkerDir() {
|
|
2220
|
-
return
|
|
2353
|
+
return path13.join(resolveExeOsDir(), SESSION_CACHE_SUBDIR);
|
|
2221
2354
|
}
|
|
2222
2355
|
function getMarkerPath() {
|
|
2223
|
-
return
|
|
2356
|
+
return path13.join(getMarkerDir(), MARKER_FILENAME);
|
|
2224
2357
|
}
|
|
2225
2358
|
var UNREAD_MESSAGE_STATUSES = ["pending", "delivered"];
|
|
2226
2359
|
function readMarker() {
|
|
2227
2360
|
try {
|
|
2228
|
-
const raw =
|
|
2361
|
+
const raw = readFileSync9(getMarkerPath(), "utf8");
|
|
2229
2362
|
const parsed = JSON.parse(raw);
|
|
2230
2363
|
if (typeof parsed.lastFiredAt !== "string" || typeof parsed.lastSurfaceHash !== "string") {
|
|
2231
2364
|
return null;
|
|
@@ -2237,13 +2370,13 @@ function readMarker() {
|
|
|
2237
2370
|
}
|
|
2238
2371
|
function writeMarker(marker) {
|
|
2239
2372
|
try {
|
|
2240
|
-
|
|
2241
|
-
|
|
2373
|
+
mkdirSync6(getMarkerDir(), { recursive: true });
|
|
2374
|
+
writeFileSync6(getMarkerPath(), JSON.stringify(marker));
|
|
2242
2375
|
} catch {
|
|
2243
2376
|
}
|
|
2244
2377
|
}
|
|
2245
2378
|
function hashOutput(text) {
|
|
2246
|
-
return
|
|
2379
|
+
return createHash2("sha256").update(text).digest("hex");
|
|
2247
2380
|
}
|
|
2248
2381
|
async function queryPendingReviews() {
|
|
2249
2382
|
let sessionScope;
|
|
@@ -2309,10 +2442,13 @@ async function queryStaleInProgress(thresholdHours) {
|
|
|
2309
2442
|
}
|
|
2310
2443
|
async function queryNewErrors(sinceIso) {
|
|
2311
2444
|
const client = getClient();
|
|
2445
|
+
const erScope = sessionScopeFilter();
|
|
2312
2446
|
const result = await client.execute({
|
|
2313
|
-
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
2447
|
+
sql: erScope.args.length > 0 ? `SELECT COUNT(*) as cnt FROM memories
|
|
2448
|
+
WHERE has_error = 1 AND timestamp > ?
|
|
2449
|
+
AND agent_id IN (SELECT DISTINCT assigned_to FROM tasks WHERE 1=1${erScope.sql})` : `SELECT COUNT(*) as cnt FROM memories
|
|
2314
2450
|
WHERE has_error = 1 AND timestamp > ?`,
|
|
2315
|
-
args: [sinceIso]
|
|
2451
|
+
args: erScope.args.length > 0 ? [sinceIso, ...erScope.args] : [sinceIso]
|
|
2316
2452
|
});
|
|
2317
2453
|
const count = Number(result.rows[0]?.cnt ?? 0);
|
|
2318
2454
|
if (count === 0) return "";
|