@askexenow/exe-os 0.9.93 → 0.9.95
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 +121 -13
- package/dist/bin/cli.js +1561 -466
- package/dist/bin/customer-readiness.js +61 -0
- package/dist/bin/exe-agent.js +17 -3
- package/dist/bin/exe-assign.js +75 -9
- package/dist/bin/exe-boot.js +114 -12
- package/dist/bin/exe-call.js +17 -3
- package/dist/bin/exe-cloud.js +76 -10
- package/dist/bin/exe-dispatch.js +136 -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 +135 -18
- package/dist/bin/exe-heartbeat.js +121 -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 +121 -13
- package/dist/bin/exe-pending-notifications.js +121 -13
- package/dist/bin/exe-pending-reviews.js +121 -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 +136 -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 +121 -13
- package/dist/bin/exe-support.js +1 -0
- package/dist/bin/exe-team.js +75 -9
- package/dist/bin/git-sweep.js +136 -18
- package/dist/bin/graph-backfill.js +65 -8
- package/dist/bin/graph-export.js +75 -9
- package/dist/bin/intercom-check.js +136 -18
- package/dist/bin/scan-tasks.js +136 -18
- package/dist/bin/setup.js +55 -4
- package/dist/bin/shard-migrate.js +65 -8
- package/dist/bin/stack-update.js +5 -6
- package/dist/bin/update.js +1 -1
- package/dist/gateway/index.js +136 -18
- package/dist/hooks/bug-report-worker.js +136 -18
- package/dist/hooks/codex-stop-task-finalizer.js +126 -14
- package/dist/hooks/commit-complete.js +136 -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 +313 -50
- package/dist/hooks/post-tool-combined.js +436 -13
- package/dist/hooks/pre-compact.js +136 -18
- package/dist/hooks/pre-tool-use.js +121 -13
- package/dist/hooks/prompt-submit.js +194 -19
- package/dist/hooks/session-end.js +136 -18
- package/dist/hooks/session-start.js +146 -13
- package/dist/hooks/stop.js +121 -13
- package/dist/hooks/subagent-stop.js +121 -13
- package/dist/hooks/summary-worker.js +99 -7
- package/dist/index.js +136 -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 +916 -42
- package/dist/lib/hybrid-search.js +100 -9
- package/dist/lib/license.js +1 -1
- package/dist/lib/messaging.js +43 -4
- package/dist/lib/schedules.js +54 -3
- package/dist/lib/store.js +75 -9
- package/dist/lib/tasks.js +61 -9
- package/dist/lib/tmux-routing.js +61 -9
- package/dist/mcp/server.js +878 -42
- package/dist/mcp/tools/create-task.js +70 -12
- package/dist/mcp/tools/list-tasks.js +49 -5
- package/dist/mcp/tools/send-message.js +43 -4
- package/dist/mcp/tools/update-task.js +61 -9
- package/dist/runtime/index.js +136 -18
- package/dist/tui/App.js +135 -18
- package/package.json +1 -1
|
@@ -3018,6 +3018,20 @@ async function ensureSchema() {
|
|
|
3018
3018
|
});
|
|
3019
3019
|
} catch {
|
|
3020
3020
|
}
|
|
3021
|
+
try {
|
|
3022
|
+
await client.execute({
|
|
3023
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3024
|
+
args: []
|
|
3025
|
+
});
|
|
3026
|
+
} catch {
|
|
3027
|
+
}
|
|
3028
|
+
try {
|
|
3029
|
+
await client.execute({
|
|
3030
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3031
|
+
args: []
|
|
3032
|
+
});
|
|
3033
|
+
} catch {
|
|
3034
|
+
}
|
|
3021
3035
|
await client.executeMultiple(`
|
|
3022
3036
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3023
3037
|
content_text,
|
|
@@ -3269,6 +3283,22 @@ async function ensureSchema() {
|
|
|
3269
3283
|
);
|
|
3270
3284
|
} catch {
|
|
3271
3285
|
}
|
|
3286
|
+
for (const col of [
|
|
3287
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3288
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3289
|
+
]) {
|
|
3290
|
+
try {
|
|
3291
|
+
await client.execute(col);
|
|
3292
|
+
} catch {
|
|
3293
|
+
}
|
|
3294
|
+
}
|
|
3295
|
+
try {
|
|
3296
|
+
await client.execute({
|
|
3297
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3298
|
+
args: []
|
|
3299
|
+
});
|
|
3300
|
+
} catch {
|
|
3301
|
+
}
|
|
3272
3302
|
try {
|
|
3273
3303
|
await client.execute({
|
|
3274
3304
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3311,6 +3341,13 @@ async function ensureSchema() {
|
|
|
3311
3341
|
} catch {
|
|
3312
3342
|
}
|
|
3313
3343
|
}
|
|
3344
|
+
try {
|
|
3345
|
+
await client.execute({
|
|
3346
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3347
|
+
args: []
|
|
3348
|
+
});
|
|
3349
|
+
} catch {
|
|
3350
|
+
}
|
|
3314
3351
|
try {
|
|
3315
3352
|
await client.execute({
|
|
3316
3353
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -4449,6 +4486,20 @@ var init_platform_procedures = __esm({
|
|
|
4449
4486
|
priority: "p1",
|
|
4450
4487
|
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."
|
|
4451
4488
|
},
|
|
4489
|
+
// --- Tool guidance ---
|
|
4490
|
+
{
|
|
4491
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4492
|
+
domain: "tools",
|
|
4493
|
+
priority: "p2",
|
|
4494
|
+
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."
|
|
4495
|
+
},
|
|
4496
|
+
// --- Release awareness ---
|
|
4497
|
+
{
|
|
4498
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4499
|
+
domain: "support",
|
|
4500
|
+
priority: "p1",
|
|
4501
|
+
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."
|
|
4502
|
+
},
|
|
4452
4503
|
// --- Platform vs Customer ownership ---
|
|
4453
4504
|
{
|
|
4454
4505
|
title: "What the platform provides vs what you customize",
|
|
@@ -4537,13 +4588,13 @@ var init_platform_procedures = __esm({
|
|
|
4537
4588
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4538
4589
|
domain: "tool-use",
|
|
4539
4590
|
priority: "p1",
|
|
4540
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
4591
|
+
content: `memory(action="recall") / recall_my_memory: search memories (semantic + FTS). Params: as_of (bi-temporal \u2014 what did I know at time X?), kind (decision|procedure|observation|raw|conversation|behavior), retrieval_mode (all|decisions_only|procedures_only|operational|recent_high_value). memory(action="ask_team") / ask_team_memory: search a colleague's memories. memory(action="store") / store_memory: persist a memory. Params: kind, procedure_for (domain tag for procedures). memory(action="commit") / commit_memory: high-importance, survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal window. Requires session_id + target_timestamp. memory(action="get_by_id"): fetch one memory by UUID with full untruncated text. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="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.`
|
|
4541
4592
|
},
|
|
4542
4593
|
{
|
|
4543
4594
|
title: "MCP tools \u2014 task orchestration",
|
|
4544
4595
|
domain: "tool-use",
|
|
4545
4596
|
priority: "p1",
|
|
4546
|
-
content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. 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.'
|
|
4597
|
+
content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Params: blocked_by (task ID for dependency), parent_task_id (subtask hierarchy), reviewer, complexity (routine|standard|complex|critical), budget_tokens (max token cap), budget_fallback_model, spawn_runtime (override runtime: claude|codex|opencode), spawn_model (override model). 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.'
|
|
4547
4598
|
},
|
|
4548
4599
|
{
|
|
4549
4600
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4573,7 +4624,7 @@ var init_platform_procedures = __esm({
|
|
|
4573
4624
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4574
4625
|
domain: "tool-use",
|
|
4575
4626
|
priority: "p1",
|
|
4576
|
-
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.'
|
|
4627
|
+
content: 'config(action="list_employees"): view roster. config(action="set_agent_config"): view or change per-agent runtime + model. Call with no args to show all agents. 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. Supports cloud_action param: status|sync|reupload. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="worker_gate"): check spawn slot availability \u2014 alive/stale/reserved counts vs max. Use before dispatching. config(action="auto_wake_status"): orphaned tasks, blocked tasks, auto-wake retry status. config(action="orchestration_phase"): view/change org phase (phase_1_coo|phase_2_executives|phase_3_parallel_org). 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="pending_work_summary"): pending reviews + messages + notifications in one call. diagnostics(action="rename_employee"): rename an agent across all systems (roster, identity, DB, symlinks). diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4577
4628
|
}
|
|
4578
4629
|
];
|
|
4579
4630
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5257,6 +5308,8 @@ async function writeMemory(record) {
|
|
|
5257
5308
|
source_type: record.source_type ?? null,
|
|
5258
5309
|
tier: record.tier ?? classifyTier(record),
|
|
5259
5310
|
supersedes_id: record.supersedes_id ?? null,
|
|
5311
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5312
|
+
invalid_at: record.invalid_at ?? null,
|
|
5260
5313
|
draft: record.draft ? 1 : 0,
|
|
5261
5314
|
memory_type: memoryType,
|
|
5262
5315
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -5275,7 +5328,8 @@ async function writeMemory(record) {
|
|
|
5275
5328
|
token_cost: record.token_cost ?? null,
|
|
5276
5329
|
audience: record.audience ?? null,
|
|
5277
5330
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5278
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5331
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5332
|
+
procedure_for: record.procedure_for ?? null
|
|
5279
5333
|
};
|
|
5280
5334
|
_pendingRecords.push(dbRow);
|
|
5281
5335
|
orgBus.emit({
|
|
@@ -5330,6 +5384,8 @@ async function flushBatch() {
|
|
|
5330
5384
|
const sourceType = row.source_type ?? null;
|
|
5331
5385
|
const tier = row.tier ?? 3;
|
|
5332
5386
|
const supersedesId = row.supersedes_id ?? null;
|
|
5387
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5388
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5333
5389
|
const draft = row.draft ? 1 : 0;
|
|
5334
5390
|
const memoryType = row.memory_type ?? "raw";
|
|
5335
5391
|
const trajectory = row.trajectory ?? null;
|
|
@@ -5349,15 +5405,16 @@ async function flushBatch() {
|
|
|
5349
5405
|
const audience = row.audience ?? null;
|
|
5350
5406
|
const languageType = row.language_type ?? null;
|
|
5351
5407
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5408
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5352
5409
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5353
5410
|
tool_name, project_name,
|
|
5354
5411
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5355
5412
|
confidence, last_accessed,
|
|
5356
5413
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5357
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5414
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5358
5415
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5359
5416
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5360
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5417
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5361
5418
|
const metaArgs = [
|
|
5362
5419
|
intent,
|
|
5363
5420
|
outcome,
|
|
@@ -5373,7 +5430,8 @@ async function flushBatch() {
|
|
|
5373
5430
|
tokenCost,
|
|
5374
5431
|
audience,
|
|
5375
5432
|
languageType,
|
|
5376
|
-
parentMemoryId
|
|
5433
|
+
parentMemoryId,
|
|
5434
|
+
procedureFor
|
|
5377
5435
|
];
|
|
5378
5436
|
const baseArgs = [
|
|
5379
5437
|
row.id,
|
|
@@ -5402,6 +5460,8 @@ async function flushBatch() {
|
|
|
5402
5460
|
sourceType,
|
|
5403
5461
|
tier,
|
|
5404
5462
|
supersedesId,
|
|
5463
|
+
validFrom,
|
|
5464
|
+
invalidAt,
|
|
5405
5465
|
draft,
|
|
5406
5466
|
memoryType,
|
|
5407
5467
|
trajectory,
|
|
@@ -5409,8 +5469,8 @@ async function flushBatch() {
|
|
|
5409
5469
|
];
|
|
5410
5470
|
return {
|
|
5411
5471
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5412
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5413
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5472
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5473
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5414
5474
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5415
5475
|
};
|
|
5416
5476
|
};
|
|
@@ -5526,6 +5586,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5526
5586
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5527
5587
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5528
5588
|
const args = [agentId];
|
|
5589
|
+
if (options?.asOf) {
|
|
5590
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5591
|
+
args.push(options.asOf, options.asOf);
|
|
5592
|
+
} else {
|
|
5593
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5594
|
+
}
|
|
5529
5595
|
const scope = buildWikiScopeFilter(options, "");
|
|
5530
5596
|
sql += scope.clause;
|
|
5531
5597
|
args.push(...scope.args);
|
|
@@ -6850,6 +6916,19 @@ __export(hybrid_search_exports, {
|
|
|
6850
6916
|
rrfMerge: () => rrfMerge,
|
|
6851
6917
|
rrfMergeMulti: () => rrfMergeMulti
|
|
6852
6918
|
});
|
|
6919
|
+
function buildTemporalFilter(options, columnPrefix) {
|
|
6920
|
+
const asOf = options?.asOf;
|
|
6921
|
+
if (asOf) {
|
|
6922
|
+
return {
|
|
6923
|
+
clause: ` AND (${columnPrefix}valid_from IS NULL OR ${columnPrefix}valid_from <= ?) AND (${columnPrefix}invalid_at IS NULL OR ${columnPrefix}invalid_at > ?)`,
|
|
6924
|
+
args: [asOf, asOf]
|
|
6925
|
+
};
|
|
6926
|
+
}
|
|
6927
|
+
return {
|
|
6928
|
+
clause: ` AND ${columnPrefix}invalid_at IS NULL`,
|
|
6929
|
+
args: []
|
|
6930
|
+
};
|
|
6931
|
+
}
|
|
6853
6932
|
function appendMemoryTypeFilter(sql, args, column, options) {
|
|
6854
6933
|
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
6855
6934
|
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
@@ -7082,6 +7161,9 @@ async function estimateCardinality(agentId, options) {
|
|
|
7082
7161
|
AND COALESCE(status, 'active') = 'active'
|
|
7083
7162
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
7084
7163
|
const args = [agentId];
|
|
7164
|
+
const temporal = buildTemporalFilter(options, "");
|
|
7165
|
+
sql += temporal.clause;
|
|
7166
|
+
args.push(...temporal.args);
|
|
7085
7167
|
const rawVisibility = buildRawVisibilityFilter(options, "");
|
|
7086
7168
|
sql += rawVisibility.clause;
|
|
7087
7169
|
args.push(...rawVisibility.args);
|
|
@@ -7210,6 +7292,9 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
|
7210
7292
|
AND m.agent_id = ?${statusFilter}${draftFilter}
|
|
7211
7293
|
AND COALESCE(m.confidence, 0.7) >= 0.3`;
|
|
7212
7294
|
const args = [matchExpr, agentId];
|
|
7295
|
+
const temporal = buildTemporalFilter(options, "m.");
|
|
7296
|
+
sql += temporal.clause;
|
|
7297
|
+
args.push(...temporal.args);
|
|
7213
7298
|
const scope = buildWikiScopeFilter(options, "m.");
|
|
7214
7299
|
sql += scope.clause;
|
|
7215
7300
|
args.push(...scope.args);
|
|
@@ -7322,6 +7407,9 @@ async function recentRecords(agentId, options, limit, textFilter) {
|
|
|
7322
7407
|
WHERE agent_id = ?${statusFilter}${draftFilter}
|
|
7323
7408
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
7324
7409
|
const args = [agentId];
|
|
7410
|
+
const temporal = buildTemporalFilter(options, "");
|
|
7411
|
+
sql += temporal.clause;
|
|
7412
|
+
args.push(...temporal.args);
|
|
7325
7413
|
const scope = buildWikiScopeFilter(options, "");
|
|
7326
7414
|
sql += scope.clause;
|
|
7327
7415
|
args.push(...scope.args);
|
|
@@ -7422,6 +7510,9 @@ async function trajectoryBypass(queryText, agentId, options, limit) {
|
|
|
7422
7510
|
AND json_extract(trajectory, '$.tool') = ?
|
|
7423
7511
|
AND agent_id = ?${statusFilter}${draftFilter}`;
|
|
7424
7512
|
const args = [toolName, agentId];
|
|
7513
|
+
const temporal = buildTemporalFilter(options, "");
|
|
7514
|
+
sql += temporal.clause;
|
|
7515
|
+
args.push(...temporal.args);
|
|
7425
7516
|
const rawVisibility = buildRawVisibilityFilter(options, "");
|
|
7426
7517
|
sql += rawVisibility.clause;
|
|
7427
7518
|
args.push(...rawVisibility.args);
|
|
@@ -7754,6 +7845,236 @@ var init_active_agent2 = __esm({
|
|
|
7754
7845
|
}
|
|
7755
7846
|
});
|
|
7756
7847
|
|
|
7848
|
+
// src/mcp/tool-gates.ts
|
|
7849
|
+
var tool_gates_exports = {};
|
|
7850
|
+
__export(tool_gates_exports, {
|
|
7851
|
+
TOOL_CATEGORIES: () => TOOL_CATEGORIES,
|
|
7852
|
+
TOOL_GATES: () => TOOL_GATES,
|
|
7853
|
+
isToolAllowed: () => isToolAllowed,
|
|
7854
|
+
isToolAllowedForPlan: () => isToolAllowedForPlan
|
|
7855
|
+
});
|
|
7856
|
+
function isToolAllowedForPlan(registerFnName, plan) {
|
|
7857
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
7858
|
+
if (!category) return true;
|
|
7859
|
+
const requiredPlan = PLAN_GATES[category] ?? "free";
|
|
7860
|
+
return PLAN_TIERS[plan] >= PLAN_TIERS[requiredPlan];
|
|
7861
|
+
}
|
|
7862
|
+
function isChiefOfStaffRole(role) {
|
|
7863
|
+
const normalized = (role ?? "").trim().toLowerCase();
|
|
7864
|
+
return normalized === "chief of staff" || normalized === "executive assistant";
|
|
7865
|
+
}
|
|
7866
|
+
function isToolAllowed(registerFnName) {
|
|
7867
|
+
const role = process.env.AGENT_ROLE;
|
|
7868
|
+
if (!role) return true;
|
|
7869
|
+
if (isChiefOfStaffRole(role)) {
|
|
7870
|
+
return CHIEF_OF_STAFF_READ_TOOLS.has(registerFnName);
|
|
7871
|
+
}
|
|
7872
|
+
const category = TOOL_CATEGORIES[registerFnName];
|
|
7873
|
+
if (!category) return true;
|
|
7874
|
+
const allowedRoles = TOOL_GATES[category];
|
|
7875
|
+
if (!allowedRoles || allowedRoles.length === 0) return true;
|
|
7876
|
+
return allowedRoles.includes(role);
|
|
7877
|
+
}
|
|
7878
|
+
var TOOL_GATES, TOOL_CATEGORIES, PLAN_TIERS, PLAN_GATES, CHIEF_OF_STAFF_READ_TOOLS;
|
|
7879
|
+
var init_tool_gates = __esm({
|
|
7880
|
+
"src/mcp/tool-gates.ts"() {
|
|
7881
|
+
"use strict";
|
|
7882
|
+
TOOL_GATES = {
|
|
7883
|
+
core: [],
|
|
7884
|
+
// all agents — recall, store, ask_team, commit, search, session, consolidate, cardinality, behavior, identity, decisions
|
|
7885
|
+
tasks: [],
|
|
7886
|
+
// all agents — create, list, get, update, close, checkpoint, resume
|
|
7887
|
+
comms: [],
|
|
7888
|
+
// all agents — send_message, acknowledge
|
|
7889
|
+
reminders: [],
|
|
7890
|
+
// all agents — create, list, complete, reminder
|
|
7891
|
+
"graph-read": [],
|
|
7892
|
+
// all agents — query_relationships, get_entity_neighbors, get_hot_entities, get_graph_stats, find_similar_trajectories, code_context
|
|
7893
|
+
"graph-write": ["COO", "CTO"],
|
|
7894
|
+
// merge_entities, export_graph
|
|
7895
|
+
wiki: ["COO", "Wiki Agent"],
|
|
7896
|
+
// read/list curated wiki pages
|
|
7897
|
+
crm: ["COO", "CRM Agent"],
|
|
7898
|
+
// CRM read/list/get and legacy add/list/get person
|
|
7899
|
+
"raw-data": ["COO", "CTO", "Gateway Agent", "CRM Agent", "Wiki Agent"],
|
|
7900
|
+
// capped read-only raw landing-pad access
|
|
7901
|
+
documents: ["COO", "CTO", "Wiki Agent"],
|
|
7902
|
+
// ingest, list, purge, set_importance, rerank
|
|
7903
|
+
gateway: ["COO", "Gateway Agent"],
|
|
7904
|
+
// send_whatsapp, query_conversations, query_company_brain, company_actions
|
|
7905
|
+
admin: ["COO"],
|
|
7906
|
+
// deploy, backup, daemon health, auto-wake, worker gate, memory audit, consolidation, cloud sync, agent config, list employees, agent spend, sessions, session kills
|
|
7907
|
+
licensing: ["COO"],
|
|
7908
|
+
// get/create/list/activate license
|
|
7909
|
+
orchestration: ["COO"]
|
|
7910
|
+
// triggers, load_skill, starter_pack, export/import orchestration, global procedures
|
|
7911
|
+
};
|
|
7912
|
+
TOOL_CATEGORIES = {
|
|
7913
|
+
// core
|
|
7914
|
+
registerMemory: "core",
|
|
7915
|
+
registerRecallMyMemory: "core",
|
|
7916
|
+
registerAskTeamMemory: "core",
|
|
7917
|
+
registerGetSessionContext: "core",
|
|
7918
|
+
registerGetMemoryById: "core",
|
|
7919
|
+
registerStoreMemory: "core",
|
|
7920
|
+
registerCommitMemory: "core",
|
|
7921
|
+
registerSearchEverything: "core",
|
|
7922
|
+
registerConsolidateMemories: "core",
|
|
7923
|
+
registerGetMemoryCardinality: "core",
|
|
7924
|
+
registerStoreBehavior: "core",
|
|
7925
|
+
registerListBehaviors: "core",
|
|
7926
|
+
registerDeactivateBehavior: "core",
|
|
7927
|
+
registerBehavior: "core",
|
|
7928
|
+
registerStoreDecision: "core",
|
|
7929
|
+
registerGetDecision: "core",
|
|
7930
|
+
registerCreateBugReport: "core",
|
|
7931
|
+
registerSupportTools: "core",
|
|
7932
|
+
registerCliParityTools: "admin",
|
|
7933
|
+
registerGetSessionEvents: "core",
|
|
7934
|
+
registerGetLastAssistantResponse: "core",
|
|
7935
|
+
registerCodeContext: "graph-read",
|
|
7936
|
+
// consolidated tools
|
|
7937
|
+
registerDecision: "core",
|
|
7938
|
+
registerSession: "core",
|
|
7939
|
+
registerSupportConsolidated: "core",
|
|
7940
|
+
registerDiagnostics: "admin",
|
|
7941
|
+
registerListBugReports: "admin",
|
|
7942
|
+
registerGetBugReport: "admin",
|
|
7943
|
+
registerTriageBugReport: "admin",
|
|
7944
|
+
registerIdentity: "core",
|
|
7945
|
+
registerGetIdentity: "core",
|
|
7946
|
+
registerUpdateIdentity: "core",
|
|
7947
|
+
// tasks
|
|
7948
|
+
registerTask: "tasks",
|
|
7949
|
+
registerCreateTask: "tasks",
|
|
7950
|
+
registerListTasks: "tasks",
|
|
7951
|
+
registerUpdateTask: "tasks",
|
|
7952
|
+
registerCloseTask: "tasks",
|
|
7953
|
+
registerGetTask: "tasks",
|
|
7954
|
+
registerCheckpointTask: "tasks",
|
|
7955
|
+
registerResumeEmployee: "tasks",
|
|
7956
|
+
// comms
|
|
7957
|
+
registerMessage: "comms",
|
|
7958
|
+
registerSendMessage: "comms",
|
|
7959
|
+
registerAcknowledgeMessages: "comms",
|
|
7960
|
+
// reminders
|
|
7961
|
+
registerCreateReminder: "reminders",
|
|
7962
|
+
registerListReminders: "reminders",
|
|
7963
|
+
registerCompleteReminder: "reminders",
|
|
7964
|
+
registerReminder: "reminders",
|
|
7965
|
+
// graph-read
|
|
7966
|
+
registerGraph: "graph-read",
|
|
7967
|
+
registerQueryRelationships: "graph-read",
|
|
7968
|
+
registerGetEntityNeighbors: "graph-read",
|
|
7969
|
+
registerGetHotEntities: "graph-read",
|
|
7970
|
+
registerGetGraphStats: "graph-read",
|
|
7971
|
+
registerFindSimilarTrajectories: "graph-read",
|
|
7972
|
+
// graph-write
|
|
7973
|
+
registerMergeEntities: "graph-write",
|
|
7974
|
+
registerExportGraph: "graph-write",
|
|
7975
|
+
// wiki
|
|
7976
|
+
registerWiki: "wiki",
|
|
7977
|
+
registerCreateWikiPage: "wiki",
|
|
7978
|
+
registerListWikiPages: "wiki",
|
|
7979
|
+
registerGetWikiPage: "wiki",
|
|
7980
|
+
// crm
|
|
7981
|
+
registerCrm: "crm",
|
|
7982
|
+
registerRawData: "raw-data",
|
|
7983
|
+
registerAddPerson: "crm",
|
|
7984
|
+
registerListPeople: "crm",
|
|
7985
|
+
registerGetPerson: "crm",
|
|
7986
|
+
// documents
|
|
7987
|
+
registerDocument: "documents",
|
|
7988
|
+
registerIngestDocument: "documents",
|
|
7989
|
+
registerListDocuments: "documents",
|
|
7990
|
+
registerPurgeDocument: "documents",
|
|
7991
|
+
registerSetDocumentImportance: "documents",
|
|
7992
|
+
registerRerankDocuments: "documents",
|
|
7993
|
+
// gateway
|
|
7994
|
+
registerGateway: "gateway",
|
|
7995
|
+
registerSendWhatsapp: "gateway",
|
|
7996
|
+
registerQueryConversations: "gateway",
|
|
7997
|
+
registerQueryCompanyBrain: "gateway",
|
|
7998
|
+
registerCompanyActions: "gateway",
|
|
7999
|
+
// admin
|
|
8000
|
+
registerConfig: "admin",
|
|
8001
|
+
registerDeployClient: "admin",
|
|
8002
|
+
registerBackupVps: "admin",
|
|
8003
|
+
registerGetDaemonHealth: "admin",
|
|
8004
|
+
registerMcpPing: "core",
|
|
8005
|
+
registerGetAutoWakeStatus: "admin",
|
|
8006
|
+
registerGetWorkerGate: "admin",
|
|
8007
|
+
registerRunMemoryAudit: "admin",
|
|
8008
|
+
registerRunConsolidation: "admin",
|
|
8009
|
+
registerCloudSync: "admin",
|
|
8010
|
+
registerOrchestrationPhase: "admin",
|
|
8011
|
+
registerSetAgentConfig: "admin",
|
|
8012
|
+
registerListEmployees: "admin",
|
|
8013
|
+
registerGetAgentSpend: "admin",
|
|
8014
|
+
registerListAgentSessions: "admin",
|
|
8015
|
+
registerGetSessionKills: "admin",
|
|
8016
|
+
// licensing
|
|
8017
|
+
registerGetLicenseStatus: "licensing",
|
|
8018
|
+
registerCreateLicense: "licensing",
|
|
8019
|
+
registerListLicenses: "licensing",
|
|
8020
|
+
registerActivateLicense: "licensing",
|
|
8021
|
+
// orchestration
|
|
8022
|
+
registerCreateTrigger: "orchestration",
|
|
8023
|
+
registerListTriggers: "orchestration",
|
|
8024
|
+
registerApplyStarterPack: "orchestration",
|
|
8025
|
+
registerLoadSkill: "orchestration",
|
|
8026
|
+
registerExportOrchestration: "orchestration",
|
|
8027
|
+
registerImportOrchestration: "orchestration",
|
|
8028
|
+
registerCompanyProcedure: "orchestration",
|
|
8029
|
+
registerGlobalProcedure: "orchestration",
|
|
8030
|
+
registerStoreGlobalProcedure: "orchestration",
|
|
8031
|
+
registerListGlobalProcedures: "orchestration",
|
|
8032
|
+
registerDeactivateGlobalProcedure: "orchestration"
|
|
8033
|
+
};
|
|
8034
|
+
PLAN_TIERS = {
|
|
8035
|
+
free: 0,
|
|
8036
|
+
pro: 1,
|
|
8037
|
+
team: 2,
|
|
8038
|
+
agency: 3,
|
|
8039
|
+
enterprise: 4
|
|
8040
|
+
};
|
|
8041
|
+
PLAN_GATES = {
|
|
8042
|
+
core: "free",
|
|
8043
|
+
tasks: "free",
|
|
8044
|
+
comms: "free",
|
|
8045
|
+
reminders: "free",
|
|
8046
|
+
"graph-read": "free",
|
|
8047
|
+
licensing: "free",
|
|
8048
|
+
// always allow checking/managing own license
|
|
8049
|
+
"graph-write": "pro",
|
|
8050
|
+
wiki: "pro",
|
|
8051
|
+
crm: "pro",
|
|
8052
|
+
"raw-data": "pro",
|
|
8053
|
+
documents: "pro",
|
|
8054
|
+
gateway: "pro",
|
|
8055
|
+
admin: "pro",
|
|
8056
|
+
orchestration: "pro"
|
|
8057
|
+
};
|
|
8058
|
+
CHIEF_OF_STAFF_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
8059
|
+
"registerRecallMyMemory",
|
|
8060
|
+
"registerAskTeamMemory",
|
|
8061
|
+
"registerGetMemoryById",
|
|
8062
|
+
"registerGetSessionContext",
|
|
8063
|
+
"registerGetSessionEvents",
|
|
8064
|
+
"registerGetLastAssistantResponse",
|
|
8065
|
+
"registerSearchEverything",
|
|
8066
|
+
"registerGetDecision",
|
|
8067
|
+
"registerGetIdentity",
|
|
8068
|
+
"registerMcpPing",
|
|
8069
|
+
"registerListTasks",
|
|
8070
|
+
"registerGetTask",
|
|
8071
|
+
"registerListReminders",
|
|
8072
|
+
"registerQueryConversations",
|
|
8073
|
+
"registerQueryCompanyBrain"
|
|
8074
|
+
]);
|
|
8075
|
+
}
|
|
8076
|
+
});
|
|
8077
|
+
|
|
7757
8078
|
// src/bin/fast-db-init.ts
|
|
7758
8079
|
var fast_db_init_exports = {};
|
|
7759
8080
|
__export(fast_db_init_exports, {
|
|
@@ -8036,7 +8357,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
8036
8357
|
import os8 from "os";
|
|
8037
8358
|
import path15 from "path";
|
|
8038
8359
|
import { jwtVerify, importSPKI } from "jose";
|
|
8039
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
8360
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
8040
8361
|
var init_license = __esm({
|
|
8041
8362
|
"src/lib/license.ts"() {
|
|
8042
8363
|
"use strict";
|
|
@@ -8044,6 +8365,7 @@ var init_license = __esm({
|
|
|
8044
8365
|
LICENSE_PATH = path15.join(EXE_AI_DIR, "license.key");
|
|
8045
8366
|
CACHE_PATH = path15.join(EXE_AI_DIR, "license-cache.json");
|
|
8046
8367
|
DEVICE_ID_PATH = path15.join(EXE_AI_DIR, "device-id");
|
|
8368
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
8047
8369
|
}
|
|
8048
8370
|
});
|
|
8049
8371
|
|
|
@@ -8087,6 +8409,9 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
8087
8409
|
function getMySession() {
|
|
8088
8410
|
return getTransport().getMySession();
|
|
8089
8411
|
}
|
|
8412
|
+
function isRootSession(name) {
|
|
8413
|
+
return name.length > 0 && !name.includes("-");
|
|
8414
|
+
}
|
|
8090
8415
|
function extractRootExe(name) {
|
|
8091
8416
|
if (!name) return null;
|
|
8092
8417
|
if (!name.includes("-")) return name;
|
|
@@ -8102,9 +8427,13 @@ function getParentExe(sessionKey) {
|
|
|
8102
8427
|
}
|
|
8103
8428
|
}
|
|
8104
8429
|
function resolveExeSession() {
|
|
8430
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
8431
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
8432
|
+
}
|
|
8105
8433
|
const mySession = getMySession();
|
|
8106
8434
|
if (!mySession) return null;
|
|
8107
8435
|
const fromSessionName = extractRootExe(mySession);
|
|
8436
|
+
let candidate = null;
|
|
8108
8437
|
try {
|
|
8109
8438
|
const key = getSessionKey();
|
|
8110
8439
|
const parentExe = getParentExe(key);
|
|
@@ -8115,13 +8444,47 @@ function resolveExeSession() {
|
|
|
8115
8444
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
8116
8445
|
`
|
|
8117
8446
|
);
|
|
8118
|
-
|
|
8447
|
+
candidate = fromSessionName;
|
|
8448
|
+
} else {
|
|
8449
|
+
candidate = fromCache;
|
|
8119
8450
|
}
|
|
8120
|
-
return fromCache;
|
|
8121
8451
|
}
|
|
8122
8452
|
} catch {
|
|
8123
8453
|
}
|
|
8124
|
-
|
|
8454
|
+
if (!candidate) {
|
|
8455
|
+
candidate = fromSessionName ?? mySession;
|
|
8456
|
+
}
|
|
8457
|
+
if (candidate && isRootSession(candidate)) {
|
|
8458
|
+
try {
|
|
8459
|
+
const transport = getTransport();
|
|
8460
|
+
const liveSessions = transport.listSessions();
|
|
8461
|
+
if (!liveSessions.includes(candidate)) {
|
|
8462
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
8463
|
+
if (liveRoots.length === 1) {
|
|
8464
|
+
process.stderr.write(
|
|
8465
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
8466
|
+
`
|
|
8467
|
+
);
|
|
8468
|
+
return liveRoots[0];
|
|
8469
|
+
} else if (liveRoots.length > 1) {
|
|
8470
|
+
const base = candidate.replace(/\d+$/, "");
|
|
8471
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
8472
|
+
const chosen = match ?? liveRoots[0];
|
|
8473
|
+
process.stderr.write(
|
|
8474
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
8475
|
+
`
|
|
8476
|
+
);
|
|
8477
|
+
return chosen;
|
|
8478
|
+
}
|
|
8479
|
+
process.stderr.write(
|
|
8480
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
8481
|
+
`
|
|
8482
|
+
);
|
|
8483
|
+
}
|
|
8484
|
+
} catch {
|
|
8485
|
+
}
|
|
8486
|
+
}
|
|
8487
|
+
return candidate;
|
|
8125
8488
|
}
|
|
8126
8489
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
8127
8490
|
var init_tmux_routing = __esm({
|
|
@@ -8651,6 +9014,66 @@ ${context}`
|
|
|
8651
9014
|
}
|
|
8652
9015
|
} catch {
|
|
8653
9016
|
}
|
|
9017
|
+
try {
|
|
9018
|
+
const payload = JSON.parse(input);
|
|
9019
|
+
const toolName = String(payload.tool_name ?? "");
|
|
9020
|
+
const { getActiveAgent: getActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent2(), active_agent_exports));
|
|
9021
|
+
const driftAgent = getActiveAgent2();
|
|
9022
|
+
if (driftAgent.agentId !== "default" && toolName) {
|
|
9023
|
+
const { existsSync: driftExists, readFileSync: driftRead, writeFileSync: driftWrite, mkdirSync: driftMkdir } = await import("fs");
|
|
9024
|
+
const driftPath = await import("path");
|
|
9025
|
+
const { TOOL_CATEGORIES: TOOL_CATEGORIES2, TOOL_GATES: TOOL_GATES2 } = await Promise.resolve().then(() => (init_tool_gates(), tool_gates_exports));
|
|
9026
|
+
const normalized = toolName.replace(/[_-]/g, "").toLowerCase();
|
|
9027
|
+
let toolCategory = "unknown";
|
|
9028
|
+
for (const [registerFn, cat] of Object.entries(TOOL_CATEGORIES2)) {
|
|
9029
|
+
const fnNormalized = registerFn.replace(/^register/, "").toLowerCase();
|
|
9030
|
+
if (fnNormalized === normalized) {
|
|
9031
|
+
toolCategory = cat;
|
|
9032
|
+
break;
|
|
9033
|
+
}
|
|
9034
|
+
}
|
|
9035
|
+
const gateRoles = TOOL_GATES2[toolCategory];
|
|
9036
|
+
const isRestricted = gateRoles && gateRoles.length > 0;
|
|
9037
|
+
const isAllowed = !isRestricted || gateRoles.includes(driftAgent.agentRole);
|
|
9038
|
+
if (isRestricted && !isAllowed) {
|
|
9039
|
+
const cacheDir = driftPath.join(
|
|
9040
|
+
process.env.EXE_OS_DIR ?? driftPath.join(process.env.HOME ?? "", ".exe-os"),
|
|
9041
|
+
"session-cache"
|
|
9042
|
+
);
|
|
9043
|
+
driftMkdir(cacheDir, { recursive: true });
|
|
9044
|
+
const counterFile = driftPath.join(cacheDir, `drift-counter-${driftAgent.agentId}.json`);
|
|
9045
|
+
let mismatches = [];
|
|
9046
|
+
try {
|
|
9047
|
+
if (driftExists(counterFile)) {
|
|
9048
|
+
const data = JSON.parse(driftRead(counterFile, "utf8"));
|
|
9049
|
+
mismatches = Array.isArray(data.mismatches) ? data.mismatches : [];
|
|
9050
|
+
}
|
|
9051
|
+
} catch {
|
|
9052
|
+
}
|
|
9053
|
+
mismatches.push(`${toolName} (${toolCategory})`);
|
|
9054
|
+
driftWrite(counterFile, JSON.stringify({
|
|
9055
|
+
mismatches,
|
|
9056
|
+
count: mismatches.length,
|
|
9057
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9058
|
+
}));
|
|
9059
|
+
const MISMATCH_THRESHOLD = 3;
|
|
9060
|
+
if (mismatches.length >= MISMATCH_THRESHOLD) {
|
|
9061
|
+
process.stderr.write(
|
|
9062
|
+
`[post-tool] ${driftAgent.agentId} has ${mismatches.length} tool-category mismatches: ${mismatches.slice(-3).join(", ")}. Injecting scope reminder.
|
|
9063
|
+
`
|
|
9064
|
+
);
|
|
9065
|
+
process.stdout.write(JSON.stringify({
|
|
9066
|
+
hookSpecificOutput: {
|
|
9067
|
+
hookEventName: "PostToolUse",
|
|
9068
|
+
additionalContext: `## Scope Reminder
|
|
9069
|
+
You are **${driftAgent.agentId}** (${driftAgent.agentRole}). You've used ${mismatches.length} tools outside your expected scope: ${mismatches.slice(-3).join(", ")}. Stay within your role. If this work was delegated to you, continue \u2014 otherwise, route it to the appropriate team member.`
|
|
9070
|
+
}
|
|
9071
|
+
}));
|
|
9072
|
+
}
|
|
9073
|
+
}
|
|
9074
|
+
}
|
|
9075
|
+
} catch {
|
|
9076
|
+
}
|
|
8654
9077
|
try {
|
|
8655
9078
|
const data = JSON.parse(input);
|
|
8656
9079
|
const { getActiveAgent: getActiveAgent2 } = await Promise.resolve().then(() => (init_active_agent2(), active_agent_exports));
|