@askexenow/exe-os 0.9.111 → 0.9.113
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/README.md +9 -7
- package/dist/bin/agentic-ontology-backfill.js +62 -12
- package/dist/bin/agentic-reflection-backfill.js +37 -2
- package/dist/bin/agentic-semantic-label.js +37 -2
- package/dist/bin/backfill-conversations.js +61 -11
- package/dist/bin/backfill-responses.js +62 -12
- package/dist/bin/backfill-vectors.js +37 -2
- package/dist/bin/bulk-sync-postgres.js +63 -13
- package/dist/bin/cleanup-stale-review-tasks.js +83 -16
- package/dist/bin/cli.js +312 -80
- package/dist/bin/exe-agent-config.js +7 -1
- package/dist/bin/exe-agent.js +29 -3
- package/dist/bin/exe-assign.js +62 -12
- package/dist/bin/exe-boot.js +500 -151
- package/dist/bin/exe-call.js +46 -5
- package/dist/bin/exe-cloud.js +101 -16
- package/dist/bin/exe-dispatch.js +827 -27
- package/dist/bin/exe-doctor.js +61 -11
- package/dist/bin/exe-export-behaviors.js +67 -14
- package/dist/bin/exe-forget.js +62 -12
- package/dist/bin/exe-gateway.js +147 -27
- package/dist/bin/exe-heartbeat.js +83 -16
- package/dist/bin/exe-kill.js +62 -12
- package/dist/bin/exe-launch-agent.js +83 -15
- package/dist/bin/exe-new-employee.js +176 -8
- package/dist/bin/exe-pending-messages.js +83 -16
- package/dist/bin/exe-pending-notifications.js +83 -16
- package/dist/bin/exe-pending-reviews.js +83 -16
- package/dist/bin/exe-rename.js +62 -12
- package/dist/bin/exe-review.js +62 -12
- package/dist/bin/exe-search.js +62 -12
- package/dist/bin/exe-session-cleanup.js +949 -149
- package/dist/bin/exe-settings.js +10 -4
- package/dist/bin/exe-start-codex.js +537 -248
- package/dist/bin/exe-start-opencode.js +547 -168
- package/dist/bin/exe-status.js +83 -16
- package/dist/bin/exe-support.js +1 -1
- package/dist/bin/exe-team.js +62 -12
- package/dist/bin/git-sweep.js +827 -27
- package/dist/bin/graph-backfill.js +62 -12
- package/dist/bin/graph-export.js +62 -12
- package/dist/bin/install.js +62 -4
- package/dist/bin/intercom-check.js +949 -149
- package/dist/bin/pre-publish.js +14 -2
- package/dist/bin/scan-tasks.js +827 -27
- package/dist/bin/setup.js +99 -14
- package/dist/bin/shard-migrate.js +62 -12
- package/dist/bin/stack-update.js +1 -1
- package/dist/bin/update.js +3 -3
- package/dist/gateway/index.js +586 -26
- package/dist/hooks/bug-report-worker.js +586 -26
- package/dist/hooks/codex-stop-task-finalizer.js +977 -143
- package/dist/hooks/commit-complete.js +827 -27
- package/dist/hooks/error-recall.js +62 -12
- package/dist/hooks/ingest.js +4579 -249
- package/dist/hooks/instructions-loaded.js +62 -12
- package/dist/hooks/notification.js +62 -12
- package/dist/hooks/post-compact.js +83 -16
- package/dist/hooks/post-tool-combined.js +83 -16
- package/dist/hooks/pre-compact.js +907 -107
- package/dist/hooks/pre-tool-use.js +98 -16
- package/dist/hooks/prompt-submit.js +596 -30
- package/dist/hooks/session-end.js +909 -112
- package/dist/hooks/session-start.js +112 -17
- package/dist/hooks/stop.js +82 -15
- package/dist/hooks/subagent-stop.js +83 -16
- package/dist/hooks/summary-worker.js +81 -8
- package/dist/index.js +595 -29
- package/dist/lib/agent-config.js +16 -1
- package/dist/lib/cloud-sync.js +45 -1
- package/dist/lib/consolidation.js +16 -1
- package/dist/lib/database.js +23 -0
- package/dist/lib/db.js +23 -0
- package/dist/lib/device-registry.js +23 -0
- package/dist/lib/employee-templates.js +30 -4
- package/dist/lib/employees.js +16 -1
- package/dist/lib/exe-daemon.js +482 -52
- package/dist/lib/hybrid-search.js +62 -12
- package/dist/lib/license.js +3 -3
- package/dist/lib/messaging.js +21 -4
- package/dist/lib/schedules.js +37 -2
- package/dist/lib/skill-learning.js +910 -41
- package/dist/lib/status-brief.js +14 -1
- package/dist/lib/store.js +62 -12
- package/dist/lib/tasks.js +843 -93
- package/dist/lib/tmux-routing.js +766 -16
- package/dist/mcp/server.js +238 -41
- package/dist/mcp/tools/create-task.js +525 -15
- package/dist/mcp/tools/deactivate-behavior.js +33 -24
- package/dist/mcp/tools/list-tasks.js +21 -4
- package/dist/mcp/tools/send-message.js +21 -4
- package/dist/mcp/tools/update-task.js +840 -93
- package/dist/runtime/index.js +913 -107
- package/dist/tui/App.js +227 -58
- package/package.json +1 -1
|
@@ -371,6 +371,7 @@ __export(agent_config_exports, {
|
|
|
371
371
|
getAgentRuntime: () => getAgentRuntime,
|
|
372
372
|
loadAgentConfig: () => loadAgentConfig,
|
|
373
373
|
saveAgentConfig: () => saveAgentConfig,
|
|
374
|
+
setAgentMcps: () => setAgentMcps,
|
|
374
375
|
setAgentRuntime: () => setAgentRuntime
|
|
375
376
|
});
|
|
376
377
|
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
@@ -397,7 +398,7 @@ function getAgentRuntime(agentId) {
|
|
|
397
398
|
if (orgDefault) return orgDefault;
|
|
398
399
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
399
400
|
}
|
|
400
|
-
function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
401
|
+
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
401
402
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
402
403
|
if (!knownModels) {
|
|
403
404
|
return {
|
|
@@ -412,12 +413,26 @@ function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
|
412
413
|
};
|
|
413
414
|
}
|
|
414
415
|
const config = loadAgentConfig();
|
|
416
|
+
const existing = config[agentId];
|
|
415
417
|
const entry = { runtime, model };
|
|
416
418
|
if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
|
|
419
|
+
if (mcps !== void 0) {
|
|
420
|
+
entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
421
|
+
} else if (existing?.mcps) {
|
|
422
|
+
entry.mcps = existing.mcps;
|
|
423
|
+
}
|
|
417
424
|
config[agentId] = entry;
|
|
418
425
|
saveAgentConfig(config);
|
|
419
426
|
return { ok: true };
|
|
420
427
|
}
|
|
428
|
+
function setAgentMcps(agentId, mcps) {
|
|
429
|
+
const config = loadAgentConfig();
|
|
430
|
+
const existing = config[agentId] ?? getAgentRuntime(agentId);
|
|
431
|
+
existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
432
|
+
config[agentId] = existing;
|
|
433
|
+
saveAgentConfig(config);
|
|
434
|
+
return { ok: true };
|
|
435
|
+
}
|
|
421
436
|
function clearAgentRuntime(agentId) {
|
|
422
437
|
const config = loadAgentConfig();
|
|
423
438
|
delete config[agentId];
|
|
@@ -2610,6 +2625,13 @@ async function ensureSchema() {
|
|
|
2610
2625
|
} catch (e) {
|
|
2611
2626
|
logCatchDebug("migration", e);
|
|
2612
2627
|
}
|
|
2628
|
+
for (const col of ["created_by_agent TEXT", "created_by_device TEXT", "source_session_id TEXT"]) {
|
|
2629
|
+
try {
|
|
2630
|
+
await client.execute({ sql: `ALTER TABLE behaviors ADD COLUMN ${col}`, args: [] });
|
|
2631
|
+
} catch (e) {
|
|
2632
|
+
logCatchDebug("migration", e);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2613
2635
|
try {
|
|
2614
2636
|
await client.execute({
|
|
2615
2637
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3826,6 +3848,22 @@ async function ensureSchema() {
|
|
|
3826
3848
|
} catch (e) {
|
|
3827
3849
|
logCatchDebug("migration", e);
|
|
3828
3850
|
}
|
|
3851
|
+
try {
|
|
3852
|
+
await client.execute({
|
|
3853
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
3854
|
+
args: []
|
|
3855
|
+
});
|
|
3856
|
+
} catch (e) {
|
|
3857
|
+
logCatchDebug("migration", e);
|
|
3858
|
+
}
|
|
3859
|
+
try {
|
|
3860
|
+
await client.execute({
|
|
3861
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
3862
|
+
args: []
|
|
3863
|
+
});
|
|
3864
|
+
} catch (e) {
|
|
3865
|
+
logCatchDebug("migration", e);
|
|
3866
|
+
}
|
|
3829
3867
|
}
|
|
3830
3868
|
async function disposeDatabase() {
|
|
3831
3869
|
if (_walCheckpointTimer) {
|
|
@@ -3892,7 +3930,7 @@ var init_license = __esm({
|
|
|
3892
3930
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3893
3931
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3894
3932
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3895
|
-
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
3933
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
3896
3934
|
}
|
|
3897
3935
|
});
|
|
3898
3936
|
|
|
@@ -3945,6 +3983,18 @@ function extractRootExe(name) {
|
|
|
3945
3983
|
const parts = name.split("-").filter(Boolean);
|
|
3946
3984
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
3947
3985
|
}
|
|
3986
|
+
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
3987
|
+
if (!existsSync12(SESSION_CACHE)) {
|
|
3988
|
+
mkdirSync7(SESSION_CACHE, { recursive: true });
|
|
3989
|
+
}
|
|
3990
|
+
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
3991
|
+
const filePath = path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
3992
|
+
writeFileSync7(filePath, JSON.stringify({
|
|
3993
|
+
parentExe: rootExe,
|
|
3994
|
+
dispatchedBy: dispatchedBy || rootExe,
|
|
3995
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3996
|
+
}));
|
|
3997
|
+
}
|
|
3948
3998
|
function getParentExe(sessionKey) {
|
|
3949
3999
|
try {
|
|
3950
4000
|
const data = JSON.parse(readFileSync10(path13.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
@@ -3954,11 +4004,12 @@ function getParentExe(sessionKey) {
|
|
|
3954
4004
|
}
|
|
3955
4005
|
}
|
|
3956
4006
|
function resolveExeSession() {
|
|
4007
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
4008
|
+
const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
4009
|
+
if (fromEnv) return fromEnv;
|
|
4010
|
+
}
|
|
3957
4011
|
const mySession = getMySession();
|
|
3958
4012
|
if (!mySession) {
|
|
3959
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
3960
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
3961
|
-
}
|
|
3962
4013
|
return null;
|
|
3963
4014
|
}
|
|
3964
4015
|
const fromSessionName = extractRootExe(mySession);
|
|
@@ -3973,6 +4024,10 @@ function resolveExeSession() {
|
|
|
3973
4024
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
3974
4025
|
`
|
|
3975
4026
|
);
|
|
4027
|
+
try {
|
|
4028
|
+
registerParentExe(key, fromSessionName);
|
|
4029
|
+
} catch {
|
|
4030
|
+
}
|
|
3976
4031
|
candidate = fromSessionName;
|
|
3977
4032
|
} else {
|
|
3978
4033
|
candidate = fromCache;
|
|
@@ -5320,11 +5375,17 @@ var init_platform_procedures = __esm({
|
|
|
5320
5375
|
content: "Founder -> coordinator (the executive agent, internally routed as 'COO') -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the coordinator does not bypass managers for specialist work. Specialists report to their manager. If you need cross-team info, use ask_team_memory \u2014 don't read other agents' task folders. Each level owns dispatch downward and review upward."
|
|
5321
5376
|
},
|
|
5322
5377
|
{
|
|
5323
|
-
title: "
|
|
5378
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
5324
5379
|
domain: "workflow",
|
|
5325
5380
|
priority: "p1",
|
|
5326
5381
|
content: "New customers start best in Phase 1: founder \u2194 coordinator/Chief of Staff, building company context. Suggest Phase 2 executives when domain work repeats; suggest Phase 3 parallel execution only when review/permission gates are ready. This is guidance, not a blocker: users may jump phases anytime. Never overwrite their phase, role titles, identities, or custom org design."
|
|
5327
5382
|
},
|
|
5383
|
+
{
|
|
5384
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
5385
|
+
domain: "identity",
|
|
5386
|
+
priority: "p0",
|
|
5387
|
+
content: "These procedures reference 'COO' as a shorthand for the coordinator role. This is an INTERNAL routing slot used by exe-os code (chain-of-command checks, dispatch logic, session detection). It is NOT your display title. Your actual title comes from your identity file's `title:` field \u2014 that is what you use externally: introductions, sign-offs, team comms, and any user-facing text. If your identity says `title: AI Chief of Staff`, you are the AI Chief of Staff. The routing slot stays `role: coo` for code compatibility \u2014 never rename it, but also never introduce yourself as 'COO' unless your identity file explicitly says so. The founder chose your title; respect it."
|
|
5388
|
+
},
|
|
5328
5389
|
{
|
|
5329
5390
|
title: "Single dispatch path \u2014 create_task only",
|
|
5330
5391
|
domain: "workflow",
|
|
@@ -5358,6 +5419,12 @@ var init_platform_procedures = __esm({
|
|
|
5358
5419
|
priority: "p0",
|
|
5359
5420
|
content: "NEVER: (1) Access the database directly \u2014 it's SQLCipher encrypted, always fails. Use MCP tools only. (2) Manually spawn tmux sessions \u2014 create_task handles it. (3) Run git checkout main \u2014 agents work in worktrees. (4) Modify another agent's in-progress task. (5) Push to remote \u2014 the COO reviews and pushes. (6) Skip update_task(done) \u2014 it's the ONLY way your work gets reviewed. (7) Run git init."
|
|
5360
5421
|
},
|
|
5422
|
+
{
|
|
5423
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
5424
|
+
domain: "security",
|
|
5425
|
+
priority: "p0",
|
|
5426
|
+
content: "Before ANY destructive operation (delete, remove, overwrite, drop, reset, force-push, truncate), you MUST: (1) Have your full task spec accessible \u2014 if you cannot read it, STOP and report to your reviewer. Never improvise destructive actions. (2) Confirm with your reviewer (assigned_by or COO) before executing. (3) If the task spec explicitly authorizes the operation, proceed \u2014 but log it. Violation = immediate task failure. This applies to ALL agents regardless of role."
|
|
5427
|
+
},
|
|
5361
5428
|
{
|
|
5362
5429
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
5363
5430
|
domain: "support",
|
|
@@ -5509,7 +5576,7 @@ var init_platform_procedures = __esm({
|
|
|
5509
5576
|
title: "MCP tool dispatch \u2014 all tools use action parameter",
|
|
5510
5577
|
domain: "tool-use",
|
|
5511
5578
|
priority: "p0",
|
|
5512
|
-
content: 'exe-os MCP tools
|
|
5579
|
+
content: 'exe-os MCP tools use consolidated action-based dispatch by default (19 tools). Call domain tools with an action parameter: memory(action="recall"), task(action="create"), config(action="list_employees"), etc. Legacy mode (108 separate tools like recall_my_memory, create_task) is still available via EXE_MCP_TOOL_SURFACE=legacy but will be removed in a future version. If you see specific tool names, call them directly \u2014 both surfaces are identical. Consolidated is the default and recommended surface.'
|
|
5513
5580
|
},
|
|
5514
5581
|
{
|
|
5515
5582
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
@@ -5643,10 +5710,24 @@ function stableId(memoryId, type, content) {
|
|
|
5643
5710
|
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
5644
5711
|
}
|
|
5645
5712
|
function cleanText(text) {
|
|
5646
|
-
|
|
5713
|
+
let cleaned = text.replace(
|
|
5714
|
+
/```(\w*)\n(.*?)(?:\n[\s\S]*?)```/g,
|
|
5715
|
+
(_m, lang, firstLine) => `[code${lang ? `:${lang}` : ""}] ${firstLine.trim()}`
|
|
5716
|
+
);
|
|
5717
|
+
cleaned = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
5718
|
+
return cleaned;
|
|
5647
5719
|
}
|
|
5648
|
-
function
|
|
5649
|
-
|
|
5720
|
+
function splitSegments(text) {
|
|
5721
|
+
const cleaned = cleanText(text);
|
|
5722
|
+
const segments = cleaned.split(/(?<=[.!?:;])\s+|\n{2,}|(?<=\))\s+(?=[A-Z])|\s*[|│]\s*/).map((s) => s.trim()).filter((s) => s.length >= MIN_SEGMENT_CHARS && s.length <= MAX_SEGMENT_CHARS);
|
|
5723
|
+
if (segments.length === 0 && cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
5724
|
+
const lines = cleaned.split(/\n+/).map((l) => l.trim()).filter((l) => l.length >= MIN_SEGMENT_CHARS && l.length <= MAX_SEGMENT_CHARS);
|
|
5725
|
+
if (lines.length > 0) return lines;
|
|
5726
|
+
if (cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
5727
|
+
return [cleaned.slice(0, MAX_SEGMENT_CHARS)];
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
5730
|
+
return segments;
|
|
5650
5731
|
}
|
|
5651
5732
|
function inferCardType(sentence, toolName) {
|
|
5652
5733
|
const lower = sentence.toLowerCase();
|
|
@@ -5678,12 +5759,12 @@ function predicateFor(type) {
|
|
|
5678
5759
|
}
|
|
5679
5760
|
}
|
|
5680
5761
|
function extractMemoryCards(row) {
|
|
5681
|
-
const
|
|
5762
|
+
const segments = splitSegments(row.raw_text);
|
|
5682
5763
|
const cards = [];
|
|
5683
|
-
for (const sentence of
|
|
5764
|
+
for (const sentence of segments) {
|
|
5684
5765
|
const type = inferCardType(sentence, row.tool_name);
|
|
5685
5766
|
const subject = extractSubject(sentence, row.agent_id);
|
|
5686
|
-
const content = sentence.length >
|
|
5767
|
+
const content = sentence.length > MAX_SEGMENT_CHARS ? `${sentence.slice(0, MAX_SEGMENT_CHARS - 1)}\u2026` : sentence;
|
|
5687
5768
|
cards.push({
|
|
5688
5769
|
id: stableId(row.id, type, content),
|
|
5689
5770
|
memory_id: row.id,
|
|
@@ -5779,13 +5860,14 @@ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
|
5779
5860
|
last_accessed: String(row.timestamp)
|
|
5780
5861
|
}));
|
|
5781
5862
|
}
|
|
5782
|
-
var MAX_CARDS_PER_MEMORY,
|
|
5863
|
+
var MAX_CARDS_PER_MEMORY, MAX_SEGMENT_CHARS, MIN_SEGMENT_CHARS;
|
|
5783
5864
|
var init_memory_cards = __esm({
|
|
5784
5865
|
"src/lib/memory-cards.ts"() {
|
|
5785
5866
|
"use strict";
|
|
5786
5867
|
init_database();
|
|
5787
|
-
MAX_CARDS_PER_MEMORY =
|
|
5788
|
-
|
|
5868
|
+
MAX_CARDS_PER_MEMORY = 8;
|
|
5869
|
+
MAX_SEGMENT_CHARS = 500;
|
|
5870
|
+
MIN_SEGMENT_CHARS = 20;
|
|
5789
5871
|
}
|
|
5790
5872
|
});
|
|
5791
5873
|
|