@askexenow/exe-os 0.8.85 → 0.8.87
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/cleanup-stale-review-tasks.js +57 -19
- package/dist/bin/cli.js +510 -340
- package/dist/bin/exe-agent-config.js +242 -0
- package/dist/bin/exe-agent.js +3 -3
- package/dist/bin/exe-boot.js +344 -346
- package/dist/bin/exe-dispatch.js +375 -250
- package/dist/bin/exe-forget.js +5 -1
- package/dist/bin/exe-gateway.js +260 -135
- package/dist/bin/exe-healthcheck.js +133 -1
- package/dist/bin/exe-heartbeat.js +72 -31
- package/dist/bin/exe-link.js +25 -2
- package/dist/bin/exe-new-employee.js +22 -0
- package/dist/bin/exe-pending-messages.js +55 -17
- package/dist/bin/exe-pending-reviews.js +57 -19
- package/dist/bin/exe-search.js +6 -2
- package/dist/bin/exe-session-cleanup.js +260 -135
- package/dist/bin/exe-start-codex.js +2598 -0
- package/dist/bin/exe-start.sh +15 -3
- package/dist/bin/exe-status.js +57 -19
- package/dist/bin/git-sweep.js +391 -266
- package/dist/bin/install.js +22 -0
- package/dist/bin/scan-tasks.js +394 -269
- package/dist/bin/setup.js +50 -5
- package/dist/gateway/index.js +257 -132
- package/dist/hooks/bug-report-worker.js +242 -117
- package/dist/hooks/commit-complete.js +389 -264
- package/dist/hooks/error-recall.js +6 -2
- package/dist/hooks/ingest-worker.js +314 -193
- package/dist/hooks/post-compact.js +84 -46
- package/dist/hooks/pre-compact.js +272 -147
- package/dist/hooks/pre-tool-use.js +104 -66
- package/dist/hooks/prompt-submit.js +126 -66
- package/dist/hooks/session-end.js +277 -152
- package/dist/hooks/session-start.js +70 -28
- package/dist/hooks/stop.js +90 -52
- package/dist/hooks/subagent-stop.js +84 -46
- package/dist/hooks/summary-worker.js +175 -114
- package/dist/index.js +296 -171
- package/dist/lib/agent-config.js +167 -0
- package/dist/lib/cloud-sync.js +25 -2
- package/dist/lib/exe-daemon.js +338 -213
- package/dist/lib/hybrid-search.js +7 -2
- package/dist/lib/messaging.js +95 -39
- package/dist/lib/runtime-table.js +16 -0
- package/dist/lib/session-wrappers.js +22 -0
- package/dist/lib/tasks.js +242 -117
- package/dist/lib/tmux-routing.js +314 -189
- package/dist/mcp/server.js +573 -274
- package/dist/mcp/tools/create-task.js +260 -135
- package/dist/mcp/tools/list-tasks.js +68 -30
- package/dist/mcp/tools/send-message.js +100 -44
- package/dist/mcp/tools/update-task.js +123 -67
- package/dist/runtime/index.js +276 -151
- package/dist/tui/App.js +479 -354
- package/package.json +1 -1
- package/src/commands/exe/agent-config.md +27 -0
- package/src/commands/exe/cc-doctor.md +10 -0
|
@@ -178,13 +178,144 @@ function checkWorkerSpawning(pkgRoot) {
|
|
|
178
178
|
}
|
|
179
179
|
return results;
|
|
180
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
|
+
}
|
|
181
311
|
function runHealthCheck() {
|
|
182
312
|
const pkgRoot = findPackageRoot();
|
|
183
313
|
const results = [
|
|
184
314
|
...checkBuildIntegrity(pkgRoot),
|
|
185
315
|
...checkEmbedPipeline(pkgRoot),
|
|
186
316
|
...checkTaskSystem(pkgRoot),
|
|
187
|
-
...checkWorkerSpawning(pkgRoot)
|
|
317
|
+
...checkWorkerSpawning(pkgRoot),
|
|
318
|
+
...checkClaudeCodeInstall()
|
|
188
319
|
];
|
|
189
320
|
const passed = results.filter((r) => r.pass).length;
|
|
190
321
|
const failed = results.filter((r) => !r.pass).length;
|
|
@@ -204,5 +335,6 @@ if (isMainModule(import.meta.url)) {
|
|
|
204
335
|
process.exit(failed > 0 ? 1 : 0);
|
|
205
336
|
}
|
|
206
337
|
export {
|
|
338
|
+
checkClaudeCodeInstall,
|
|
207
339
|
runHealthCheck
|
|
208
340
|
};
|
|
@@ -1968,39 +1968,75 @@ var init_provider_table = __esm({
|
|
|
1968
1968
|
}
|
|
1969
1969
|
});
|
|
1970
1970
|
|
|
1971
|
-
// src/lib/
|
|
1972
|
-
|
|
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";
|
|
1973
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";
|
|
1974
2010
|
import os6 from "os";
|
|
1975
2011
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
1976
2012
|
var init_intercom_queue = __esm({
|
|
1977
2013
|
"src/lib/intercom-queue.ts"() {
|
|
1978
2014
|
"use strict";
|
|
1979
|
-
QUEUE_PATH =
|
|
2015
|
+
QUEUE_PATH = path8.join(os6.homedir(), ".exe-os", "intercom-queue.json");
|
|
1980
2016
|
TTL_MS = 60 * 60 * 1e3;
|
|
1981
|
-
INTERCOM_LOG =
|
|
2017
|
+
INTERCOM_LOG = path8.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
1982
2018
|
}
|
|
1983
2019
|
});
|
|
1984
2020
|
|
|
1985
2021
|
// src/lib/license.ts
|
|
1986
|
-
import { readFileSync as
|
|
2022
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
1987
2023
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1988
|
-
import
|
|
2024
|
+
import path9 from "path";
|
|
1989
2025
|
import { jwtVerify, importSPKI } from "jose";
|
|
1990
2026
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
1991
2027
|
var init_license = __esm({
|
|
1992
2028
|
"src/lib/license.ts"() {
|
|
1993
2029
|
"use strict";
|
|
1994
2030
|
init_config();
|
|
1995
|
-
LICENSE_PATH =
|
|
1996
|
-
CACHE_PATH =
|
|
1997
|
-
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");
|
|
1998
2034
|
}
|
|
1999
2035
|
});
|
|
2000
2036
|
|
|
2001
2037
|
// src/lib/plan-limits.ts
|
|
2002
|
-
import { readFileSync as
|
|
2003
|
-
import
|
|
2038
|
+
import { readFileSync as readFileSync7, existsSync as existsSync9 } from "fs";
|
|
2039
|
+
import path10 from "path";
|
|
2004
2040
|
var CACHE_PATH2;
|
|
2005
2041
|
var init_plan_limits = __esm({
|
|
2006
2042
|
"src/lib/plan-limits.ts"() {
|
|
@@ -2009,13 +2045,13 @@ var init_plan_limits = __esm({
|
|
|
2009
2045
|
init_employees();
|
|
2010
2046
|
init_license();
|
|
2011
2047
|
init_config();
|
|
2012
|
-
CACHE_PATH2 =
|
|
2048
|
+
CACHE_PATH2 = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
2013
2049
|
}
|
|
2014
2050
|
});
|
|
2015
2051
|
|
|
2016
2052
|
// src/lib/tmux-routing.ts
|
|
2017
|
-
import { readFileSync as
|
|
2018
|
-
import
|
|
2053
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync10, appendFileSync } from "fs";
|
|
2054
|
+
import path11 from "path";
|
|
2019
2055
|
import os7 from "os";
|
|
2020
2056
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2021
2057
|
function getMySession() {
|
|
@@ -2029,7 +2065,7 @@ function extractRootExe(name) {
|
|
|
2029
2065
|
}
|
|
2030
2066
|
function getParentExe(sessionKey) {
|
|
2031
2067
|
try {
|
|
2032
|
-
const data = JSON.parse(
|
|
2068
|
+
const data = JSON.parse(readFileSync8(path11.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
2033
2069
|
return data.parentExe || null;
|
|
2034
2070
|
} catch {
|
|
2035
2071
|
return null;
|
|
@@ -2063,20 +2099,22 @@ var init_tmux_routing = __esm({
|
|
|
2063
2099
|
init_cc_agent_support();
|
|
2064
2100
|
init_mcp_prefix();
|
|
2065
2101
|
init_provider_table();
|
|
2102
|
+
init_agent_config();
|
|
2103
|
+
init_runtime_table();
|
|
2066
2104
|
init_intercom_queue();
|
|
2067
2105
|
init_plan_limits();
|
|
2068
2106
|
init_employees();
|
|
2069
|
-
SPAWN_LOCK_DIR =
|
|
2070
|
-
SESSION_CACHE =
|
|
2071
|
-
INTERCOM_LOG2 =
|
|
2072
|
-
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");
|
|
2073
2111
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
2074
2112
|
}
|
|
2075
2113
|
});
|
|
2076
2114
|
|
|
2077
2115
|
// src/lib/tasks-review.ts
|
|
2078
|
-
import
|
|
2079
|
-
import { existsSync as
|
|
2116
|
+
import path12 from "path";
|
|
2117
|
+
import { existsSync as existsSync11, readdirSync as readdirSync3, unlinkSync as unlinkSync3 } from "fs";
|
|
2080
2118
|
async function listPendingReviews(limit, sessionScope) {
|
|
2081
2119
|
const client = getClient();
|
|
2082
2120
|
if (sessionScope) {
|
|
@@ -2136,9 +2174,9 @@ var init_task_scope = __esm({
|
|
|
2136
2174
|
|
|
2137
2175
|
// src/bin/exe-heartbeat.ts
|
|
2138
2176
|
import { createHash as createHash2 } from "crypto";
|
|
2139
|
-
import { readFileSync as
|
|
2177
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
|
|
2140
2178
|
import os8 from "os";
|
|
2141
|
-
import
|
|
2179
|
+
import path13 from "path";
|
|
2142
2180
|
|
|
2143
2181
|
// src/lib/store.ts
|
|
2144
2182
|
import { createHash } from "crypto";
|
|
@@ -2309,18 +2347,18 @@ var MESSAGE_PREVIEW_CHARS = 80;
|
|
|
2309
2347
|
var MARKER_FILENAME = "exe-heartbeat-marker.json";
|
|
2310
2348
|
var SESSION_CACHE_SUBDIR = "session-cache";
|
|
2311
2349
|
function resolveExeOsDir() {
|
|
2312
|
-
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");
|
|
2313
2351
|
}
|
|
2314
2352
|
function getMarkerDir() {
|
|
2315
|
-
return
|
|
2353
|
+
return path13.join(resolveExeOsDir(), SESSION_CACHE_SUBDIR);
|
|
2316
2354
|
}
|
|
2317
2355
|
function getMarkerPath() {
|
|
2318
|
-
return
|
|
2356
|
+
return path13.join(getMarkerDir(), MARKER_FILENAME);
|
|
2319
2357
|
}
|
|
2320
2358
|
var UNREAD_MESSAGE_STATUSES = ["pending", "delivered"];
|
|
2321
2359
|
function readMarker() {
|
|
2322
2360
|
try {
|
|
2323
|
-
const raw =
|
|
2361
|
+
const raw = readFileSync9(getMarkerPath(), "utf8");
|
|
2324
2362
|
const parsed = JSON.parse(raw);
|
|
2325
2363
|
if (typeof parsed.lastFiredAt !== "string" || typeof parsed.lastSurfaceHash !== "string") {
|
|
2326
2364
|
return null;
|
|
@@ -2332,8 +2370,8 @@ function readMarker() {
|
|
|
2332
2370
|
}
|
|
2333
2371
|
function writeMarker(marker) {
|
|
2334
2372
|
try {
|
|
2335
|
-
|
|
2336
|
-
|
|
2373
|
+
mkdirSync6(getMarkerDir(), { recursive: true });
|
|
2374
|
+
writeFileSync6(getMarkerPath(), JSON.stringify(marker));
|
|
2337
2375
|
} catch {
|
|
2338
2376
|
}
|
|
2339
2377
|
}
|
|
@@ -2404,10 +2442,13 @@ async function queryStaleInProgress(thresholdHours) {
|
|
|
2404
2442
|
}
|
|
2405
2443
|
async function queryNewErrors(sinceIso) {
|
|
2406
2444
|
const client = getClient();
|
|
2445
|
+
const erScope = sessionScopeFilter();
|
|
2407
2446
|
const result = await client.execute({
|
|
2408
|
-
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
|
|
2409
2450
|
WHERE has_error = 1 AND timestamp > ?`,
|
|
2410
|
-
args: [sinceIso]
|
|
2451
|
+
args: erScope.args.length > 0 ? [sinceIso, ...erScope.args] : [sinceIso]
|
|
2411
2452
|
});
|
|
2412
2453
|
const count = Number(result.rows[0]?.cnt ?? 0);
|
|
2413
2454
|
if (count === 0) return "";
|
package/dist/bin/exe-link.js
CHANGED
|
@@ -2810,10 +2810,18 @@ function buildRosterBlob(paths) {
|
|
|
2810
2810
|
} catch {
|
|
2811
2811
|
}
|
|
2812
2812
|
}
|
|
2813
|
+
let agentConfig;
|
|
2814
|
+
const agentConfigPath = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
2815
|
+
if (existsSync7(agentConfigPath)) {
|
|
2816
|
+
try {
|
|
2817
|
+
agentConfig = JSON.parse(readFileSync6(agentConfigPath, "utf-8"));
|
|
2818
|
+
} catch {
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2813
2821
|
const deletedNames = consumeRosterDeletions();
|
|
2814
|
-
const content = JSON.stringify({ roster, identities, config, deletedNames });
|
|
2822
|
+
const content = JSON.stringify({ roster, identities, config, agentConfig, deletedNames });
|
|
2815
2823
|
const hash = crypto2.createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
2816
|
-
return { roster, identities, config, deletedNames, version: hash };
|
|
2824
|
+
return { roster, identities, config, agentConfig, deletedNames, version: hash };
|
|
2817
2825
|
}
|
|
2818
2826
|
async function cloudPushRoster(config) {
|
|
2819
2827
|
assertSecureEndpoint(config.endpoint);
|
|
@@ -2951,6 +2959,21 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
2951
2959
|
} catch {
|
|
2952
2960
|
}
|
|
2953
2961
|
}
|
|
2962
|
+
if (remote.agentConfig && Object.keys(remote.agentConfig).length > 0) {
|
|
2963
|
+
try {
|
|
2964
|
+
const agentConfigPath = path7.join(EXE_AI_DIR, "agent-config.json");
|
|
2965
|
+
let local = {};
|
|
2966
|
+
if (existsSync7(agentConfigPath)) {
|
|
2967
|
+
try {
|
|
2968
|
+
local = JSON.parse(readFileSync6(agentConfigPath, "utf-8"));
|
|
2969
|
+
} catch {
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
const merged = { ...remote.agentConfig, ...local };
|
|
2973
|
+
writeFileSync4(agentConfigPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
2974
|
+
} catch {
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2954
2977
|
return { added, identitiesUpdated };
|
|
2955
2978
|
});
|
|
2956
2979
|
}
|
|
@@ -1610,6 +1610,28 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
1610
1610
|
created++;
|
|
1611
1611
|
}
|
|
1612
1612
|
}
|
|
1613
|
+
const codexLauncherCandidates = [
|
|
1614
|
+
path.join(packageRoot, "dist", "bin", "exe-start-codex.js"),
|
|
1615
|
+
path.join(packageRoot, "src", "bin", "exe-start-codex.ts")
|
|
1616
|
+
];
|
|
1617
|
+
let codexLauncher = null;
|
|
1618
|
+
for (const c of codexLauncherCandidates) {
|
|
1619
|
+
if (existsSync(c)) {
|
|
1620
|
+
codexLauncher = c;
|
|
1621
|
+
break;
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
if (codexLauncher) {
|
|
1625
|
+
for (const emp of employees) {
|
|
1626
|
+
const wrapperPath = path.join(binDir, `${emp.name}-codex`);
|
|
1627
|
+
const content = `#!/bin/bash
|
|
1628
|
+
exec node "${codexLauncher}" --agent ${emp.name} "$@"
|
|
1629
|
+
`;
|
|
1630
|
+
writeFileSync(wrapperPath, content);
|
|
1631
|
+
chmodSync(wrapperPath, 493);
|
|
1632
|
+
created++;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1613
1635
|
const pathConfigured = ensurePath(home, binDir);
|
|
1614
1636
|
return { created, pathConfigured };
|
|
1615
1637
|
}
|
|
@@ -1792,39 +1792,75 @@ var init_provider_table = __esm({
|
|
|
1792
1792
|
}
|
|
1793
1793
|
});
|
|
1794
1794
|
|
|
1795
|
-
// src/lib/
|
|
1796
|
-
|
|
1795
|
+
// src/lib/runtime-table.ts
|
|
1796
|
+
var RUNTIME_TABLE;
|
|
1797
|
+
var init_runtime_table = __esm({
|
|
1798
|
+
"src/lib/runtime-table.ts"() {
|
|
1799
|
+
"use strict";
|
|
1800
|
+
RUNTIME_TABLE = {
|
|
1801
|
+
codex: {
|
|
1802
|
+
binary: "codex",
|
|
1803
|
+
launchMode: "exec",
|
|
1804
|
+
autoApproveFlag: "--full-auto",
|
|
1805
|
+
inlineFlag: "--no-alt-screen",
|
|
1806
|
+
apiKeyEnv: "OPENAI_API_KEY",
|
|
1807
|
+
defaultModel: "gpt-5.4"
|
|
1808
|
+
}
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
});
|
|
1812
|
+
|
|
1813
|
+
// src/lib/agent-config.ts
|
|
1814
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
|
|
1797
1815
|
import path6 from "path";
|
|
1816
|
+
var AGENT_CONFIG_PATH, DEFAULT_MODELS;
|
|
1817
|
+
var init_agent_config = __esm({
|
|
1818
|
+
"src/lib/agent-config.ts"() {
|
|
1819
|
+
"use strict";
|
|
1820
|
+
init_config();
|
|
1821
|
+
init_runtime_table();
|
|
1822
|
+
AGENT_CONFIG_PATH = path6.join(EXE_AI_DIR, "agent-config.json");
|
|
1823
|
+
DEFAULT_MODELS = {
|
|
1824
|
+
claude: "claude-opus-4",
|
|
1825
|
+
codex: RUNTIME_TABLE.codex?.defaultModel ?? "gpt-5.4",
|
|
1826
|
+
opencode: "minimax-m2.7"
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
|
|
1831
|
+
// src/lib/intercom-queue.ts
|
|
1832
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, renameSync as renameSync3, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "fs";
|
|
1833
|
+
import path7 from "path";
|
|
1798
1834
|
import os5 from "os";
|
|
1799
1835
|
var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
1800
1836
|
var init_intercom_queue = __esm({
|
|
1801
1837
|
"src/lib/intercom-queue.ts"() {
|
|
1802
1838
|
"use strict";
|
|
1803
|
-
QUEUE_PATH =
|
|
1839
|
+
QUEUE_PATH = path7.join(os5.homedir(), ".exe-os", "intercom-queue.json");
|
|
1804
1840
|
TTL_MS = 60 * 60 * 1e3;
|
|
1805
|
-
INTERCOM_LOG =
|
|
1841
|
+
INTERCOM_LOG = path7.join(os5.homedir(), ".exe-os", "intercom.log");
|
|
1806
1842
|
}
|
|
1807
1843
|
});
|
|
1808
1844
|
|
|
1809
1845
|
// src/lib/license.ts
|
|
1810
|
-
import { readFileSync as
|
|
1846
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
|
|
1811
1847
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
1812
|
-
import
|
|
1848
|
+
import path8 from "path";
|
|
1813
1849
|
import { jwtVerify, importSPKI } from "jose";
|
|
1814
1850
|
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
1815
1851
|
var init_license = __esm({
|
|
1816
1852
|
"src/lib/license.ts"() {
|
|
1817
1853
|
"use strict";
|
|
1818
1854
|
init_config();
|
|
1819
|
-
LICENSE_PATH =
|
|
1820
|
-
CACHE_PATH =
|
|
1821
|
-
DEVICE_ID_PATH =
|
|
1855
|
+
LICENSE_PATH = path8.join(EXE_AI_DIR, "license.key");
|
|
1856
|
+
CACHE_PATH = path8.join(EXE_AI_DIR, "license-cache.json");
|
|
1857
|
+
DEVICE_ID_PATH = path8.join(EXE_AI_DIR, "device-id");
|
|
1822
1858
|
}
|
|
1823
1859
|
});
|
|
1824
1860
|
|
|
1825
1861
|
// src/lib/plan-limits.ts
|
|
1826
|
-
import { readFileSync as
|
|
1827
|
-
import
|
|
1862
|
+
import { readFileSync as readFileSync6, existsSync as existsSync8 } from "fs";
|
|
1863
|
+
import path9 from "path";
|
|
1828
1864
|
var CACHE_PATH2;
|
|
1829
1865
|
var init_plan_limits = __esm({
|
|
1830
1866
|
"src/lib/plan-limits.ts"() {
|
|
@@ -1833,12 +1869,12 @@ var init_plan_limits = __esm({
|
|
|
1833
1869
|
init_employees();
|
|
1834
1870
|
init_license();
|
|
1835
1871
|
init_config();
|
|
1836
|
-
CACHE_PATH2 =
|
|
1872
|
+
CACHE_PATH2 = path9.join(EXE_AI_DIR, "license-cache.json");
|
|
1837
1873
|
}
|
|
1838
1874
|
});
|
|
1839
1875
|
|
|
1840
1876
|
// src/lib/tmux-routing.ts
|
|
1841
|
-
import
|
|
1877
|
+
import path10 from "path";
|
|
1842
1878
|
import os6 from "os";
|
|
1843
1879
|
import { fileURLToPath } from "url";
|
|
1844
1880
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
@@ -1851,13 +1887,15 @@ var init_tmux_routing = __esm({
|
|
|
1851
1887
|
init_cc_agent_support();
|
|
1852
1888
|
init_mcp_prefix();
|
|
1853
1889
|
init_provider_table();
|
|
1890
|
+
init_agent_config();
|
|
1891
|
+
init_runtime_table();
|
|
1854
1892
|
init_intercom_queue();
|
|
1855
1893
|
init_plan_limits();
|
|
1856
1894
|
init_employees();
|
|
1857
|
-
SPAWN_LOCK_DIR =
|
|
1858
|
-
SESSION_CACHE =
|
|
1859
|
-
INTERCOM_LOG2 =
|
|
1860
|
-
DEBOUNCE_FILE =
|
|
1895
|
+
SPAWN_LOCK_DIR = path10.join(os6.homedir(), ".exe-os", "spawn-locks");
|
|
1896
|
+
SESSION_CACHE = path10.join(os6.homedir(), ".exe-os", "session-cache");
|
|
1897
|
+
INTERCOM_LOG2 = path10.join(os6.homedir(), ".exe-os", "intercom.log");
|
|
1898
|
+
DEBOUNCE_FILE = path10.join(SESSION_CACHE, "intercom-debounce.json");
|
|
1861
1899
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
1862
1900
|
}
|
|
1863
1901
|
});
|