@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
package/dist/bin/graph-export.js
CHANGED
|
@@ -2765,6 +2765,20 @@ async function ensureSchema() {
|
|
|
2765
2765
|
});
|
|
2766
2766
|
} catch {
|
|
2767
2767
|
}
|
|
2768
|
+
try {
|
|
2769
|
+
await client.execute({
|
|
2770
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2771
|
+
args: []
|
|
2772
|
+
});
|
|
2773
|
+
} catch {
|
|
2774
|
+
}
|
|
2775
|
+
try {
|
|
2776
|
+
await client.execute({
|
|
2777
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2778
|
+
args: []
|
|
2779
|
+
});
|
|
2780
|
+
} catch {
|
|
2781
|
+
}
|
|
2768
2782
|
await client.executeMultiple(`
|
|
2769
2783
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2770
2784
|
content_text,
|
|
@@ -3016,6 +3030,22 @@ async function ensureSchema() {
|
|
|
3016
3030
|
);
|
|
3017
3031
|
} catch {
|
|
3018
3032
|
}
|
|
3033
|
+
for (const col of [
|
|
3034
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3035
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3036
|
+
]) {
|
|
3037
|
+
try {
|
|
3038
|
+
await client.execute(col);
|
|
3039
|
+
} catch {
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
try {
|
|
3043
|
+
await client.execute({
|
|
3044
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3045
|
+
args: []
|
|
3046
|
+
});
|
|
3047
|
+
} catch {
|
|
3048
|
+
}
|
|
3019
3049
|
try {
|
|
3020
3050
|
await client.execute({
|
|
3021
3051
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3058,6 +3088,13 @@ async function ensureSchema() {
|
|
|
3058
3088
|
} catch {
|
|
3059
3089
|
}
|
|
3060
3090
|
}
|
|
3091
|
+
try {
|
|
3092
|
+
await client.execute({
|
|
3093
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3094
|
+
args: []
|
|
3095
|
+
});
|
|
3096
|
+
} catch {
|
|
3097
|
+
}
|
|
3061
3098
|
try {
|
|
3062
3099
|
await client.execute({
|
|
3063
3100
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -4196,6 +4233,20 @@ var init_platform_procedures = __esm({
|
|
|
4196
4233
|
priority: "p1",
|
|
4197
4234
|
content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
4198
4235
|
},
|
|
4236
|
+
// --- Tool guidance ---
|
|
4237
|
+
{
|
|
4238
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4239
|
+
domain: "tools",
|
|
4240
|
+
priority: "p2",
|
|
4241
|
+
content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
|
|
4242
|
+
},
|
|
4243
|
+
// --- Release awareness ---
|
|
4244
|
+
{
|
|
4245
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4246
|
+
domain: "support",
|
|
4247
|
+
priority: "p1",
|
|
4248
|
+
content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
|
|
4249
|
+
},
|
|
4199
4250
|
// --- Platform vs Customer ownership ---
|
|
4200
4251
|
{
|
|
4201
4252
|
title: "What the platform provides vs what you customize",
|
|
@@ -4284,13 +4335,13 @@ var init_platform_procedures = __esm({
|
|
|
4284
4335
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4285
4336
|
domain: "tool-use",
|
|
4286
4337
|
priority: "p1",
|
|
4287
|
-
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4338
|
+
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4288
4339
|
},
|
|
4289
4340
|
{
|
|
4290
4341
|
title: "MCP tools \u2014 task orchestration",
|
|
4291
4342
|
domain: "tool-use",
|
|
4292
4343
|
priority: "p1",
|
|
4293
|
-
content:
|
|
4344
|
+
content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
|
|
4294
4345
|
},
|
|
4295
4346
|
{
|
|
4296
4347
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4320,7 +4371,7 @@ var init_platform_procedures = __esm({
|
|
|
4320
4371
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4321
4372
|
domain: "tool-use",
|
|
4322
4373
|
priority: "p1",
|
|
4323
|
-
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4374
|
+
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4324
4375
|
}
|
|
4325
4376
|
];
|
|
4326
4377
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5004,6 +5055,8 @@ async function writeMemory(record) {
|
|
|
5004
5055
|
source_type: record.source_type ?? null,
|
|
5005
5056
|
tier: record.tier ?? classifyTier(record),
|
|
5006
5057
|
supersedes_id: record.supersedes_id ?? null,
|
|
5058
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5059
|
+
invalid_at: record.invalid_at ?? null,
|
|
5007
5060
|
draft: record.draft ? 1 : 0,
|
|
5008
5061
|
memory_type: memoryType,
|
|
5009
5062
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -5022,7 +5075,8 @@ async function writeMemory(record) {
|
|
|
5022
5075
|
token_cost: record.token_cost ?? null,
|
|
5023
5076
|
audience: record.audience ?? null,
|
|
5024
5077
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5025
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5078
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5079
|
+
procedure_for: record.procedure_for ?? null
|
|
5026
5080
|
};
|
|
5027
5081
|
_pendingRecords.push(dbRow);
|
|
5028
5082
|
orgBus.emit({
|
|
@@ -5077,6 +5131,8 @@ async function flushBatch() {
|
|
|
5077
5131
|
const sourceType = row.source_type ?? null;
|
|
5078
5132
|
const tier = row.tier ?? 3;
|
|
5079
5133
|
const supersedesId = row.supersedes_id ?? null;
|
|
5134
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5135
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5080
5136
|
const draft = row.draft ? 1 : 0;
|
|
5081
5137
|
const memoryType = row.memory_type ?? "raw";
|
|
5082
5138
|
const trajectory = row.trajectory ?? null;
|
|
@@ -5096,15 +5152,16 @@ async function flushBatch() {
|
|
|
5096
5152
|
const audience = row.audience ?? null;
|
|
5097
5153
|
const languageType = row.language_type ?? null;
|
|
5098
5154
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5155
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5099
5156
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5100
5157
|
tool_name, project_name,
|
|
5101
5158
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5102
5159
|
confidence, last_accessed,
|
|
5103
5160
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5104
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5161
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5105
5162
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5106
5163
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5107
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5164
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5108
5165
|
const metaArgs = [
|
|
5109
5166
|
intent,
|
|
5110
5167
|
outcome,
|
|
@@ -5120,7 +5177,8 @@ async function flushBatch() {
|
|
|
5120
5177
|
tokenCost,
|
|
5121
5178
|
audience,
|
|
5122
5179
|
languageType,
|
|
5123
|
-
parentMemoryId
|
|
5180
|
+
parentMemoryId,
|
|
5181
|
+
procedureFor
|
|
5124
5182
|
];
|
|
5125
5183
|
const baseArgs = [
|
|
5126
5184
|
row.id,
|
|
@@ -5149,6 +5207,8 @@ async function flushBatch() {
|
|
|
5149
5207
|
sourceType,
|
|
5150
5208
|
tier,
|
|
5151
5209
|
supersedesId,
|
|
5210
|
+
validFrom,
|
|
5211
|
+
invalidAt,
|
|
5152
5212
|
draft,
|
|
5153
5213
|
memoryType,
|
|
5154
5214
|
trajectory,
|
|
@@ -5156,8 +5216,8 @@ async function flushBatch() {
|
|
|
5156
5216
|
];
|
|
5157
5217
|
return {
|
|
5158
5218
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5159
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5160
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5219
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5220
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5161
5221
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5162
5222
|
};
|
|
5163
5223
|
};
|
|
@@ -5273,6 +5333,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5273
5333
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5274
5334
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5275
5335
|
const args = [agentId];
|
|
5336
|
+
if (options?.asOf) {
|
|
5337
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5338
|
+
args.push(options.asOf, options.asOf);
|
|
5339
|
+
} else {
|
|
5340
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5341
|
+
}
|
|
5276
5342
|
const scope = buildWikiScopeFilter(options, "");
|
|
5277
5343
|
sql += scope.clause;
|
|
5278
5344
|
args.push(...scope.args);
|
|
@@ -2874,6 +2874,20 @@ async function ensureSchema() {
|
|
|
2874
2874
|
});
|
|
2875
2875
|
} catch {
|
|
2876
2876
|
}
|
|
2877
|
+
try {
|
|
2878
|
+
await client.execute({
|
|
2879
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2880
|
+
args: []
|
|
2881
|
+
});
|
|
2882
|
+
} catch {
|
|
2883
|
+
}
|
|
2884
|
+
try {
|
|
2885
|
+
await client.execute({
|
|
2886
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2887
|
+
args: []
|
|
2888
|
+
});
|
|
2889
|
+
} catch {
|
|
2890
|
+
}
|
|
2877
2891
|
await client.executeMultiple(`
|
|
2878
2892
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2879
2893
|
content_text,
|
|
@@ -3125,6 +3139,22 @@ async function ensureSchema() {
|
|
|
3125
3139
|
);
|
|
3126
3140
|
} catch {
|
|
3127
3141
|
}
|
|
3142
|
+
for (const col of [
|
|
3143
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3144
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3145
|
+
]) {
|
|
3146
|
+
try {
|
|
3147
|
+
await client.execute(col);
|
|
3148
|
+
} catch {
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
try {
|
|
3152
|
+
await client.execute({
|
|
3153
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3154
|
+
args: []
|
|
3155
|
+
});
|
|
3156
|
+
} catch {
|
|
3157
|
+
}
|
|
3128
3158
|
try {
|
|
3129
3159
|
await client.execute({
|
|
3130
3160
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3167,6 +3197,13 @@ async function ensureSchema() {
|
|
|
3167
3197
|
} catch {
|
|
3168
3198
|
}
|
|
3169
3199
|
}
|
|
3200
|
+
try {
|
|
3201
|
+
await client.execute({
|
|
3202
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3203
|
+
args: []
|
|
3204
|
+
});
|
|
3205
|
+
} catch {
|
|
3206
|
+
}
|
|
3170
3207
|
try {
|
|
3171
3208
|
await client.execute({
|
|
3172
3209
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -4305,6 +4342,20 @@ var init_platform_procedures = __esm({
|
|
|
4305
4342
|
priority: "p1",
|
|
4306
4343
|
content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
4307
4344
|
},
|
|
4345
|
+
// --- Tool guidance ---
|
|
4346
|
+
{
|
|
4347
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4348
|
+
domain: "tools",
|
|
4349
|
+
priority: "p2",
|
|
4350
|
+
content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
|
|
4351
|
+
},
|
|
4352
|
+
// --- Release awareness ---
|
|
4353
|
+
{
|
|
4354
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4355
|
+
domain: "support",
|
|
4356
|
+
priority: "p1",
|
|
4357
|
+
content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
|
|
4358
|
+
},
|
|
4308
4359
|
// --- Platform vs Customer ownership ---
|
|
4309
4360
|
{
|
|
4310
4361
|
title: "What the platform provides vs what you customize",
|
|
@@ -4393,13 +4444,13 @@ var init_platform_procedures = __esm({
|
|
|
4393
4444
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4394
4445
|
domain: "tool-use",
|
|
4395
4446
|
priority: "p1",
|
|
4396
|
-
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4447
|
+
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4397
4448
|
},
|
|
4398
4449
|
{
|
|
4399
4450
|
title: "MCP tools \u2014 task orchestration",
|
|
4400
4451
|
domain: "tool-use",
|
|
4401
4452
|
priority: "p1",
|
|
4402
|
-
content:
|
|
4453
|
+
content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
|
|
4403
4454
|
},
|
|
4404
4455
|
{
|
|
4405
4456
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4429,7 +4480,7 @@ var init_platform_procedures = __esm({
|
|
|
4429
4480
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4430
4481
|
domain: "tool-use",
|
|
4431
4482
|
priority: "p1",
|
|
4432
|
-
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4483
|
+
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4433
4484
|
}
|
|
4434
4485
|
];
|
|
4435
4486
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5113,6 +5164,8 @@ async function writeMemory(record) {
|
|
|
5113
5164
|
source_type: record.source_type ?? null,
|
|
5114
5165
|
tier: record.tier ?? classifyTier(record),
|
|
5115
5166
|
supersedes_id: record.supersedes_id ?? null,
|
|
5167
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5168
|
+
invalid_at: record.invalid_at ?? null,
|
|
5116
5169
|
draft: record.draft ? 1 : 0,
|
|
5117
5170
|
memory_type: memoryType,
|
|
5118
5171
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -5131,7 +5184,8 @@ async function writeMemory(record) {
|
|
|
5131
5184
|
token_cost: record.token_cost ?? null,
|
|
5132
5185
|
audience: record.audience ?? null,
|
|
5133
5186
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5134
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5187
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5188
|
+
procedure_for: record.procedure_for ?? null
|
|
5135
5189
|
};
|
|
5136
5190
|
_pendingRecords.push(dbRow);
|
|
5137
5191
|
orgBus.emit({
|
|
@@ -5186,6 +5240,8 @@ async function flushBatch() {
|
|
|
5186
5240
|
const sourceType = row.source_type ?? null;
|
|
5187
5241
|
const tier = row.tier ?? 3;
|
|
5188
5242
|
const supersedesId = row.supersedes_id ?? null;
|
|
5243
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5244
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5189
5245
|
const draft = row.draft ? 1 : 0;
|
|
5190
5246
|
const memoryType = row.memory_type ?? "raw";
|
|
5191
5247
|
const trajectory = row.trajectory ?? null;
|
|
@@ -5205,15 +5261,16 @@ async function flushBatch() {
|
|
|
5205
5261
|
const audience = row.audience ?? null;
|
|
5206
5262
|
const languageType = row.language_type ?? null;
|
|
5207
5263
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5264
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5208
5265
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5209
5266
|
tool_name, project_name,
|
|
5210
5267
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5211
5268
|
confidence, last_accessed,
|
|
5212
5269
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5213
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5270
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5214
5271
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5215
5272
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5216
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5273
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5217
5274
|
const metaArgs = [
|
|
5218
5275
|
intent,
|
|
5219
5276
|
outcome,
|
|
@@ -5229,7 +5286,8 @@ async function flushBatch() {
|
|
|
5229
5286
|
tokenCost,
|
|
5230
5287
|
audience,
|
|
5231
5288
|
languageType,
|
|
5232
|
-
parentMemoryId
|
|
5289
|
+
parentMemoryId,
|
|
5290
|
+
procedureFor
|
|
5233
5291
|
];
|
|
5234
5292
|
const baseArgs = [
|
|
5235
5293
|
row.id,
|
|
@@ -5258,6 +5316,8 @@ async function flushBatch() {
|
|
|
5258
5316
|
sourceType,
|
|
5259
5317
|
tier,
|
|
5260
5318
|
supersedesId,
|
|
5319
|
+
validFrom,
|
|
5320
|
+
invalidAt,
|
|
5261
5321
|
draft,
|
|
5262
5322
|
memoryType,
|
|
5263
5323
|
trajectory,
|
|
@@ -5265,8 +5325,8 @@ async function flushBatch() {
|
|
|
5265
5325
|
];
|
|
5266
5326
|
return {
|
|
5267
5327
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5268
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5269
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5328
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5329
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5270
5330
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5271
5331
|
};
|
|
5272
5332
|
};
|
|
@@ -5382,6 +5442,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5382
5442
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5383
5443
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5384
5444
|
const args = [agentId];
|
|
5445
|
+
if (options?.asOf) {
|
|
5446
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5447
|
+
args.push(options.asOf, options.asOf);
|
|
5448
|
+
} else {
|
|
5449
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5450
|
+
}
|
|
5385
5451
|
const scope = buildWikiScopeFilter(options, "");
|
|
5386
5452
|
sql += scope.clause;
|
|
5387
5453
|
args.push(...scope.args);
|
|
@@ -6130,7 +6196,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
6130
6196
|
import os8 from "os";
|
|
6131
6197
|
import path11 from "path";
|
|
6132
6198
|
import { jwtVerify, importSPKI } from "jose";
|
|
6133
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
6199
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
6134
6200
|
var init_license = __esm({
|
|
6135
6201
|
"src/lib/license.ts"() {
|
|
6136
6202
|
"use strict";
|
|
@@ -6138,6 +6204,7 @@ var init_license = __esm({
|
|
|
6138
6204
|
LICENSE_PATH = path11.join(EXE_AI_DIR, "license.key");
|
|
6139
6205
|
CACHE_PATH = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
6140
6206
|
DEVICE_ID_PATH = path11.join(EXE_AI_DIR, "device-id");
|
|
6207
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
6141
6208
|
PLAN_LIMITS = {
|
|
6142
6209
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
6143
6210
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -6652,8 +6719,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
6652
6719
|
const complexity = input.complexity ?? "standard";
|
|
6653
6720
|
const sessionScope = earlySessionScope;
|
|
6654
6721
|
await client.execute({
|
|
6655
|
-
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)
|
|
6656
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
6722
|
+
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)
|
|
6723
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
6657
6724
|
args: [
|
|
6658
6725
|
id,
|
|
6659
6726
|
input.title,
|
|
@@ -6673,6 +6740,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
6673
6740
|
0,
|
|
6674
6741
|
null,
|
|
6675
6742
|
sessionScope,
|
|
6743
|
+
input.spawnRuntime ?? null,
|
|
6744
|
+
input.spawnModel ?? null,
|
|
6676
6745
|
now,
|
|
6677
6746
|
now
|
|
6678
6747
|
]
|
|
@@ -6729,7 +6798,9 @@ ${input.context}
|
|
|
6729
6798
|
budgetTokens: input.budgetTokens ?? null,
|
|
6730
6799
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
6731
6800
|
tokensUsed: 0,
|
|
6732
|
-
tokensWarnedAt: null
|
|
6801
|
+
tokensWarnedAt: null,
|
|
6802
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
6803
|
+
spawnModel: input.spawnModel ?? null
|
|
6733
6804
|
};
|
|
6734
6805
|
}
|
|
6735
6806
|
async function listTasks(input) {
|
|
@@ -6779,7 +6850,9 @@ async function listTasks(input) {
|
|
|
6779
6850
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
6780
6851
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
6781
6852
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
6782
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
6853
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
6854
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
6855
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
6783
6856
|
}));
|
|
6784
6857
|
}
|
|
6785
6858
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -7768,6 +7841,8 @@ async function updateTask(input) {
|
|
|
7768
7841
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
7769
7842
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
7770
7843
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
7844
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
7845
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
7771
7846
|
nextTask
|
|
7772
7847
|
};
|
|
7773
7848
|
}
|
|
@@ -8263,6 +8338,7 @@ function resolveExeSession() {
|
|
|
8263
8338
|
const mySession = getMySession();
|
|
8264
8339
|
if (!mySession) return null;
|
|
8265
8340
|
const fromSessionName = extractRootExe(mySession);
|
|
8341
|
+
let candidate = null;
|
|
8266
8342
|
try {
|
|
8267
8343
|
const key = getSessionKey();
|
|
8268
8344
|
const parentExe = getParentExe(key);
|
|
@@ -8273,13 +8349,47 @@ function resolveExeSession() {
|
|
|
8273
8349
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
8274
8350
|
`
|
|
8275
8351
|
);
|
|
8276
|
-
|
|
8352
|
+
candidate = fromSessionName;
|
|
8353
|
+
} else {
|
|
8354
|
+
candidate = fromCache;
|
|
8277
8355
|
}
|
|
8278
|
-
return fromCache;
|
|
8279
8356
|
}
|
|
8280
8357
|
} catch {
|
|
8281
8358
|
}
|
|
8282
|
-
|
|
8359
|
+
if (!candidate) {
|
|
8360
|
+
candidate = fromSessionName ?? mySession;
|
|
8361
|
+
}
|
|
8362
|
+
if (candidate && isRootSession(candidate)) {
|
|
8363
|
+
try {
|
|
8364
|
+
const transport = getTransport();
|
|
8365
|
+
const liveSessions = transport.listSessions();
|
|
8366
|
+
if (!liveSessions.includes(candidate)) {
|
|
8367
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
8368
|
+
if (liveRoots.length === 1) {
|
|
8369
|
+
process.stderr.write(
|
|
8370
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
8371
|
+
`
|
|
8372
|
+
);
|
|
8373
|
+
return liveRoots[0];
|
|
8374
|
+
} else if (liveRoots.length > 1) {
|
|
8375
|
+
const base = candidate.replace(/\d+$/, "");
|
|
8376
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
8377
|
+
const chosen = match ?? liveRoots[0];
|
|
8378
|
+
process.stderr.write(
|
|
8379
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
8380
|
+
`
|
|
8381
|
+
);
|
|
8382
|
+
return chosen;
|
|
8383
|
+
}
|
|
8384
|
+
process.stderr.write(
|
|
8385
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
8386
|
+
`
|
|
8387
|
+
);
|
|
8388
|
+
}
|
|
8389
|
+
} catch {
|
|
8390
|
+
}
|
|
8391
|
+
}
|
|
8392
|
+
return candidate;
|
|
8283
8393
|
}
|
|
8284
8394
|
function isEmployeeAlive(sessionName) {
|
|
8285
8395
|
return getTransport().isAlive(sessionName);
|
|
@@ -8681,7 +8791,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
8681
8791
|
}
|
|
8682
8792
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
8683
8793
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
8684
|
-
const
|
|
8794
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
8795
|
+
const agentRtConfig = {
|
|
8796
|
+
...baseRtConfig,
|
|
8797
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
8798
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
8799
|
+
};
|
|
8685
8800
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
8686
8801
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
8687
8802
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|