@askexenow/exe-os 0.9.35 → 0.9.37
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/dist/bin/backfill-conversations.js +5 -1
- package/dist/bin/backfill-responses.js +5 -1
- package/dist/bin/backfill-vectors.js +1 -1
- package/dist/bin/cleanup-stale-review-tasks.js +10 -2
- package/dist/bin/cli.js +48 -14
- package/dist/bin/exe-agent.js +1 -1
- package/dist/bin/exe-assign.js +10 -2
- package/dist/bin/exe-boot.js +1 -1
- package/dist/bin/exe-call.js +7 -5
- package/dist/bin/exe-dispatch.js +10 -2
- package/dist/bin/exe-doctor.js +1 -1
- package/dist/bin/exe-export-behaviors.js +87 -4
- package/dist/bin/exe-forget.js +31 -11
- package/dist/bin/exe-gateway.js +10 -2
- package/dist/bin/exe-heartbeat.js +10 -2
- package/dist/bin/exe-kill.js +10 -2
- package/dist/bin/exe-launch-agent.js +85 -7
- package/dist/bin/exe-new-employee.js +26 -2
- package/dist/bin/exe-pending-messages.js +10 -2
- package/dist/bin/exe-pending-notifications.js +10 -2
- package/dist/bin/exe-pending-reviews.js +10 -2
- package/dist/bin/exe-rename.js +1 -1
- package/dist/bin/exe-review.js +10 -2
- package/dist/bin/exe-search.js +38 -19
- package/dist/bin/exe-session-cleanup.js +14 -3
- package/dist/bin/exe-start-codex.js +69 -3
- package/dist/bin/exe-start-opencode.js +80 -3
- package/dist/bin/exe-status.js +10 -2
- package/dist/bin/exe-team.js +10 -2
- package/dist/bin/git-sweep.js +10 -2
- package/dist/bin/graph-backfill.js +2 -1
- package/dist/bin/graph-export.js +10 -2
- package/dist/bin/install.js +25 -1
- package/dist/bin/intercom-check.js +10 -2
- package/dist/bin/scan-tasks.js +10 -2
- package/dist/bin/setup.js +7 -5
- package/dist/bin/shard-migrate.js +2 -1
- package/dist/gateway/index.js +10 -2
- package/dist/hooks/bug-report-worker.js +10 -2
- package/dist/hooks/codex-stop-task-finalizer.js +10 -2
- package/dist/hooks/commit-complete.js +10 -2
- package/dist/hooks/error-recall.js +38 -19
- package/dist/hooks/ingest-worker.js +9 -2
- package/dist/hooks/ingest.js +10 -2
- package/dist/hooks/instructions-loaded.js +10 -2
- package/dist/hooks/notification.js +10 -2
- package/dist/hooks/post-compact.js +10 -2
- package/dist/hooks/post-tool-combined.js +47 -21
- package/dist/hooks/pre-compact.js +12 -3
- package/dist/hooks/pre-tool-use.js +20 -8
- package/dist/hooks/prompt-submit.js +133 -20
- package/dist/hooks/session-end.js +138 -5
- package/dist/hooks/session-start.js +216 -46
- package/dist/hooks/stop.js +14 -4
- package/dist/hooks/subagent-stop.js +10 -2
- package/dist/hooks/summary-worker.js +121 -19
- package/dist/index.js +32 -16
- package/dist/lib/employee-templates.js +7 -5
- package/dist/lib/exe-daemon.js +124 -34
- package/dist/lib/hybrid-search.js +38 -19
- package/dist/lib/schedules.js +1 -1
- package/dist/lib/store.js +10 -2
- package/dist/mcp/server.js +118 -34
- package/dist/runtime/index.js +32 -16
- package/dist/tui/App.js +10 -2
- package/package.json +1 -1
- package/src/commands/exe/save.md +52 -0
package/dist/mcp/server.js
CHANGED
|
@@ -3601,6 +3601,9 @@ function classifyMemoryType(input) {
|
|
|
3601
3601
|
if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
|
|
3602
3602
|
if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
|
|
3603
3603
|
if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
|
|
3604
|
+
if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
|
|
3605
|
+
if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
|
|
3606
|
+
if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
|
|
3604
3607
|
if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
|
|
3605
3608
|
if (tool === "store_memory" || tool === "manual") return "observation";
|
|
3606
3609
|
return "raw";
|
|
@@ -3743,6 +3746,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
3743
3746
|
}
|
|
3744
3747
|
}
|
|
3745
3748
|
function schedulePostWriteMemoryHygiene(memoryIds) {
|
|
3749
|
+
if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
|
|
3746
3750
|
if (memoryIds.length === 0) return;
|
|
3747
3751
|
const run = () => {
|
|
3748
3752
|
void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
|
|
@@ -4137,7 +4141,7 @@ var init_platform_procedures = __esm({
|
|
|
4137
4141
|
title: "Chain of command \u2014 who talks to whom",
|
|
4138
4142
|
domain: "workflow",
|
|
4139
4143
|
priority: "p0",
|
|
4140
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
4144
|
+
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."
|
|
4141
4145
|
},
|
|
4142
4146
|
{
|
|
4143
4147
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -4809,7 +4813,11 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
4809
4813
|
sql += ` AND timestamp >= ?`;
|
|
4810
4814
|
args.push(options.since);
|
|
4811
4815
|
}
|
|
4812
|
-
if (options?.
|
|
4816
|
+
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
4817
|
+
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
4818
|
+
sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
|
|
4819
|
+
args.push(...uniqueTypes);
|
|
4820
|
+
} else if (options?.memoryType) {
|
|
4813
4821
|
sql += ` AND memory_type = ?`;
|
|
4814
4822
|
args.push(options.memoryType);
|
|
4815
4823
|
}
|
|
@@ -6039,6 +6047,17 @@ __export(hybrid_search_exports, {
|
|
|
6039
6047
|
rrfMerge: () => rrfMerge,
|
|
6040
6048
|
rrfMergeMulti: () => rrfMergeMulti
|
|
6041
6049
|
});
|
|
6050
|
+
function appendMemoryTypeFilter(sql, args, column, options) {
|
|
6051
|
+
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
6052
|
+
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
6053
|
+
sql += ` AND ${column} IN (${uniqueTypes.map(() => "?").join(",")})`;
|
|
6054
|
+
args.push(...uniqueTypes);
|
|
6055
|
+
} else if (options?.memoryType) {
|
|
6056
|
+
sql += ` AND ${column} = ?`;
|
|
6057
|
+
args.push(options.memoryType);
|
|
6058
|
+
}
|
|
6059
|
+
return sql;
|
|
6060
|
+
}
|
|
6042
6061
|
async function hybridSearch(queryText, agentId, options) {
|
|
6043
6062
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
6044
6063
|
const config2 = await loadConfig2();
|
|
@@ -6134,7 +6153,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6134
6153
|
}
|
|
6135
6154
|
if (lists.length === 0) return [];
|
|
6136
6155
|
if (lists.length === 1 && !effectiveIsBroad) return lists[0].slice(0, limit);
|
|
6137
|
-
const rrfLimit = effectiveIsBroad ? Math.max(limit * 5,
|
|
6156
|
+
const rrfLimit = effectiveIsBroad ? Math.max(limit * 5, broadFetchTopK) : limit;
|
|
6138
6157
|
let merged = lists.length === 1 ? lists[0].slice(0, rrfLimit) : rrfMergeMulti(lists, rrfLimit, RRF_K, weights);
|
|
6139
6158
|
let graphContextMap = /* @__PURE__ */ new Map();
|
|
6140
6159
|
let entityBoostRan = false;
|
|
@@ -6155,6 +6174,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6155
6174
|
returnTopK: 5
|
|
6156
6175
|
};
|
|
6157
6176
|
let rerankedAndBlended = null;
|
|
6177
|
+
const rerankReturnLimit = Math.max(limit, auto.returnTopK ?? 5);
|
|
6158
6178
|
if (effectiveIsBroad && auto.enabled && rerankerAvailable) {
|
|
6159
6179
|
const cardinality2 = await estimateCardinality(agentId, effectiveOptions);
|
|
6160
6180
|
if (cardinality2 > auto.broadQueryMinCardinality) {
|
|
@@ -6166,16 +6186,16 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6166
6186
|
text: m.raw_text,
|
|
6167
6187
|
context: graphContextMap.get(m.id)
|
|
6168
6188
|
}));
|
|
6169
|
-
const scored = await rerankWithContext2(effectiveQuery, candidates,
|
|
6189
|
+
const scored = await rerankWithContext2(effectiveQuery, candidates, rerankReturnLimit);
|
|
6170
6190
|
rerankedRecords = scored.map((s) => merged[s.index]);
|
|
6171
6191
|
} else {
|
|
6172
6192
|
const { rerank: rerank2 } = await Promise.resolve().then(() => (init_reranker(), reranker_exports));
|
|
6173
|
-
rerankedRecords = await rerank2(effectiveQuery, merged,
|
|
6193
|
+
rerankedRecords = await rerank2(effectiveQuery, merged, rerankReturnLimit);
|
|
6174
6194
|
}
|
|
6175
6195
|
if (rerankedRecords.length > 0) {
|
|
6176
6196
|
rerankedAndBlended = rrfMergeMulti(
|
|
6177
6197
|
[rerankedRecords],
|
|
6178
|
-
|
|
6198
|
+
rerankReturnLimit,
|
|
6179
6199
|
RRF_K
|
|
6180
6200
|
);
|
|
6181
6201
|
}
|
|
@@ -6183,10 +6203,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6183
6203
|
}
|
|
6184
6204
|
}
|
|
6185
6205
|
}
|
|
6186
|
-
const finalResults = (rerankedAndBlended ?? merged).slice(
|
|
6187
|
-
0,
|
|
6188
|
-
rerankedAndBlended ? auto.returnTopK : limit
|
|
6189
|
-
);
|
|
6206
|
+
const finalResults = (rerankedAndBlended ?? merged).slice(0, limit);
|
|
6190
6207
|
if (options?.includeSource && finalResults.length > 0) {
|
|
6191
6208
|
await attachDocumentMetadata(finalResults);
|
|
6192
6209
|
}
|
|
@@ -6267,6 +6284,7 @@ async function estimateCardinality(agentId, options) {
|
|
|
6267
6284
|
sql += ` AND timestamp >= ?`;
|
|
6268
6285
|
args.push(options.since);
|
|
6269
6286
|
}
|
|
6287
|
+
sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
|
|
6270
6288
|
try {
|
|
6271
6289
|
const result = await client.execute({ sql, args });
|
|
6272
6290
|
return Number(result.rows[0]?.cnt) || 0;
|
|
@@ -6388,10 +6406,7 @@ async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
|
6388
6406
|
sql += ` AND m.timestamp >= ?`;
|
|
6389
6407
|
args.push(options.since);
|
|
6390
6408
|
}
|
|
6391
|
-
|
|
6392
|
-
sql += ` AND m.memory_type = ?`;
|
|
6393
|
-
args.push(options.memoryType);
|
|
6394
|
-
}
|
|
6409
|
+
sql = appendMemoryTypeFilter(sql, args, "m.memory_type", options);
|
|
6395
6410
|
sql += ` ORDER BY rank LIMIT ?`;
|
|
6396
6411
|
args.push(limit);
|
|
6397
6412
|
const result = await client.execute({ sql, args });
|
|
@@ -6448,9 +6463,16 @@ async function recentRecords(agentId, options, limit, textFilter) {
|
|
|
6448
6463
|
AND timestamp >= ? AND timestamp <= ?
|
|
6449
6464
|
AND COALESCE(status, 'active') = 'active'
|
|
6450
6465
|
AND ${options?.includeRaw === false ? "COALESCE(memory_type, 'raw') != 'raw'" : "1 = 1"}
|
|
6466
|
+
${options?.memoryTypes?.length ? `AND memory_type IN (${options.memoryTypes.map(() => "?").join(",")})` : options?.memoryType ? "AND memory_type = ?" : ""}
|
|
6451
6467
|
AND COALESCE(confidence, 0.7) >= 0.3
|
|
6452
6468
|
ORDER BY timestamp DESC LIMIT ?`,
|
|
6453
|
-
args: [
|
|
6469
|
+
args: [
|
|
6470
|
+
agentId,
|
|
6471
|
+
windowStart,
|
|
6472
|
+
killedAt,
|
|
6473
|
+
...options?.memoryTypes?.length ? [...new Set(options.memoryTypes)] : options?.memoryType ? [options.memoryType] : [],
|
|
6474
|
+
boundarySlots
|
|
6475
|
+
]
|
|
6454
6476
|
});
|
|
6455
6477
|
for (const row of boundaryResult.rows) {
|
|
6456
6478
|
sessionBoundaryMemories.push(rowToMemoryRecord(row));
|
|
@@ -6496,10 +6518,7 @@ async function recentRecords(agentId, options, limit, textFilter) {
|
|
|
6496
6518
|
sql += ` AND timestamp >= ?`;
|
|
6497
6519
|
args.push(options.since);
|
|
6498
6520
|
}
|
|
6499
|
-
|
|
6500
|
-
sql += ` AND memory_type = ?`;
|
|
6501
|
-
args.push(options.memoryType);
|
|
6502
|
-
}
|
|
6521
|
+
sql = appendMemoryTypeFilter(sql, args, "memory_type", options);
|
|
6503
6522
|
if (textFilter) {
|
|
6504
6523
|
sql += ` AND raw_text LIKE '%' || ? || '%'`;
|
|
6505
6524
|
args.push(textFilter);
|
|
@@ -12685,6 +12704,63 @@ init_hybrid_search();
|
|
|
12685
12704
|
init_store();
|
|
12686
12705
|
init_active_agent();
|
|
12687
12706
|
import { z } from "zod";
|
|
12707
|
+
|
|
12708
|
+
// src/lib/memory-retrieval-modes.ts
|
|
12709
|
+
var RETRIEVAL_MODES = [
|
|
12710
|
+
"all",
|
|
12711
|
+
"decisions_only",
|
|
12712
|
+
"behaviors_only",
|
|
12713
|
+
"procedures_only",
|
|
12714
|
+
"operational",
|
|
12715
|
+
"no_raw",
|
|
12716
|
+
"recent_high_value"
|
|
12717
|
+
];
|
|
12718
|
+
var RETRIEVAL_MODE_DESCRIPTIONS = {
|
|
12719
|
+
all: "All visible memory types.",
|
|
12720
|
+
decisions_only: "Only decisions and ADRs.",
|
|
12721
|
+
behaviors_only: "Only durable behavior/correction memories.",
|
|
12722
|
+
procedures_only: "Only procedures/runbooks.",
|
|
12723
|
+
operational: "Raw operational/debug/tool output.",
|
|
12724
|
+
no_raw: "All non-raw memory types.",
|
|
12725
|
+
recent_high_value: "High-value durable memory types, intended for recency recovery."
|
|
12726
|
+
};
|
|
12727
|
+
function applyRetrievalMode(base, mode) {
|
|
12728
|
+
if (!mode || mode === "all") return base;
|
|
12729
|
+
const next = { ...base };
|
|
12730
|
+
switch (mode) {
|
|
12731
|
+
case "decisions_only":
|
|
12732
|
+
next.memoryTypes = ["decision", "adr"];
|
|
12733
|
+
next.includeRaw = false;
|
|
12734
|
+
break;
|
|
12735
|
+
case "behaviors_only":
|
|
12736
|
+
next.memoryTypes = ["behavior"];
|
|
12737
|
+
next.includeRaw = false;
|
|
12738
|
+
break;
|
|
12739
|
+
case "procedures_only":
|
|
12740
|
+
next.memoryTypes = ["procedure"];
|
|
12741
|
+
next.includeRaw = false;
|
|
12742
|
+
break;
|
|
12743
|
+
case "operational":
|
|
12744
|
+
next.memoryTypes = ["raw", "observation"];
|
|
12745
|
+
next.includeRaw = true;
|
|
12746
|
+
break;
|
|
12747
|
+
case "no_raw":
|
|
12748
|
+
next.includeRaw = false;
|
|
12749
|
+
break;
|
|
12750
|
+
case "recent_high_value":
|
|
12751
|
+
next.memoryTypes = ["decision", "adr", "behavior", "procedure"];
|
|
12752
|
+
next.includeRaw = false;
|
|
12753
|
+
break;
|
|
12754
|
+
default:
|
|
12755
|
+
return next;
|
|
12756
|
+
}
|
|
12757
|
+
return next;
|
|
12758
|
+
}
|
|
12759
|
+
function formatRetrievalModes() {
|
|
12760
|
+
return RETRIEVAL_MODES.map((mode) => `${mode}: ${RETRIEVAL_MODE_DESCRIPTIONS[mode]}`).join("; ");
|
|
12761
|
+
}
|
|
12762
|
+
|
|
12763
|
+
// src/mcp/tools/recall-my-memory.ts
|
|
12688
12764
|
function formatSourceLine(record) {
|
|
12689
12765
|
const doc2 = record.document_metadata;
|
|
12690
12766
|
if (!doc2) return "";
|
|
@@ -12720,7 +12796,8 @@ function registerRecallMyMemory(server2) {
|
|
|
12720
12796
|
),
|
|
12721
12797
|
include_source: z.boolean().optional().default(false).describe(
|
|
12722
12798
|
"When true, attach parent document metadata (filename, mime, source_type) to each result. Default false."
|
|
12723
|
-
)
|
|
12799
|
+
),
|
|
12800
|
+
retrieval_mode: z.enum(RETRIEVAL_MODES).optional().default("all").describe(`Typed retrieval mode. ${formatRetrievalModes()}`)
|
|
12724
12801
|
}
|
|
12725
12802
|
},
|
|
12726
12803
|
async ({
|
|
@@ -12734,7 +12811,8 @@ function registerRecallMyMemory(server2) {
|
|
|
12734
12811
|
include_archived,
|
|
12735
12812
|
workspace_id,
|
|
12736
12813
|
user_id,
|
|
12737
|
-
include_source
|
|
12814
|
+
include_source,
|
|
12815
|
+
retrieval_mode
|
|
12738
12816
|
}) => {
|
|
12739
12817
|
try {
|
|
12740
12818
|
if (!recent && !query) {
|
|
@@ -12744,7 +12822,7 @@ function registerRecallMyMemory(server2) {
|
|
|
12744
12822
|
};
|
|
12745
12823
|
}
|
|
12746
12824
|
const { agentId } = getActiveAgent();
|
|
12747
|
-
const searchOptions = {
|
|
12825
|
+
const searchOptions = applyRetrievalMode({
|
|
12748
12826
|
projectName: project_name,
|
|
12749
12827
|
hasError: has_error,
|
|
12750
12828
|
toolName: tool_name,
|
|
@@ -12755,7 +12833,7 @@ function registerRecallMyMemory(server2) {
|
|
|
12755
12833
|
includeSource: include_source,
|
|
12756
12834
|
includeDrafts: true,
|
|
12757
12835
|
...user_id !== void 0 ? { userId: user_id } : {}
|
|
12758
|
-
};
|
|
12836
|
+
}, retrieval_mode);
|
|
12759
12837
|
let results;
|
|
12760
12838
|
if (recent) {
|
|
12761
12839
|
results = await recentRecords(agentId, searchOptions, limit, query);
|
|
@@ -12843,10 +12921,11 @@ function registerAskTeamMemory(server2) {
|
|
|
12843
12921
|
),
|
|
12844
12922
|
include_raw: z2.boolean().optional().default(false).describe(
|
|
12845
12923
|
"Include raw technical memories when ACL allows it (default: non-raw memories only for cross-agent reads)"
|
|
12846
|
-
)
|
|
12924
|
+
),
|
|
12925
|
+
retrieval_mode: z2.enum(RETRIEVAL_MODES).optional().default("all").describe(`Typed retrieval mode. Raw visibility is still ACL-gated. ${formatRetrievalModes()}`)
|
|
12847
12926
|
}
|
|
12848
12927
|
},
|
|
12849
|
-
async ({ team_member, query, project_name, limit, since, include_archived, include_raw: _include_raw }) => {
|
|
12928
|
+
async ({ team_member, query, project_name, limit, since, include_archived, include_raw: _include_raw, retrieval_mode }) => {
|
|
12850
12929
|
try {
|
|
12851
12930
|
const { agentId: queryingAgentId, agentRole: queryingAgentRole } = getActiveAgent();
|
|
12852
12931
|
const employees = loadEmployeesSync();
|
|
@@ -12855,16 +12934,18 @@ function registerAskTeamMemory(server2) {
|
|
|
12855
12934
|
const targetRole = targetEmployee?.role ?? "";
|
|
12856
12935
|
const hasRawAccess = canSeeRaw(queryingRole, targetRole);
|
|
12857
12936
|
const effectiveIncludeRaw = _include_raw && hasRawAccess;
|
|
12858
|
-
const
|
|
12937
|
+
const requestedMode = retrieval_mode ?? "all";
|
|
12938
|
+
const safeMode = !effectiveIncludeRaw && ["all", "operational"].includes(requestedMode) ? "no_raw" : requestedMode;
|
|
12939
|
+
const searchOptions = applyRetrievalMode({
|
|
12859
12940
|
projectName: project_name,
|
|
12860
12941
|
limit,
|
|
12861
12942
|
since,
|
|
12862
12943
|
includeArchived: include_archived,
|
|
12863
12944
|
includeDrafts: false,
|
|
12864
|
-
includeRaw: effectiveIncludeRaw
|
|
12865
|
-
|
|
12866
|
-
|
|
12867
|
-
|
|
12945
|
+
includeRaw: effectiveIncludeRaw
|
|
12946
|
+
}, safeMode);
|
|
12947
|
+
if (!effectiveIncludeRaw) searchOptions.includeRaw = false;
|
|
12948
|
+
const results = await hybridSearch(query, team_member, searchOptions);
|
|
12868
12949
|
if (results.length === 0) {
|
|
12869
12950
|
return {
|
|
12870
12951
|
content: [
|
|
@@ -15695,7 +15776,7 @@ created_by: system
|
|
|
15695
15776
|
---
|
|
15696
15777
|
## Identity
|
|
15697
15778
|
|
|
15698
|
-
You are {{agent_name}}, the
|
|
15779
|
+
You are {{agent_name}}, the {{title}} at {{company_name}}.
|
|
15699
15780
|
|
|
15700
15781
|
You are {{founder_name}}'s most reliable teammate in business \u2014 the knowledgeable older sibling who has been through it all. You have seen projects succeed and fail. You know what matters and what is noise. You do not get anxious about problems; you see them coming, stay calm, and handle them.
|
|
15701
15782
|
|
|
@@ -15782,11 +15863,13 @@ All memory, tasks, behaviors, documents, and wiki content belonging to {{company
|
|
|
15782
15863
|
var CLIENT_COO_PLACEHOLDERS = [
|
|
15783
15864
|
"agent_name",
|
|
15784
15865
|
"company_name",
|
|
15785
|
-
"founder_name"
|
|
15866
|
+
"founder_name",
|
|
15867
|
+
"title"
|
|
15786
15868
|
];
|
|
15787
15869
|
function renderClientCOOTemplate(vars) {
|
|
15870
|
+
const resolved = { ...vars, title: vars.title || "Chief Operating Officer" };
|
|
15788
15871
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
15789
|
-
const value =
|
|
15872
|
+
const value = resolved[key];
|
|
15790
15873
|
if (typeof value !== "string" || value.length === 0) {
|
|
15791
15874
|
throw new Error(
|
|
15792
15875
|
`renderClientCOOTemplate: missing required variable "${key}"`
|
|
@@ -15795,7 +15878,7 @@ function renderClientCOOTemplate(vars) {
|
|
|
15795
15878
|
}
|
|
15796
15879
|
let out = CLIENT_COO_TEMPLATE;
|
|
15797
15880
|
for (const key of CLIENT_COO_PLACEHOLDERS) {
|
|
15798
|
-
out = out.split(`{{${key}}}`).join(
|
|
15881
|
+
out = out.split(`{{${key}}}`).join(resolved[key]);
|
|
15799
15882
|
}
|
|
15800
15883
|
if (vars.industry_context) {
|
|
15801
15884
|
out += "\n" + vars.industry_context;
|
|
@@ -15961,6 +16044,7 @@ ${vars}`);
|
|
|
15961
16044
|
agent_name,
|
|
15962
16045
|
company_name,
|
|
15963
16046
|
founder_name,
|
|
16047
|
+
title: "Chief Operating Officer",
|
|
15964
16048
|
industry_context: pack.identityContext ?? void 0
|
|
15965
16049
|
});
|
|
15966
16050
|
cooSummaryLines = [
|
package/dist/runtime/index.js
CHANGED
|
@@ -6788,6 +6788,9 @@ function classifyMemoryType(input) {
|
|
|
6788
6788
|
if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
|
|
6789
6789
|
if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
|
|
6790
6790
|
if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
|
|
6791
|
+
if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
|
|
6792
|
+
if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
|
|
6793
|
+
if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
|
|
6791
6794
|
if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
|
|
6792
6795
|
if (tool === "store_memory" || tool === "manual") return "observation";
|
|
6793
6796
|
return "raw";
|
|
@@ -6930,6 +6933,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
6930
6933
|
}
|
|
6931
6934
|
}
|
|
6932
6935
|
function schedulePostWriteMemoryHygiene(memoryIds) {
|
|
6936
|
+
if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
|
|
6933
6937
|
if (memoryIds.length === 0) return;
|
|
6934
6938
|
const run = () => {
|
|
6935
6939
|
void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
|
|
@@ -7324,7 +7328,7 @@ var init_platform_procedures = __esm({
|
|
|
7324
7328
|
title: "Chain of command \u2014 who talks to whom",
|
|
7325
7329
|
domain: "workflow",
|
|
7326
7330
|
priority: "p0",
|
|
7327
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
7331
|
+
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."
|
|
7328
7332
|
},
|
|
7329
7333
|
{
|
|
7330
7334
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -7996,7 +8000,11 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
7996
8000
|
sql += ` AND timestamp >= ?`;
|
|
7997
8001
|
args.push(options.since);
|
|
7998
8002
|
}
|
|
7999
|
-
if (options?.
|
|
8003
|
+
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
8004
|
+
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
8005
|
+
sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
|
|
8006
|
+
args.push(...uniqueTypes);
|
|
8007
|
+
} else if (options?.memoryType) {
|
|
8000
8008
|
sql += ` AND memory_type = ?`;
|
|
8001
8009
|
args.push(options.memoryType);
|
|
8002
8010
|
}
|
|
@@ -10228,20 +10236,28 @@ function createExeOSHooks(config) {
|
|
|
10228
10236
|
async onSessionEnd(_context, summary) {
|
|
10229
10237
|
try {
|
|
10230
10238
|
const { writeMemory: writeMemory2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10239
|
+
await writeMemory2({
|
|
10240
|
+
id: randomUUID5(),
|
|
10241
|
+
agent_id: config.agentId,
|
|
10242
|
+
agent_role: "employee",
|
|
10243
|
+
session_id: `api-${config.agentId}`,
|
|
10244
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10245
|
+
tool_name: "SessionEnd",
|
|
10246
|
+
project_name: config.projectName,
|
|
10247
|
+
has_error: false,
|
|
10248
|
+
raw_text: [
|
|
10249
|
+
"CONTEXT CHECKPOINT [auto:session-end]",
|
|
10250
|
+
`Agent: ${config.agentId}`,
|
|
10251
|
+
`Project: ${config.projectName}`,
|
|
10252
|
+
`Time: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
10253
|
+
"",
|
|
10254
|
+
"## Runtime Summary",
|
|
10255
|
+
summary || "Session ended. No runtime summary was provided."
|
|
10256
|
+
].join("\n"),
|
|
10257
|
+
vector: null,
|
|
10258
|
+
importance: 8,
|
|
10259
|
+
memory_type: "checkpoint"
|
|
10260
|
+
});
|
|
10245
10261
|
} catch (err) {
|
|
10246
10262
|
process.stderr.write(
|
|
10247
10263
|
`[exe-hooks] session summary store failed: ${err instanceof Error ? err.message : String(err)}
|
package/dist/tui/App.js
CHANGED
|
@@ -8520,7 +8520,7 @@ var init_platform_procedures = __esm({
|
|
|
8520
8520
|
title: "Chain of command \u2014 who talks to whom",
|
|
8521
8521
|
domain: "workflow",
|
|
8522
8522
|
priority: "p0",
|
|
8523
|
-
content: "Founder -> COO -> CTO/CMO. CTO -> engineers. CMO -> content production. Never skip levels: the
|
|
8523
|
+
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."
|
|
8524
8524
|
},
|
|
8525
8525
|
{
|
|
8526
8526
|
title: "Single dispatch path \u2014 create_task only",
|
|
@@ -11097,6 +11097,9 @@ function classifyMemoryType(input) {
|
|
|
11097
11097
|
if (tool.includes("commit") || text.includes("adr-") || text.includes("architectural decision")) return "adr";
|
|
11098
11098
|
if (tool.includes("store_behavior") || tool.includes("behavior")) return "behavior";
|
|
11099
11099
|
if (tool.includes("global_procedure") || text.includes("organization-wide procedures")) return "procedure";
|
|
11100
|
+
if (tool.includes("checkpoint") || text.startsWith("context checkpoint")) return "checkpoint";
|
|
11101
|
+
if (tool.includes("sessionsummary") || tool.includes("session-summary")) return "summary";
|
|
11102
|
+
if (tool.includes("sessionend") || text.startsWith("session ended")) return "summary";
|
|
11100
11103
|
if (tool.includes("send_whatsapp") || tool.includes("conversation")) return "conversation";
|
|
11101
11104
|
if (tool === "store_memory" || tool === "manual") return "observation";
|
|
11102
11105
|
return "raw";
|
|
@@ -11239,6 +11242,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
11239
11242
|
}
|
|
11240
11243
|
}
|
|
11241
11244
|
function schedulePostWriteMemoryHygiene(memoryIds) {
|
|
11245
|
+
if (process.env.EXE_SKIP_MEMORY_HYGIENE === "1") return;
|
|
11242
11246
|
if (memoryIds.length === 0) return;
|
|
11243
11247
|
const run = () => {
|
|
11244
11248
|
void Promise.all(memoryIds.map((id) => runPostWriteMemoryHygiene(id)));
|
|
@@ -12056,7 +12060,11 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
12056
12060
|
sql += ` AND timestamp >= ?`;
|
|
12057
12061
|
args.push(options.since);
|
|
12058
12062
|
}
|
|
12059
|
-
if (options?.
|
|
12063
|
+
if (options?.memoryTypes && options.memoryTypes.length > 0) {
|
|
12064
|
+
const uniqueTypes = [...new Set(options.memoryTypes)];
|
|
12065
|
+
sql += ` AND memory_type IN (${uniqueTypes.map(() => "?").join(",")})`;
|
|
12066
|
+
args.push(...uniqueTypes);
|
|
12067
|
+
} else if (options?.memoryType) {
|
|
12060
12068
|
sql += ` AND memory_type = ?`;
|
|
12061
12069
|
args.push(options.memoryType);
|
|
12062
12070
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.37",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# /exe-save
|
|
2
|
+
|
|
3
|
+
Manual escape hatch for saving a context checkpoint.
|
|
4
|
+
|
|
5
|
+
Normally you do **not** need this. Exe OS automatically creates structured
|
|
6
|
+
`CONTEXT CHECKPOINT` memories in the background during meaningful work, before
|
|
7
|
+
compaction/context pressure, and at session end. Use `/exe-save` only when the
|
|
8
|
+
founder explicitly says "save everything" or you want an immediate extra
|
|
9
|
+
checkpoint before risky manual work.
|
|
10
|
+
|
|
11
|
+
## What to save
|
|
12
|
+
|
|
13
|
+
Store a structured memory checkpoint with ALL of the following:
|
|
14
|
+
|
|
15
|
+
1. **What you accomplished** — list every completed task, fix, or deliverable
|
|
16
|
+
2. **Decisions made** — architectural choices, trade-offs, priorities decided
|
|
17
|
+
3. **Open items** — anything unfinished, blocked, or deferred
|
|
18
|
+
4. **Key file paths** — files you created, modified, or need to revisit
|
|
19
|
+
5. **Risks or concerns** — anything that might break or needs follow-up
|
|
20
|
+
|
|
21
|
+
## How to save
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Use store_memory MCP tool with a structured checkpoint
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Call `store_memory` with this format:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
CONTEXT CHECKPOINT [session-date]:
|
|
31
|
+
## Completed
|
|
32
|
+
- [list what was done]
|
|
33
|
+
|
|
34
|
+
## Decisions
|
|
35
|
+
- [list decisions and why]
|
|
36
|
+
|
|
37
|
+
## Open Items
|
|
38
|
+
- [list what's unfinished]
|
|
39
|
+
|
|
40
|
+
## Key Files
|
|
41
|
+
- [list important file paths]
|
|
42
|
+
|
|
43
|
+
## Risks
|
|
44
|
+
- [list concerns]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Then call `store_memory` again for each major decision as a separate `decision` type memory — these survive consolidation and are always retrievable via `recall_my_memory(query, retrieval_mode="decisions_only")`.
|
|
48
|
+
|
|
49
|
+
## When to use
|
|
50
|
+
|
|
51
|
+
- When the founder explicitly asks to save everything
|
|
52
|
+
- Before risky/manual infrastructure work where an extra checkpoint is useful
|