@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/lib/exe-daemon.js
CHANGED
|
@@ -257,8 +257,8 @@ var init_config = __esm({
|
|
|
257
257
|
rerankerAutoTrigger: {
|
|
258
258
|
enabled: true,
|
|
259
259
|
broadQueryMinCardinality: 5e4,
|
|
260
|
-
fetchTopK:
|
|
261
|
-
returnTopK:
|
|
260
|
+
fetchTopK: 200,
|
|
261
|
+
returnTopK: 20
|
|
262
262
|
}
|
|
263
263
|
},
|
|
264
264
|
graphRagEnabled: true,
|
|
@@ -313,6 +313,15 @@ var init_memory = __esm({
|
|
|
313
313
|
});
|
|
314
314
|
|
|
315
315
|
// src/lib/daemon-protocol.ts
|
|
316
|
+
var daemon_protocol_exports = {};
|
|
317
|
+
__export(daemon_protocol_exports, {
|
|
318
|
+
deserializeArgs: () => deserializeArgs,
|
|
319
|
+
deserializeResultSet: () => deserializeResultSet,
|
|
320
|
+
deserializeValue: () => deserializeValue,
|
|
321
|
+
serializeArgs: () => serializeArgs,
|
|
322
|
+
serializeResultSet: () => serializeResultSet,
|
|
323
|
+
serializeValue: () => serializeValue
|
|
324
|
+
});
|
|
316
325
|
function serializeValue(v) {
|
|
317
326
|
if (v === null || v === void 0) return null;
|
|
318
327
|
if (typeof v === "bigint") return Number(v);
|
|
@@ -337,6 +346,9 @@ function deserializeValue(v) {
|
|
|
337
346
|
}
|
|
338
347
|
return v;
|
|
339
348
|
}
|
|
349
|
+
function serializeArgs(args) {
|
|
350
|
+
return args.map(serializeValue);
|
|
351
|
+
}
|
|
340
352
|
function deserializeArgs(args) {
|
|
341
353
|
return args.map(deserializeValue);
|
|
342
354
|
}
|
|
@@ -3109,6 +3121,51 @@ async function ensureSchema() {
|
|
|
3109
3121
|
VALUES (new.rowid, new.content_text, new.sender_name, new.agent_response);
|
|
3110
3122
|
END;
|
|
3111
3123
|
`);
|
|
3124
|
+
await client.executeMultiple(`
|
|
3125
|
+
CREATE TABLE IF NOT EXISTS memory_cards (
|
|
3126
|
+
id TEXT PRIMARY KEY,
|
|
3127
|
+
memory_id TEXT NOT NULL,
|
|
3128
|
+
agent_id TEXT NOT NULL,
|
|
3129
|
+
session_id TEXT NOT NULL,
|
|
3130
|
+
project_name TEXT,
|
|
3131
|
+
timestamp TEXT NOT NULL,
|
|
3132
|
+
card_type TEXT NOT NULL,
|
|
3133
|
+
subject TEXT,
|
|
3134
|
+
predicate TEXT,
|
|
3135
|
+
object TEXT,
|
|
3136
|
+
content TEXT NOT NULL,
|
|
3137
|
+
source_ref TEXT,
|
|
3138
|
+
confidence REAL DEFAULT 0.6,
|
|
3139
|
+
active INTEGER DEFAULT 1,
|
|
3140
|
+
created_at TEXT NOT NULL
|
|
3141
|
+
);
|
|
3142
|
+
|
|
3143
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_agent
|
|
3144
|
+
ON memory_cards(agent_id, active, timestamp);
|
|
3145
|
+
|
|
3146
|
+
CREATE INDEX IF NOT EXISTS idx_memory_cards_memory
|
|
3147
|
+
ON memory_cards(memory_id);
|
|
3148
|
+
|
|
3149
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memory_cards_fts
|
|
3150
|
+
USING fts5(content, subject, predicate, object, content='memory_cards', content_rowid='rowid');
|
|
3151
|
+
|
|
3152
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ai AFTER INSERT ON memory_cards BEGIN
|
|
3153
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
3154
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
3155
|
+
END;
|
|
3156
|
+
|
|
3157
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_ad AFTER DELETE ON memory_cards BEGIN
|
|
3158
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
3159
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
3160
|
+
END;
|
|
3161
|
+
|
|
3162
|
+
CREATE TRIGGER IF NOT EXISTS memory_cards_fts_au AFTER UPDATE ON memory_cards BEGIN
|
|
3163
|
+
INSERT INTO memory_cards_fts(memory_cards_fts, rowid, content, subject, predicate, object)
|
|
3164
|
+
VALUES('delete', old.rowid, old.content, old.subject, old.predicate, old.object);
|
|
3165
|
+
INSERT INTO memory_cards_fts(rowid, content, subject, predicate, object)
|
|
3166
|
+
VALUES (new.rowid, new.content, new.subject, new.predicate, new.object);
|
|
3167
|
+
END;
|
|
3168
|
+
`);
|
|
3112
3169
|
try {
|
|
3113
3170
|
await client.execute({
|
|
3114
3171
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
@@ -4745,6 +4802,164 @@ ${p.content}`).join("\n\n");
|
|
|
4745
4802
|
}
|
|
4746
4803
|
});
|
|
4747
4804
|
|
|
4805
|
+
// src/lib/memory-cards.ts
|
|
4806
|
+
var memory_cards_exports = {};
|
|
4807
|
+
__export(memory_cards_exports, {
|
|
4808
|
+
extractMemoryCards: () => extractMemoryCards,
|
|
4809
|
+
insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
|
|
4810
|
+
searchMemoryCards: () => searchMemoryCards
|
|
4811
|
+
});
|
|
4812
|
+
import { createHash as createHash2 } from "crypto";
|
|
4813
|
+
function stableId(memoryId, type, content) {
|
|
4814
|
+
return createHash2("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4815
|
+
}
|
|
4816
|
+
function cleanText(text3) {
|
|
4817
|
+
return text3.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
4818
|
+
}
|
|
4819
|
+
function splitSentences(text3) {
|
|
4820
|
+
return cleanText(text3).split(/(?<=[.!?])\s+|\n+/).map((s) => s.trim()).filter((s) => s.length >= 24 && s.length <= MAX_SENTENCE_CHARS);
|
|
4821
|
+
}
|
|
4822
|
+
function inferCardType(sentence, toolName) {
|
|
4823
|
+
const lower = sentence.toLowerCase();
|
|
4824
|
+
if (toolName === "store_decision" || /\b(decided|decision|adr|approved|rejected)\b/.test(lower)) return "decision";
|
|
4825
|
+
if (/\b(prefers|preference|likes|dislikes|wants|doesn't want|does not want)\b/.test(lower)) return "preference";
|
|
4826
|
+
if (/\b(changed|updated|replaced|now|no longer|instead|supersedes)\b/.test(lower)) return "belief_update";
|
|
4827
|
+
if (toolName && ["Read", "Write", "Edit", "Bash"].includes(toolName)) return "code";
|
|
4828
|
+
if (/\b(meeting|deadline|shipped|launched|completed|failed|blocked|assigned|created)\b/.test(lower)) return "event";
|
|
4829
|
+
return "fact";
|
|
4830
|
+
}
|
|
4831
|
+
function extractSubject(sentence, agentId) {
|
|
4832
|
+
const explicit = sentence.match(/\b([A-Z][a-zA-Z0-9_-]{2,}(?:\s+[A-Z][a-zA-Z0-9_-]{2,})?)\b/);
|
|
4833
|
+
return explicit?.[1] ?? agentId;
|
|
4834
|
+
}
|
|
4835
|
+
function predicateFor(type) {
|
|
4836
|
+
switch (type) {
|
|
4837
|
+
case "preference":
|
|
4838
|
+
return "prefers";
|
|
4839
|
+
case "belief_update":
|
|
4840
|
+
return "updated";
|
|
4841
|
+
case "decision":
|
|
4842
|
+
return "decided";
|
|
4843
|
+
case "event":
|
|
4844
|
+
return "happened";
|
|
4845
|
+
case "code":
|
|
4846
|
+
return "implemented";
|
|
4847
|
+
default:
|
|
4848
|
+
return "states";
|
|
4849
|
+
}
|
|
4850
|
+
}
|
|
4851
|
+
function extractMemoryCards(row) {
|
|
4852
|
+
const sentences = splitSentences(row.raw_text);
|
|
4853
|
+
const cards = [];
|
|
4854
|
+
for (const sentence of sentences) {
|
|
4855
|
+
const type = inferCardType(sentence, row.tool_name);
|
|
4856
|
+
const subject = extractSubject(sentence, row.agent_id);
|
|
4857
|
+
const content = sentence.length > MAX_SENTENCE_CHARS ? `${sentence.slice(0, MAX_SENTENCE_CHARS - 1)}\u2026` : sentence;
|
|
4858
|
+
cards.push({
|
|
4859
|
+
id: stableId(row.id, type, content),
|
|
4860
|
+
memory_id: row.id,
|
|
4861
|
+
agent_id: row.agent_id,
|
|
4862
|
+
session_id: row.session_id,
|
|
4863
|
+
project_name: row.project_name ?? null,
|
|
4864
|
+
timestamp: row.timestamp,
|
|
4865
|
+
card_type: type,
|
|
4866
|
+
subject,
|
|
4867
|
+
predicate: predicateFor(type),
|
|
4868
|
+
object: content,
|
|
4869
|
+
content,
|
|
4870
|
+
source_ref: row.id,
|
|
4871
|
+
confidence: type === "fact" ? 0.55 : 0.65
|
|
4872
|
+
});
|
|
4873
|
+
if (cards.length >= MAX_CARDS_PER_MEMORY) break;
|
|
4874
|
+
}
|
|
4875
|
+
return cards;
|
|
4876
|
+
}
|
|
4877
|
+
async function insertMemoryCardsForBatch(rows) {
|
|
4878
|
+
const cards = rows.flatMap(extractMemoryCards);
|
|
4879
|
+
if (cards.length === 0) return 0;
|
|
4880
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4881
|
+
const client = getClient();
|
|
4882
|
+
const stmts = cards.map((card) => ({
|
|
4883
|
+
sql: `INSERT OR IGNORE INTO memory_cards
|
|
4884
|
+
(id, memory_id, agent_id, session_id, project_name, timestamp, card_type,
|
|
4885
|
+
subject, predicate, object, content, source_ref, confidence, active, created_at)
|
|
4886
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?)`,
|
|
4887
|
+
args: [
|
|
4888
|
+
card.id,
|
|
4889
|
+
card.memory_id,
|
|
4890
|
+
card.agent_id,
|
|
4891
|
+
card.session_id,
|
|
4892
|
+
card.project_name,
|
|
4893
|
+
card.timestamp,
|
|
4894
|
+
card.card_type,
|
|
4895
|
+
card.subject,
|
|
4896
|
+
card.predicate,
|
|
4897
|
+
card.object,
|
|
4898
|
+
card.content,
|
|
4899
|
+
card.source_ref,
|
|
4900
|
+
card.confidence,
|
|
4901
|
+
now
|
|
4902
|
+
]
|
|
4903
|
+
}));
|
|
4904
|
+
await client.batch(stmts, "write");
|
|
4905
|
+
return cards.length;
|
|
4906
|
+
}
|
|
4907
|
+
function buildMatchExpr(queryText) {
|
|
4908
|
+
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);
|
|
4909
|
+
if (terms.length === 0) return null;
|
|
4910
|
+
return terms.map((t) => `${t}*`).join(terms.length >= 3 ? " AND " : " OR ");
|
|
4911
|
+
}
|
|
4912
|
+
async function searchMemoryCards(queryText, agentId, options) {
|
|
4913
|
+
const limit = options?.limit ?? 10;
|
|
4914
|
+
const matchExpr = buildMatchExpr(queryText);
|
|
4915
|
+
if (!matchExpr) return [];
|
|
4916
|
+
let sql = `SELECT c.id, c.memory_id, c.agent_id, c.session_id, c.project_name,
|
|
4917
|
+
c.timestamp, c.card_type, c.content, c.source_ref, c.confidence
|
|
4918
|
+
FROM memory_cards c
|
|
4919
|
+
JOIN memory_cards_fts fts ON c.rowid = fts.rowid
|
|
4920
|
+
WHERE memory_cards_fts MATCH ?
|
|
4921
|
+
AND c.agent_id = ?
|
|
4922
|
+
AND COALESCE(c.active, 1) = 1`;
|
|
4923
|
+
const args = [matchExpr, agentId];
|
|
4924
|
+
if (options?.projectName) {
|
|
4925
|
+
sql += ` AND c.project_name = ?`;
|
|
4926
|
+
args.push(options.projectName);
|
|
4927
|
+
}
|
|
4928
|
+
if (options?.since) {
|
|
4929
|
+
sql += ` AND c.timestamp >= ?`;
|
|
4930
|
+
args.push(options.since);
|
|
4931
|
+
}
|
|
4932
|
+
sql += ` ORDER BY rank LIMIT ?`;
|
|
4933
|
+
args.push(limit);
|
|
4934
|
+
const result = await getClient().execute({ sql, args });
|
|
4935
|
+
return result.rows.map((row) => ({
|
|
4936
|
+
id: `card:${String(row.id)}`,
|
|
4937
|
+
agent_id: String(row.agent_id),
|
|
4938
|
+
agent_role: "memory_card",
|
|
4939
|
+
session_id: String(row.session_id),
|
|
4940
|
+
timestamp: String(row.timestamp),
|
|
4941
|
+
tool_name: `memory_card:${String(row.card_type)}`,
|
|
4942
|
+
project_name: row.project_name == null ? "" : String(row.project_name),
|
|
4943
|
+
has_error: false,
|
|
4944
|
+
raw_text: `[${String(row.card_type)}] ${String(row.content)}
|
|
4945
|
+
Source memory: ${String(row.source_ref ?? row.memory_id)}`,
|
|
4946
|
+
vector: [],
|
|
4947
|
+
importance: 6,
|
|
4948
|
+
status: "active",
|
|
4949
|
+
confidence: Number(row.confidence ?? 0.6),
|
|
4950
|
+
last_accessed: String(row.timestamp)
|
|
4951
|
+
}));
|
|
4952
|
+
}
|
|
4953
|
+
var MAX_CARDS_PER_MEMORY, MAX_SENTENCE_CHARS;
|
|
4954
|
+
var init_memory_cards = __esm({
|
|
4955
|
+
"src/lib/memory-cards.ts"() {
|
|
4956
|
+
"use strict";
|
|
4957
|
+
init_database();
|
|
4958
|
+
MAX_CARDS_PER_MEMORY = 6;
|
|
4959
|
+
MAX_SENTENCE_CHARS = 360;
|
|
4960
|
+
}
|
|
4961
|
+
});
|
|
4962
|
+
|
|
4748
4963
|
// src/lib/store.ts
|
|
4749
4964
|
var store_exports = {};
|
|
4750
4965
|
__export(store_exports, {
|
|
@@ -5083,6 +5298,11 @@ async function flushBatch() {
|
|
|
5083
5298
|
const globalClient = getClient();
|
|
5084
5299
|
const globalStmts = batch.map(buildStmt);
|
|
5085
5300
|
await globalClient.batch(globalStmts, "write");
|
|
5301
|
+
try {
|
|
5302
|
+
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
5303
|
+
await insertMemoryCardsForBatch2(batch);
|
|
5304
|
+
} catch {
|
|
5305
|
+
}
|
|
5086
5306
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
5087
5307
|
_pendingRecords.splice(0, batch.length);
|
|
5088
5308
|
try {
|
|
@@ -6738,9 +6958,18 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6738
6958
|
} catch {
|
|
6739
6959
|
}
|
|
6740
6960
|
}
|
|
6741
|
-
const
|
|
6961
|
+
const includeStructuredCards = effectiveIsBroad || effectiveOptions.includeStructuredCards === true;
|
|
6962
|
+
const [ftsResults, vectorResults, cardResults, grepResults] = await Promise.all([
|
|
6742
6963
|
lightweightSearch(effectiveQuery, agentId, fetchOptions),
|
|
6743
6964
|
queryVector ? searchMemories(queryVector, agentId, fetchOptions) : Promise.resolve([]),
|
|
6965
|
+
includeStructuredCards ? (async () => {
|
|
6966
|
+
try {
|
|
6967
|
+
const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
6968
|
+
return await searchMemoryCards2(effectiveQuery, agentId, fetchOptions);
|
|
6969
|
+
} catch {
|
|
6970
|
+
return [];
|
|
6971
|
+
}
|
|
6972
|
+
})() : Promise.resolve([]),
|
|
6744
6973
|
grepPromise
|
|
6745
6974
|
]);
|
|
6746
6975
|
const lists = [];
|
|
@@ -6753,6 +6982,10 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6753
6982
|
lists.push(vectorResults);
|
|
6754
6983
|
weights.push(1);
|
|
6755
6984
|
}
|
|
6985
|
+
if (cardResults.length > 0) {
|
|
6986
|
+
lists.push(cardResults);
|
|
6987
|
+
weights.push(1.2);
|
|
6988
|
+
}
|
|
6756
6989
|
if (grepResults.length > 0) {
|
|
6757
6990
|
lists.push(grepResults);
|
|
6758
6991
|
weights.push(0.5);
|
|
@@ -6821,6 +7054,7 @@ async function hybridSearch(queryText, agentId, options) {
|
|
|
6821
7054
|
signals: {
|
|
6822
7055
|
fts: ftsResults.length,
|
|
6823
7056
|
vector: vectorResults.length,
|
|
7057
|
+
cards: cardResults.length,
|
|
6824
7058
|
grep: grepResults.length,
|
|
6825
7059
|
entityBoost: entityBoostRan,
|
|
6826
7060
|
reranker: rerankedAndBlended !== null,
|
|
@@ -6970,6 +7204,15 @@ async function lightweightSearch(queryText, agentId, options) {
|
|
|
6970
7204
|
if (options?.includeSource && results.length > 0) {
|
|
6971
7205
|
await attachDocumentMetadata(results);
|
|
6972
7206
|
}
|
|
7207
|
+
if (options?.includeStructuredCards !== true) return results;
|
|
7208
|
+
try {
|
|
7209
|
+
const { searchMemoryCards: searchMemoryCards2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
7210
|
+
const cardResults = await searchMemoryCards2(queryText, agentId, options);
|
|
7211
|
+
if (cardResults.length > 0) {
|
|
7212
|
+
return rrfMergeMulti([results, cardResults], limit, RRF_K, [1, 1.2]);
|
|
7213
|
+
}
|
|
7214
|
+
} catch {
|
|
7215
|
+
}
|
|
6973
7216
|
return results;
|
|
6974
7217
|
}
|
|
6975
7218
|
async function ftsQuery(client, matchExpr, agentId, options, limit) {
|
|
@@ -13353,7 +13596,7 @@ __export(identity_exports, {
|
|
|
13353
13596
|
import { existsSync as existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "fs";
|
|
13354
13597
|
import { readdirSync as readdirSync7 } from "fs";
|
|
13355
13598
|
import path29 from "path";
|
|
13356
|
-
import { createHash as
|
|
13599
|
+
import { createHash as createHash3 } from "crypto";
|
|
13357
13600
|
function ensureDir2() {
|
|
13358
13601
|
if (!existsSync23(IDENTITY_DIR2)) {
|
|
13359
13602
|
mkdirSync10(IDENTITY_DIR2, { recursive: true });
|
|
@@ -13400,7 +13643,7 @@ function parseFrontmatter(raw) {
|
|
|
13400
13643
|
};
|
|
13401
13644
|
}
|
|
13402
13645
|
function contentHash(content) {
|
|
13403
|
-
return
|
|
13646
|
+
return createHash3("sha256").update(content).digest("hex").slice(0, 16);
|
|
13404
13647
|
}
|
|
13405
13648
|
function getIdentity(agentId) {
|
|
13406
13649
|
const filePath = identityPath(agentId);
|
|
@@ -20760,6 +21003,218 @@ var init_conflict_detector = __esm({
|
|
|
20760
21003
|
}
|
|
20761
21004
|
});
|
|
20762
21005
|
|
|
21006
|
+
// src/adapters/runtime-hook-manifest.ts
|
|
21007
|
+
function manifestEntryForCommand(command) {
|
|
21008
|
+
return EXE_HOOK_MANIFEST.find((entry) => command.includes(entry.commandMarker));
|
|
21009
|
+
}
|
|
21010
|
+
var EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
|
|
21011
|
+
var init_runtime_hook_manifest = __esm({
|
|
21012
|
+
"src/adapters/runtime-hook-manifest.ts"() {
|
|
21013
|
+
"use strict";
|
|
21014
|
+
EXE_HOOKS = {
|
|
21015
|
+
postToolCombined: "dist/hooks/post-tool-combined.js",
|
|
21016
|
+
sessionStart: "dist/hooks/session-start.js",
|
|
21017
|
+
promptSubmit: "dist/hooks/prompt-submit.js",
|
|
21018
|
+
heartbeat: "dist/hooks/exe-heartbeat-hook.js",
|
|
21019
|
+
stop: "dist/hooks/stop.js",
|
|
21020
|
+
preToolUse: "dist/hooks/pre-tool-use.js",
|
|
21021
|
+
subagentStop: "dist/hooks/subagent-stop.js",
|
|
21022
|
+
preCompact: "dist/hooks/pre-compact.js",
|
|
21023
|
+
postCompact: "dist/hooks/post-compact.js",
|
|
21024
|
+
sessionEnd: "dist/hooks/session-end.js",
|
|
21025
|
+
notification: "dist/hooks/notification.js",
|
|
21026
|
+
instructionsLoaded: "dist/hooks/instructions-loaded.js"
|
|
21027
|
+
};
|
|
21028
|
+
EXE_HOOK_MANIFEST = [
|
|
21029
|
+
{
|
|
21030
|
+
key: "postToolCombined",
|
|
21031
|
+
event: "PostToolUse",
|
|
21032
|
+
commandMarker: EXE_HOOKS.postToolCombined,
|
|
21033
|
+
owner: "exe-os",
|
|
21034
|
+
purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
|
|
21035
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
21036
|
+
checkpointRole: "none"
|
|
21037
|
+
},
|
|
21038
|
+
{
|
|
21039
|
+
key: "sessionStart",
|
|
21040
|
+
event: "SessionStart",
|
|
21041
|
+
commandMarker: EXE_HOOKS.sessionStart,
|
|
21042
|
+
owner: "exe-os",
|
|
21043
|
+
purpose: "Loads agent identity, procedures, and boot context.",
|
|
21044
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
21045
|
+
checkpointRole: "none"
|
|
21046
|
+
},
|
|
21047
|
+
{
|
|
21048
|
+
key: "promptSubmit",
|
|
21049
|
+
event: "UserPromptSubmit",
|
|
21050
|
+
commandMarker: EXE_HOOKS.promptSubmit,
|
|
21051
|
+
owner: "exe-os",
|
|
21052
|
+
purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
|
|
21053
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
21054
|
+
checkpointRole: "none"
|
|
21055
|
+
},
|
|
21056
|
+
{
|
|
21057
|
+
key: "heartbeat",
|
|
21058
|
+
event: "UserPromptSubmit",
|
|
21059
|
+
commandMarker: EXE_HOOKS.heartbeat,
|
|
21060
|
+
owner: "exe-os",
|
|
21061
|
+
purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
|
|
21062
|
+
runtimes: ["claude"],
|
|
21063
|
+
checkpointRole: "none"
|
|
21064
|
+
},
|
|
21065
|
+
{
|
|
21066
|
+
key: "stop",
|
|
21067
|
+
event: "Stop",
|
|
21068
|
+
commandMarker: EXE_HOOKS.stop,
|
|
21069
|
+
owner: "exe-os",
|
|
21070
|
+
purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
|
|
21071
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
21072
|
+
checkpointRole: "capacity_checkpoint"
|
|
21073
|
+
},
|
|
21074
|
+
{
|
|
21075
|
+
key: "preToolUse",
|
|
21076
|
+
event: "PreToolUse",
|
|
21077
|
+
commandMarker: EXE_HOOKS.preToolUse,
|
|
21078
|
+
owner: "exe-os",
|
|
21079
|
+
purpose: "Preflight guardrails before shell/tool execution.",
|
|
21080
|
+
runtimes: ["claude", "codex", "opencode"],
|
|
21081
|
+
checkpointRole: "none"
|
|
21082
|
+
},
|
|
21083
|
+
{
|
|
21084
|
+
key: "subagentStop",
|
|
21085
|
+
event: "SubagentStop",
|
|
21086
|
+
commandMarker: EXE_HOOKS.subagentStop,
|
|
21087
|
+
owner: "exe-os",
|
|
21088
|
+
purpose: "Captures subagent completion context.",
|
|
21089
|
+
runtimes: ["claude"],
|
|
21090
|
+
checkpointRole: "none"
|
|
21091
|
+
},
|
|
21092
|
+
{
|
|
21093
|
+
key: "preCompact",
|
|
21094
|
+
event: "PreCompact",
|
|
21095
|
+
commandMarker: EXE_HOOKS.preCompact,
|
|
21096
|
+
owner: "exe-os",
|
|
21097
|
+
purpose: "Writes active-task snapshot and compaction recovery context.",
|
|
21098
|
+
runtimes: ["claude"],
|
|
21099
|
+
checkpointRole: "recovery_context"
|
|
21100
|
+
},
|
|
21101
|
+
{
|
|
21102
|
+
key: "postCompact",
|
|
21103
|
+
event: "PostCompact",
|
|
21104
|
+
commandMarker: EXE_HOOKS.postCompact,
|
|
21105
|
+
owner: "exe-os",
|
|
21106
|
+
purpose: "Rehydrates recovery context after compaction.",
|
|
21107
|
+
runtimes: ["claude"],
|
|
21108
|
+
checkpointRole: "recovery_context"
|
|
21109
|
+
},
|
|
21110
|
+
{
|
|
21111
|
+
key: "sessionEnd",
|
|
21112
|
+
event: "SessionEnd",
|
|
21113
|
+
commandMarker: EXE_HOOKS.sessionEnd,
|
|
21114
|
+
owner: "exe-os",
|
|
21115
|
+
purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
|
|
21116
|
+
runtimes: ["claude"],
|
|
21117
|
+
checkpointRole: "session_summary"
|
|
21118
|
+
},
|
|
21119
|
+
{
|
|
21120
|
+
key: "notification",
|
|
21121
|
+
event: "Notification",
|
|
21122
|
+
commandMarker: EXE_HOOKS.notification,
|
|
21123
|
+
owner: "exe-os",
|
|
21124
|
+
purpose: "Captures runtime notifications and nudges.",
|
|
21125
|
+
runtimes: ["claude"],
|
|
21126
|
+
checkpointRole: "none"
|
|
21127
|
+
},
|
|
21128
|
+
{
|
|
21129
|
+
key: "instructionsLoaded",
|
|
21130
|
+
event: "InstructionsLoaded",
|
|
21131
|
+
commandMarker: EXE_HOOKS.instructionsLoaded,
|
|
21132
|
+
owner: "exe-os",
|
|
21133
|
+
purpose: "Applies runtime instruction post-processing.",
|
|
21134
|
+
runtimes: ["claude"],
|
|
21135
|
+
checkpointRole: "none"
|
|
21136
|
+
}
|
|
21137
|
+
];
|
|
21138
|
+
LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
|
|
21139
|
+
"dist/hooks/ingest.js",
|
|
21140
|
+
"dist/hooks/error-recall.js",
|
|
21141
|
+
"dist/hooks/ingest-worker.js"
|
|
21142
|
+
];
|
|
21143
|
+
}
|
|
21144
|
+
});
|
|
21145
|
+
|
|
21146
|
+
// src/bin/fast-db-init.ts
|
|
21147
|
+
var fast_db_init_exports = {};
|
|
21148
|
+
__export(fast_db_init_exports, {
|
|
21149
|
+
fastDbInit: () => fastDbInit
|
|
21150
|
+
});
|
|
21151
|
+
async function fastDbInit() {
|
|
21152
|
+
const { isInitialized: isInitialized2, getClient: getClient2, setExternalClient: setExternalClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
21153
|
+
if (isInitialized2()) {
|
|
21154
|
+
return getClient2();
|
|
21155
|
+
}
|
|
21156
|
+
try {
|
|
21157
|
+
const { connectEmbedDaemon: connectEmbedDaemon2, sendDaemonRequest: sendDaemonRequest2, isClientConnected: isClientConnected2 } = await Promise.resolve().then(() => (init_exe_daemon_client(), exe_daemon_client_exports));
|
|
21158
|
+
const { deserializeResultSet: deserializeResultSet2 } = await Promise.resolve().then(() => (init_daemon_protocol(), daemon_protocol_exports));
|
|
21159
|
+
await connectEmbedDaemon2();
|
|
21160
|
+
if (isClientConnected2()) {
|
|
21161
|
+
const daemonClient = {
|
|
21162
|
+
async execute(stmt) {
|
|
21163
|
+
const sql = typeof stmt === "string" ? stmt : stmt.sql;
|
|
21164
|
+
const args = typeof stmt === "string" ? [] : Array.isArray(stmt.args) ? stmt.args : [];
|
|
21165
|
+
const resp = await sendDaemonRequest2({ type: "db-execute", sql, args });
|
|
21166
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
21167
|
+
if (resp.db) return deserializeResultSet2(resp.db);
|
|
21168
|
+
throw new Error("Unexpected daemon response");
|
|
21169
|
+
},
|
|
21170
|
+
async batch(stmts, mode) {
|
|
21171
|
+
const statements = stmts.map((s) => {
|
|
21172
|
+
const sql = typeof s === "string" ? s : s.sql;
|
|
21173
|
+
const args = typeof s === "string" ? [] : Array.isArray(s.args) ? s.args : [];
|
|
21174
|
+
return { sql, args };
|
|
21175
|
+
});
|
|
21176
|
+
const resp = await sendDaemonRequest2({ type: "db-batch", statements, mode: mode ?? "deferred" });
|
|
21177
|
+
if (resp.error) throw new Error(String(resp.error));
|
|
21178
|
+
const batchResults = resp["db-batch"];
|
|
21179
|
+
if (batchResults) return batchResults.map(deserializeResultSet2);
|
|
21180
|
+
throw new Error("Unexpected daemon batch response");
|
|
21181
|
+
},
|
|
21182
|
+
async transaction(_mode) {
|
|
21183
|
+
throw new Error("Transactions not supported via daemon socket");
|
|
21184
|
+
},
|
|
21185
|
+
async executeMultiple(_sql) {
|
|
21186
|
+
throw new Error("executeMultiple not supported via daemon socket");
|
|
21187
|
+
},
|
|
21188
|
+
async migrate(_stmts) {
|
|
21189
|
+
throw new Error("migrate not supported via daemon socket");
|
|
21190
|
+
},
|
|
21191
|
+
sync() {
|
|
21192
|
+
return Promise.resolve(void 0);
|
|
21193
|
+
},
|
|
21194
|
+
close() {
|
|
21195
|
+
},
|
|
21196
|
+
get closed() {
|
|
21197
|
+
return false;
|
|
21198
|
+
},
|
|
21199
|
+
get protocol() {
|
|
21200
|
+
return "file";
|
|
21201
|
+
}
|
|
21202
|
+
};
|
|
21203
|
+
setExternalClient2(daemonClient);
|
|
21204
|
+
return daemonClient;
|
|
21205
|
+
}
|
|
21206
|
+
} catch {
|
|
21207
|
+
}
|
|
21208
|
+
const { initStore: initStore2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
21209
|
+
await initStore2({ lightweight: true });
|
|
21210
|
+
return getClient2();
|
|
21211
|
+
}
|
|
21212
|
+
var init_fast_db_init = __esm({
|
|
21213
|
+
"src/bin/fast-db-init.ts"() {
|
|
21214
|
+
"use strict";
|
|
21215
|
+
}
|
|
21216
|
+
});
|
|
21217
|
+
|
|
20763
21218
|
// src/lib/db-backup.ts
|
|
20764
21219
|
var db_backup_exports = {};
|
|
20765
21220
|
__export(db_backup_exports, {
|
|
@@ -21066,6 +21521,121 @@ function auditHookHealth() {
|
|
|
21066
21521
|
const topPatterns = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([pattern, count]) => ({ pattern, count }));
|
|
21067
21522
|
return { logExists: true, totalLines, errorsLastHour, topPatterns };
|
|
21068
21523
|
}
|
|
21524
|
+
function safeReadJson(filePath) {
|
|
21525
|
+
if (!existsSync31(filePath)) return null;
|
|
21526
|
+
try {
|
|
21527
|
+
return JSON.parse(readFileSync23(filePath, "utf-8"));
|
|
21528
|
+
} catch {
|
|
21529
|
+
return null;
|
|
21530
|
+
}
|
|
21531
|
+
}
|
|
21532
|
+
function collectHookCommandsFromClaudeSettings(settings) {
|
|
21533
|
+
const hooks = settings?.hooks;
|
|
21534
|
+
if (!hooks || typeof hooks !== "object") return [];
|
|
21535
|
+
const commands = [];
|
|
21536
|
+
for (const [event, groups] of Object.entries(hooks)) {
|
|
21537
|
+
if (!Array.isArray(groups)) continue;
|
|
21538
|
+
for (const group of groups) {
|
|
21539
|
+
const hooksForGroup = group?.hooks;
|
|
21540
|
+
if (!Array.isArray(hooksForGroup)) continue;
|
|
21541
|
+
for (const hook of hooksForGroup) {
|
|
21542
|
+
const command = hook?.command;
|
|
21543
|
+
if (typeof command === "string") commands.push({ event, command });
|
|
21544
|
+
}
|
|
21545
|
+
}
|
|
21546
|
+
}
|
|
21547
|
+
return commands;
|
|
21548
|
+
}
|
|
21549
|
+
function collectHookCommandsFromCodexHooks(config2) {
|
|
21550
|
+
const commands = [];
|
|
21551
|
+
if (!config2 || typeof config2 !== "object") return commands;
|
|
21552
|
+
const root = config2;
|
|
21553
|
+
for (const [event, value] of Object.entries(root)) {
|
|
21554
|
+
const entries = Array.isArray(value) ? value : value && typeof value === "object" ? Object.values(value) : [];
|
|
21555
|
+
for (const entry of entries) {
|
|
21556
|
+
if (typeof entry === "string") commands.push({ event, command: entry });
|
|
21557
|
+
const command = entry?.command;
|
|
21558
|
+
if (typeof command === "string") commands.push({ event, command });
|
|
21559
|
+
}
|
|
21560
|
+
}
|
|
21561
|
+
return commands;
|
|
21562
|
+
}
|
|
21563
|
+
function buildHookOwnershipIssues(runtime, commands) {
|
|
21564
|
+
const issues = [];
|
|
21565
|
+
for (const marker of LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS) {
|
|
21566
|
+
const count = commands.filter((cmd) => cmd.command.includes(marker)).length;
|
|
21567
|
+
if (count > 0) {
|
|
21568
|
+
issues.push({
|
|
21569
|
+
runtime,
|
|
21570
|
+
event: "PostToolUse",
|
|
21571
|
+
marker,
|
|
21572
|
+
count,
|
|
21573
|
+
message: `Legacy split PostToolUse hook still installed: ${marker}`
|
|
21574
|
+
});
|
|
21575
|
+
}
|
|
21576
|
+
}
|
|
21577
|
+
for (const entry of EXE_HOOK_MANIFEST.filter((hook) => hook.runtimes.includes(runtime))) {
|
|
21578
|
+
const matching = commands.filter((cmd) => cmd.command.includes(entry.commandMarker));
|
|
21579
|
+
if (matching.length > 1) {
|
|
21580
|
+
issues.push({
|
|
21581
|
+
runtime,
|
|
21582
|
+
event: entry.event,
|
|
21583
|
+
marker: entry.commandMarker,
|
|
21584
|
+
count: matching.length,
|
|
21585
|
+
message: `Duplicate exe-os hook owner for ${entry.event}: ${entry.commandMarker}`
|
|
21586
|
+
});
|
|
21587
|
+
}
|
|
21588
|
+
for (const cmd of matching) {
|
|
21589
|
+
if (cmd.event !== entry.event) {
|
|
21590
|
+
issues.push({
|
|
21591
|
+
runtime,
|
|
21592
|
+
event: cmd.event,
|
|
21593
|
+
marker: entry.commandMarker,
|
|
21594
|
+
count: 1,
|
|
21595
|
+
message: `exe-os hook ${entry.commandMarker} is registered under ${cmd.event}, expected ${entry.event}`
|
|
21596
|
+
});
|
|
21597
|
+
}
|
|
21598
|
+
}
|
|
21599
|
+
}
|
|
21600
|
+
for (const cmd of commands) {
|
|
21601
|
+
if (!cmd.command.includes("dist/hooks/")) continue;
|
|
21602
|
+
if (!cmd.command.includes("exe-os")) continue;
|
|
21603
|
+
const entry = manifestEntryForCommand(cmd.command);
|
|
21604
|
+
const isLegacy = LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS.some((marker) => cmd.command.includes(marker));
|
|
21605
|
+
if (!entry && !isLegacy) {
|
|
21606
|
+
issues.push({
|
|
21607
|
+
runtime,
|
|
21608
|
+
event: cmd.event,
|
|
21609
|
+
marker: "dist/hooks/",
|
|
21610
|
+
count: 1,
|
|
21611
|
+
message: `Unknown exe-os hook command not present in ownership manifest: ${cmd.command.slice(0, 160)}`
|
|
21612
|
+
});
|
|
21613
|
+
}
|
|
21614
|
+
}
|
|
21615
|
+
return issues;
|
|
21616
|
+
}
|
|
21617
|
+
function auditHookOwnership() {
|
|
21618
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
21619
|
+
const checkedFiles = [];
|
|
21620
|
+
const issues = [];
|
|
21621
|
+
const claudeSettingsPath = path36.join(home, ".claude", "settings.json");
|
|
21622
|
+
const claudeSettings = safeReadJson(claudeSettingsPath);
|
|
21623
|
+
if (claudeSettings) {
|
|
21624
|
+
checkedFiles.push(claudeSettingsPath);
|
|
21625
|
+
issues.push(...buildHookOwnershipIssues("claude", collectHookCommandsFromClaudeSettings(claudeSettings)));
|
|
21626
|
+
}
|
|
21627
|
+
const codexHooksPath = path36.join(home, ".codex", "hooks.json");
|
|
21628
|
+
const codexHooks = safeReadJson(codexHooksPath);
|
|
21629
|
+
if (codexHooks) {
|
|
21630
|
+
checkedFiles.push(codexHooksPath);
|
|
21631
|
+
issues.push(...buildHookOwnershipIssues("codex", collectHookCommandsFromCodexHooks(codexHooks)));
|
|
21632
|
+
}
|
|
21633
|
+
return {
|
|
21634
|
+
checkedFiles,
|
|
21635
|
+
issues,
|
|
21636
|
+
staleLegacyHooks: issues.filter((issue) => issue.message.includes("Legacy split"))
|
|
21637
|
+
};
|
|
21638
|
+
}
|
|
21069
21639
|
async function auditShards() {
|
|
21070
21640
|
try {
|
|
21071
21641
|
const { auditShardHealth: auditShardHealth2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
@@ -21110,7 +21680,8 @@ async function runAudit(client, flags) {
|
|
|
21110
21680
|
}
|
|
21111
21681
|
const duplicateCount = duplicates.reduce((sum, d) => sum + d.delete_ids.length, 0);
|
|
21112
21682
|
const hookHealth = auditHookHealth();
|
|
21113
|
-
|
|
21683
|
+
const hookOwnership = auditHookOwnership();
|
|
21684
|
+
return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, hookOwnership, shards };
|
|
21114
21685
|
}
|
|
21115
21686
|
function indicator(value, warn) {
|
|
21116
21687
|
if (value === 0) return "\u{1F7E2}";
|
|
@@ -21189,6 +21760,15 @@ function formatReport(report, flags) {
|
|
|
21189
21760
|
lines.push(` ${p.count}x: ${p.pattern}`);
|
|
21190
21761
|
}
|
|
21191
21762
|
}
|
|
21763
|
+
const ho = report.hookOwnership;
|
|
21764
|
+
if (ho.issues.length === 0) {
|
|
21765
|
+
lines.push(`\u{1F7E2} Hook ownership: ${ho.checkedFiles.length > 0 ? "manifest clean" : "no local hook config found"}`);
|
|
21766
|
+
} else {
|
|
21767
|
+
lines.push(`\u{1F534} Hook ownership: ${fmtNum(ho.issues.length)} issue(s)`);
|
|
21768
|
+
for (const issue of ho.issues.slice(0, 5)) {
|
|
21769
|
+
lines.push(` [${issue.runtime}/${issue.event}] ${issue.message}`);
|
|
21770
|
+
}
|
|
21771
|
+
}
|
|
21192
21772
|
const sh = report.shards;
|
|
21193
21773
|
if (sh.total > 0) {
|
|
21194
21774
|
if (sh.unreadable === 0) {
|
|
@@ -21258,6 +21838,9 @@ function formatReport(report, flags) {
|
|
|
21258
21838
|
if (report.conflicts.superseded > 0) {
|
|
21259
21839
|
recs.push(`${fmtNum(report.conflicts.superseded)} superseded memories can be deactivated`);
|
|
21260
21840
|
}
|
|
21841
|
+
if (report.hookOwnership.issues.length > 0) {
|
|
21842
|
+
recs.push(`Run exe-os install to refresh hook config; remove stale exe-os hook commands if they remain`);
|
|
21843
|
+
}
|
|
21261
21844
|
if (recs.length > 0) {
|
|
21262
21845
|
lines.push("Recommendations:");
|
|
21263
21846
|
for (const r of recs) {
|
|
@@ -21391,8 +21974,8 @@ function splitAtSentences(text3, maxChunkSize) {
|
|
|
21391
21974
|
}
|
|
21392
21975
|
async function main(argv = process.argv.slice(2)) {
|
|
21393
21976
|
const flags = parseFlags(argv);
|
|
21394
|
-
await
|
|
21395
|
-
const client =
|
|
21977
|
+
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
21978
|
+
const client = await fastDbInit2();
|
|
21396
21979
|
const report = await runAudit(client, flags);
|
|
21397
21980
|
console.log(formatReport(report, flags));
|
|
21398
21981
|
if (flags.fix || flags.dryRun) {
|
|
@@ -21452,10 +22035,9 @@ ${mode} Complete.`);
|
|
|
21452
22035
|
var init_exe_doctor = __esm({
|
|
21453
22036
|
"src/bin/exe-doctor.ts"() {
|
|
21454
22037
|
"use strict";
|
|
21455
|
-
init_store();
|
|
21456
|
-
init_database();
|
|
21457
22038
|
init_is_main();
|
|
21458
22039
|
init_conflict_detector();
|
|
22040
|
+
init_runtime_hook_manifest();
|
|
21459
22041
|
if (isMainModule(import.meta.url) && (process.argv[1] ?? "").includes("exe-doctor")) {
|
|
21460
22042
|
main().catch((err) => {
|
|
21461
22043
|
console.error(err instanceof Error ? err.message : String(err));
|