@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
package/dist/bin/exe-call.js
CHANGED
|
@@ -290,11 +290,17 @@ var init_platform_procedures = __esm({
|
|
|
290
290
|
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."
|
|
291
291
|
},
|
|
292
292
|
{
|
|
293
|
-
title: "
|
|
293
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
294
294
|
domain: "workflow",
|
|
295
295
|
priority: "p1",
|
|
296
296
|
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."
|
|
297
297
|
},
|
|
298
|
+
{
|
|
299
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
300
|
+
domain: "identity",
|
|
301
|
+
priority: "p0",
|
|
302
|
+
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."
|
|
303
|
+
},
|
|
298
304
|
{
|
|
299
305
|
title: "Single dispatch path \u2014 create_task only",
|
|
300
306
|
domain: "workflow",
|
|
@@ -328,6 +334,12 @@ var init_platform_procedures = __esm({
|
|
|
328
334
|
priority: "p0",
|
|
329
335
|
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."
|
|
330
336
|
},
|
|
337
|
+
{
|
|
338
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
339
|
+
domain: "security",
|
|
340
|
+
priority: "p0",
|
|
341
|
+
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."
|
|
342
|
+
},
|
|
331
343
|
{
|
|
332
344
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
333
345
|
domain: "support",
|
|
@@ -479,7 +491,7 @@ var init_platform_procedures = __esm({
|
|
|
479
491
|
title: "MCP tool dispatch \u2014 all tools use action parameter",
|
|
480
492
|
domain: "tool-use",
|
|
481
493
|
priority: "p0",
|
|
482
|
-
content: 'exe-os MCP tools
|
|
494
|
+
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.'
|
|
483
495
|
},
|
|
484
496
|
{
|
|
485
497
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
@@ -573,9 +585,23 @@ __export(employee_templates_exports, {
|
|
|
573
585
|
function getSessionPrompt(storedPrompt) {
|
|
574
586
|
const markerIndex = storedPrompt.indexOf(PROCEDURES_MARKER);
|
|
575
587
|
const withoutProcedures = markerIndex >= 0 ? storedPrompt.slice(0, markerIndex).trimEnd() : storedPrompt;
|
|
588
|
+
let titlePrefix = "";
|
|
589
|
+
const frontmatterMatch = withoutProcedures.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
590
|
+
if (frontmatterMatch) {
|
|
591
|
+
const titleMatch = frontmatterMatch[1].match(/^title:\s*(.+)$/m);
|
|
592
|
+
const roleMatch = frontmatterMatch[1].match(/^role:\s*(.+)$/m);
|
|
593
|
+
if (titleMatch) {
|
|
594
|
+
const title = titleMatch[1].trim();
|
|
595
|
+
const role = roleMatch ? roleMatch[1].trim() : "";
|
|
596
|
+
if (title && role && title.toLowerCase() !== role.toLowerCase()) {
|
|
597
|
+
titlePrefix = `## Your Identity
|
|
598
|
+
You are **${title}** (specialist). `;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
576
602
|
const rolePrompt = withoutProcedures.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "").replace(/<!--[\s\S]*?-->/g, "").trimStart();
|
|
577
603
|
const globalBlock = getGlobalProceduresBlock();
|
|
578
|
-
return `${globalBlock}${rolePrompt}
|
|
604
|
+
return `${globalBlock}${titlePrefix}${rolePrompt}
|
|
579
605
|
${BASE_OPERATING_PROCEDURES}`;
|
|
580
606
|
}
|
|
581
607
|
function buildCustomEmployeePrompt(name, role) {
|
|
@@ -594,7 +620,7 @@ function personalizePrompt(prompt, templateName, actualName) {
|
|
|
594
620
|
return prompt.replace(new RegExp(`\\bYou are ${escaped}\\b`, "g"), `You are ${actualName}`);
|
|
595
621
|
}
|
|
596
622
|
function renderClientCOOTemplate(vars) {
|
|
597
|
-
const resolved = { ...vars, title: vars.title || "Chief
|
|
623
|
+
const resolved = { ...vars, title: vars.title || "Chief of Staff" };
|
|
598
624
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
599
625
|
const value = resolved[key];
|
|
600
626
|
if (typeof value !== "string" || value.length === 0) {
|
|
@@ -1238,6 +1264,7 @@ __export(agent_config_exports, {
|
|
|
1238
1264
|
getAgentRuntime: () => getAgentRuntime,
|
|
1239
1265
|
loadAgentConfig: () => loadAgentConfig,
|
|
1240
1266
|
saveAgentConfig: () => saveAgentConfig,
|
|
1267
|
+
setAgentMcps: () => setAgentMcps,
|
|
1241
1268
|
setAgentRuntime: () => setAgentRuntime
|
|
1242
1269
|
});
|
|
1243
1270
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync5 } from "fs";
|
|
@@ -1264,7 +1291,7 @@ function getAgentRuntime(agentId) {
|
|
|
1264
1291
|
if (orgDefault) return orgDefault;
|
|
1265
1292
|
return { runtime: DEFAULT_RUNTIME, model: DEFAULT_MODELS[DEFAULT_RUNTIME] };
|
|
1266
1293
|
}
|
|
1267
|
-
function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
1294
|
+
function setAgentRuntime(agentId, runtime, model, reasoning_effort, mcps) {
|
|
1268
1295
|
const knownModels = KNOWN_RUNTIMES[runtime];
|
|
1269
1296
|
if (!knownModels) {
|
|
1270
1297
|
return {
|
|
@@ -1279,12 +1306,26 @@ function setAgentRuntime(agentId, runtime, model, reasoning_effort) {
|
|
|
1279
1306
|
};
|
|
1280
1307
|
}
|
|
1281
1308
|
const config = loadAgentConfig();
|
|
1309
|
+
const existing = config[agentId];
|
|
1282
1310
|
const entry = { runtime, model };
|
|
1283
1311
|
if (reasoning_effort) entry.reasoning_effort = reasoning_effort;
|
|
1312
|
+
if (mcps !== void 0) {
|
|
1313
|
+
entry.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
1314
|
+
} else if (existing?.mcps) {
|
|
1315
|
+
entry.mcps = existing.mcps;
|
|
1316
|
+
}
|
|
1284
1317
|
config[agentId] = entry;
|
|
1285
1318
|
saveAgentConfig(config);
|
|
1286
1319
|
return { ok: true };
|
|
1287
1320
|
}
|
|
1321
|
+
function setAgentMcps(agentId, mcps) {
|
|
1322
|
+
const config = loadAgentConfig();
|
|
1323
|
+
const existing = config[agentId] ?? getAgentRuntime(agentId);
|
|
1324
|
+
existing.mcps = mcps.includes("exe-os") ? mcps : ["exe-os", ...mcps];
|
|
1325
|
+
config[agentId] = existing;
|
|
1326
|
+
saveAgentConfig(config);
|
|
1327
|
+
return { ok: true };
|
|
1328
|
+
}
|
|
1288
1329
|
function clearAgentRuntime(agentId) {
|
|
1289
1330
|
const config = loadAgentConfig();
|
|
1290
1331
|
delete config[agentId];
|
package/dist/bin/exe-cloud.js
CHANGED
|
@@ -2549,6 +2549,13 @@ async function ensureSchema() {
|
|
|
2549
2549
|
} catch (e) {
|
|
2550
2550
|
logCatchDebug("migration", e);
|
|
2551
2551
|
}
|
|
2552
|
+
for (const col of ["created_by_agent TEXT", "created_by_device TEXT", "source_session_id TEXT"]) {
|
|
2553
|
+
try {
|
|
2554
|
+
await client.execute({ sql: `ALTER TABLE behaviors ADD COLUMN ${col}`, args: [] });
|
|
2555
|
+
} catch (e) {
|
|
2556
|
+
logCatchDebug("migration", e);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2552
2559
|
try {
|
|
2553
2560
|
await client.execute({
|
|
2554
2561
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3765,6 +3772,22 @@ async function ensureSchema() {
|
|
|
3765
3772
|
} catch (e) {
|
|
3766
3773
|
logCatchDebug("migration", e);
|
|
3767
3774
|
}
|
|
3775
|
+
try {
|
|
3776
|
+
await client.execute({
|
|
3777
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
3778
|
+
args: []
|
|
3779
|
+
});
|
|
3780
|
+
} catch (e) {
|
|
3781
|
+
logCatchDebug("migration", e);
|
|
3782
|
+
}
|
|
3783
|
+
try {
|
|
3784
|
+
await client.execute({
|
|
3785
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
3786
|
+
args: []
|
|
3787
|
+
});
|
|
3788
|
+
} catch (e) {
|
|
3789
|
+
logCatchDebug("migration", e);
|
|
3790
|
+
}
|
|
3768
3791
|
}
|
|
3769
3792
|
async function disposeDatabase() {
|
|
3770
3793
|
if (_walCheckpointTimer) {
|
|
@@ -4262,7 +4285,7 @@ async function assertVpsLicense(opts) {
|
|
|
4262
4285
|
}
|
|
4263
4286
|
if (!transientFailure) {
|
|
4264
4287
|
throw new Error(
|
|
4265
|
-
"License validation failed: unknown backend state. Restore network connectivity to https://askexe.com
|
|
4288
|
+
"License validation failed: unknown backend state. Restore network connectivity to https://cloud.askexe.com and retry."
|
|
4266
4289
|
);
|
|
4267
4290
|
}
|
|
4268
4291
|
const fresh = await getCachedLicense();
|
|
@@ -4299,7 +4322,7 @@ async function assertVpsLicense(opts) {
|
|
|
4299
4322
|
} catch {
|
|
4300
4323
|
}
|
|
4301
4324
|
throw new Error(
|
|
4302
|
-
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://askexe.com
|
|
4325
|
+
`License validation unreachable for more than ${graceDays} days. Restore network connectivity to https://cloud.askexe.com and retry. This VPS image refuses to boot after the offline grace window.`
|
|
4303
4326
|
);
|
|
4304
4327
|
}
|
|
4305
4328
|
function startLicenseRevalidation(intervalMs = 36e5) {
|
|
@@ -4331,7 +4354,7 @@ var init_license = __esm({
|
|
|
4331
4354
|
LICENSE_PATH = path7.join(EXE_AI_DIR, "license.key");
|
|
4332
4355
|
CACHE_PATH = path7.join(EXE_AI_DIR, "license-cache.json");
|
|
4333
4356
|
DEVICE_ID_PATH = path7.join(EXE_AI_DIR, "device-id");
|
|
4334
|
-
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
4357
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
4335
4358
|
RETRY_DELAY_MS = 500;
|
|
4336
4359
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
4337
4360
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
@@ -5134,6 +5157,27 @@ async function cloudSync(config) {
|
|
|
5134
5157
|
if (stmts.length > 0) await client.batch(stmts, "write");
|
|
5135
5158
|
pulled = pullResult.records.length;
|
|
5136
5159
|
} else {
|
|
5160
|
+
try {
|
|
5161
|
+
const incomingIds = pullResult.records.map((r) => sqlSafe(r.id));
|
|
5162
|
+
if (incomingIds.length > 0) {
|
|
5163
|
+
const ph = incomingIds.map(() => "?").join(",");
|
|
5164
|
+
const existing = await client.execute({
|
|
5165
|
+
sql: `SELECT id, version, timestamp FROM memories WHERE id IN (${ph})`,
|
|
5166
|
+
args: incomingIds
|
|
5167
|
+
});
|
|
5168
|
+
const localMap = new Map(existing.rows.map((r) => [String(r.id), r]));
|
|
5169
|
+
for (const rec of pullResult.records) {
|
|
5170
|
+
const local = localMap.get(String(rec.id));
|
|
5171
|
+
if (local && Number(local.version) > 0 && Number(local.version) !== Number(rec.version ?? 0)) {
|
|
5172
|
+
process.stderr.write(
|
|
5173
|
+
`[cloud-sync] CONFLICT: memory ${String(rec.id).slice(0, 8)} \u2014 local v${local.version} vs remote v${rec.version ?? 0}. Remote wins (LWW).
|
|
5174
|
+
`
|
|
5175
|
+
);
|
|
5176
|
+
}
|
|
5177
|
+
}
|
|
5178
|
+
}
|
|
5179
|
+
} catch {
|
|
5180
|
+
}
|
|
5137
5181
|
const stmts = pullResult.records.map((rec) => ({
|
|
5138
5182
|
sql: `INSERT OR REPLACE INTO memories
|
|
5139
5183
|
(id, agent_id, agent_role, session_id, timestamp,
|
|
@@ -6891,11 +6935,17 @@ var init_platform_procedures = __esm({
|
|
|
6891
6935
|
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."
|
|
6892
6936
|
},
|
|
6893
6937
|
{
|
|
6894
|
-
title: "
|
|
6938
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
6895
6939
|
domain: "workflow",
|
|
6896
6940
|
priority: "p1",
|
|
6897
6941
|
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."
|
|
6898
6942
|
},
|
|
6943
|
+
{
|
|
6944
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
6945
|
+
domain: "identity",
|
|
6946
|
+
priority: "p0",
|
|
6947
|
+
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."
|
|
6948
|
+
},
|
|
6899
6949
|
{
|
|
6900
6950
|
title: "Single dispatch path \u2014 create_task only",
|
|
6901
6951
|
domain: "workflow",
|
|
@@ -6929,6 +6979,12 @@ var init_platform_procedures = __esm({
|
|
|
6929
6979
|
priority: "p0",
|
|
6930
6980
|
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."
|
|
6931
6981
|
},
|
|
6982
|
+
{
|
|
6983
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
6984
|
+
domain: "security",
|
|
6985
|
+
priority: "p0",
|
|
6986
|
+
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."
|
|
6987
|
+
},
|
|
6932
6988
|
{
|
|
6933
6989
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
6934
6990
|
domain: "support",
|
|
@@ -7080,7 +7136,7 @@ var init_platform_procedures = __esm({
|
|
|
7080
7136
|
title: "MCP tool dispatch \u2014 all tools use action parameter",
|
|
7081
7137
|
domain: "tool-use",
|
|
7082
7138
|
priority: "p0",
|
|
7083
|
-
content: 'exe-os MCP tools
|
|
7139
|
+
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.'
|
|
7084
7140
|
},
|
|
7085
7141
|
{
|
|
7086
7142
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
@@ -7214,10 +7270,24 @@ function stableId(memoryId, type, content) {
|
|
|
7214
7270
|
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
7215
7271
|
}
|
|
7216
7272
|
function cleanText(text) {
|
|
7217
|
-
|
|
7273
|
+
let cleaned = text.replace(
|
|
7274
|
+
/```(\w*)\n(.*?)(?:\n[\s\S]*?)```/g,
|
|
7275
|
+
(_m, lang, firstLine) => `[code${lang ? `:${lang}` : ""}] ${firstLine.trim()}`
|
|
7276
|
+
);
|
|
7277
|
+
cleaned = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
7278
|
+
return cleaned;
|
|
7218
7279
|
}
|
|
7219
|
-
function
|
|
7220
|
-
|
|
7280
|
+
function splitSegments(text) {
|
|
7281
|
+
const cleaned = cleanText(text);
|
|
7282
|
+
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);
|
|
7283
|
+
if (segments.length === 0 && cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
7284
|
+
const lines = cleaned.split(/\n+/).map((l) => l.trim()).filter((l) => l.length >= MIN_SEGMENT_CHARS && l.length <= MAX_SEGMENT_CHARS);
|
|
7285
|
+
if (lines.length > 0) return lines;
|
|
7286
|
+
if (cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
7287
|
+
return [cleaned.slice(0, MAX_SEGMENT_CHARS)];
|
|
7288
|
+
}
|
|
7289
|
+
}
|
|
7290
|
+
return segments;
|
|
7221
7291
|
}
|
|
7222
7292
|
function inferCardType(sentence, toolName) {
|
|
7223
7293
|
const lower = sentence.toLowerCase();
|
|
@@ -7249,12 +7319,12 @@ function predicateFor(type) {
|
|
|
7249
7319
|
}
|
|
7250
7320
|
}
|
|
7251
7321
|
function extractMemoryCards(row) {
|
|
7252
|
-
const
|
|
7322
|
+
const segments = splitSegments(row.raw_text);
|
|
7253
7323
|
const cards = [];
|
|
7254
|
-
for (const sentence of
|
|
7324
|
+
for (const sentence of segments) {
|
|
7255
7325
|
const type = inferCardType(sentence, row.tool_name);
|
|
7256
7326
|
const subject = extractSubject(sentence, row.agent_id);
|
|
7257
|
-
const content = sentence.length >
|
|
7327
|
+
const content = sentence.length > MAX_SEGMENT_CHARS ? `${sentence.slice(0, MAX_SEGMENT_CHARS - 1)}\u2026` : sentence;
|
|
7258
7328
|
cards.push({
|
|
7259
7329
|
id: stableId(row.id, type, content),
|
|
7260
7330
|
memory_id: row.id,
|
|
@@ -7350,13 +7420,14 @@ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
|
7350
7420
|
last_accessed: String(row.timestamp)
|
|
7351
7421
|
}));
|
|
7352
7422
|
}
|
|
7353
|
-
var MAX_CARDS_PER_MEMORY,
|
|
7423
|
+
var MAX_CARDS_PER_MEMORY, MAX_SEGMENT_CHARS, MIN_SEGMENT_CHARS;
|
|
7354
7424
|
var init_memory_cards = __esm({
|
|
7355
7425
|
"src/lib/memory-cards.ts"() {
|
|
7356
7426
|
"use strict";
|
|
7357
7427
|
init_database();
|
|
7358
|
-
MAX_CARDS_PER_MEMORY =
|
|
7359
|
-
|
|
7428
|
+
MAX_CARDS_PER_MEMORY = 8;
|
|
7429
|
+
MAX_SEGMENT_CHARS = 500;
|
|
7430
|
+
MIN_SEGMENT_CHARS = 20;
|
|
7360
7431
|
}
|
|
7361
7432
|
});
|
|
7362
7433
|
|
|
@@ -8479,7 +8550,7 @@ async function setupMode() {
|
|
|
8479
8550
|
rl.close();
|
|
8480
8551
|
return;
|
|
8481
8552
|
}
|
|
8482
|
-
const endpoint = await ask(rl, " Endpoint [https://askexe.com
|
|
8553
|
+
const endpoint = await ask(rl, " Endpoint [https://cloud.askexe.com]: ") || "https://cloud.askexe.com";
|
|
8483
8554
|
console.log(" Validating...");
|
|
8484
8555
|
try {
|
|
8485
8556
|
assertSecureEndpoint(endpoint);
|
|
@@ -8545,6 +8616,14 @@ async function setupMode() {
|
|
|
8545
8616
|
}
|
|
8546
8617
|
console.log("");
|
|
8547
8618
|
}
|
|
8619
|
+
try {
|
|
8620
|
+
const keyInfo = await getKeyStorageInfo();
|
|
8621
|
+
if (keyInfo.kind !== "missing") {
|
|
8622
|
+
console.log(` \u2713 Encryption key: ${keyInfo.note}`);
|
|
8623
|
+
}
|
|
8624
|
+
} catch {
|
|
8625
|
+
}
|
|
8626
|
+
console.log("");
|
|
8548
8627
|
console.log(BAR);
|
|
8549
8628
|
console.log(latestConfig.cloud?.apiKey ? " Setup complete. Cloud sync is connected." : " Setup complete. Cloud sync is not configured yet.");
|
|
8550
8629
|
console.log(BAR);
|
|
@@ -8636,7 +8715,13 @@ async function statusMode() {
|
|
|
8636
8715
|
console.log("");
|
|
8637
8716
|
if (key) {
|
|
8638
8717
|
const fingerprint = key.toString("hex").slice(0, 8);
|
|
8639
|
-
|
|
8718
|
+
let storageNote = "";
|
|
8719
|
+
try {
|
|
8720
|
+
const keyInfo = await getKeyStorageInfo();
|
|
8721
|
+
if (keyInfo.kind !== "missing") storageNote = ` [${keyInfo.note}]`;
|
|
8722
|
+
} catch {
|
|
8723
|
+
}
|
|
8724
|
+
console.log(` Encryption key: \u2713 present (${fingerprint}...)${storageNote}`);
|
|
8640
8725
|
} else {
|
|
8641
8726
|
console.log(" Encryption key: \u2717 not found \u2014 run /exe-setup");
|
|
8642
8727
|
}
|