@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
|
@@ -3069,6 +3069,20 @@ async function ensureSchema() {
|
|
|
3069
3069
|
});
|
|
3070
3070
|
} catch {
|
|
3071
3071
|
}
|
|
3072
|
+
try {
|
|
3073
|
+
await client.execute({
|
|
3074
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3075
|
+
args: []
|
|
3076
|
+
});
|
|
3077
|
+
} catch {
|
|
3078
|
+
}
|
|
3079
|
+
try {
|
|
3080
|
+
await client.execute({
|
|
3081
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3082
|
+
args: []
|
|
3083
|
+
});
|
|
3084
|
+
} catch {
|
|
3085
|
+
}
|
|
3072
3086
|
await client.executeMultiple(`
|
|
3073
3087
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3074
3088
|
content_text,
|
|
@@ -3320,6 +3334,22 @@ async function ensureSchema() {
|
|
|
3320
3334
|
);
|
|
3321
3335
|
} catch {
|
|
3322
3336
|
}
|
|
3337
|
+
for (const col of [
|
|
3338
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3339
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3340
|
+
]) {
|
|
3341
|
+
try {
|
|
3342
|
+
await client.execute(col);
|
|
3343
|
+
} catch {
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
try {
|
|
3347
|
+
await client.execute({
|
|
3348
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3349
|
+
args: []
|
|
3350
|
+
});
|
|
3351
|
+
} catch {
|
|
3352
|
+
}
|
|
3323
3353
|
try {
|
|
3324
3354
|
await client.execute({
|
|
3325
3355
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3362,6 +3392,13 @@ async function ensureSchema() {
|
|
|
3362
3392
|
} catch {
|
|
3363
3393
|
}
|
|
3364
3394
|
}
|
|
3395
|
+
try {
|
|
3396
|
+
await client.execute({
|
|
3397
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3398
|
+
args: []
|
|
3399
|
+
});
|
|
3400
|
+
} catch {
|
|
3401
|
+
}
|
|
3365
3402
|
try {
|
|
3366
3403
|
await client.execute({
|
|
3367
3404
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3422,7 +3459,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3422
3459
|
import os7 from "os";
|
|
3423
3460
|
import path10 from "path";
|
|
3424
3461
|
import { jwtVerify, importSPKI } from "jose";
|
|
3425
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
3462
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
3426
3463
|
var init_license = __esm({
|
|
3427
3464
|
"src/lib/license.ts"() {
|
|
3428
3465
|
"use strict";
|
|
@@ -3430,6 +3467,7 @@ var init_license = __esm({
|
|
|
3430
3467
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3431
3468
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3432
3469
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3470
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3433
3471
|
}
|
|
3434
3472
|
});
|
|
3435
3473
|
|
|
@@ -3473,6 +3511,9 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
3473
3511
|
function getMySession() {
|
|
3474
3512
|
return getTransport().getMySession();
|
|
3475
3513
|
}
|
|
3514
|
+
function isRootSession(name) {
|
|
3515
|
+
return name.length > 0 && !name.includes("-");
|
|
3516
|
+
}
|
|
3476
3517
|
function extractRootExe(name) {
|
|
3477
3518
|
if (!name) return null;
|
|
3478
3519
|
if (!name.includes("-")) return name;
|
|
@@ -3488,9 +3529,13 @@ function getParentExe(sessionKey) {
|
|
|
3488
3529
|
}
|
|
3489
3530
|
}
|
|
3490
3531
|
function resolveExeSession() {
|
|
3532
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
3533
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
3534
|
+
}
|
|
3491
3535
|
const mySession = getMySession();
|
|
3492
3536
|
if (!mySession) return null;
|
|
3493
3537
|
const fromSessionName = extractRootExe(mySession);
|
|
3538
|
+
let candidate = null;
|
|
3494
3539
|
try {
|
|
3495
3540
|
const key = getSessionKey();
|
|
3496
3541
|
const parentExe = getParentExe(key);
|
|
@@ -3501,13 +3546,47 @@ function resolveExeSession() {
|
|
|
3501
3546
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
3502
3547
|
`
|
|
3503
3548
|
);
|
|
3504
|
-
|
|
3549
|
+
candidate = fromSessionName;
|
|
3550
|
+
} else {
|
|
3551
|
+
candidate = fromCache;
|
|
3505
3552
|
}
|
|
3506
|
-
return fromCache;
|
|
3507
3553
|
}
|
|
3508
3554
|
} catch {
|
|
3509
3555
|
}
|
|
3510
|
-
|
|
3556
|
+
if (!candidate) {
|
|
3557
|
+
candidate = fromSessionName ?? mySession;
|
|
3558
|
+
}
|
|
3559
|
+
if (candidate && isRootSession(candidate)) {
|
|
3560
|
+
try {
|
|
3561
|
+
const transport = getTransport();
|
|
3562
|
+
const liveSessions = transport.listSessions();
|
|
3563
|
+
if (!liveSessions.includes(candidate)) {
|
|
3564
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
3565
|
+
if (liveRoots.length === 1) {
|
|
3566
|
+
process.stderr.write(
|
|
3567
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
3568
|
+
`
|
|
3569
|
+
);
|
|
3570
|
+
return liveRoots[0];
|
|
3571
|
+
} else if (liveRoots.length > 1) {
|
|
3572
|
+
const base = candidate.replace(/\d+$/, "");
|
|
3573
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
3574
|
+
const chosen = match ?? liveRoots[0];
|
|
3575
|
+
process.stderr.write(
|
|
3576
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
3577
|
+
`
|
|
3578
|
+
);
|
|
3579
|
+
return chosen;
|
|
3580
|
+
}
|
|
3581
|
+
process.stderr.write(
|
|
3582
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
3583
|
+
`
|
|
3584
|
+
);
|
|
3585
|
+
}
|
|
3586
|
+
} catch {
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
return candidate;
|
|
3511
3590
|
}
|
|
3512
3591
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
3513
3592
|
var init_tmux_routing = __esm({
|
|
@@ -4643,6 +4722,20 @@ var init_platform_procedures = __esm({
|
|
|
4643
4722
|
priority: "p1",
|
|
4644
4723
|
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."
|
|
4645
4724
|
},
|
|
4725
|
+
// --- Tool guidance ---
|
|
4726
|
+
{
|
|
4727
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4728
|
+
domain: "tools",
|
|
4729
|
+
priority: "p2",
|
|
4730
|
+
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."
|
|
4731
|
+
},
|
|
4732
|
+
// --- Release awareness ---
|
|
4733
|
+
{
|
|
4734
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4735
|
+
domain: "support",
|
|
4736
|
+
priority: "p1",
|
|
4737
|
+
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."
|
|
4738
|
+
},
|
|
4646
4739
|
// --- Platform vs Customer ownership ---
|
|
4647
4740
|
{
|
|
4648
4741
|
title: "What the platform provides vs what you customize",
|
|
@@ -4731,13 +4824,13 @@ var init_platform_procedures = __esm({
|
|
|
4731
4824
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4732
4825
|
domain: "tool-use",
|
|
4733
4826
|
priority: "p1",
|
|
4734
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
4827
|
+
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.`
|
|
4735
4828
|
},
|
|
4736
4829
|
{
|
|
4737
4830
|
title: "MCP tools \u2014 task orchestration",
|
|
4738
4831
|
domain: "tool-use",
|
|
4739
4832
|
priority: "p1",
|
|
4740
|
-
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.'
|
|
4833
|
+
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.'
|
|
4741
4834
|
},
|
|
4742
4835
|
{
|
|
4743
4836
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4767,7 +4860,7 @@ var init_platform_procedures = __esm({
|
|
|
4767
4860
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4768
4861
|
domain: "tool-use",
|
|
4769
4862
|
priority: "p1",
|
|
4770
|
-
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.'
|
|
4863
|
+
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.'
|
|
4771
4864
|
}
|
|
4772
4865
|
];
|
|
4773
4866
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5451,6 +5544,8 @@ async function writeMemory(record) {
|
|
|
5451
5544
|
source_type: record.source_type ?? null,
|
|
5452
5545
|
tier: record.tier ?? classifyTier(record),
|
|
5453
5546
|
supersedes_id: record.supersedes_id ?? null,
|
|
5547
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5548
|
+
invalid_at: record.invalid_at ?? null,
|
|
5454
5549
|
draft: record.draft ? 1 : 0,
|
|
5455
5550
|
memory_type: memoryType,
|
|
5456
5551
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -5469,7 +5564,8 @@ async function writeMemory(record) {
|
|
|
5469
5564
|
token_cost: record.token_cost ?? null,
|
|
5470
5565
|
audience: record.audience ?? null,
|
|
5471
5566
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5472
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5567
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5568
|
+
procedure_for: record.procedure_for ?? null
|
|
5473
5569
|
};
|
|
5474
5570
|
_pendingRecords.push(dbRow);
|
|
5475
5571
|
orgBus.emit({
|
|
@@ -5524,6 +5620,8 @@ async function flushBatch() {
|
|
|
5524
5620
|
const sourceType = row.source_type ?? null;
|
|
5525
5621
|
const tier = row.tier ?? 3;
|
|
5526
5622
|
const supersedesId = row.supersedes_id ?? null;
|
|
5623
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5624
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5527
5625
|
const draft = row.draft ? 1 : 0;
|
|
5528
5626
|
const memoryType = row.memory_type ?? "raw";
|
|
5529
5627
|
const trajectory = row.trajectory ?? null;
|
|
@@ -5543,15 +5641,16 @@ async function flushBatch() {
|
|
|
5543
5641
|
const audience = row.audience ?? null;
|
|
5544
5642
|
const languageType = row.language_type ?? null;
|
|
5545
5643
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5644
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5546
5645
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5547
5646
|
tool_name, project_name,
|
|
5548
5647
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5549
5648
|
confidence, last_accessed,
|
|
5550
5649
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5551
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5650
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5552
5651
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5553
5652
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5554
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5653
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5555
5654
|
const metaArgs = [
|
|
5556
5655
|
intent,
|
|
5557
5656
|
outcome,
|
|
@@ -5567,7 +5666,8 @@ async function flushBatch() {
|
|
|
5567
5666
|
tokenCost,
|
|
5568
5667
|
audience,
|
|
5569
5668
|
languageType,
|
|
5570
|
-
parentMemoryId
|
|
5669
|
+
parentMemoryId,
|
|
5670
|
+
procedureFor
|
|
5571
5671
|
];
|
|
5572
5672
|
const baseArgs = [
|
|
5573
5673
|
row.id,
|
|
@@ -5596,6 +5696,8 @@ async function flushBatch() {
|
|
|
5596
5696
|
sourceType,
|
|
5597
5697
|
tier,
|
|
5598
5698
|
supersedesId,
|
|
5699
|
+
validFrom,
|
|
5700
|
+
invalidAt,
|
|
5599
5701
|
draft,
|
|
5600
5702
|
memoryType,
|
|
5601
5703
|
trajectory,
|
|
@@ -5603,8 +5705,8 @@ async function flushBatch() {
|
|
|
5603
5705
|
];
|
|
5604
5706
|
return {
|
|
5605
5707
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5606
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5607
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5708
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5709
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5608
5710
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5609
5711
|
};
|
|
5610
5712
|
};
|
|
@@ -5720,6 +5822,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5720
5822
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5721
5823
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5722
5824
|
const args = [agentId];
|
|
5825
|
+
if (options?.asOf) {
|
|
5826
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5827
|
+
args.push(options.asOf, options.asOf);
|
|
5828
|
+
} else {
|
|
5829
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5830
|
+
}
|
|
5723
5831
|
const scope = buildWikiScopeFilter(options, "");
|
|
5724
5832
|
sql += scope.clause;
|
|
5725
5833
|
args.push(...scope.args);
|
|
@@ -2836,6 +2836,20 @@ async function ensureSchema() {
|
|
|
2836
2836
|
});
|
|
2837
2837
|
} catch {
|
|
2838
2838
|
}
|
|
2839
|
+
try {
|
|
2840
|
+
await client.execute({
|
|
2841
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2842
|
+
args: []
|
|
2843
|
+
});
|
|
2844
|
+
} catch {
|
|
2845
|
+
}
|
|
2846
|
+
try {
|
|
2847
|
+
await client.execute({
|
|
2848
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2849
|
+
args: []
|
|
2850
|
+
});
|
|
2851
|
+
} catch {
|
|
2852
|
+
}
|
|
2839
2853
|
await client.executeMultiple(`
|
|
2840
2854
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2841
2855
|
content_text,
|
|
@@ -3087,6 +3101,22 @@ async function ensureSchema() {
|
|
|
3087
3101
|
);
|
|
3088
3102
|
} catch {
|
|
3089
3103
|
}
|
|
3104
|
+
for (const col of [
|
|
3105
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3106
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3107
|
+
]) {
|
|
3108
|
+
try {
|
|
3109
|
+
await client.execute(col);
|
|
3110
|
+
} catch {
|
|
3111
|
+
}
|
|
3112
|
+
}
|
|
3113
|
+
try {
|
|
3114
|
+
await client.execute({
|
|
3115
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3116
|
+
args: []
|
|
3117
|
+
});
|
|
3118
|
+
} catch {
|
|
3119
|
+
}
|
|
3090
3120
|
try {
|
|
3091
3121
|
await client.execute({
|
|
3092
3122
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3129,6 +3159,13 @@ async function ensureSchema() {
|
|
|
3129
3159
|
} catch {
|
|
3130
3160
|
}
|
|
3131
3161
|
}
|
|
3162
|
+
try {
|
|
3163
|
+
await client.execute({
|
|
3164
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3165
|
+
args: []
|
|
3166
|
+
});
|
|
3167
|
+
} catch {
|
|
3168
|
+
}
|
|
3132
3169
|
try {
|
|
3133
3170
|
await client.execute({
|
|
3134
3171
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -4242,6 +4279,20 @@ var init_platform_procedures = __esm({
|
|
|
4242
4279
|
priority: "p1",
|
|
4243
4280
|
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."
|
|
4244
4281
|
},
|
|
4282
|
+
// --- Tool guidance ---
|
|
4283
|
+
{
|
|
4284
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4285
|
+
domain: "tools",
|
|
4286
|
+
priority: "p2",
|
|
4287
|
+
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."
|
|
4288
|
+
},
|
|
4289
|
+
// --- Release awareness ---
|
|
4290
|
+
{
|
|
4291
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4292
|
+
domain: "support",
|
|
4293
|
+
priority: "p1",
|
|
4294
|
+
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."
|
|
4295
|
+
},
|
|
4245
4296
|
// --- Platform vs Customer ownership ---
|
|
4246
4297
|
{
|
|
4247
4298
|
title: "What the platform provides vs what you customize",
|
|
@@ -4330,13 +4381,13 @@ var init_platform_procedures = __esm({
|
|
|
4330
4381
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4331
4382
|
domain: "tool-use",
|
|
4332
4383
|
priority: "p1",
|
|
4333
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
4384
|
+
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.`
|
|
4334
4385
|
},
|
|
4335
4386
|
{
|
|
4336
4387
|
title: "MCP tools \u2014 task orchestration",
|
|
4337
4388
|
domain: "tool-use",
|
|
4338
4389
|
priority: "p1",
|
|
4339
|
-
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.'
|
|
4390
|
+
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.'
|
|
4340
4391
|
},
|
|
4341
4392
|
{
|
|
4342
4393
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4366,7 +4417,7 @@ var init_platform_procedures = __esm({
|
|
|
4366
4417
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4367
4418
|
domain: "tool-use",
|
|
4368
4419
|
priority: "p1",
|
|
4369
|
-
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.'
|
|
4420
|
+
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.'
|
|
4370
4421
|
}
|
|
4371
4422
|
];
|
|
4372
4423
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5167,7 +5218,7 @@ var init_license = __esm({
|
|
|
5167
5218
|
LICENSE_PATH = path11.join(EXE_AI_DIR, "license.key");
|
|
5168
5219
|
CACHE_PATH = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
5169
5220
|
DEVICE_ID_PATH = path11.join(EXE_AI_DIR, "device-id");
|
|
5170
|
-
API_BASE = "https://askexe.com/cloud";
|
|
5221
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
5171
5222
|
RETRY_DELAY_MS = 500;
|
|
5172
5223
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
5173
5224
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
@@ -5347,6 +5398,9 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
5347
5398
|
function getMySession() {
|
|
5348
5399
|
return getTransport().getMySession();
|
|
5349
5400
|
}
|
|
5401
|
+
function isRootSession(name) {
|
|
5402
|
+
return name.length > 0 && !name.includes("-");
|
|
5403
|
+
}
|
|
5350
5404
|
function extractRootExe(name) {
|
|
5351
5405
|
if (!name) return null;
|
|
5352
5406
|
if (!name.includes("-")) return name;
|
|
@@ -5362,9 +5416,13 @@ function getParentExe(sessionKey) {
|
|
|
5362
5416
|
}
|
|
5363
5417
|
}
|
|
5364
5418
|
function resolveExeSession() {
|
|
5419
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
5420
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
5421
|
+
}
|
|
5365
5422
|
const mySession = getMySession();
|
|
5366
5423
|
if (!mySession) return null;
|
|
5367
5424
|
const fromSessionName = extractRootExe(mySession);
|
|
5425
|
+
let candidate = null;
|
|
5368
5426
|
try {
|
|
5369
5427
|
const key = getSessionKey();
|
|
5370
5428
|
const parentExe = getParentExe(key);
|
|
@@ -5375,13 +5433,47 @@ function resolveExeSession() {
|
|
|
5375
5433
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
5376
5434
|
`
|
|
5377
5435
|
);
|
|
5378
|
-
|
|
5436
|
+
candidate = fromSessionName;
|
|
5437
|
+
} else {
|
|
5438
|
+
candidate = fromCache;
|
|
5379
5439
|
}
|
|
5380
|
-
return fromCache;
|
|
5381
5440
|
}
|
|
5382
5441
|
} catch {
|
|
5383
5442
|
}
|
|
5384
|
-
|
|
5443
|
+
if (!candidate) {
|
|
5444
|
+
candidate = fromSessionName ?? mySession;
|
|
5445
|
+
}
|
|
5446
|
+
if (candidate && isRootSession(candidate)) {
|
|
5447
|
+
try {
|
|
5448
|
+
const transport = getTransport();
|
|
5449
|
+
const liveSessions = transport.listSessions();
|
|
5450
|
+
if (!liveSessions.includes(candidate)) {
|
|
5451
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
5452
|
+
if (liveRoots.length === 1) {
|
|
5453
|
+
process.stderr.write(
|
|
5454
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
5455
|
+
`
|
|
5456
|
+
);
|
|
5457
|
+
return liveRoots[0];
|
|
5458
|
+
} else if (liveRoots.length > 1) {
|
|
5459
|
+
const base = candidate.replace(/\d+$/, "");
|
|
5460
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
5461
|
+
const chosen = match ?? liveRoots[0];
|
|
5462
|
+
process.stderr.write(
|
|
5463
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
5464
|
+
`
|
|
5465
|
+
);
|
|
5466
|
+
return chosen;
|
|
5467
|
+
}
|
|
5468
|
+
process.stderr.write(
|
|
5469
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
5470
|
+
`
|
|
5471
|
+
);
|
|
5472
|
+
}
|
|
5473
|
+
} catch {
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
return candidate;
|
|
5385
5477
|
}
|
|
5386
5478
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
5387
5479
|
var init_tmux_routing = __esm({
|