@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
package/dist/index.js
CHANGED
|
@@ -3574,6 +3574,20 @@ async function ensureSchema() {
|
|
|
3574
3574
|
});
|
|
3575
3575
|
} catch {
|
|
3576
3576
|
}
|
|
3577
|
+
try {
|
|
3578
|
+
await client.execute({
|
|
3579
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3580
|
+
args: []
|
|
3581
|
+
});
|
|
3582
|
+
} catch {
|
|
3583
|
+
}
|
|
3584
|
+
try {
|
|
3585
|
+
await client.execute({
|
|
3586
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3587
|
+
args: []
|
|
3588
|
+
});
|
|
3589
|
+
} catch {
|
|
3590
|
+
}
|
|
3577
3591
|
await client.executeMultiple(`
|
|
3578
3592
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3579
3593
|
content_text,
|
|
@@ -3825,6 +3839,22 @@ async function ensureSchema() {
|
|
|
3825
3839
|
);
|
|
3826
3840
|
} catch {
|
|
3827
3841
|
}
|
|
3842
|
+
for (const col of [
|
|
3843
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3844
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3845
|
+
]) {
|
|
3846
|
+
try {
|
|
3847
|
+
await client.execute(col);
|
|
3848
|
+
} catch {
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
try {
|
|
3852
|
+
await client.execute({
|
|
3853
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3854
|
+
args: []
|
|
3855
|
+
});
|
|
3856
|
+
} catch {
|
|
3857
|
+
}
|
|
3828
3858
|
try {
|
|
3829
3859
|
await client.execute({
|
|
3830
3860
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3867,6 +3897,13 @@ async function ensureSchema() {
|
|
|
3867
3897
|
} catch {
|
|
3868
3898
|
}
|
|
3869
3899
|
}
|
|
3900
|
+
try {
|
|
3901
|
+
await client.execute({
|
|
3902
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3903
|
+
args: []
|
|
3904
|
+
});
|
|
3905
|
+
} catch {
|
|
3906
|
+
}
|
|
3870
3907
|
try {
|
|
3871
3908
|
await client.execute({
|
|
3872
3909
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3927,7 +3964,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3927
3964
|
import os8 from "os";
|
|
3928
3965
|
import path10 from "path";
|
|
3929
3966
|
import { jwtVerify, importSPKI } from "jose";
|
|
3930
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
3967
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
3931
3968
|
var init_license = __esm({
|
|
3932
3969
|
"src/lib/license.ts"() {
|
|
3933
3970
|
"use strict";
|
|
@@ -3935,6 +3972,7 @@ var init_license = __esm({
|
|
|
3935
3972
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3936
3973
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3937
3974
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3975
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3938
3976
|
PLAN_LIMITS = {
|
|
3939
3977
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
3940
3978
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -4591,8 +4629,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4591
4629
|
const complexity = input.complexity ?? "standard";
|
|
4592
4630
|
const sessionScope = earlySessionScope;
|
|
4593
4631
|
await client.execute({
|
|
4594
|
-
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)
|
|
4595
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4632
|
+
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)
|
|
4633
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4596
4634
|
args: [
|
|
4597
4635
|
id,
|
|
4598
4636
|
input.title,
|
|
@@ -4612,6 +4650,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4612
4650
|
0,
|
|
4613
4651
|
null,
|
|
4614
4652
|
sessionScope,
|
|
4653
|
+
input.spawnRuntime ?? null,
|
|
4654
|
+
input.spawnModel ?? null,
|
|
4615
4655
|
now,
|
|
4616
4656
|
now
|
|
4617
4657
|
]
|
|
@@ -4668,7 +4708,9 @@ ${input.context}
|
|
|
4668
4708
|
budgetTokens: input.budgetTokens ?? null,
|
|
4669
4709
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
4670
4710
|
tokensUsed: 0,
|
|
4671
|
-
tokensWarnedAt: null
|
|
4711
|
+
tokensWarnedAt: null,
|
|
4712
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
4713
|
+
spawnModel: input.spawnModel ?? null
|
|
4672
4714
|
};
|
|
4673
4715
|
}
|
|
4674
4716
|
async function listTasks(input) {
|
|
@@ -4718,7 +4760,9 @@ async function listTasks(input) {
|
|
|
4718
4760
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
4719
4761
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
4720
4762
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
4721
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
4763
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
4764
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
4765
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
4722
4766
|
}));
|
|
4723
4767
|
}
|
|
4724
4768
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -6086,6 +6130,8 @@ async function updateTask(input) {
|
|
|
6086
6130
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
6087
6131
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
6088
6132
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
6133
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
6134
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
6089
6135
|
nextTask
|
|
6090
6136
|
};
|
|
6091
6137
|
}
|
|
@@ -6578,9 +6624,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
6578
6624
|
}
|
|
6579
6625
|
}
|
|
6580
6626
|
function resolveExeSession() {
|
|
6627
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
6628
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6629
|
+
}
|
|
6581
6630
|
const mySession = getMySession();
|
|
6582
6631
|
if (!mySession) return null;
|
|
6583
6632
|
const fromSessionName = extractRootExe(mySession);
|
|
6633
|
+
let candidate = null;
|
|
6584
6634
|
try {
|
|
6585
6635
|
const key = getSessionKey();
|
|
6586
6636
|
const parentExe = getParentExe(key);
|
|
@@ -6591,13 +6641,47 @@ function resolveExeSession() {
|
|
|
6591
6641
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
6592
6642
|
`
|
|
6593
6643
|
);
|
|
6594
|
-
|
|
6644
|
+
candidate = fromSessionName;
|
|
6645
|
+
} else {
|
|
6646
|
+
candidate = fromCache;
|
|
6595
6647
|
}
|
|
6596
|
-
return fromCache;
|
|
6597
6648
|
}
|
|
6598
6649
|
} catch {
|
|
6599
6650
|
}
|
|
6600
|
-
|
|
6651
|
+
if (!candidate) {
|
|
6652
|
+
candidate = fromSessionName ?? mySession;
|
|
6653
|
+
}
|
|
6654
|
+
if (candidate && isRootSession(candidate)) {
|
|
6655
|
+
try {
|
|
6656
|
+
const transport = getTransport();
|
|
6657
|
+
const liveSessions = transport.listSessions();
|
|
6658
|
+
if (!liveSessions.includes(candidate)) {
|
|
6659
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
6660
|
+
if (liveRoots.length === 1) {
|
|
6661
|
+
process.stderr.write(
|
|
6662
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
6663
|
+
`
|
|
6664
|
+
);
|
|
6665
|
+
return liveRoots[0];
|
|
6666
|
+
} else if (liveRoots.length > 1) {
|
|
6667
|
+
const base = candidate.replace(/\d+$/, "");
|
|
6668
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
6669
|
+
const chosen = match ?? liveRoots[0];
|
|
6670
|
+
process.stderr.write(
|
|
6671
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
6672
|
+
`
|
|
6673
|
+
);
|
|
6674
|
+
return chosen;
|
|
6675
|
+
}
|
|
6676
|
+
process.stderr.write(
|
|
6677
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
6678
|
+
`
|
|
6679
|
+
);
|
|
6680
|
+
}
|
|
6681
|
+
} catch {
|
|
6682
|
+
}
|
|
6683
|
+
}
|
|
6684
|
+
return candidate;
|
|
6601
6685
|
}
|
|
6602
6686
|
function isEmployeeAlive(sessionName) {
|
|
6603
6687
|
return getTransport().isAlive(sessionName);
|
|
@@ -6999,7 +7083,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6999
7083
|
}
|
|
7000
7084
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
7001
7085
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
7002
|
-
const
|
|
7086
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
7087
|
+
const agentRtConfig = {
|
|
7088
|
+
...baseRtConfig,
|
|
7089
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
7090
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
7091
|
+
};
|
|
7003
7092
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
7004
7093
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
7005
7094
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -8259,6 +8348,20 @@ var init_platform_procedures = __esm({
|
|
|
8259
8348
|
priority: "p1",
|
|
8260
8349
|
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."
|
|
8261
8350
|
},
|
|
8351
|
+
// --- Tool guidance ---
|
|
8352
|
+
{
|
|
8353
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
8354
|
+
domain: "tools",
|
|
8355
|
+
priority: "p2",
|
|
8356
|
+
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."
|
|
8357
|
+
},
|
|
8358
|
+
// --- Release awareness ---
|
|
8359
|
+
{
|
|
8360
|
+
title: "What's New check \u2014 surface new features after update",
|
|
8361
|
+
domain: "support",
|
|
8362
|
+
priority: "p1",
|
|
8363
|
+
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."
|
|
8364
|
+
},
|
|
8262
8365
|
// --- Platform vs Customer ownership ---
|
|
8263
8366
|
{
|
|
8264
8367
|
title: "What the platform provides vs what you customize",
|
|
@@ -8347,13 +8450,13 @@ var init_platform_procedures = __esm({
|
|
|
8347
8450
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
8348
8451
|
domain: "tool-use",
|
|
8349
8452
|
priority: "p1",
|
|
8350
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
8453
|
+
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.`
|
|
8351
8454
|
},
|
|
8352
8455
|
{
|
|
8353
8456
|
title: "MCP tools \u2014 task orchestration",
|
|
8354
8457
|
domain: "tool-use",
|
|
8355
8458
|
priority: "p1",
|
|
8356
|
-
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.'
|
|
8459
|
+
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.'
|
|
8357
8460
|
},
|
|
8358
8461
|
{
|
|
8359
8462
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -8383,7 +8486,7 @@ var init_platform_procedures = __esm({
|
|
|
8383
8486
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
8384
8487
|
domain: "tool-use",
|
|
8385
8488
|
priority: "p1",
|
|
8386
|
-
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.'
|
|
8489
|
+
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.'
|
|
8387
8490
|
}
|
|
8388
8491
|
];
|
|
8389
8492
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -9067,6 +9170,8 @@ async function writeMemory(record) {
|
|
|
9067
9170
|
source_type: record.source_type ?? null,
|
|
9068
9171
|
tier: record.tier ?? classifyTier(record),
|
|
9069
9172
|
supersedes_id: record.supersedes_id ?? null,
|
|
9173
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
9174
|
+
invalid_at: record.invalid_at ?? null,
|
|
9070
9175
|
draft: record.draft ? 1 : 0,
|
|
9071
9176
|
memory_type: memoryType,
|
|
9072
9177
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -9085,7 +9190,8 @@ async function writeMemory(record) {
|
|
|
9085
9190
|
token_cost: record.token_cost ?? null,
|
|
9086
9191
|
audience: record.audience ?? null,
|
|
9087
9192
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
9088
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
9193
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
9194
|
+
procedure_for: record.procedure_for ?? null
|
|
9089
9195
|
};
|
|
9090
9196
|
_pendingRecords.push(dbRow);
|
|
9091
9197
|
orgBus.emit({
|
|
@@ -9140,6 +9246,8 @@ async function flushBatch() {
|
|
|
9140
9246
|
const sourceType = row.source_type ?? null;
|
|
9141
9247
|
const tier = row.tier ?? 3;
|
|
9142
9248
|
const supersedesId = row.supersedes_id ?? null;
|
|
9249
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
9250
|
+
const invalidAt = row.invalid_at ?? null;
|
|
9143
9251
|
const draft = row.draft ? 1 : 0;
|
|
9144
9252
|
const memoryType = row.memory_type ?? "raw";
|
|
9145
9253
|
const trajectory = row.trajectory ?? null;
|
|
@@ -9159,15 +9267,16 @@ async function flushBatch() {
|
|
|
9159
9267
|
const audience = row.audience ?? null;
|
|
9160
9268
|
const languageType = row.language_type ?? null;
|
|
9161
9269
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
9270
|
+
const procedureFor = row.procedure_for ?? null;
|
|
9162
9271
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
9163
9272
|
tool_name, project_name,
|
|
9164
9273
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
9165
9274
|
confidence, last_accessed,
|
|
9166
9275
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
9167
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
9276
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
9168
9277
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
9169
9278
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
9170
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
9279
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
9171
9280
|
const metaArgs = [
|
|
9172
9281
|
intent,
|
|
9173
9282
|
outcome,
|
|
@@ -9183,7 +9292,8 @@ async function flushBatch() {
|
|
|
9183
9292
|
tokenCost,
|
|
9184
9293
|
audience,
|
|
9185
9294
|
languageType,
|
|
9186
|
-
parentMemoryId
|
|
9295
|
+
parentMemoryId,
|
|
9296
|
+
procedureFor
|
|
9187
9297
|
];
|
|
9188
9298
|
const baseArgs = [
|
|
9189
9299
|
row.id,
|
|
@@ -9212,6 +9322,8 @@ async function flushBatch() {
|
|
|
9212
9322
|
sourceType,
|
|
9213
9323
|
tier,
|
|
9214
9324
|
supersedesId,
|
|
9325
|
+
validFrom,
|
|
9326
|
+
invalidAt,
|
|
9215
9327
|
draft,
|
|
9216
9328
|
memoryType,
|
|
9217
9329
|
trajectory,
|
|
@@ -9219,8 +9331,8 @@ async function flushBatch() {
|
|
|
9219
9331
|
];
|
|
9220
9332
|
return {
|
|
9221
9333
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
9222
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
9223
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
9334
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
9335
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
9224
9336
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
9225
9337
|
};
|
|
9226
9338
|
};
|
|
@@ -9336,6 +9448,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
9336
9448
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
9337
9449
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
9338
9450
|
const args = [agentId];
|
|
9451
|
+
if (options?.asOf) {
|
|
9452
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
9453
|
+
args.push(options.asOf, options.asOf);
|
|
9454
|
+
} else {
|
|
9455
|
+
sql += ` AND invalid_at IS NULL`;
|
|
9456
|
+
}
|
|
9339
9457
|
const scope = buildWikiScopeFilter(options, "");
|
|
9340
9458
|
sql += scope.clause;
|
|
9341
9459
|
args.push(...scope.args);
|
package/dist/lib/cloud-sync.js
CHANGED
|
@@ -2488,6 +2488,20 @@ async function ensureSchema() {
|
|
|
2488
2488
|
});
|
|
2489
2489
|
} catch {
|
|
2490
2490
|
}
|
|
2491
|
+
try {
|
|
2492
|
+
await client.execute({
|
|
2493
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2494
|
+
args: []
|
|
2495
|
+
});
|
|
2496
|
+
} catch {
|
|
2497
|
+
}
|
|
2498
|
+
try {
|
|
2499
|
+
await client.execute({
|
|
2500
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2501
|
+
args: []
|
|
2502
|
+
});
|
|
2503
|
+
} catch {
|
|
2504
|
+
}
|
|
2491
2505
|
await client.executeMultiple(`
|
|
2492
2506
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2493
2507
|
content_text,
|
|
@@ -2739,6 +2753,22 @@ async function ensureSchema() {
|
|
|
2739
2753
|
);
|
|
2740
2754
|
} catch {
|
|
2741
2755
|
}
|
|
2756
|
+
for (const col of [
|
|
2757
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
2758
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
2759
|
+
]) {
|
|
2760
|
+
try {
|
|
2761
|
+
await client.execute(col);
|
|
2762
|
+
} catch {
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
try {
|
|
2766
|
+
await client.execute({
|
|
2767
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
2768
|
+
args: []
|
|
2769
|
+
});
|
|
2770
|
+
} catch {
|
|
2771
|
+
}
|
|
2742
2772
|
try {
|
|
2743
2773
|
await client.execute({
|
|
2744
2774
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -2781,6 +2811,13 @@ async function ensureSchema() {
|
|
|
2781
2811
|
} catch {
|
|
2782
2812
|
}
|
|
2783
2813
|
}
|
|
2814
|
+
try {
|
|
2815
|
+
await client.execute({
|
|
2816
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
2817
|
+
args: []
|
|
2818
|
+
});
|
|
2819
|
+
} catch {
|
|
2820
|
+
}
|
|
2784
2821
|
try {
|
|
2785
2822
|
await client.execute({
|
|
2786
2823
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3734,6 +3771,7 @@ import { jwtVerify, importSPKI } from "jose";
|
|
|
3734
3771
|
var LICENSE_PATH = path6.join(EXE_AI_DIR, "license.key");
|
|
3735
3772
|
var CACHE_PATH = path6.join(EXE_AI_DIR, "license-cache.json");
|
|
3736
3773
|
var DEVICE_ID_PATH = path6.join(EXE_AI_DIR, "device-id");
|
|
3774
|
+
var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3737
3775
|
function loadDeviceId() {
|
|
3738
3776
|
const deviceJsonPath = path6.join(EXE_AI_DIR, "device.json");
|
|
3739
3777
|
try {
|
|
@@ -635,6 +635,7 @@ async function selectUnconsolidated(client, limit = 200) {
|
|
|
635
635
|
sql: `SELECT id, agent_id, project_name, tool_name, raw_text, timestamp
|
|
636
636
|
FROM memories
|
|
637
637
|
WHERE consolidated = 0
|
|
638
|
+
AND COALESCE(memory_type, 'raw') != 'procedure'
|
|
638
639
|
ORDER BY timestamp DESC
|
|
639
640
|
LIMIT ?`,
|
|
640
641
|
args: [limit]
|
|
@@ -1009,7 +1010,8 @@ async function isUserIdle(client, idleMinutes = 30) {
|
|
|
1009
1010
|
async function countUnconsolidated(client) {
|
|
1010
1011
|
const result = await client.execute({
|
|
1011
1012
|
sql: `SELECT COUNT(*) as cnt FROM memories
|
|
1012
|
-
WHERE consolidated = 0
|
|
1013
|
+
WHERE consolidated = 0
|
|
1014
|
+
AND COALESCE(memory_type, 'raw') != 'procedure'`,
|
|
1013
1015
|
args: []
|
|
1014
1016
|
});
|
|
1015
1017
|
return Number(result.rows[0]?.cnt ?? 0);
|
package/dist/lib/database.js
CHANGED
|
@@ -2404,6 +2404,20 @@ async function ensureSchema() {
|
|
|
2404
2404
|
});
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
}
|
|
2407
|
+
try {
|
|
2408
|
+
await client.execute({
|
|
2409
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2410
|
+
args: []
|
|
2411
|
+
});
|
|
2412
|
+
} catch {
|
|
2413
|
+
}
|
|
2414
|
+
try {
|
|
2415
|
+
await client.execute({
|
|
2416
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2417
|
+
args: []
|
|
2418
|
+
});
|
|
2419
|
+
} catch {
|
|
2420
|
+
}
|
|
2407
2421
|
await client.executeMultiple(`
|
|
2408
2422
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2409
2423
|
content_text,
|
|
@@ -2655,6 +2669,22 @@ async function ensureSchema() {
|
|
|
2655
2669
|
);
|
|
2656
2670
|
} catch {
|
|
2657
2671
|
}
|
|
2672
|
+
for (const col of [
|
|
2673
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
2674
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
2675
|
+
]) {
|
|
2676
|
+
try {
|
|
2677
|
+
await client.execute(col);
|
|
2678
|
+
} catch {
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
try {
|
|
2682
|
+
await client.execute({
|
|
2683
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
2684
|
+
args: []
|
|
2685
|
+
});
|
|
2686
|
+
} catch {
|
|
2687
|
+
}
|
|
2658
2688
|
try {
|
|
2659
2689
|
await client.execute({
|
|
2660
2690
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -2697,6 +2727,13 @@ async function ensureSchema() {
|
|
|
2697
2727
|
} catch {
|
|
2698
2728
|
}
|
|
2699
2729
|
}
|
|
2730
|
+
try {
|
|
2731
|
+
await client.execute({
|
|
2732
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
2733
|
+
args: []
|
|
2734
|
+
});
|
|
2735
|
+
} catch {
|
|
2736
|
+
}
|
|
2700
2737
|
try {
|
|
2701
2738
|
await client.execute({
|
|
2702
2739
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
package/dist/lib/db.js
CHANGED
|
@@ -2404,6 +2404,20 @@ async function ensureSchema() {
|
|
|
2404
2404
|
});
|
|
2405
2405
|
} catch {
|
|
2406
2406
|
}
|
|
2407
|
+
try {
|
|
2408
|
+
await client.execute({
|
|
2409
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2410
|
+
args: []
|
|
2411
|
+
});
|
|
2412
|
+
} catch {
|
|
2413
|
+
}
|
|
2414
|
+
try {
|
|
2415
|
+
await client.execute({
|
|
2416
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2417
|
+
args: []
|
|
2418
|
+
});
|
|
2419
|
+
} catch {
|
|
2420
|
+
}
|
|
2407
2421
|
await client.executeMultiple(`
|
|
2408
2422
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2409
2423
|
content_text,
|
|
@@ -2655,6 +2669,22 @@ async function ensureSchema() {
|
|
|
2655
2669
|
);
|
|
2656
2670
|
} catch {
|
|
2657
2671
|
}
|
|
2672
|
+
for (const col of [
|
|
2673
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
2674
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
2675
|
+
]) {
|
|
2676
|
+
try {
|
|
2677
|
+
await client.execute(col);
|
|
2678
|
+
} catch {
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
try {
|
|
2682
|
+
await client.execute({
|
|
2683
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
2684
|
+
args: []
|
|
2685
|
+
});
|
|
2686
|
+
} catch {
|
|
2687
|
+
}
|
|
2658
2688
|
try {
|
|
2659
2689
|
await client.execute({
|
|
2660
2690
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -2697,6 +2727,13 @@ async function ensureSchema() {
|
|
|
2697
2727
|
} catch {
|
|
2698
2728
|
}
|
|
2699
2729
|
}
|
|
2730
|
+
try {
|
|
2731
|
+
await client.execute({
|
|
2732
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
2733
|
+
args: []
|
|
2734
|
+
});
|
|
2735
|
+
} catch {
|
|
2736
|
+
}
|
|
2700
2737
|
try {
|
|
2701
2738
|
await client.execute({
|
|
2702
2739
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -2433,6 +2433,20 @@ async function ensureSchema() {
|
|
|
2433
2433
|
});
|
|
2434
2434
|
} catch {
|
|
2435
2435
|
}
|
|
2436
|
+
try {
|
|
2437
|
+
await client.execute({
|
|
2438
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
2439
|
+
args: []
|
|
2440
|
+
});
|
|
2441
|
+
} catch {
|
|
2442
|
+
}
|
|
2443
|
+
try {
|
|
2444
|
+
await client.execute({
|
|
2445
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
2446
|
+
args: []
|
|
2447
|
+
});
|
|
2448
|
+
} catch {
|
|
2449
|
+
}
|
|
2436
2450
|
await client.executeMultiple(`
|
|
2437
2451
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
2438
2452
|
content_text,
|
|
@@ -2684,6 +2698,22 @@ async function ensureSchema() {
|
|
|
2684
2698
|
);
|
|
2685
2699
|
} catch {
|
|
2686
2700
|
}
|
|
2701
|
+
for (const col of [
|
|
2702
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
2703
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
2704
|
+
]) {
|
|
2705
|
+
try {
|
|
2706
|
+
await client.execute(col);
|
|
2707
|
+
} catch {
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
try {
|
|
2711
|
+
await client.execute({
|
|
2712
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
2713
|
+
args: []
|
|
2714
|
+
});
|
|
2715
|
+
} catch {
|
|
2716
|
+
}
|
|
2687
2717
|
try {
|
|
2688
2718
|
await client.execute({
|
|
2689
2719
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -2726,6 +2756,13 @@ async function ensureSchema() {
|
|
|
2726
2756
|
} catch {
|
|
2727
2757
|
}
|
|
2728
2758
|
}
|
|
2759
|
+
try {
|
|
2760
|
+
await client.execute({
|
|
2761
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
2762
|
+
args: []
|
|
2763
|
+
});
|
|
2764
|
+
} catch {
|
|
2765
|
+
}
|
|
2729
2766
|
try {
|
|
2730
2767
|
await client.execute({
|
|
2731
2768
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -253,6 +253,20 @@ var PLATFORM_PROCEDURES = [
|
|
|
253
253
|
priority: "p1",
|
|
254
254
|
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."
|
|
255
255
|
},
|
|
256
|
+
// --- Tool guidance ---
|
|
257
|
+
{
|
|
258
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
259
|
+
domain: "tools",
|
|
260
|
+
priority: "p2",
|
|
261
|
+
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."
|
|
262
|
+
},
|
|
263
|
+
// --- Release awareness ---
|
|
264
|
+
{
|
|
265
|
+
title: "What's New check \u2014 surface new features after update",
|
|
266
|
+
domain: "support",
|
|
267
|
+
priority: "p1",
|
|
268
|
+
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."
|
|
269
|
+
},
|
|
256
270
|
// --- Platform vs Customer ownership ---
|
|
257
271
|
{
|
|
258
272
|
title: "What the platform provides vs what you customize",
|
|
@@ -341,13 +355,13 @@ var PLATFORM_PROCEDURES = [
|
|
|
341
355
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
342
356
|
domain: "tool-use",
|
|
343
357
|
priority: "p1",
|
|
344
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
358
|
+
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.`
|
|
345
359
|
},
|
|
346
360
|
{
|
|
347
361
|
title: "MCP tools \u2014 task orchestration",
|
|
348
362
|
domain: "tool-use",
|
|
349
363
|
priority: "p1",
|
|
350
|
-
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.'
|
|
364
|
+
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.'
|
|
351
365
|
},
|
|
352
366
|
{
|
|
353
367
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -377,7 +391,7 @@ var PLATFORM_PROCEDURES = [
|
|
|
377
391
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
378
392
|
domain: "tool-use",
|
|
379
393
|
priority: "p1",
|
|
380
|
-
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.'
|
|
394
|
+
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.'
|
|
381
395
|
}
|
|
382
396
|
];
|
|
383
397
|
var PLATFORM_PROCEDURE_TITLES = new Set(
|