@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-status.js
CHANGED
|
@@ -2048,6 +2048,13 @@ async function ensureSchema() {
|
|
|
2048
2048
|
} catch (e) {
|
|
2049
2049
|
logCatchDebug("migration", e);
|
|
2050
2050
|
}
|
|
2051
|
+
for (const col of ["created_by_agent TEXT", "created_by_device TEXT", "source_session_id TEXT"]) {
|
|
2052
|
+
try {
|
|
2053
|
+
await client.execute({ sql: `ALTER TABLE behaviors ADD COLUMN ${col}`, args: [] });
|
|
2054
|
+
} catch (e) {
|
|
2055
|
+
logCatchDebug("migration", e);
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2051
2058
|
try {
|
|
2052
2059
|
await client.execute({
|
|
2053
2060
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3264,6 +3271,22 @@ async function ensureSchema() {
|
|
|
3264
3271
|
} catch (e) {
|
|
3265
3272
|
logCatchDebug("migration", e);
|
|
3266
3273
|
}
|
|
3274
|
+
try {
|
|
3275
|
+
await client.execute({
|
|
3276
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
3277
|
+
args: []
|
|
3278
|
+
});
|
|
3279
|
+
} catch (e) {
|
|
3280
|
+
logCatchDebug("migration", e);
|
|
3281
|
+
}
|
|
3282
|
+
try {
|
|
3283
|
+
await client.execute({
|
|
3284
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
3285
|
+
args: []
|
|
3286
|
+
});
|
|
3287
|
+
} catch (e) {
|
|
3288
|
+
logCatchDebug("migration", e);
|
|
3289
|
+
}
|
|
3267
3290
|
}
|
|
3268
3291
|
async function disposeDatabase() {
|
|
3269
3292
|
if (_walCheckpointTimer) {
|
|
@@ -4387,11 +4410,17 @@ var init_platform_procedures = __esm({
|
|
|
4387
4410
|
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."
|
|
4388
4411
|
},
|
|
4389
4412
|
{
|
|
4390
|
-
title: "
|
|
4413
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
4391
4414
|
domain: "workflow",
|
|
4392
4415
|
priority: "p1",
|
|
4393
4416
|
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."
|
|
4394
4417
|
},
|
|
4418
|
+
{
|
|
4419
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
4420
|
+
domain: "identity",
|
|
4421
|
+
priority: "p0",
|
|
4422
|
+
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."
|
|
4423
|
+
},
|
|
4395
4424
|
{
|
|
4396
4425
|
title: "Single dispatch path \u2014 create_task only",
|
|
4397
4426
|
domain: "workflow",
|
|
@@ -4425,6 +4454,12 @@ var init_platform_procedures = __esm({
|
|
|
4425
4454
|
priority: "p0",
|
|
4426
4455
|
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."
|
|
4427
4456
|
},
|
|
4457
|
+
{
|
|
4458
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
4459
|
+
domain: "security",
|
|
4460
|
+
priority: "p0",
|
|
4461
|
+
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."
|
|
4462
|
+
},
|
|
4428
4463
|
{
|
|
4429
4464
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
4430
4465
|
domain: "support",
|
|
@@ -4576,7 +4611,7 @@ var init_platform_procedures = __esm({
|
|
|
4576
4611
|
title: "MCP tool dispatch \u2014 all tools use action parameter",
|
|
4577
4612
|
domain: "tool-use",
|
|
4578
4613
|
priority: "p0",
|
|
4579
|
-
content: 'exe-os MCP tools
|
|
4614
|
+
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.'
|
|
4580
4615
|
},
|
|
4581
4616
|
{
|
|
4582
4617
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
@@ -4710,10 +4745,24 @@ function stableId(memoryId, type, content) {
|
|
|
4710
4745
|
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4711
4746
|
}
|
|
4712
4747
|
function cleanText(text) {
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4748
|
+
let cleaned = text.replace(
|
|
4749
|
+
/```(\w*)\n(.*?)(?:\n[\s\S]*?)```/g,
|
|
4750
|
+
(_m, lang, firstLine) => `[code${lang ? `:${lang}` : ""}] ${firstLine.trim()}`
|
|
4751
|
+
);
|
|
4752
|
+
cleaned = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
4753
|
+
return cleaned;
|
|
4754
|
+
}
|
|
4755
|
+
function splitSegments(text) {
|
|
4756
|
+
const cleaned = cleanText(text);
|
|
4757
|
+
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);
|
|
4758
|
+
if (segments.length === 0 && cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
4759
|
+
const lines = cleaned.split(/\n+/).map((l) => l.trim()).filter((l) => l.length >= MIN_SEGMENT_CHARS && l.length <= MAX_SEGMENT_CHARS);
|
|
4760
|
+
if (lines.length > 0) return lines;
|
|
4761
|
+
if (cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
4762
|
+
return [cleaned.slice(0, MAX_SEGMENT_CHARS)];
|
|
4763
|
+
}
|
|
4764
|
+
}
|
|
4765
|
+
return segments;
|
|
4717
4766
|
}
|
|
4718
4767
|
function inferCardType(sentence, toolName) {
|
|
4719
4768
|
const lower = sentence.toLowerCase();
|
|
@@ -4745,12 +4794,12 @@ function predicateFor(type) {
|
|
|
4745
4794
|
}
|
|
4746
4795
|
}
|
|
4747
4796
|
function extractMemoryCards(row) {
|
|
4748
|
-
const
|
|
4797
|
+
const segments = splitSegments(row.raw_text);
|
|
4749
4798
|
const cards = [];
|
|
4750
|
-
for (const sentence of
|
|
4799
|
+
for (const sentence of segments) {
|
|
4751
4800
|
const type = inferCardType(sentence, row.tool_name);
|
|
4752
4801
|
const subject = extractSubject(sentence, row.agent_id);
|
|
4753
|
-
const content = sentence.length >
|
|
4802
|
+
const content = sentence.length > MAX_SEGMENT_CHARS ? `${sentence.slice(0, MAX_SEGMENT_CHARS - 1)}\u2026` : sentence;
|
|
4754
4803
|
cards.push({
|
|
4755
4804
|
id: stableId(row.id, type, content),
|
|
4756
4805
|
memory_id: row.id,
|
|
@@ -4846,13 +4895,14 @@ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
|
4846
4895
|
last_accessed: String(row.timestamp)
|
|
4847
4896
|
}));
|
|
4848
4897
|
}
|
|
4849
|
-
var MAX_CARDS_PER_MEMORY,
|
|
4898
|
+
var MAX_CARDS_PER_MEMORY, MAX_SEGMENT_CHARS, MIN_SEGMENT_CHARS;
|
|
4850
4899
|
var init_memory_cards = __esm({
|
|
4851
4900
|
"src/lib/memory-cards.ts"() {
|
|
4852
4901
|
"use strict";
|
|
4853
4902
|
init_database();
|
|
4854
|
-
MAX_CARDS_PER_MEMORY =
|
|
4855
|
-
|
|
4903
|
+
MAX_CARDS_PER_MEMORY = 8;
|
|
4904
|
+
MAX_SEGMENT_CHARS = 500;
|
|
4905
|
+
MIN_SEGMENT_CHARS = 20;
|
|
4856
4906
|
}
|
|
4857
4907
|
});
|
|
4858
4908
|
|
|
@@ -6087,7 +6137,7 @@ var init_license = __esm({
|
|
|
6087
6137
|
LICENSE_PATH = path11.join(EXE_AI_DIR, "license.key");
|
|
6088
6138
|
CACHE_PATH = path11.join(EXE_AI_DIR, "license-cache.json");
|
|
6089
6139
|
DEVICE_ID_PATH = path11.join(EXE_AI_DIR, "device-id");
|
|
6090
|
-
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
6140
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
6091
6141
|
}
|
|
6092
6142
|
});
|
|
6093
6143
|
|
|
@@ -6140,6 +6190,18 @@ function extractRootExe(name) {
|
|
|
6140
6190
|
const parts = name.split("-").filter(Boolean);
|
|
6141
6191
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
6142
6192
|
}
|
|
6193
|
+
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
6194
|
+
if (!existsSync14(SESSION_CACHE)) {
|
|
6195
|
+
mkdirSync7(SESSION_CACHE, { recursive: true });
|
|
6196
|
+
}
|
|
6197
|
+
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
6198
|
+
const filePath = path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
6199
|
+
writeFileSync6(filePath, JSON.stringify({
|
|
6200
|
+
parentExe: rootExe,
|
|
6201
|
+
dispatchedBy: dispatchedBy || rootExe,
|
|
6202
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6203
|
+
}));
|
|
6204
|
+
}
|
|
6143
6205
|
function getParentExe(sessionKey) {
|
|
6144
6206
|
try {
|
|
6145
6207
|
const data = JSON.parse(readFileSync9(path14.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
@@ -6149,11 +6211,12 @@ function getParentExe(sessionKey) {
|
|
|
6149
6211
|
}
|
|
6150
6212
|
}
|
|
6151
6213
|
function resolveExeSession() {
|
|
6214
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
6215
|
+
const fromEnv = extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6216
|
+
if (fromEnv) return fromEnv;
|
|
6217
|
+
}
|
|
6152
6218
|
const mySession = getMySession();
|
|
6153
6219
|
if (!mySession) {
|
|
6154
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
6155
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6156
|
-
}
|
|
6157
6220
|
return null;
|
|
6158
6221
|
}
|
|
6159
6222
|
const fromSessionName = extractRootExe(mySession);
|
|
@@ -6168,6 +6231,10 @@ function resolveExeSession() {
|
|
|
6168
6231
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
6169
6232
|
`
|
|
6170
6233
|
);
|
|
6234
|
+
try {
|
|
6235
|
+
registerParentExe(key, fromSessionName);
|
|
6236
|
+
} catch {
|
|
6237
|
+
}
|
|
6171
6238
|
candidate = fromSessionName;
|
|
6172
6239
|
} else {
|
|
6173
6240
|
candidate = fromCache;
|
package/dist/bin/exe-support.js
CHANGED
|
@@ -232,7 +232,7 @@ import { jwtVerify, importSPKI } from "jose";
|
|
|
232
232
|
var LICENSE_PATH = path2.join(EXE_AI_DIR, "license.key");
|
|
233
233
|
var CACHE_PATH = path2.join(EXE_AI_DIR, "license-cache.json");
|
|
234
234
|
var DEVICE_ID_PATH = path2.join(EXE_AI_DIR, "device-id");
|
|
235
|
-
var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com
|
|
235
|
+
var API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://cloud.askexe.com";
|
|
236
236
|
function loadLicense() {
|
|
237
237
|
try {
|
|
238
238
|
if (!existsSync3(LICENSE_PATH)) return null;
|
package/dist/bin/exe-team.js
CHANGED
|
@@ -2037,6 +2037,13 @@ async function ensureSchema() {
|
|
|
2037
2037
|
} catch (e) {
|
|
2038
2038
|
logCatchDebug("migration", e);
|
|
2039
2039
|
}
|
|
2040
|
+
for (const col of ["created_by_agent TEXT", "created_by_device TEXT", "source_session_id TEXT"]) {
|
|
2041
|
+
try {
|
|
2042
|
+
await client.execute({ sql: `ALTER TABLE behaviors ADD COLUMN ${col}`, args: [] });
|
|
2043
|
+
} catch (e) {
|
|
2044
|
+
logCatchDebug("migration", e);
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2040
2047
|
try {
|
|
2041
2048
|
await client.execute({
|
|
2042
2049
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
@@ -3253,6 +3260,22 @@ async function ensureSchema() {
|
|
|
3253
3260
|
} catch (e) {
|
|
3254
3261
|
logCatchDebug("migration", e);
|
|
3255
3262
|
}
|
|
3263
|
+
try {
|
|
3264
|
+
await client.execute({
|
|
3265
|
+
sql: `ALTER TABLE memories ADD COLUMN visibility TEXT DEFAULT 'private'`,
|
|
3266
|
+
args: []
|
|
3267
|
+
});
|
|
3268
|
+
} catch (e) {
|
|
3269
|
+
logCatchDebug("migration", e);
|
|
3270
|
+
}
|
|
3271
|
+
try {
|
|
3272
|
+
await client.execute({
|
|
3273
|
+
sql: `ALTER TABLE memories ADD COLUMN strength REAL DEFAULT 1.0`,
|
|
3274
|
+
args: []
|
|
3275
|
+
});
|
|
3276
|
+
} catch (e) {
|
|
3277
|
+
logCatchDebug("migration", e);
|
|
3278
|
+
}
|
|
3256
3279
|
}
|
|
3257
3280
|
async function disposeDatabase() {
|
|
3258
3281
|
if (_walCheckpointTimer) {
|
|
@@ -4376,11 +4399,17 @@ var init_platform_procedures = __esm({
|
|
|
4376
4399
|
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."
|
|
4377
4400
|
},
|
|
4378
4401
|
{
|
|
4379
|
-
title: "
|
|
4402
|
+
title: "Orchestration phase guidance \u2014 recommend, never trap",
|
|
4380
4403
|
domain: "workflow",
|
|
4381
4404
|
priority: "p1",
|
|
4382
4405
|
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."
|
|
4383
4406
|
},
|
|
4407
|
+
{
|
|
4408
|
+
title: "Routing slot vs display title \u2014 internal 'coo' is plumbing, not your name",
|
|
4409
|
+
domain: "identity",
|
|
4410
|
+
priority: "p0",
|
|
4411
|
+
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."
|
|
4412
|
+
},
|
|
4384
4413
|
{
|
|
4385
4414
|
title: "Single dispatch path \u2014 create_task only",
|
|
4386
4415
|
domain: "workflow",
|
|
@@ -4414,6 +4443,12 @@ var init_platform_procedures = __esm({
|
|
|
4414
4443
|
priority: "p0",
|
|
4415
4444
|
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."
|
|
4416
4445
|
},
|
|
4446
|
+
{
|
|
4447
|
+
title: "Destructive operations \u2014 mandatory reviewer gate",
|
|
4448
|
+
domain: "security",
|
|
4449
|
+
priority: "p0",
|
|
4450
|
+
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."
|
|
4451
|
+
},
|
|
4417
4452
|
{
|
|
4418
4453
|
title: "Customer patch triage \u2014 upstream bug vs customization",
|
|
4419
4454
|
domain: "support",
|
|
@@ -4565,7 +4600,7 @@ var init_platform_procedures = __esm({
|
|
|
4565
4600
|
title: "MCP tool dispatch \u2014 all tools use action parameter",
|
|
4566
4601
|
domain: "tool-use",
|
|
4567
4602
|
priority: "p0",
|
|
4568
|
-
content: 'exe-os MCP tools
|
|
4603
|
+
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.'
|
|
4569
4604
|
},
|
|
4570
4605
|
{
|
|
4571
4606
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
@@ -4699,10 +4734,24 @@ function stableId(memoryId, type, content) {
|
|
|
4699
4734
|
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4700
4735
|
}
|
|
4701
4736
|
function cleanText(text) {
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4737
|
+
let cleaned = text.replace(
|
|
4738
|
+
/```(\w*)\n(.*?)(?:\n[\s\S]*?)```/g,
|
|
4739
|
+
(_m, lang, firstLine) => `[code${lang ? `:${lang}` : ""}] ${firstLine.trim()}`
|
|
4740
|
+
);
|
|
4741
|
+
cleaned = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
4742
|
+
return cleaned;
|
|
4743
|
+
}
|
|
4744
|
+
function splitSegments(text) {
|
|
4745
|
+
const cleaned = cleanText(text);
|
|
4746
|
+
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);
|
|
4747
|
+
if (segments.length === 0 && cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
4748
|
+
const lines = cleaned.split(/\n+/).map((l) => l.trim()).filter((l) => l.length >= MIN_SEGMENT_CHARS && l.length <= MAX_SEGMENT_CHARS);
|
|
4749
|
+
if (lines.length > 0) return lines;
|
|
4750
|
+
if (cleaned.length >= MIN_SEGMENT_CHARS) {
|
|
4751
|
+
return [cleaned.slice(0, MAX_SEGMENT_CHARS)];
|
|
4752
|
+
}
|
|
4753
|
+
}
|
|
4754
|
+
return segments;
|
|
4706
4755
|
}
|
|
4707
4756
|
function inferCardType(sentence, toolName) {
|
|
4708
4757
|
const lower = sentence.toLowerCase();
|
|
@@ -4734,12 +4783,12 @@ function predicateFor(type) {
|
|
|
4734
4783
|
}
|
|
4735
4784
|
}
|
|
4736
4785
|
function extractMemoryCards(row) {
|
|
4737
|
-
const
|
|
4786
|
+
const segments = splitSegments(row.raw_text);
|
|
4738
4787
|
const cards = [];
|
|
4739
|
-
for (const sentence of
|
|
4788
|
+
for (const sentence of segments) {
|
|
4740
4789
|
const type = inferCardType(sentence, row.tool_name);
|
|
4741
4790
|
const subject = extractSubject(sentence, row.agent_id);
|
|
4742
|
-
const content = sentence.length >
|
|
4791
|
+
const content = sentence.length > MAX_SEGMENT_CHARS ? `${sentence.slice(0, MAX_SEGMENT_CHARS - 1)}\u2026` : sentence;
|
|
4743
4792
|
cards.push({
|
|
4744
4793
|
id: stableId(row.id, type, content),
|
|
4745
4794
|
memory_id: row.id,
|
|
@@ -4835,13 +4884,14 @@ Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
|
4835
4884
|
last_accessed: String(row.timestamp)
|
|
4836
4885
|
}));
|
|
4837
4886
|
}
|
|
4838
|
-
var MAX_CARDS_PER_MEMORY,
|
|
4887
|
+
var MAX_CARDS_PER_MEMORY, MAX_SEGMENT_CHARS, MIN_SEGMENT_CHARS;
|
|
4839
4888
|
var init_memory_cards = __esm({
|
|
4840
4889
|
"src/lib/memory-cards.ts"() {
|
|
4841
4890
|
"use strict";
|
|
4842
4891
|
init_database();
|
|
4843
|
-
MAX_CARDS_PER_MEMORY =
|
|
4844
|
-
|
|
4892
|
+
MAX_CARDS_PER_MEMORY = 8;
|
|
4893
|
+
MAX_SEGMENT_CHARS = 500;
|
|
4894
|
+
MIN_SEGMENT_CHARS = 20;
|
|
4845
4895
|
}
|
|
4846
4896
|
});
|
|
4847
4897
|
|