@askexenow/exe-os 0.9.61 → 0.9.63
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/deploy/stack-manifests/v0.9.json +62 -13
- package/dist/bin/backfill-conversations.js +210 -2
- package/dist/bin/backfill-responses.js +210 -2
- package/dist/bin/backfill-vectors.js +47 -2
- package/dist/bin/cleanup-stale-review-tasks.js +210 -2
- package/dist/bin/cli.js +488 -25
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +2 -2
- package/dist/bin/exe-assign.js +210 -2
- package/dist/bin/exe-boot.js +47 -2
- package/dist/bin/exe-call.js +2 -2
- package/dist/bin/exe-cloud.js +2 -2
- package/dist/bin/exe-dispatch.js +210 -2
- package/dist/bin/exe-doctor.js +2691 -1212
- package/dist/bin/exe-export-behaviors.js +210 -2
- package/dist/bin/exe-forget.js +264 -2
- package/dist/bin/exe-gateway.js +210 -2
- package/dist/bin/exe-heartbeat.js +212 -4
- package/dist/bin/exe-kill.js +210 -2
- package/dist/bin/exe-launch-agent.js +210 -2
- package/dist/bin/exe-link.js +47 -2
- package/dist/bin/exe-new-employee.js +113 -3
- package/dist/bin/exe-pending-messages.js +210 -2
- package/dist/bin/exe-pending-notifications.js +210 -2
- package/dist/bin/exe-pending-reviews.js +210 -2
- package/dist/bin/exe-rename.js +210 -2
- package/dist/bin/exe-review.js +210 -2
- package/dist/bin/exe-search.js +234 -3
- package/dist/bin/exe-session-cleanup.js +210 -2
- package/dist/bin/exe-settings.js +2 -2
- package/dist/bin/exe-start-codex.js +322 -4
- package/dist/bin/exe-start-opencode.js +336 -4
- package/dist/bin/exe-status.js +210 -2
- package/dist/bin/exe-team.js +210 -2
- package/dist/bin/git-sweep.js +210 -2
- package/dist/bin/graph-backfill.js +210 -2
- package/dist/bin/graph-export.js +210 -2
- package/dist/bin/install.js +113 -3
- package/dist/bin/intercom-check.js +210 -2
- package/dist/bin/scan-tasks.js +210 -2
- package/dist/bin/setup.js +47 -2
- package/dist/bin/shard-migrate.js +210 -2
- package/dist/bin/stack-update.js +158 -13
- package/dist/bin/update.js +2 -2
- package/dist/gateway/index.js +210 -2
- package/dist/hooks/bug-report-worker.js +321 -44
- package/dist/hooks/codex-stop-task-finalizer.js +210 -2
- package/dist/hooks/commit-complete.js +210 -2
- package/dist/hooks/error-recall.js +234 -3
- package/dist/hooks/exe-heartbeat-hook.js +2 -2
- package/dist/hooks/ingest-worker.js +2 -2
- package/dist/hooks/ingest.js +210 -2
- package/dist/hooks/instructions-loaded.js +210 -2
- package/dist/hooks/notification.js +210 -2
- package/dist/hooks/post-compact.js +210 -2
- package/dist/hooks/post-tool-combined.js +234 -3
- package/dist/hooks/pre-compact.js +446 -111
- package/dist/hooks/pre-tool-use.js +210 -2
- package/dist/hooks/prompt-submit.js +234 -3
- package/dist/hooks/session-end.js +347 -124
- package/dist/hooks/session-start.js +236 -5
- package/dist/hooks/stop.js +210 -2
- package/dist/hooks/subagent-stop.js +210 -2
- package/dist/hooks/summary-worker.js +171 -74
- package/dist/index.js +210 -2
- package/dist/lib/agent-config.js +2 -2
- package/dist/lib/cloud-sync.js +47 -2
- package/dist/lib/config.js +2 -2
- package/dist/lib/consolidation.js +2 -2
- package/dist/lib/database.js +47 -2
- package/dist/lib/db-daemon-client.js +2 -2
- package/dist/lib/db.js +47 -2
- package/dist/lib/device-registry.js +47 -2
- package/dist/lib/embedder.js +2 -2
- package/dist/lib/employee-templates.js +2 -2
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +2 -2
- package/dist/lib/exe-daemon.js +592 -10
- package/dist/lib/hybrid-search.js +234 -3
- package/dist/lib/identity.js +2 -2
- package/dist/lib/license.js +2 -2
- package/dist/lib/messaging.js +2 -2
- package/dist/lib/reminders.js +2 -2
- package/dist/lib/schedules.js +47 -2
- package/dist/lib/skill-learning.js +2 -2
- package/dist/lib/store.js +210 -2
- package/dist/lib/task-router.js +2 -2
- package/dist/lib/tasks.js +2 -2
- package/dist/lib/tmux-routing.js +2 -2
- package/dist/lib/token-spend.js +2 -2
- package/dist/mcp/server.js +608 -10
- package/dist/mcp/tools/complete-reminder.js +2 -2
- package/dist/mcp/tools/create-reminder.js +2 -2
- package/dist/mcp/tools/create-task.js +2 -2
- package/dist/mcp/tools/deactivate-behavior.js +2 -2
- package/dist/mcp/tools/list-reminders.js +2 -2
- package/dist/mcp/tools/list-tasks.js +2 -2
- package/dist/mcp/tools/send-message.js +2 -2
- package/dist/mcp/tools/update-task.js +2 -2
- package/dist/runtime/index.js +210 -2
- package/dist/tui/App.js +210 -2
- package/package.json +3 -2
- package/stack.release.json +23 -7
package/dist/mcp/server.js
CHANGED
|
@@ -266,8 +266,8 @@ var init_config = __esm({
|
|
|
266
266
|
rerankerAutoTrigger: {
|
|
267
267
|
enabled: true,
|
|
268
268
|
broadQueryMinCardinality: 5e4,
|
|
269
|
-
fetchTopK:
|
|
270
|
-
returnTopK:
|
|
269
|
+
fetchTopK: 200,
|
|
270
|
+
returnTopK: 20
|
|
271
271
|
}
|
|
272
272
|
},
|
|
273
273
|
graphRagEnabled: true,
|
|
@@ -1893,6 +1893,15 @@ var init_database_adapter = __esm({
|
|
|
1893
1893
|
});
|
|
1894
1894
|
|
|
1895
1895
|
// src/lib/daemon-protocol.ts
|
|
1896
|
+
var daemon_protocol_exports = {};
|
|
1897
|
+
__export(daemon_protocol_exports, {
|
|
1898
|
+
deserializeArgs: () => deserializeArgs,
|
|
1899
|
+
deserializeResultSet: () => deserializeResultSet,
|
|
1900
|
+
deserializeValue: () => deserializeValue,
|
|
1901
|
+
serializeArgs: () => serializeArgs,
|
|
1902
|
+
serializeResultSet: () => serializeResultSet,
|
|
1903
|
+
serializeValue: () => serializeValue
|
|
1904
|
+
});
|
|
1896
1905
|
function serializeValue(v) {
|
|
1897
1906
|
if (v === null || v === void 0) return null;
|
|
1898
1907
|
if (typeof v === "bigint") return Number(v);
|
|
@@ -1917,6 +1926,32 @@ function deserializeValue(v) {
|
|
|
1917
1926
|
}
|
|
1918
1927
|
return v;
|
|
1919
1928
|
}
|
|
1929
|
+
function serializeArgs(args) {
|
|
1930
|
+
return args.map(serializeValue);
|
|
1931
|
+
}
|
|
1932
|
+
function deserializeArgs(args) {
|
|
1933
|
+
return args.map(deserializeValue);
|
|
1934
|
+
}
|
|
1935
|
+
function serializeResultSet(rs) {
|
|
1936
|
+
const rows = [];
|
|
1937
|
+
for (const row of rs.rows) {
|
|
1938
|
+
const obj = {};
|
|
1939
|
+
for (let i = 0; i < rs.columns.length; i++) {
|
|
1940
|
+
const col = rs.columns[i];
|
|
1941
|
+
if (col !== void 0) {
|
|
1942
|
+
obj[col] = serializeValue(row[i]);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
rows.push(obj);
|
|
1946
|
+
}
|
|
1947
|
+
return {
|
|
1948
|
+
columns: [...rs.columns],
|
|
1949
|
+
columnTypes: [...rs.columnTypes ?? []],
|
|
1950
|
+
rows,
|
|
1951
|
+
rowsAffected: typeof rs.rowsAffected === "bigint" ? Number(rs.rowsAffected) : rs.rowsAffected ?? 0,
|
|
1952
|
+
lastInsertRowid: rs.lastInsertRowid != null ? typeof rs.lastInsertRowid === "bigint" ? Number(rs.lastInsertRowid) : rs.lastInsertRowid : null
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1920
1955
|
function deserializeResultSet(srs) {
|
|
1921
1956
|
const rows = srs.rows.map((obj) => {
|
|
1922
1957
|
const values = srs.columns.map(
|
|
@@ -3154,6 +3189,51 @@ async function ensureSchema() {
|
|
|
3154
3189
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
3155
3190
|
END;
|
|
3156
3191
|
`);
|
|
3192
|
+
await client.executeMultiple(`
|
|
3193
|
+
CREATE TABLE IF NOT EXISTS memory_cards (
|
|
3194
|
+
id TEXT PRIMARY KEY,
|
|
3195
|
+
memory_id TEXT NOT NULL,
|
|
3196
|
+
agent_id TEXT NOT NULL,
|
|
3197
|
+
session_id TEXT NOT NULL,
|
|
3198
|
+
project_name TEXT,
|
|
3199
|
+
timestamp TEXT NOT NULL,
|
|
3200
|
+
card_type TEXT NOT NULL,
|
|
3201
|
+
subject TEXT,
|
|
3202
|
+
predicate TEXT,
|
|
3203
|
+
object TEXT,
|
|
3204
|
+
content TEXT NOT NULL,
|
|
3205
|
+
source_ref TEXT,
|
|
3206
|
+
confidence REAL DEFAULT 0.6,
|
|
3207
|
+
active INTEGER DEFAULT 1,
|
|
3208
|
+
created_at TEXT NOT NULL
|
|
3209
|
+
);
|
|
3210
|
+
|
|
3211
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
|
|
3212
|
+
ON memory_cards(agent_id, active, timestamp);
|
|
3213
|
+
|
|
3214
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
|
|
3215
|
+
ON memory_cards(memory_id);
|
|
3216
|
+
|
|
3217
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
|
|
3218
|
+
USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
|
|
3219
|
+
|
|
3220
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
|
|
3221
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
3222
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
3223
|
+
END;
|
|
3224
|
+
|
|
3225
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
|
|
3226
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
3227
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
3228
|
+
END;
|
|
3229
|
+
|
|
3230
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
|
|
3231
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
3232
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
3233
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
3234
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
3235
|
+
END;
|
|
3236
|
+
`);
|
|
3157
3237
|
try {
|
|
3158
3238
|
await client.execute({
|
|
3159
3239
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
@@ -4541,6 +4621,164 @@ ${p.content}`).join("\n\n");
|
|
|
4541
4621
|
}
|
|
4542
4622
|
});
|
|
4543
4623
|
|
|
4624
|
+
// src/lib/memory-cards.ts
|
|
4625
|
+
var memory_cards_exports = {};
|
|
4626
|
+
__export(memory_cards_exports, {
|
|
4627
|
+
extractMemoryCards: () => extractMemoryCards,
|
|
4628
|
+
insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
|
|
4629
|
+
searchMemoryCards: () => searchMemoryCards
|
|
4630
|
+
});
|
|
4631
|
+
import { createHash as createHash2 } from "crypto";
|
|
4632
|
+
function stableId(memoryId, type, content) {
|
|
4633
|
+
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4634
|
+
}
|
|
4635
|
+
function cleanText(text3) {
|
|
4636
|
+
return text3.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
4637
|
+
}
|
|
4638
|
+
function splitSentences(text3) {
|
|
4639
|
+
return cleanText(text3).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
|
|
4640
|
+
}
|
|
4641
|
+
function inferCardType(sentence, toolName) {
|
|
4642
|
+
const lower = sentence.toLowerCase();
|
|
4643
|
+
if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
|
|
4644
|
+
if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
|
|
4645
|
+
if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
|
|
4646
|
+
if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
|
|
4647
|
+
if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
|
|
4648
|
+
return "fact";
|
|
4649
|
+
}
|
|
4650
|
+
function extractSubject(sentence, agentId) {
|
|
4651
|
+
const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
|
|
4652
|
+
return explicit?.[1] ?? agentId;
|
|
4653
|
+
}
|
|
4654
|
+
function predicateFor(type) {
|
|
4655
|
+
switch (type) {
|
|
4656
|
+
case "preference":
|
|
4657
|
+
return "prefers";
|
|
4658
|
+
case "belief_update":
|
|
4659
|
+
return "updated";
|
|
4660
|
+
case "decision":
|
|
4661
|
+
return "decided";
|
|
4662
|
+
case "event":
|
|
4663
|
+
return "happened";
|
|
4664
|
+
case "code":
|
|
4665
|
+
return "implemented";
|
|
4666
|
+
default:
|
|
4667
|
+
return "states";
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
function extractMemoryCards(row) {
|
|
4671
|
+
const sentences = splitSentences(row.raw_text);
|
|
4672
|
+
const cards = [];
|
|
4673
|
+
for (const sentence of sentences) {
|
|
4674
|
+
const type = inferCardType(sentence, row.tool_name);
|
|
4675
|
+
const subject = extractSubject(sentence, row.agent_id);
|
|
4676
|
+
const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
|
|
4677
|
+
cards.push({
|
|
4678
|
+
id: stableId(row.id, type, content),
|
|
4679
|
+
memory_id: row.id,
|
|
4680
|
+
agent_id: row.agent_id,
|
|
4681
|
+
session_id: row.session_id,
|
|
4682
|
+
project_name: row.project_name ?? null,
|
|
4683
|
+
timestamp: row.timestamp,
|
|
4684
|
+
card_type: type,
|
|
4685
|
+
subject,
|
|
4686
|
+
predicate: predicateFor(type),
|
|
4687
|
+
object: content,
|
|
4688
|
+
content,
|
|
4689
|
+
source_ref: row.id,
|
|
4690
|
+
confidence: type === "fact" ? 0.55 : 0.65
|
|
4691
|
+
});
|
|
4692
|
+
if (cards.length >= MAX_CARDS_PER_MEMORY) break;
|
|
4693
|
+
}
|
|
4694
|
+
return cards;
|
|
4695
|
+
}
|
|
4696
|
+
async function insertMemoryCardsForBatch(rows) {
|
|
4697
|
+
const cards = rows.flatMap(extractMemoryCards);
|
|
4698
|
+
if (cards.length === 0) return 0;
|
|
4699
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4700
|
+
const client = getClient();
|
|
4701
|
+
const stmts = cards.map((card) => ({
|
|
4702
|
+
sql: `INSERT OR IGNORE INTO memory_cards
|
|
4703
|
+
(id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
|
|
4704
|
+
subject, predicate, object, content, source_ref, confidence, active, created_at)
|
|
4705
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
|
|
4706
|
+
args: [
|
|
4707
|
+
card.id,
|
|
4708
|
+
card.memory_id,
|
|
4709
|
+
card.agent_id,
|
|
4710
|
+
card.session_id,
|
|
4711
|
+
card.project_name,
|
|
4712
|
+
card.timestamp,
|
|
4713
|
+
card.card_type,
|
|
4714
|
+
card.subject,
|
|
4715
|
+
card.predicate,
|
|
4716
|
+
card.object,
|
|
4717
|
+
card.content,
|
|
4718
|
+
card.source_ref,
|
|
4719
|
+
card.confidence,
|
|
4720
|
+
now
|
|
4721
|
+
]
|
|
4722
|
+
}));
|
|
4723
|
+
await client.batch(stmts, "write");
|
|
4724
|
+
return cards.length;
|
|
4725
|
+
}
|
|
4726
|
+
function buildMatchExpr(queryText) {
|
|
4727
|
+
const terms = queryText.toLowerCase().split(/\s+/).filter((t) => t.length >= 3).map((t) => t.replace(/[^a-z0-9_]/g, "")).filter((t) => t.length >= 3).slice(0, 12);
|
|
4728
|
+
if (terms.length === 0) return null;
|
|
4729
|
+
return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
|
|
4730
|
+
}
|
|
4731
|
+
async function searchMemoryCards(queryText, agentId, options) {
|
|
4732
|
+
const limit = options?.limit ?? 10;
|
|
4733
|
+
const matchExpr = buildMatchExpr(queryText);
|
|
4734
|
+
if (!matchExpr) return [];
|
|
4735
|
+
let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
|
|
4736
|
+
c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
|
|
4737
|
+
FROM memory_cards c
|
|
4738
|
+
JOIN memory_cards_fts fts ON c.rowid = fts.rowid
|
|
4739
|
+
WHERE memory_cards_fts MATCH ?
|
|
4740
|
+
AND c.agent_id = ?
|
|
4741
|
+
AND COALESCE(c.active, 1) = 1`;
|
|
4742
|
+
const args = [matchExpr, agentId];
|
|
4743
|
+
if (options?.projectName) {
|
|
4744
|
+
sql += ` AND c.project_name = ?`;
|
|
4745
|
+
args.push(options.projectName);
|
|
4746
|
+
}
|
|
4747
|
+
if (options?.since) {
|
|
4748
|
+
sql += ` AND c.timestamp >= ?`;
|
|
4749
|
+
args.push(options.since);
|
|
4750
|
+
}
|
|
4751
|
+
sql += ` ORDER BY rank LIMIT ?`;
|
|
4752
|
+
args.push(limit);
|
|
4753
|
+
const result = await getClient().execute({ sql, args });
|
|
4754
|
+
return result.rows.map((row) => ({
|
|
4755
|
+
id: `card:${String(row.id)}`,
|
|
4756
|
+
agent_id: String(row.agent_id),
|
|
4757
|
+
agent_role: "memory_card",
|
|
4758
|
+
session_id: String(row.session_id),
|
|
4759
|
+
timestamp: String(row.timestamp),
|
|
4760
|
+
tool_name: `memory_card:${String(row.card_type)}`,
|
|
4761
|
+
project_name: row.project_name == null ? "" : String(row.project_name),
|
|
4762
|
+
has_error: false,
|
|
4763
|
+
raw_text: `[${String(row.card_type)}] ${String(row.content)}
|
|
4764
|
+
Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
4765
|
+
vector: [],
|
|
4766
|
+
importance: 6,
|
|
4767
|
+
status: "active",
|
|
4768
|
+
confidence: Number(row.confidence ?? 0.6),
|
|
4769
|
+
last_accessed: String(row.timestamp)
|
|
4770
|
+
}));
|
|
4771
|
+
}
|
|
4772
|
+
var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
|
|
4773
|
+
var init_memory_cards = __esm({
|
|
4774
|
+
"src/lib/memory-cards.ts"() {
|
|
4775
|
+
"use strict";
|
|
4776
|
+
init_database();
|
|
4777
|
+
MAX_CARDS_PER_MEMORY = 6;
|
|
4778
|
+
MAX_SENTENCE_CHARS = 360;
|
|
4779
|
+
}
|
|
4780
|
+
});
|
|
4781
|
+
|
|
4544
4782
|
// src/lib/store.ts
|
|
4545
4783
|
var store_exports = {};
|
|
4546
4784
|
__export(store_exports, {
|
|
@@ -4879,6 +5117,11 @@ async function flushBatch() {
|
|
|
4879
5117
|
const globalClient = getClient();
|
|
4880
5118
|
const globalStmts = batch.map(buildStmt);
|
|
4881
5119
|
await globalClient.batch(globalStmts, "write");
|
|
5120
|
+
try {
|
|
5121
|
+
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5122
|
+
await insertMemoryCardsForBatch2(batch);
|
|
5123
|
+
} catch {
|
|
5124
|
+
}
|
|
4882
5125
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
4883
5126
|
_pendingRecords.splice(0, batch.length);
|
|
4884
5127
|
try {
|
|
@@ -6319,9 +6562,18 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6319
6562
|
} catch {
|
|
6320
6563
|
}
|
|
6321
6564
|
}
|
|
6322
|
-
const
|
|
6565
|
+
const includeStructuredCards = effectiveIsBroad || effectiveOptions.includeStructuredCards === true;
|
|
6566
|
+
const [ftsResults, vectorResults, cardResults, grepResults] = await Promise.all([
|
|
6323
6567
|
lightweightSearch(effectiveQuery, agentId, fetchOptions),
|
|
6324
6568
|
queryVector ? searchMemories(queryVector, agentId, fetchOptions) : Promise.resolve([]),
|
|
6569
|
+
includeStructuredCards ? (async () => {
|
|
6570
|
+
try {
|
|
6571
|
+
const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
6572
|
+
return await searchMemoryCards2(effectiveQuery, agentId, fetchOptions);
|
|
6573
|
+
} catch {
|
|
6574
|
+
return [];
|
|
6575
|
+
}
|
|
6576
|
+
})() : Promise.resolve([]),
|
|
6325
6577
|
grepPromise
|
|
6326
6578
|
]);
|
|
6327
6579
|
const lists = [];
|
|
@@ -6334,6 +6586,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6334
6586
|
lists.push(vectorResults);
|
|
6335
6587
|
weights.push(1);
|
|
6336
6588
|
}
|
|
6589
|
+
if (cardResults.length > 0) {
|
|
6590
|
+
lists.push(cardResults);
|
|
6591
|
+
weights.push(1.2);
|
|
6592
|
+
}
|
|
6337
6593
|
if (grepResults.length > 0) {
|
|
6338
6594
|
lists.push(grepResults);
|
|
6339
6595
|
weights.push(0.5);
|
|
@@ -6402,6 +6658,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6402
6658
|
signals: {
|
|
6403
6659
|
fts: ftsResults.length,
|
|
6404
6660
|
vector: vectorResults.length,
|
|
6661
|
+
cards: cardResults.length,
|
|
6405
6662
|
grep: grepResults.length,
|
|
6406
6663
|
entityBoost: entityBoostRan,
|
|
6407
6664
|
reranker: rerankedAndBlended !== null,
|
|
@@ -6551,6 +6808,15 @@ async function lightweightSearch(queryText, agentId, options) {
|
|
|
6551
6808
|
if (options?.includeSource && results.length > 0) {
|
|
6552
6809
|
await attachDocumentMetadata(results);
|
|
6553
6810
|
}
|
|
6811
|
+
if (options?.includeStructuredCards !== true) return results;
|
|
6812
|
+
try {
|
|
6813
|
+
const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
6814
|
+
const cardResults = await searchMemoryCards2(queryText, agentId, options);
|
|
6815
|
+
if (cardResults.length > 0) {
|
|
6816
|
+
return rrfMergeMulti([results, cardResults], limit, RRF_K, [1, 1.2]);
|
|
6817
|
+
}
|
|
6818
|
+
} catch {
|
|
6819
|
+
}
|
|
6554
6820
|
return results;
|
|
6555
6821
|
}
|
|
6556
6822
|
async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
@@ -11647,7 +11913,7 @@ __export(identity_exports, {
|
|
|
11647
11913
|
import { existsSync as existsSync20, mkdirSync as mkdirSync10, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "fs";
|
|
11648
11914
|
import { readdirSync as readdirSync7 } from "fs";
|
|
11649
11915
|
import path26 from "path";
|
|
11650
|
-
import { createHash as
|
|
11916
|
+
import { createHash as createHash3 } from "crypto";
|
|
11651
11917
|
function ensureDir2() {
|
|
11652
11918
|
if (!existsSync20(IDENTITY_DIR2)) {
|
|
11653
11919
|
mkdirSync10(IDENTITY_DIR2, { recursive: true });
|
|
@@ -11694,7 +11960,7 @@ function parseFrontmatter(raw) {
|
|
|
11694
11960
|
};
|
|
11695
11961
|
}
|
|
11696
11962
|
function contentHash(content) {
|
|
11697
|
-
return
|
|
11963
|
+
return createHash3("sha256").update(content).digest("hex").slice(0, 16);
|
|
11698
11964
|
}
|
|
11699
11965
|
function getIdentity(agentId) {
|
|
11700
11966
|
const filePath = identityPath(agentId);
|
|
@@ -12622,6 +12888,78 @@ var init_worker_gate = __esm({
|
|
|
12622
12888
|
}
|
|
12623
12889
|
});
|
|
12624
12890
|
|
|
12891
|
+
// src/bin/fast-db-init.ts
|
|
12892
|
+
var fast_db_init_exports = {};
|
|
12893
|
+
__export(fast_db_init_exports, {
|
|
12894
|
+
fastDbInit: () => fastDbInit
|
|
12895
|
+
});
|
|
12896
|
+
async function fastDbInit() {
|
|
12897
|
+
const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
12898
|
+
if (isInitialized2()) {
|
|
12899
|
+
return getClient2();
|
|
12900
|
+
}
|
|
12901
|
+
try {
|
|
12902
|
+
const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
|
|
12903
|
+
const { deserializeResultSet: deserializeResultSet2 } = await Promise.resolve().then(() => (init_daemon_protocol(), daemon_protocol_exports));
|
|
12904
|
+
await connectEmbedDaemon2();
|
|
12905
|
+
if (isClientConnected2()) {
|
|
12906
|
+
const daemonClient = {
|
|
12907
|
+
async execute(stmt) {
|
|
12908
|
+
const sql = typeof stmt === "string" ? stmt : stmt.sql;
|
|
12909
|
+
const args = typeof stmt === "string" ? [] : Array.isArray(stmt.args) ? stmt.args : [];
|
|
12910
|
+
const resp = await sendDaemonRequest2({ type: "db-execute", sql, args });
|
|
12911
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
12912
|
+
if (resp.db) return deserializeResultSet2(resp.db);
|
|
12913
|
+
throw new Error("Unexpected daemon response");
|
|
12914
|
+
},
|
|
12915
|
+
async batch(stmts, mode) {
|
|
12916
|
+
const statements = stmts.map((s) => {
|
|
12917
|
+
const sql = typeof s === "string" ? s : s.sql;
|
|
12918
|
+
const args = typeof s === "string" ? [] : Array.isArray(s.args) ? s.args : [];
|
|
12919
|
+
return { sql, args };
|
|
12920
|
+
});
|
|
12921
|
+
const resp = await sendDaemonRequest2({ type: "db-batch", statements, mode: mode ?? "deferred" });
|
|
12922
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
12923
|
+
const batchResults = resp["db-batch"];
|
|
12924
|
+
if (batchResults) return batchResults.map(deserializeResultSet2);
|
|
12925
|
+
throw new Error("Unexpected daemon batch response");
|
|
12926
|
+
},
|
|
12927
|
+
async transaction(_mode) {
|
|
12928
|
+
throw new Error("Transactions not supported via daemon socket");
|
|
12929
|
+
},
|
|
12930
|
+
async executeMultiple(_sql) {
|
|
12931
|
+
throw new Error("executeMultiple not supported via daemon socket");
|
|
12932
|
+
},
|
|
12933
|
+
async migrate(_stmts) {
|
|
12934
|
+
throw new Error("migrate not supported via daemon socket");
|
|
12935
|
+
},
|
|
12936
|
+
sync() {
|
|
12937
|
+
return Promise.resolve(void 0);
|
|
12938
|
+
},
|
|
12939
|
+
close() {
|
|
12940
|
+
},
|
|
12941
|
+
get closed() {
|
|
12942
|
+
return false;
|
|
12943
|
+
},
|
|
12944
|
+
get protocol() {
|
|
12945
|
+
return "file";
|
|
12946
|
+
}
|
|
12947
|
+
};
|
|
12948
|
+
setExternalClient2(daemonClient);
|
|
12949
|
+
return daemonClient;
|
|
12950
|
+
}
|
|
12951
|
+
} catch {
|
|
12952
|
+
}
|
|
12953
|
+
const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
12954
|
+
await initStore2({ lightweight: true });
|
|
12955
|
+
return getClient2();
|
|
12956
|
+
}
|
|
12957
|
+
var init_fast_db_init = __esm({
|
|
12958
|
+
"src/bin/fast-db-init.ts"() {
|
|
12959
|
+
"use strict";
|
|
12960
|
+
}
|
|
12961
|
+
});
|
|
12962
|
+
|
|
12625
12963
|
// src/lib/db-backup.ts
|
|
12626
12964
|
var db_backup_exports = {};
|
|
12627
12965
|
__export(db_backup_exports, {
|
|
@@ -18454,8 +18792,6 @@ init_database();
|
|
|
18454
18792
|
import { z as z56 } from "zod";
|
|
18455
18793
|
|
|
18456
18794
|
// src/bin/exe-doctor.ts
|
|
18457
|
-
init_store();
|
|
18458
|
-
init_database();
|
|
18459
18795
|
import os14 from "os";
|
|
18460
18796
|
|
|
18461
18797
|
// src/lib/is-main.ts
|
|
@@ -18739,6 +19075,140 @@ async function detectConflicts(client, projectFilter, agentFilter2) {
|
|
|
18739
19075
|
};
|
|
18740
19076
|
}
|
|
18741
19077
|
|
|
19078
|
+
// src/adapters/runtime-hook-manifest.ts
|
|
19079
|
+
var EXE_HOOKS = {
|
|
19080
|
+
postToolCombined: "dist/hooks/post-tool-combined.js",
|
|
19081
|
+
sessionStart: "dist/hooks/session-start.js",
|
|
19082
|
+
promptSubmit: "dist/hooks/prompt-submit.js",
|
|
19083
|
+
heartbeat: "dist/hooks/exe-heartbeat-hook.js",
|
|
19084
|
+
stop: "dist/hooks/stop.js",
|
|
19085
|
+
preToolUse: "dist/hooks/pre-tool-use.js",
|
|
19086
|
+
subagentStop: "dist/hooks/subagent-stop.js",
|
|
19087
|
+
preCompact: "dist/hooks/pre-compact.js",
|
|
19088
|
+
postCompact: "dist/hooks/post-compact.js",
|
|
19089
|
+
sessionEnd: "dist/hooks/session-end.js",
|
|
19090
|
+
notification: "dist/hooks/notification.js",
|
|
19091
|
+
instructionsLoaded: "dist/hooks/instructions-loaded.js"
|
|
19092
|
+
};
|
|
19093
|
+
var EXE_HOOK_MANIFEST = [
|
|
19094
|
+
{
|
|
19095
|
+
key: "postToolCombined",
|
|
19096
|
+
event: "PostToolUse",
|
|
19097
|
+
commandMarker: EXE_HOOKS.postToolCombined,
|
|
19098
|
+
owner: "exe-os",
|
|
19099
|
+
purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
|
|
19100
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
19101
|
+
checkpointRole: "none"
|
|
19102
|
+
},
|
|
19103
|
+
{
|
|
19104
|
+
key: "sessionStart",
|
|
19105
|
+
event: "SessionStart",
|
|
19106
|
+
commandMarker: EXE_HOOKS.sessionStart,
|
|
19107
|
+
owner: "exe-os",
|
|
19108
|
+
purpose: "Loads agent identity, procedures, and boot context.",
|
|
19109
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
19110
|
+
checkpointRole: "none"
|
|
19111
|
+
},
|
|
19112
|
+
{
|
|
19113
|
+
key: "promptSubmit",
|
|
19114
|
+
event: "UserPromptSubmit",
|
|
19115
|
+
commandMarker: EXE_HOOKS.promptSubmit,
|
|
19116
|
+
owner: "exe-os",
|
|
19117
|
+
purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
|
|
19118
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
19119
|
+
checkpointRole: "none"
|
|
19120
|
+
},
|
|
19121
|
+
{
|
|
19122
|
+
key: "heartbeat",
|
|
19123
|
+
event: "UserPromptSubmit",
|
|
19124
|
+
commandMarker: EXE_HOOKS.heartbeat,
|
|
19125
|
+
owner: "exe-os",
|
|
19126
|
+
purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
|
|
19127
|
+
runtimes: ["claude"],
|
|
19128
|
+
checkpointRole: "none"
|
|
19129
|
+
},
|
|
19130
|
+
{
|
|
19131
|
+
key: "stop",
|
|
19132
|
+
event: "Stop",
|
|
19133
|
+
commandMarker: EXE_HOOKS.stop,
|
|
19134
|
+
owner: "exe-os",
|
|
19135
|
+
purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
|
|
19136
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
19137
|
+
checkpointRole: "capacity_checkpoint"
|
|
19138
|
+
},
|
|
19139
|
+
{
|
|
19140
|
+
key: "preToolUse",
|
|
19141
|
+
event: "PreToolUse",
|
|
19142
|
+
commandMarker: EXE_HOOKS.preToolUse,
|
|
19143
|
+
owner: "exe-os",
|
|
19144
|
+
purpose: "Preflight guardrails before shell/tool execution.",
|
|
19145
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
19146
|
+
checkpointRole: "none"
|
|
19147
|
+
},
|
|
19148
|
+
{
|
|
19149
|
+
key: "subagentStop",
|
|
19150
|
+
event: "SubagentStop",
|
|
19151
|
+
commandMarker: EXE_HOOKS.subagentStop,
|
|
19152
|
+
owner: "exe-os",
|
|
19153
|
+
purpose: "Captures subagent completion context.",
|
|
19154
|
+
runtimes: ["claude"],
|
|
19155
|
+
checkpointRole: "none"
|
|
19156
|
+
},
|
|
19157
|
+
{
|
|
19158
|
+
key: "preCompact",
|
|
19159
|
+
event: "PreCompact",
|
|
19160
|
+
commandMarker: EXE_HOOKS.preCompact,
|
|
19161
|
+
owner: "exe-os",
|
|
19162
|
+
purpose: "Writes active-task snapshot and compaction recovery context.",
|
|
19163
|
+
runtimes: ["claude"],
|
|
19164
|
+
checkpointRole: "recovery_context"
|
|
19165
|
+
},
|
|
19166
|
+
{
|
|
19167
|
+
key: "postCompact",
|
|
19168
|
+
event: "PostCompact",
|
|
19169
|
+
commandMarker: EXE_HOOKS.postCompact,
|
|
19170
|
+
owner: "exe-os",
|
|
19171
|
+
purpose: "Rehydrates recovery context after compaction.",
|
|
19172
|
+
runtimes: ["claude"],
|
|
19173
|
+
checkpointRole: "recovery_context"
|
|
19174
|
+
},
|
|
19175
|
+
{
|
|
19176
|
+
key: "sessionEnd",
|
|
19177
|
+
event: "SessionEnd",
|
|
19178
|
+
commandMarker: EXE_HOOKS.sessionEnd,
|
|
19179
|
+
owner: "exe-os",
|
|
19180
|
+
purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
|
|
19181
|
+
runtimes: ["claude"],
|
|
19182
|
+
checkpointRole: "session_summary"
|
|
19183
|
+
},
|
|
19184
|
+
{
|
|
19185
|
+
key: "notification",
|
|
19186
|
+
event: "Notification",
|
|
19187
|
+
commandMarker: EXE_HOOKS.notification,
|
|
19188
|
+
owner: "exe-os",
|
|
19189
|
+
purpose: "Captures runtime notifications and nudges.",
|
|
19190
|
+
runtimes: ["claude"],
|
|
19191
|
+
checkpointRole: "none"
|
|
19192
|
+
},
|
|
19193
|
+
{
|
|
19194
|
+
key: "instructionsLoaded",
|
|
19195
|
+
event: "InstructionsLoaded",
|
|
19196
|
+
commandMarker: EXE_HOOKS.instructionsLoaded,
|
|
19197
|
+
owner: "exe-os",
|
|
19198
|
+
purpose: "Applies runtime instruction post-processing.",
|
|
19199
|
+
runtimes: ["claude"],
|
|
19200
|
+
checkpointRole: "none"
|
|
19201
|
+
}
|
|
19202
|
+
];
|
|
19203
|
+
var LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
|
|
19204
|
+
"dist/hooks/ingest.js",
|
|
19205
|
+
"dist/hooks/error-recall.js",
|
|
19206
|
+
"dist/hooks/ingest-worker.js"
|
|
19207
|
+
];
|
|
19208
|
+
function manifestEntryForCommand(command) {
|
|
19209
|
+
return EXE_HOOK_MANIFEST.find((entry) => command.includes(entry.commandMarker));
|
|
19210
|
+
}
|
|
19211
|
+
|
|
18742
19212
|
// src/bin/exe-doctor.ts
|
|
18743
19213
|
function parseFlags(argv) {
|
|
18744
19214
|
const flags = { fix: false, dryRun: false, verbose: false, conflicts: false };
|
|
@@ -18937,6 +19407,121 @@ function auditHookHealth() {
|
|
|
18937
19407
|
const topPatterns = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([pattern, count]) => ({ pattern, count }));
|
|
18938
19408
|
return { logExists: true, totalLines, errorsLastHour, topPatterns };
|
|
18939
19409
|
}
|
|
19410
|
+
function safeReadJson(filePath) {
|
|
19411
|
+
if (!existsSync27(filePath)) return null;
|
|
19412
|
+
try {
|
|
19413
|
+
return JSON.parse(readFileSync20(filePath, "utf-8"));
|
|
19414
|
+
} catch {
|
|
19415
|
+
return null;
|
|
19416
|
+
}
|
|
19417
|
+
}
|
|
19418
|
+
function collectHookCommandsFromClaudeSettings(settings) {
|
|
19419
|
+
const hooks = settings?.hooks;
|
|
19420
|
+
if (!hooks || typeof hooks !== "object") return [];
|
|
19421
|
+
const commands = [];
|
|
19422
|
+
for (const [event, groups] of Object.entries(hooks)) {
|
|
19423
|
+
if (!Array.isArray(groups)) continue;
|
|
19424
|
+
for (const group of groups) {
|
|
19425
|
+
const hooksForGroup = group?.hooks;
|
|
19426
|
+
if (!Array.isArray(hooksForGroup)) continue;
|
|
19427
|
+
for (const hook of hooksForGroup) {
|
|
19428
|
+
const command = hook?.command;
|
|
19429
|
+
if (typeof command === "string") commands.push({ event, command });
|
|
19430
|
+
}
|
|
19431
|
+
}
|
|
19432
|
+
}
|
|
19433
|
+
return commands;
|
|
19434
|
+
}
|
|
19435
|
+
function collectHookCommandsFromCodexHooks(config2) {
|
|
19436
|
+
const commands = [];
|
|
19437
|
+
if (!config2 || typeof config2 !== "object") return commands;
|
|
19438
|
+
const root = config2;
|
|
19439
|
+
for (const [event, value] of Object.entries(root)) {
|
|
19440
|
+
const entries = Array.isArray(value) ? value : value && typeof value === "object" ? Object.values(value) : [];
|
|
19441
|
+
for (const entry of entries) {
|
|
19442
|
+
if (typeof entry === "string") commands.push({ event, command: entry });
|
|
19443
|
+
const command = entry?.command;
|
|
19444
|
+
if (typeof command === "string") commands.push({ event, command });
|
|
19445
|
+
}
|
|
19446
|
+
}
|
|
19447
|
+
return commands;
|
|
19448
|
+
}
|
|
19449
|
+
function buildHookOwnershipIssues(runtime, commands) {
|
|
19450
|
+
const issues = [];
|
|
19451
|
+
for (const marker of LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS) {
|
|
19452
|
+
const count = commands.filter((cmd) => cmd.command.includes(marker)).length;
|
|
19453
|
+
if (count > 0) {
|
|
19454
|
+
issues.push({
|
|
19455
|
+
runtime,
|
|
19456
|
+
event: "PostToolUse",
|
|
19457
|
+
marker,
|
|
19458
|
+
count,
|
|
19459
|
+
message: `Legacy split PostToolUse hook still installed: ${marker}`
|
|
19460
|
+
});
|
|
19461
|
+
}
|
|
19462
|
+
}
|
|
19463
|
+
for (const entry of EXE_HOOK_MANIFEST.filter((hook) => hook.runtimes.includes(runtime))) {
|
|
19464
|
+
const matching = commands.filter((cmd) => cmd.command.includes(entry.commandMarker));
|
|
19465
|
+
if (matching.length > 1) {
|
|
19466
|
+
issues.push({
|
|
19467
|
+
runtime,
|
|
19468
|
+
event: entry.event,
|
|
19469
|
+
marker: entry.commandMarker,
|
|
19470
|
+
count: matching.length,
|
|
19471
|
+
message: `Duplicate exe-os hook owner for ${entry.event}: ${entry.commandMarker}`
|
|
19472
|
+
});
|
|
19473
|
+
}
|
|
19474
|
+
for (const cmd of matching) {
|
|
19475
|
+
if (cmd.event !== entry.event) {
|
|
19476
|
+
issues.push({
|
|
19477
|
+
runtime,
|
|
19478
|
+
event: cmd.event,
|
|
19479
|
+
marker: entry.commandMarker,
|
|
19480
|
+
count: 1,
|
|
19481
|
+
message: `exe-os hook ${entry.commandMarker} is registered under ${cmd.event}, expected ${entry.event}`
|
|
19482
|
+
});
|
|
19483
|
+
}
|
|
19484
|
+
}
|
|
19485
|
+
}
|
|
19486
|
+
for (const cmd of commands) {
|
|
19487
|
+
if (!cmd.command.includes("dist/hooks/")) continue;
|
|
19488
|
+
if (!cmd.command.includes("exe-os")) continue;
|
|
19489
|
+
const entry = manifestEntryForCommand(cmd.command);
|
|
19490
|
+
const isLegacy = LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS.some((marker) => cmd.command.includes(marker));
|
|
19491
|
+
if (!entry && !isLegacy) {
|
|
19492
|
+
issues.push({
|
|
19493
|
+
runtime,
|
|
19494
|
+
event: cmd.event,
|
|
19495
|
+
marker: "dist/hooks/",
|
|
19496
|
+
count: 1,
|
|
19497
|
+
message: `Unknown exe-os hook command not present in ownership manifest: ${cmd.command.slice(0, 160)}`
|
|
19498
|
+
});
|
|
19499
|
+
}
|
|
19500
|
+
}
|
|
19501
|
+
return issues;
|
|
19502
|
+
}
|
|
19503
|
+
function auditHookOwnership() {
|
|
19504
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
19505
|
+
const checkedFiles = [];
|
|
19506
|
+
const issues = [];
|
|
19507
|
+
const claudeSettingsPath = path32.join(home, ".claude", "settings.json");
|
|
19508
|
+
const claudeSettings = safeReadJson(claudeSettingsPath);
|
|
19509
|
+
if (claudeSettings) {
|
|
19510
|
+
checkedFiles.push(claudeSettingsPath);
|
|
19511
|
+
issues.push(...buildHookOwnershipIssues("claude", collectHookCommandsFromClaudeSettings(claudeSettings)));
|
|
19512
|
+
}
|
|
19513
|
+
const codexHooksPath = path32.join(home, ".codex", "hooks.json");
|
|
19514
|
+
const codexHooks = safeReadJson(codexHooksPath);
|
|
19515
|
+
if (codexHooks) {
|
|
19516
|
+
checkedFiles.push(codexHooksPath);
|
|
19517
|
+
issues.push(...buildHookOwnershipIssues("codex", collectHookCommandsFromCodexHooks(codexHooks)));
|
|
19518
|
+
}
|
|
19519
|
+
return {
|
|
19520
|
+
checkedFiles,
|
|
19521
|
+
issues,
|
|
19522
|
+
staleLegacyHooks: issues.filter((issue) => issue.message.includes("Legacy split"))
|
|
19523
|
+
};
|
|
19524
|
+
}
|
|
18940
19525
|
async function auditShards() {
|
|
18941
19526
|
try {
|
|
18942
19527
|
const { auditShardHealth: auditShardHealth2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
@@ -18981,7 +19566,8 @@ async function runAudit(client, flags) {
|
|
|
18981
19566
|
}
|
|
18982
19567
|
const duplicateCount = duplicates.reduce((sum, d) => sum + d.delete_ids.length, 0);
|
|
18983
19568
|
const hookHealth = auditHookHealth();
|
|
18984
|
-
|
|
19569
|
+
const hookOwnership = auditHookOwnership();
|
|
19570
|
+
return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, hookOwnership, shards };
|
|
18985
19571
|
}
|
|
18986
19572
|
function indicator(value, warn) {
|
|
18987
19573
|
if (value === 0) return "\u{1F7E2}";
|
|
@@ -19060,6 +19646,15 @@ function formatReport(report, flags) {
|
|
|
19060
19646
|
lines.push(` ${p.count}x: ${p.pattern}`);
|
|
19061
19647
|
}
|
|
19062
19648
|
}
|
|
19649
|
+
const ho = report.hookOwnership;
|
|
19650
|
+
if (ho.issues.length === 0) {
|
|
19651
|
+
lines.push(`\u{1F7E2} Hook ownership: ${ho.checkedFiles.length > 0 ? "manifest clean" : "no local hook config found"}`);
|
|
19652
|
+
} else {
|
|
19653
|
+
lines.push(`\u{1F534} Hook ownership: ${fmtNum(ho.issues.length)} issue(s)`);
|
|
19654
|
+
for (const issue of ho.issues.slice(0, 5)) {
|
|
19655
|
+
lines.push(` [${issue.runtime}/${issue.event}] ${issue.message}`);
|
|
19656
|
+
}
|
|
19657
|
+
}
|
|
19063
19658
|
const sh = report.shards;
|
|
19064
19659
|
if (sh.total > 0) {
|
|
19065
19660
|
if (sh.unreadable === 0) {
|
|
@@ -19129,6 +19724,9 @@ function formatReport(report, flags) {
|
|
|
19129
19724
|
if (report.conflicts.superseded > 0) {
|
|
19130
19725
|
recs.push(`${fmtNum(report.conflicts.superseded)} superseded memories can be deactivated`);
|
|
19131
19726
|
}
|
|
19727
|
+
if (report.hookOwnership.issues.length > 0) {
|
|
19728
|
+
recs.push(`Run exe-os install to refresh hook config; remove stale exe-os hook commands if they remain`);
|
|
19729
|
+
}
|
|
19132
19730
|
if (recs.length > 0) {
|
|
19133
19731
|
lines.push("Recommendations:");
|
|
19134
19732
|
for (const r of recs) {
|
|
@@ -19262,8 +19860,8 @@ function splitAtSentences(text3, maxChunkSize) {
|
|
|
19262
19860
|
}
|
|
19263
19861
|
async function main(argv = process.argv.slice(2)) {
|
|
19264
19862
|
const flags = parseFlags(argv);
|
|
19265
|
-
await
|
|
19266
|
-
const client =
|
|
19863
|
+
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
19864
|
+
const client = await fastDbInit2();
|
|
19267
19865
|
const report = await runAudit(client, flags);
|
|
19268
19866
|
console.log(formatReport(report, flags));
|
|
19269
19867
|
if (flags.fix || flags.dryRun) {
|