@askexenow/exe-os 0.9.32 → 0.9.33
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/exe-doctor.js +24 -14
- package/dist/bin/exe-start-codex.js +8 -5
- package/dist/mcp/server.js +24 -14
- package/package.json +1 -1
package/dist/bin/exe-doctor.js
CHANGED
|
@@ -4028,9 +4028,9 @@ async function auditDuplicates(client, flags) {
|
|
|
4028
4028
|
const { clause, args } = agentFilter(flags);
|
|
4029
4029
|
const backfillExclude = clause ? " AND tool_name != 'ConversationBackfill'" : " WHERE tool_name != 'ConversationBackfill'";
|
|
4030
4030
|
const groups = await client.execute({
|
|
4031
|
-
sql: `SELECT raw_text, COUNT(*) as cnt
|
|
4031
|
+
sql: `SELECT SUBSTR(raw_text, 1, 200) as text_head, LENGTH(raw_text) as text_len, COUNT(*) as cnt
|
|
4032
4032
|
FROM memories${clause}${backfillExclude}
|
|
4033
|
-
GROUP BY
|
|
4033
|
+
GROUP BY text_head, text_len
|
|
4034
4034
|
HAVING cnt > 1
|
|
4035
4035
|
ORDER BY cnt DESC
|
|
4036
4036
|
LIMIT 500`,
|
|
@@ -4038,23 +4038,33 @@ async function auditDuplicates(client, flags) {
|
|
|
4038
4038
|
});
|
|
4039
4039
|
const duplicates = [];
|
|
4040
4040
|
for (const g of groups.rows) {
|
|
4041
|
-
const
|
|
4042
|
-
const
|
|
4043
|
-
const filterArgs = [
|
|
4044
|
-
let filterClause = " WHERE raw_text = ?";
|
|
4041
|
+
const textHead = g.text_head;
|
|
4042
|
+
const textLen = Number(g.text_len);
|
|
4043
|
+
const filterArgs = [textHead, textLen, ...args];
|
|
4044
|
+
let filterClause = " WHERE SUBSTR(raw_text, 1, 200) = ? AND LENGTH(raw_text) = ?";
|
|
4045
4045
|
if (flags.agent) filterClause += " AND agent_id = ?";
|
|
4046
4046
|
if (flags.project) filterClause += " AND project_name = ?";
|
|
4047
4047
|
const ids = await client.execute({
|
|
4048
|
-
sql: `SELECT id FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
|
|
4048
|
+
sql: `SELECT id, raw_text FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
|
|
4049
4049
|
args: filterArgs
|
|
4050
4050
|
});
|
|
4051
|
-
const
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4051
|
+
const byText = /* @__PURE__ */ new Map();
|
|
4052
|
+
for (const r of ids.rows) {
|
|
4053
|
+
const text = r.raw_text;
|
|
4054
|
+
const id = r.id;
|
|
4055
|
+
const existing = byText.get(text);
|
|
4056
|
+
if (existing) existing.push(id);
|
|
4057
|
+
else byText.set(text, [id]);
|
|
4058
|
+
}
|
|
4059
|
+
for (const [text, allIds] of byText) {
|
|
4060
|
+
if (allIds.length <= 1) continue;
|
|
4061
|
+
duplicates.push({
|
|
4062
|
+
raw_text: text.length > 100 ? text.slice(0, 100) + "..." : text,
|
|
4063
|
+
count: allIds.length,
|
|
4064
|
+
keep_id: allIds[0],
|
|
4065
|
+
delete_ids: allIds.slice(1)
|
|
4066
|
+
});
|
|
4067
|
+
}
|
|
4058
4068
|
}
|
|
4059
4069
|
return duplicates;
|
|
4060
4070
|
}
|
|
@@ -4559,16 +4559,19 @@ MCP tools are available under the exe-os server. Call them directly by name:
|
|
|
4559
4559
|
- get_task \u2014 read full task context
|
|
4560
4560
|
- update_task \u2014 mark tasks in_progress or done
|
|
4561
4561
|
- store_memory \u2014 persist findings for future sessions
|
|
4562
|
-
- recall_my_memory \u2014 search your past work
|
|
4562
|
+
- recall_my_memory \u2014 search your past work (IMPORTANT: call this before starting any task)
|
|
4563
4563
|
- ask_team_memory \u2014 query a colleague's knowledge
|
|
4564
4564
|
|
|
4565
|
+
CRITICAL \u2014 Memory retrieval is NOT automatic in this runtime.
|
|
4566
|
+
You MUST call recall_my_memory proactively:
|
|
4567
|
+
- Before starting any task: recall relevant past work, decisions, and patterns
|
|
4568
|
+
- When encountering an error: recall past solutions
|
|
4569
|
+
- When making architectural decisions: recall past ADRs and constraints
|
|
4570
|
+
Do NOT assume you remember \u2014 always check memory first.
|
|
4571
|
+
|
|
4565
4572
|
On startup: call list_tasks to check for assigned work.
|
|
4566
4573
|
When done with a task: call update_task with status "done" and a result summary.
|
|
4567
4574
|
Always call store_memory to persist important decisions.
|
|
4568
|
-
|
|
4569
|
-
\u26A0 FIRST RUN: If hooks haven't been approved yet, run /hooks in Codex and approve
|
|
4570
|
-
all exe-os hooks before starting work. Without approved hooks, memory capture
|
|
4571
|
-
and session tracking won't function.
|
|
4572
4575
|
`;
|
|
4573
4576
|
function resolveAgent(argv) {
|
|
4574
4577
|
const invokedAs = path15.basename(argv[1] ?? "");
|
package/dist/mcp/server.js
CHANGED
|
@@ -20074,9 +20074,9 @@ async function auditDuplicates(client, flags) {
|
|
|
20074
20074
|
const { clause, args } = agentFilter(flags);
|
|
20075
20075
|
const backfillExclude = clause ? " AND tool_name != 'ConversationBackfill'" : " WHERE tool_name != 'ConversationBackfill'";
|
|
20076
20076
|
const groups = await client.execute({
|
|
20077
|
-
sql: `SELECT raw_text, COUNT(*) as cnt
|
|
20077
|
+
sql: `SELECT SUBSTR(raw_text, 1, 200) as text_head, LENGTH(raw_text) as text_len, COUNT(*) as cnt
|
|
20078
20078
|
FROM memories${clause}${backfillExclude}
|
|
20079
|
-
GROUP BY
|
|
20079
|
+
GROUP BY text_head, text_len
|
|
20080
20080
|
HAVING cnt > 1
|
|
20081
20081
|
ORDER BY cnt DESC
|
|
20082
20082
|
LIMIT 500`,
|
|
@@ -20084,23 +20084,33 @@ async function auditDuplicates(client, flags) {
|
|
|
20084
20084
|
});
|
|
20085
20085
|
const duplicates = [];
|
|
20086
20086
|
for (const g of groups.rows) {
|
|
20087
|
-
const
|
|
20088
|
-
const
|
|
20089
|
-
const filterArgs = [
|
|
20090
|
-
let filterClause = " WHERE raw_text = ?";
|
|
20087
|
+
const textHead = g.text_head;
|
|
20088
|
+
const textLen = Number(g.text_len);
|
|
20089
|
+
const filterArgs = [textHead, textLen, ...args];
|
|
20090
|
+
let filterClause = " WHERE SUBSTR(raw_text, 1, 200) = ? AND LENGTH(raw_text) = ?";
|
|
20091
20091
|
if (flags.agent) filterClause += " AND agent_id = ?";
|
|
20092
20092
|
if (flags.project) filterClause += " AND project_name = ?";
|
|
20093
20093
|
const ids = await client.execute({
|
|
20094
|
-
sql: `SELECT id FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
|
|
20094
|
+
sql: `SELECT id, raw_text FROM memories${filterClause} ORDER BY timestamp DESC LIMIT 10000`,
|
|
20095
20095
|
args: filterArgs
|
|
20096
20096
|
});
|
|
20097
|
-
const
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20097
|
+
const byText = /* @__PURE__ */ new Map();
|
|
20098
|
+
for (const r of ids.rows) {
|
|
20099
|
+
const text = r.raw_text;
|
|
20100
|
+
const id = r.id;
|
|
20101
|
+
const existing = byText.get(text);
|
|
20102
|
+
if (existing) existing.push(id);
|
|
20103
|
+
else byText.set(text, [id]);
|
|
20104
|
+
}
|
|
20105
|
+
for (const [text, allIds] of byText) {
|
|
20106
|
+
if (allIds.length <= 1) continue;
|
|
20107
|
+
duplicates.push({
|
|
20108
|
+
raw_text: text.length > 100 ? text.slice(0, 100) + "..." : text,
|
|
20109
|
+
count: allIds.length,
|
|
20110
|
+
keep_id: allIds[0],
|
|
20111
|
+
delete_ids: allIds.slice(1)
|
|
20112
|
+
});
|
|
20113
|
+
}
|
|
20104
20114
|
}
|
|
20105
20115
|
return duplicates;
|
|
20106
20116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.33",
|
|
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",
|