@askexenow/exe-os 0.9.92 → 0.9.94
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/deploy/compose/docker-compose.yml +1 -0
- package/dist/bin/agentic-ontology-backfill.js +65 -8
- package/dist/bin/agentic-reflection-backfill.js +54 -3
- package/dist/bin/agentic-semantic-label.js +54 -3
- package/dist/bin/backfill-conversations.js +69 -9
- package/dist/bin/backfill-responses.js +69 -9
- package/dist/bin/backfill-vectors.js +54 -3
- package/dist/bin/bulk-sync-postgres.js +66 -8
- package/dist/bin/cleanup-stale-review-tasks.js +118 -13
- package/dist/bin/cli.js +1605 -456
- package/dist/bin/customer-readiness.js +51 -0
- package/dist/bin/exe-agent.js +17 -3
- package/dist/bin/exe-assign.js +75 -9
- package/dist/bin/exe-boot.js +111 -12
- package/dist/bin/exe-call.js +17 -3
- package/dist/bin/exe-cloud.js +76 -10
- package/dist/bin/exe-dispatch.js +133 -18
- package/dist/bin/exe-doctor.js +75 -9
- package/dist/bin/exe-export-behaviors.js +75 -9
- package/dist/bin/exe-forget.js +94 -9
- package/dist/bin/exe-gateway.js +132 -18
- package/dist/bin/exe-heartbeat.js +118 -13
- package/dist/bin/exe-kill.js +75 -9
- package/dist/bin/exe-launch-agent.js +75 -9
- package/dist/bin/exe-new-employee.js +18 -4
- package/dist/bin/exe-pending-messages.js +118 -13
- package/dist/bin/exe-pending-notifications.js +118 -13
- package/dist/bin/exe-pending-reviews.js +118 -13
- package/dist/bin/exe-rename.js +75 -9
- package/dist/bin/exe-review.js +75 -9
- package/dist/bin/exe-search.js +100 -9
- package/dist/bin/exe-session-cleanup.js +133 -18
- package/dist/bin/exe-settings.js +1 -0
- package/dist/bin/exe-start-codex.js +65 -8
- package/dist/bin/exe-start-opencode.js +65 -8
- package/dist/bin/exe-status.js +118 -13
- package/dist/bin/exe-support.js +1 -0
- package/dist/bin/exe-team.js +75 -9
- package/dist/bin/git-sweep.js +133 -18
- package/dist/bin/graph-backfill.js +65 -8
- package/dist/bin/graph-export.js +75 -9
- package/dist/bin/intercom-check.js +133 -18
- package/dist/bin/scan-tasks.js +133 -18
- package/dist/bin/setup.js +55 -4
- package/dist/bin/shard-migrate.js +65 -8
- package/dist/bin/stack-update.js +57 -1
- package/dist/bin/update.js +1 -1
- package/dist/gateway/index.js +133 -18
- package/dist/hooks/bug-report-worker.js +133 -18
- package/dist/hooks/codex-stop-task-finalizer.js +123 -14
- package/dist/hooks/commit-complete.js +133 -18
- package/dist/hooks/error-recall.js +100 -9
- package/dist/hooks/ingest.js +75 -9
- package/dist/hooks/instructions-loaded.js +75 -9
- package/dist/hooks/notification.js +75 -9
- package/dist/hooks/post-compact.js +310 -50
- package/dist/hooks/post-tool-combined.js +433 -13
- package/dist/hooks/pre-compact.js +133 -18
- package/dist/hooks/pre-tool-use.js +118 -13
- package/dist/hooks/prompt-submit.js +191 -19
- package/dist/hooks/session-end.js +133 -18
- package/dist/hooks/session-start.js +143 -13
- package/dist/hooks/stop.js +118 -13
- package/dist/hooks/subagent-stop.js +118 -13
- package/dist/hooks/summary-worker.js +96 -7
- package/dist/index.js +133 -18
- package/dist/lib/cloud-sync.js +38 -0
- package/dist/lib/consolidation.js +3 -1
- package/dist/lib/database.js +37 -0
- package/dist/lib/db.js +37 -0
- package/dist/lib/device-registry.js +37 -0
- package/dist/lib/employee-templates.js +17 -3
- package/dist/lib/exe-daemon.js +913 -42
- package/dist/lib/hybrid-search.js +100 -9
- package/dist/lib/license.js +1 -1
- package/dist/lib/messaging.js +40 -4
- package/dist/lib/schedules.js +54 -3
- package/dist/lib/store.js +75 -9
- package/dist/lib/tasks.js +58 -9
- package/dist/lib/tmux-routing.js +58 -9
- package/dist/mcp/server.js +875 -42
- package/dist/mcp/tools/create-task.js +67 -12
- package/dist/mcp/tools/list-tasks.js +46 -5
- package/dist/mcp/tools/send-message.js +40 -4
- package/dist/mcp/tools/update-task.js +58 -9
- package/dist/runtime/index.js +133 -18
- package/dist/tui/App.js +132 -18
- package/package.json +1 -1
|
@@ -1201,7 +1201,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
1201
1201
|
import os6 from "os";
|
|
1202
1202
|
import path7 from "path";
|
|
1203
1203
|
import { jwtVerify, importSPKI } from "jose";
|
|
1204
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
1204
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
1205
1205
|
var init_license = __esm({
|
|
1206
1206
|
"src/lib/license.ts"() {
|
|
1207
1207
|
"use strict";
|
|
@@ -1209,6 +1209,7 @@ var init_license = __esm({
|
|
|
1209
1209
|
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
1210
1210
|
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
1211
1211
|
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
1212
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
1212
1213
|
PLAN_LIMITS = {
|
|
1213
1214
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
1214
1215
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -2218,6 +2219,7 @@ function resolveExeSession() {
|
|
|
2218
2219
|
const mySession = getMySession();
|
|
2219
2220
|
if (!mySession) return null;
|
|
2220
2221
|
const fromSessionName = extractRootExe(mySession);
|
|
2222
|
+
let candidate = null;
|
|
2221
2223
|
try {
|
|
2222
2224
|
const key = getSessionKey();
|
|
2223
2225
|
const parentExe = getParentExe(key);
|
|
@@ -2228,13 +2230,47 @@ function resolveExeSession() {
|
|
|
2228
2230
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
2229
2231
|
`
|
|
2230
2232
|
);
|
|
2231
|
-
|
|
2233
|
+
candidate = fromSessionName;
|
|
2234
|
+
} else {
|
|
2235
|
+
candidate = fromCache;
|
|
2232
2236
|
}
|
|
2233
|
-
return fromCache;
|
|
2234
2237
|
}
|
|
2235
2238
|
} catch {
|
|
2236
2239
|
}
|
|
2237
|
-
|
|
2240
|
+
if (!candidate) {
|
|
2241
|
+
candidate = fromSessionName ?? mySession;
|
|
2242
|
+
}
|
|
2243
|
+
if (candidate && isRootSession(candidate)) {
|
|
2244
|
+
try {
|
|
2245
|
+
const transport = getTransport();
|
|
2246
|
+
const liveSessions = transport.listSessions();
|
|
2247
|
+
if (!liveSessions.includes(candidate)) {
|
|
2248
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
2249
|
+
if (liveRoots.length === 1) {
|
|
2250
|
+
process.stderr.write(
|
|
2251
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
2252
|
+
`
|
|
2253
|
+
);
|
|
2254
|
+
return liveRoots[0];
|
|
2255
|
+
} else if (liveRoots.length > 1) {
|
|
2256
|
+
const base = candidate.replace(/\d+$/, "");
|
|
2257
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
2258
|
+
const chosen = match ?? liveRoots[0];
|
|
2259
|
+
process.stderr.write(
|
|
2260
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
2261
|
+
`
|
|
2262
|
+
);
|
|
2263
|
+
return chosen;
|
|
2264
|
+
}
|
|
2265
|
+
process.stderr.write(
|
|
2266
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
2267
|
+
`
|
|
2268
|
+
);
|
|
2269
|
+
}
|
|
2270
|
+
} catch {
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
return candidate;
|
|
2238
2274
|
}
|
|
2239
2275
|
function isEmployeeAlive(sessionName) {
|
|
2240
2276
|
return getTransport().isAlive(sessionName);
|
|
@@ -2636,7 +2672,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2636
2672
|
}
|
|
2637
2673
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
2638
2674
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
2639
|
-
const
|
|
2675
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
2676
|
+
const agentRtConfig = {
|
|
2677
|
+
...baseRtConfig,
|
|
2678
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
2679
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
2680
|
+
};
|
|
2640
2681
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
2641
2682
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
2642
2683
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -3274,8 +3315,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
3274
3315
|
const complexity = input.complexity ?? "standard";
|
|
3275
3316
|
const sessionScope = earlySessionScope;
|
|
3276
3317
|
await client.execute({
|
|
3277
|
-
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, created_at, updated_at)
|
|
3278
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3318
|
+
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, created_at, updated_at)
|
|
3319
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3279
3320
|
args: [
|
|
3280
3321
|
id,
|
|
3281
3322
|
input.title,
|
|
@@ -3295,6 +3336,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
3295
3336
|
0,
|
|
3296
3337
|
null,
|
|
3297
3338
|
sessionScope,
|
|
3339
|
+
input.spawnRuntime ?? null,
|
|
3340
|
+
input.spawnModel ?? null,
|
|
3298
3341
|
now,
|
|
3299
3342
|
now
|
|
3300
3343
|
]
|
|
@@ -3351,7 +3394,9 @@ ${input.context}
|
|
|
3351
3394
|
budgetTokens: input.budgetTokens ?? null,
|
|
3352
3395
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
3353
3396
|
tokensUsed: 0,
|
|
3354
|
-
tokensWarnedAt: null
|
|
3397
|
+
tokensWarnedAt: null,
|
|
3398
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
3399
|
+
spawnModel: input.spawnModel ?? null
|
|
3355
3400
|
};
|
|
3356
3401
|
}
|
|
3357
3402
|
async function listTasks(input) {
|
|
@@ -3401,7 +3446,9 @@ async function listTasks(input) {
|
|
|
3401
3446
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
3402
3447
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
3403
3448
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
3404
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
3449
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
3450
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
3451
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
3405
3452
|
}));
|
|
3406
3453
|
}
|
|
3407
3454
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -4868,6 +4915,8 @@ async function updateTask(input) {
|
|
|
4868
4915
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
4869
4916
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
4870
4917
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
4918
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
4919
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
4871
4920
|
nextTask
|
|
4872
4921
|
};
|
|
4873
4922
|
}
|
|
@@ -5721,10 +5770,12 @@ function registerCreateTask(server) {
|
|
|
5721
5770
|
parent_task_id: z.string().optional().describe("Parent task ID or slug. Links this task as a subtask."),
|
|
5722
5771
|
reviewer: z.string().optional().describe("Who should review this task when done. Defaults to assigner."),
|
|
5723
5772
|
budget_tokens: z.number().optional().describe("Max tokens allowed for this task (null = unlimited)"),
|
|
5724
|
-
budget_fallback_model: z.string().optional().describe("Model to route to when budget is exhausted")
|
|
5773
|
+
budget_fallback_model: z.string().optional().describe("Model to route to when budget is exhausted"),
|
|
5774
|
+
spawn_runtime: z.string().optional().describe("Override runtime for spawned session (e.g., 'claude', 'codex', 'opencode')"),
|
|
5775
|
+
spawn_model: z.string().optional().describe("Override model for spawned session (e.g., 'claude-sonnet-4.6', 'claude-haiku-4.5')")
|
|
5725
5776
|
}
|
|
5726
5777
|
},
|
|
5727
|
-
async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model }) => {
|
|
5778
|
+
async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model, spawn_runtime, spawn_model }) => {
|
|
5728
5779
|
if (!isCoordinatorName(assigned_to)) {
|
|
5729
5780
|
const license = getLicenseSync();
|
|
5730
5781
|
if (license.plan === "free") {
|
|
@@ -5752,6 +5803,8 @@ function registerCreateTask(server) {
|
|
|
5752
5803
|
reviewer,
|
|
5753
5804
|
budgetTokens: budget_tokens,
|
|
5754
5805
|
budgetFallbackModel: budget_fallback_model,
|
|
5806
|
+
spawnRuntime: spawn_runtime,
|
|
5807
|
+
spawnModel: spawn_model,
|
|
5755
5808
|
// Skip internal dispatch — we handle it below with autoInstance
|
|
5756
5809
|
// support. Without this, createTask fires dispatchTaskToEmployee
|
|
5757
5810
|
// (no autoInstance) in parallel, racing with our ensureEmployee
|
|
@@ -5789,7 +5842,9 @@ function registerCreateTask(server) {
|
|
|
5789
5842
|
const cfg = loadConfigSync2();
|
|
5790
5843
|
const result = ensureEmployee(assigned_to, exeSession, process.cwd(), {
|
|
5791
5844
|
autoInstance: useAutoInstance,
|
|
5792
|
-
maxAutoInstances: useAutoInstance ? cfg.sessionLifecycle.maxAutoInstances : void 0
|
|
5845
|
+
maxAutoInstances: useAutoInstance ? cfg.sessionLifecycle.maxAutoInstances : void 0,
|
|
5846
|
+
runtimeOverride: spawn_runtime ?? void 0,
|
|
5847
|
+
modelOverride: spawn_model ?? void 0
|
|
5793
5848
|
});
|
|
5794
5849
|
switch (result.status) {
|
|
5795
5850
|
case "intercom_sent":
|
|
@@ -527,7 +527,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
527
527
|
import os6 from "os";
|
|
528
528
|
import path7 from "path";
|
|
529
529
|
import { jwtVerify, importSPKI } from "jose";
|
|
530
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
530
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
531
531
|
var init_license = __esm({
|
|
532
532
|
"src/lib/license.ts"() {
|
|
533
533
|
"use strict";
|
|
@@ -535,6 +535,7 @@ var init_license = __esm({
|
|
|
535
535
|
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
536
536
|
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
537
537
|
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
538
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
538
539
|
}
|
|
539
540
|
});
|
|
540
541
|
|
|
@@ -578,6 +579,9 @@ import { fileURLToPath } from "url";
|
|
|
578
579
|
function getMySession() {
|
|
579
580
|
return getTransport().getMySession();
|
|
580
581
|
}
|
|
582
|
+
function isRootSession(name) {
|
|
583
|
+
return name.length > 0 && !name.includes("-");
|
|
584
|
+
}
|
|
581
585
|
function extractRootExe(name) {
|
|
582
586
|
if (!name) return null;
|
|
583
587
|
if (!name.includes("-")) return name;
|
|
@@ -596,6 +600,7 @@ function resolveExeSession() {
|
|
|
596
600
|
const mySession = getMySession();
|
|
597
601
|
if (!mySession) return null;
|
|
598
602
|
const fromSessionName = extractRootExe(mySession);
|
|
603
|
+
let candidate = null;
|
|
599
604
|
try {
|
|
600
605
|
const key = getSessionKey();
|
|
601
606
|
const parentExe = getParentExe(key);
|
|
@@ -606,13 +611,47 @@ function resolveExeSession() {
|
|
|
606
611
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
607
612
|
`
|
|
608
613
|
);
|
|
609
|
-
|
|
614
|
+
candidate = fromSessionName;
|
|
615
|
+
} else {
|
|
616
|
+
candidate = fromCache;
|
|
610
617
|
}
|
|
611
|
-
return fromCache;
|
|
612
618
|
}
|
|
613
619
|
} catch {
|
|
614
620
|
}
|
|
615
|
-
|
|
621
|
+
if (!candidate) {
|
|
622
|
+
candidate = fromSessionName ?? mySession;
|
|
623
|
+
}
|
|
624
|
+
if (candidate && isRootSession(candidate)) {
|
|
625
|
+
try {
|
|
626
|
+
const transport = getTransport();
|
|
627
|
+
const liveSessions = transport.listSessions();
|
|
628
|
+
if (!liveSessions.includes(candidate)) {
|
|
629
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
630
|
+
if (liveRoots.length === 1) {
|
|
631
|
+
process.stderr.write(
|
|
632
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
633
|
+
`
|
|
634
|
+
);
|
|
635
|
+
return liveRoots[0];
|
|
636
|
+
} else if (liveRoots.length > 1) {
|
|
637
|
+
const base = candidate.replace(/\d+$/, "");
|
|
638
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
639
|
+
const chosen = match ?? liveRoots[0];
|
|
640
|
+
process.stderr.write(
|
|
641
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
642
|
+
`
|
|
643
|
+
);
|
|
644
|
+
return chosen;
|
|
645
|
+
}
|
|
646
|
+
process.stderr.write(
|
|
647
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
648
|
+
`
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
} catch {
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return candidate;
|
|
616
655
|
}
|
|
617
656
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
618
657
|
var init_tmux_routing = __esm({
|
|
@@ -801,7 +840,9 @@ async function listTasks(input) {
|
|
|
801
840
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
802
841
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
803
842
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
804
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
843
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
844
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
845
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
805
846
|
}));
|
|
806
847
|
}
|
|
807
848
|
var LANE_KEYWORDS, KEYWORD_INDEX;
|
|
@@ -590,7 +590,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
590
590
|
import os6 from "os";
|
|
591
591
|
import path7 from "path";
|
|
592
592
|
import { jwtVerify, importSPKI } from "jose";
|
|
593
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
593
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
594
594
|
var init_license = __esm({
|
|
595
595
|
"src/lib/license.ts"() {
|
|
596
596
|
"use strict";
|
|
@@ -598,6 +598,7 @@ var init_license = __esm({
|
|
|
598
598
|
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
599
599
|
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
600
600
|
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
601
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
601
602
|
}
|
|
602
603
|
});
|
|
603
604
|
|
|
@@ -686,6 +687,7 @@ function resolveExeSession() {
|
|
|
686
687
|
const mySession = getMySession();
|
|
687
688
|
if (!mySession) return null;
|
|
688
689
|
const fromSessionName = extractRootExe(mySession);
|
|
690
|
+
let candidate = null;
|
|
689
691
|
try {
|
|
690
692
|
const key = getSessionKey();
|
|
691
693
|
const parentExe = getParentExe(key);
|
|
@@ -696,13 +698,47 @@ function resolveExeSession() {
|
|
|
696
698
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
697
699
|
`
|
|
698
700
|
);
|
|
699
|
-
|
|
701
|
+
candidate = fromSessionName;
|
|
702
|
+
} else {
|
|
703
|
+
candidate = fromCache;
|
|
700
704
|
}
|
|
701
|
-
return fromCache;
|
|
702
705
|
}
|
|
703
706
|
} catch {
|
|
704
707
|
}
|
|
705
|
-
|
|
708
|
+
if (!candidate) {
|
|
709
|
+
candidate = fromSessionName ?? mySession;
|
|
710
|
+
}
|
|
711
|
+
if (candidate && isRootSession(candidate)) {
|
|
712
|
+
try {
|
|
713
|
+
const transport = getTransport();
|
|
714
|
+
const liveSessions = transport.listSessions();
|
|
715
|
+
if (!liveSessions.includes(candidate)) {
|
|
716
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
717
|
+
if (liveRoots.length === 1) {
|
|
718
|
+
process.stderr.write(
|
|
719
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
720
|
+
`
|
|
721
|
+
);
|
|
722
|
+
return liveRoots[0];
|
|
723
|
+
} else if (liveRoots.length > 1) {
|
|
724
|
+
const base = candidate.replace(/\d+$/, "");
|
|
725
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
726
|
+
const chosen = match ?? liveRoots[0];
|
|
727
|
+
process.stderr.write(
|
|
728
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
729
|
+
`
|
|
730
|
+
);
|
|
731
|
+
return chosen;
|
|
732
|
+
}
|
|
733
|
+
process.stderr.write(
|
|
734
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
735
|
+
`
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
} catch {
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return candidate;
|
|
706
742
|
}
|
|
707
743
|
function isEmployeeAlive(sessionName) {
|
|
708
744
|
return getTransport().isAlive(sessionName);
|
|
@@ -964,7 +964,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
964
964
|
import os6 from "os";
|
|
965
965
|
import path7 from "path";
|
|
966
966
|
import { jwtVerify, importSPKI } from "jose";
|
|
967
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
967
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
968
968
|
var init_license = __esm({
|
|
969
969
|
"src/lib/license.ts"() {
|
|
970
970
|
"use strict";
|
|
@@ -972,6 +972,7 @@ var init_license = __esm({
|
|
|
972
972
|
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
973
973
|
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
974
974
|
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
975
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
975
976
|
PLAN_LIMITS = {
|
|
976
977
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
977
978
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -1981,6 +1982,7 @@ function resolveExeSession() {
|
|
|
1981
1982
|
const mySession = getMySession();
|
|
1982
1983
|
if (!mySession) return null;
|
|
1983
1984
|
const fromSessionName = extractRootExe(mySession);
|
|
1985
|
+
let candidate = null;
|
|
1984
1986
|
try {
|
|
1985
1987
|
const key = getSessionKey();
|
|
1986
1988
|
const parentExe = getParentExe(key);
|
|
@@ -1991,13 +1993,47 @@ function resolveExeSession() {
|
|
|
1991
1993
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
1992
1994
|
`
|
|
1993
1995
|
);
|
|
1994
|
-
|
|
1996
|
+
candidate = fromSessionName;
|
|
1997
|
+
} else {
|
|
1998
|
+
candidate = fromCache;
|
|
1995
1999
|
}
|
|
1996
|
-
return fromCache;
|
|
1997
2000
|
}
|
|
1998
2001
|
} catch {
|
|
1999
2002
|
}
|
|
2000
|
-
|
|
2003
|
+
if (!candidate) {
|
|
2004
|
+
candidate = fromSessionName ?? mySession;
|
|
2005
|
+
}
|
|
2006
|
+
if (candidate && isRootSession(candidate)) {
|
|
2007
|
+
try {
|
|
2008
|
+
const transport = getTransport();
|
|
2009
|
+
const liveSessions = transport.listSessions();
|
|
2010
|
+
if (!liveSessions.includes(candidate)) {
|
|
2011
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
2012
|
+
if (liveRoots.length === 1) {
|
|
2013
|
+
process.stderr.write(
|
|
2014
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
2015
|
+
`
|
|
2016
|
+
);
|
|
2017
|
+
return liveRoots[0];
|
|
2018
|
+
} else if (liveRoots.length > 1) {
|
|
2019
|
+
const base = candidate.replace(/\d+$/, "");
|
|
2020
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
2021
|
+
const chosen = match ?? liveRoots[0];
|
|
2022
|
+
process.stderr.write(
|
|
2023
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
2024
|
+
`
|
|
2025
|
+
);
|
|
2026
|
+
return chosen;
|
|
2027
|
+
}
|
|
2028
|
+
process.stderr.write(
|
|
2029
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
2030
|
+
`
|
|
2031
|
+
);
|
|
2032
|
+
}
|
|
2033
|
+
} catch {
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
return candidate;
|
|
2001
2037
|
}
|
|
2002
2038
|
function isEmployeeAlive(sessionName) {
|
|
2003
2039
|
return getTransport().isAlive(sessionName);
|
|
@@ -2399,7 +2435,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
2399
2435
|
}
|
|
2400
2436
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
2401
2437
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
2402
|
-
const
|
|
2438
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
2439
|
+
const agentRtConfig = {
|
|
2440
|
+
...baseRtConfig,
|
|
2441
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
2442
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
2443
|
+
};
|
|
2403
2444
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
2404
2445
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
2405
2446
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -3037,8 +3078,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
3037
3078
|
const complexity = input.complexity ?? "standard";
|
|
3038
3079
|
const sessionScope = earlySessionScope;
|
|
3039
3080
|
await client.execute({
|
|
3040
|
-
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, created_at, updated_at)
|
|
3041
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3081
|
+
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, created_at, updated_at)
|
|
3082
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3042
3083
|
args: [
|
|
3043
3084
|
id,
|
|
3044
3085
|
input.title,
|
|
@@ -3058,6 +3099,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
3058
3099
|
0,
|
|
3059
3100
|
null,
|
|
3060
3101
|
sessionScope,
|
|
3102
|
+
input.spawnRuntime ?? null,
|
|
3103
|
+
input.spawnModel ?? null,
|
|
3061
3104
|
now,
|
|
3062
3105
|
now
|
|
3063
3106
|
]
|
|
@@ -3114,7 +3157,9 @@ ${input.context}
|
|
|
3114
3157
|
budgetTokens: input.budgetTokens ?? null,
|
|
3115
3158
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
3116
3159
|
tokensUsed: 0,
|
|
3117
|
-
tokensWarnedAt: null
|
|
3160
|
+
tokensWarnedAt: null,
|
|
3161
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
3162
|
+
spawnModel: input.spawnModel ?? null
|
|
3118
3163
|
};
|
|
3119
3164
|
}
|
|
3120
3165
|
async function listTasks(input) {
|
|
@@ -3164,7 +3209,9 @@ async function listTasks(input) {
|
|
|
3164
3209
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
3165
3210
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
3166
3211
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
3167
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
3212
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
3213
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
3214
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
3168
3215
|
}));
|
|
3169
3216
|
}
|
|
3170
3217
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -4631,6 +4678,8 @@ async function updateTask(input) {
|
|
|
4631
4678
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
4632
4679
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
4633
4680
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
4681
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
4682
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
4634
4683
|
nextTask
|
|
4635
4684
|
};
|
|
4636
4685
|
}
|