@askexenow/exe-os 0.9.113 → 0.9.115
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 +36 -12
- package/dist/bin/agentic-reflection-backfill.js +36 -12
- package/dist/bin/agentic-semantic-label.js +36 -12
- package/dist/bin/backfill-conversations.js +36 -12
- package/dist/bin/backfill-responses.js +36 -12
- package/dist/bin/backfill-vectors.js +36 -12
- package/dist/bin/bulk-sync-postgres.js +36 -12
- package/dist/bin/cleanup-stale-review-tasks.js +470 -113
- package/dist/bin/cli.js +413 -62
- package/dist/bin/exe-agent.js +27 -0
- package/dist/bin/exe-assign.js +36 -12
- package/dist/bin/exe-boot.js +246 -54
- package/dist/bin/exe-call.js +8 -0
- package/dist/bin/exe-cloud.js +47 -12
- package/dist/bin/exe-dispatch.js +348 -53
- package/dist/bin/exe-doctor.js +51 -13
- package/dist/bin/exe-export-behaviors.js +37 -12
- package/dist/bin/exe-forget.js +36 -12
- package/dist/bin/exe-gateway.js +348 -53
- package/dist/bin/exe-heartbeat.js +471 -113
- package/dist/bin/exe-kill.js +36 -12
- package/dist/bin/exe-launch-agent.js +117 -18
- package/dist/bin/exe-new-employee.js +9 -1
- package/dist/bin/exe-pending-messages.js +452 -95
- package/dist/bin/exe-pending-notifications.js +452 -95
- package/dist/bin/exe-pending-reviews.js +452 -95
- package/dist/bin/exe-rename.js +36 -12
- package/dist/bin/exe-review.js +36 -12
- package/dist/bin/exe-search.js +37 -12
- package/dist/bin/exe-session-cleanup.js +348 -53
- package/dist/bin/exe-settings.js +12 -0
- package/dist/bin/exe-start-codex.js +46 -13
- package/dist/bin/exe-start-opencode.js +46 -13
- package/dist/bin/exe-status.js +460 -114
- package/dist/bin/exe-support.js +12 -0
- package/dist/bin/exe-team.js +36 -12
- package/dist/bin/git-sweep.js +348 -53
- package/dist/bin/graph-backfill.js +36 -12
- package/dist/bin/graph-export.js +36 -12
- package/dist/bin/install.js +9 -1
- package/dist/bin/intercom-check.js +255 -53
- package/dist/bin/scan-tasks.js +348 -53
- package/dist/bin/setup.js +74 -12
- package/dist/bin/shard-migrate.js +36 -12
- package/dist/gateway/index.js +348 -53
- package/dist/hooks/bug-report-worker.js +348 -53
- package/dist/hooks/codex-stop-task-finalizer.js +308 -37
- package/dist/hooks/commit-complete.js +348 -53
- package/dist/hooks/error-recall.js +37 -12
- package/dist/hooks/ingest.js +363 -54
- package/dist/hooks/instructions-loaded.js +36 -12
- package/dist/hooks/notification.js +36 -12
- package/dist/hooks/post-compact.js +426 -72
- package/dist/hooks/post-tool-combined.js +501 -146
- package/dist/hooks/pre-compact.js +348 -53
- package/dist/hooks/pre-tool-use.js +92 -13
- package/dist/hooks/prompt-submit.js +348 -53
- package/dist/hooks/session-end.js +158 -53
- package/dist/hooks/session-start.js +66 -13
- package/dist/hooks/stop.js +420 -72
- package/dist/hooks/subagent-stop.js +419 -72
- package/dist/hooks/summary-worker.js +442 -121
- package/dist/index.js +375 -53
- package/dist/lib/agent-config.js +8 -0
- package/dist/lib/cloud-sync.js +35 -12
- package/dist/lib/config.js +13 -0
- package/dist/lib/consolidation.js +9 -1
- package/dist/lib/embedder.js +13 -0
- package/dist/lib/employees.js +8 -0
- package/dist/lib/exe-daemon.js +524 -60
- package/dist/lib/hybrid-search.js +37 -12
- package/dist/lib/keychain.js +25 -13
- package/dist/lib/messaging.js +395 -74
- package/dist/lib/schedules.js +36 -12
- package/dist/lib/skill-learning.js +21 -0
- package/dist/lib/store.js +36 -12
- package/dist/lib/tasks.js +324 -41
- package/dist/lib/tmux-routing.js +324 -41
- package/dist/mcp/server.js +374 -54
- package/dist/mcp/tools/create-task.js +324 -41
- package/dist/mcp/tools/list-tasks.js +406 -57
- package/dist/mcp/tools/send-message.js +395 -74
- package/dist/mcp/tools/update-task.js +324 -41
- package/dist/runtime/index.js +375 -53
- package/dist/tui/App.js +377 -55
- package/package.json +1 -1
|
@@ -139,6 +139,17 @@ function normalizeOrchestration(raw) {
|
|
|
139
139
|
const userOrg = raw.orchestration ?? {};
|
|
140
140
|
raw.orchestration = { ...defaultOrg, ...userOrg };
|
|
141
141
|
}
|
|
142
|
+
function normalizeCloudEndpoint(raw) {
|
|
143
|
+
const cloud = raw.cloud;
|
|
144
|
+
if (!cloud?.endpoint) return;
|
|
145
|
+
const ep = String(cloud.endpoint);
|
|
146
|
+
if (ep === "https://askexe.com/cloud" || ep === "https://askexe.com/cloud/") {
|
|
147
|
+
cloud.endpoint = "https://cloud.askexe.com";
|
|
148
|
+
process.stderr.write(
|
|
149
|
+
"[config] Auto-migrated cloud endpoint: askexe.com/cloud \u2192 cloud.askexe.com\n"
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
142
153
|
async function loadConfig() {
|
|
143
154
|
const dir = process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? EXE_AI_DIR;
|
|
144
155
|
await ensurePrivateDir(dir);
|
|
@@ -164,6 +175,7 @@ async function loadConfig() {
|
|
|
164
175
|
normalizeSessionLifecycle(migratedCfg);
|
|
165
176
|
normalizeAutoUpdate(migratedCfg);
|
|
166
177
|
normalizeOrchestration(migratedCfg);
|
|
178
|
+
normalizeCloudEndpoint(migratedCfg);
|
|
167
179
|
const config = { ...DEFAULT_CONFIG, dbPath: path.join(dir, "memories.db"), ...migratedCfg };
|
|
168
180
|
if (config.dbPath.startsWith("~")) {
|
|
169
181
|
config.dbPath = config.dbPath.replace(/^~/, os.homedir());
|
|
@@ -370,6 +382,7 @@ __export(agent_config_exports, {
|
|
|
370
382
|
clearAgentRuntime: () => clearAgentRuntime,
|
|
371
383
|
getAgentRuntime: () => getAgentRuntime,
|
|
372
384
|
loadAgentConfig: () => loadAgentConfig,
|
|
385
|
+
normalizeCcModelName: () => normalizeCcModelName,
|
|
373
386
|
saveAgentConfig: () => saveAgentConfig,
|
|
374
387
|
setAgentMcps: () => setAgentMcps,
|
|
375
388
|
setAgentRuntime: () => setAgentRuntime
|
|
@@ -398,6 +411,13 @@ function getAgentRuntime(agentId) {
|
|
|
398
411
|
if (orgDefault) return orgDefault;
|
|
399
412
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
400
413
|
}
|
|
414
|
+
function normalizeCcModelName(model) {
|
|
415
|
+
let ccModel = model.replace(/(\d+)\.(\d+)/g, "$1-$2");
|
|
416
|
+
if (/claude-(opus|sonnet)-4-[6-9]/.test(ccModel) && !ccModel.includes("[1m]")) {
|
|
417
|
+
ccModel += "[1m]";
|
|
418
|
+
}
|
|
419
|
+
return ccModel;
|
|
420
|
+
}
|
|
401
421
|
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
402
422
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
403
423
|
if (!knownModels) {
|
|
@@ -3980,6 +4000,21 @@ function isRootSession(name) {
|
|
|
3980
4000
|
function extractRootExe(name) {
|
|
3981
4001
|
if (!name) return null;
|
|
3982
4002
|
if (!name.includes("-")) return name;
|
|
4003
|
+
try {
|
|
4004
|
+
const roster = (init_employees(), __toCommonJS(employees_exports)).loadEmployeesSync();
|
|
4005
|
+
if (roster.length > 0) {
|
|
4006
|
+
const sortedNames = roster.map((e) => e.name).sort((a, b) => b.length - a.length);
|
|
4007
|
+
for (const agentName of sortedNames) {
|
|
4008
|
+
const escaped = agentName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4009
|
+
const regex = new RegExp(`^${escaped}\\d*-(.+)$`);
|
|
4010
|
+
const match = name.match(regex);
|
|
4011
|
+
if (match) {
|
|
4012
|
+
return extractRootExe(match[1]);
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
} catch {
|
|
4017
|
+
}
|
|
3983
4018
|
const parts = name.split("-").filter(Boolean);
|
|
3984
4019
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
3985
4020
|
}
|
|
@@ -3998,6 +4033,10 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
3998
4033
|
function getParentExe(sessionKey) {
|
|
3999
4034
|
try {
|
|
4000
4035
|
const data = JSON.parse(readFileSync10(path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
4036
|
+
if (data.registeredAt) {
|
|
4037
|
+
const age = Date.now() - new Date(data.registeredAt).getTime();
|
|
4038
|
+
if (age > PARENT_EXE_CACHE_TTL_MS) return null;
|
|
4039
|
+
}
|
|
4001
4040
|
return data.parentExe || null;
|
|
4002
4041
|
} catch {
|
|
4003
4042
|
return null;
|
|
@@ -4070,7 +4109,7 @@ function resolveExeSession() {
|
|
|
4070
4109
|
}
|
|
4071
4110
|
return candidate;
|
|
4072
4111
|
}
|
|
4073
|
-
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
4112
|
+
var SPAWN_LOCK_DIR, SESSION_CACHE, PARENT_EXE_CACHE_TTL_MS, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
4074
4113
|
var init_tmux_routing = __esm({
|
|
4075
4114
|
"src/lib/tmux-routing.ts"() {
|
|
4076
4115
|
"use strict";
|
|
@@ -4088,6 +4127,7 @@ var init_tmux_routing = __esm({
|
|
|
4088
4127
|
init_agent_symlinks();
|
|
4089
4128
|
SPAWN_LOCK_DIR = path13.join(os9.homedir(), ".exe-os", "spawn-locks");
|
|
4090
4129
|
SESSION_CACHE = path13.join(os9.homedir(), ".exe-os", "session-cache");
|
|
4130
|
+
PARENT_EXE_CACHE_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
4091
4131
|
INTERCOM_LOG2 = path13.join(os9.homedir(), ".exe-os", "intercom.log");
|
|
4092
4132
|
DEBOUNCE_FILE = path13.join(SESSION_CACHE, "intercom-debounce.json");
|
|
4093
4133
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
@@ -4303,7 +4343,7 @@ var init_cto_delegation_gate = __esm({
|
|
|
4303
4343
|
});
|
|
4304
4344
|
|
|
4305
4345
|
// src/lib/keychain.ts
|
|
4306
|
-
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
4346
|
+
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2, rename, copyFile } from "fs/promises";
|
|
4307
4347
|
import { existsSync as existsSync14, statSync as statSync4 } from "fs";
|
|
4308
4348
|
import { execSync as execSync6 } from "child_process";
|
|
4309
4349
|
import path15 from "path";
|
|
@@ -4338,12 +4378,14 @@ function linuxSecretAvailable() {
|
|
|
4338
4378
|
function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
4339
4379
|
if (process.platform !== "linux") return false;
|
|
4340
4380
|
try {
|
|
4341
|
-
const uid = typeof os11.userInfo().uid === "number" ? os11.userInfo().uid : -1;
|
|
4342
4381
|
const st = statSync4(keyPath);
|
|
4343
4382
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
4383
|
+
const uid = typeof os11.userInfo().uid === "number" ? os11.userInfo().uid : -1;
|
|
4344
4384
|
if (uid === 0) return true;
|
|
4345
4385
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
4346
|
-
|
|
4386
|
+
if (exeOsDir && path15.resolve(keyPath).startsWith(path15.resolve(exeOsDir) + path15.sep)) return true;
|
|
4387
|
+
if (!linuxSecretAvailable()) return true;
|
|
4388
|
+
return false;
|
|
4347
4389
|
} catch {
|
|
4348
4390
|
return false;
|
|
4349
4391
|
}
|
|
@@ -4493,15 +4535,25 @@ async function writeMachineBoundFileFallback(b64) {
|
|
|
4493
4535
|
await mkdir3(dir, { recursive: true });
|
|
4494
4536
|
const keyPath = getKeyPath();
|
|
4495
4537
|
const machineKey = deriveMachineKey();
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4538
|
+
const content = machineKey ? encryptWithMachineKey(b64, machineKey) + "\n" : b64 + "\n";
|
|
4539
|
+
const result = machineKey ? "encrypted" : "plaintext";
|
|
4540
|
+
const tmpPath = keyPath + ".tmp";
|
|
4541
|
+
try {
|
|
4542
|
+
if (existsSync14(keyPath)) {
|
|
4543
|
+
await copyFile(keyPath, keyPath + ".bak").catch(() => {
|
|
4544
|
+
});
|
|
4545
|
+
}
|
|
4546
|
+
await writeFile3(tmpPath, content, "utf-8");
|
|
4547
|
+
await chmod2(tmpPath, 384);
|
|
4548
|
+
await rename(tmpPath, keyPath);
|
|
4549
|
+
} catch (err) {
|
|
4550
|
+
try {
|
|
4551
|
+
await unlink(tmpPath);
|
|
4552
|
+
} catch {
|
|
4553
|
+
}
|
|
4554
|
+
throw err;
|
|
4501
4555
|
}
|
|
4502
|
-
|
|
4503
|
-
await chmod2(keyPath, 384);
|
|
4504
|
-
return "plaintext";
|
|
4556
|
+
return result;
|
|
4505
4557
|
}
|
|
4506
4558
|
async function getMasterKey() {
|
|
4507
4559
|
let nativeValue = macKeychainGet() ?? linuxSecretGet();
|
|
@@ -4568,7 +4620,7 @@ async function getMasterKey() {
|
|
|
4568
4620
|
b64Value = content;
|
|
4569
4621
|
}
|
|
4570
4622
|
const key = Buffer.from(b64Value, "base64");
|
|
4571
|
-
if (
|
|
4623
|
+
if (isRootOnlyTrustedServerKeyFile(keyPath)) {
|
|
4572
4624
|
return key;
|
|
4573
4625
|
}
|
|
4574
4626
|
const migrated = macKeychainSet(b64Value) || linuxSecretSet(b64Value);
|
|
@@ -7352,6 +7404,33 @@ Do NOT report this as successful. No file was changed. If you are a sub-agent, r
|
|
|
7352
7404
|
} catch {
|
|
7353
7405
|
}
|
|
7354
7406
|
}
|
|
7407
|
+
if (data.tool_name === "Bash") {
|
|
7408
|
+
const command = String(data.tool_input?.command ?? "");
|
|
7409
|
+
if (command) {
|
|
7410
|
+
const mcpBypassPatterns = [
|
|
7411
|
+
{ regex: /\bsqlite3\b.*\b(memories\.db|\.exe-os)\b/, reason: "Direct SQLite access to exe-os database" },
|
|
7412
|
+
{ regex: /\bnode\s+-e\b.*\b(better-sqlite3|libsql|sqlite3)\b/, reason: "Inline Node.js script accessing SQLite" },
|
|
7413
|
+
{ regex: /\brequire\s*\(\s*['"].*memories\.db['"]\s*\)/, reason: "Direct require of memories database" }
|
|
7414
|
+
];
|
|
7415
|
+
for (const { regex, reason } of mcpBypassPatterns) {
|
|
7416
|
+
if (regex.test(command)) {
|
|
7417
|
+
process.stderr.write(
|
|
7418
|
+
`[pre-tool-use] MCP bypass BLOCKED: ${reason}
|
|
7419
|
+
`
|
|
7420
|
+
);
|
|
7421
|
+
const output = JSON.stringify({
|
|
7422
|
+
hookSpecificOutput: { permissionDecision: "deny" },
|
|
7423
|
+
systemMessage: `BLOCKED: ${reason}.
|
|
7424
|
+
The exe-os database is encrypted and must ONLY be accessed through MCP tools.
|
|
7425
|
+
If MCP is disconnected, tell the user: "MCP server is disconnected. Please run /mcp to reconnect."
|
|
7426
|
+
Do NOT attempt workarounds \u2014 direct DB access bypasses encryption, breaks data integrity, and violates the contract boundary.`
|
|
7427
|
+
});
|
|
7428
|
+
process.stdout.write(output);
|
|
7429
|
+
process.exit(0);
|
|
7430
|
+
}
|
|
7431
|
+
}
|
|
7432
|
+
}
|
|
7433
|
+
}
|
|
7355
7434
|
} catch {
|
|
7356
7435
|
}
|
|
7357
7436
|
clearTimeout(timeout);
|