@askexenow/exe-os 0.9.63 → 0.9.65
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/cli.js +70 -117
- package/dist/bin/exe-boot.js +27 -6
- package/dist/bin/exe-doctor.js +1154 -2588
- package/dist/bin/exe-link.js +27 -6
- package/dist/bin/exe-new-employee.js +1 -111
- package/dist/bin/exe-start-codex.js +1 -111
- package/dist/bin/exe-start-opencode.js +1 -125
- package/dist/bin/install.js +1 -111
- package/dist/bin/setup.js +27 -6
- package/dist/bin/stack-update.js +42 -0
- package/dist/hooks/bug-report-worker.js +42 -111
- package/dist/hooks/pre-compact.js +109 -236
- package/dist/hooks/session-end.js +122 -137
- package/dist/hooks/summary-worker.js +99 -130
- package/dist/lib/cloud-sync.js +27 -6
- package/dist/lib/exe-daemon.js +95 -387
- package/dist/mcp/server.js +32 -378
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -1893,15 +1893,6 @@ 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
|
-
});
|
|
1905
1896
|
function serializeValue(v) {
|
|
1906
1897
|
if (v === null || v === void 0) return null;
|
|
1907
1898
|
if (typeof v === "bigint") return Number(v);
|
|
@@ -1926,32 +1917,6 @@ function deserializeValue(v) {
|
|
|
1926
1917
|
}
|
|
1927
1918
|
return v;
|
|
1928
1919
|
}
|
|
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
|
-
}
|
|
1955
1920
|
function deserializeResultSet(srs) {
|
|
1956
1921
|
const rows = srs.rows.map((obj) => {
|
|
1957
1922
|
const values = srs.columns.map(
|
|
@@ -12888,78 +12853,6 @@ var init_worker_gate = __esm({
|
|
|
12888
12853
|
}
|
|
12889
12854
|
});
|
|
12890
12855
|
|
|
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
|
-
|
|
12963
12856
|
// src/lib/db-backup.ts
|
|
12964
12857
|
var db_backup_exports = {};
|
|
12965
12858
|
__export(db_backup_exports, {
|
|
@@ -18792,6 +18685,8 @@ init_database();
|
|
|
18792
18685
|
import { z as z56 } from "zod";
|
|
18793
18686
|
|
|
18794
18687
|
// src/bin/exe-doctor.ts
|
|
18688
|
+
init_store();
|
|
18689
|
+
init_database();
|
|
18795
18690
|
import os14 from "os";
|
|
18796
18691
|
|
|
18797
18692
|
// src/lib/is-main.ts
|
|
@@ -19075,140 +18970,6 @@ async function detectConflicts(client, projectFilter, agentFilter2) {
|
|
|
19075
18970
|
};
|
|
19076
18971
|
}
|
|
19077
18972
|
|
|
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
|
-
|
|
19212
18973
|
// src/bin/exe-doctor.ts
|
|
19213
18974
|
function parseFlags(argv) {
|
|
19214
18975
|
const flags = { fix: false, dryRun: false, verbose: false, conflicts: false };
|
|
@@ -19407,121 +19168,6 @@ function auditHookHealth() {
|
|
|
19407
19168
|
const topPatterns = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([pattern, count]) => ({ pattern, count }));
|
|
19408
19169
|
return { logExists: true, totalLines, errorsLastHour, topPatterns };
|
|
19409
19170
|
}
|
|
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
|
-
}
|
|
19525
19171
|
async function auditShards() {
|
|
19526
19172
|
try {
|
|
19527
19173
|
const { auditShardHealth: auditShardHealth2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
@@ -19566,8 +19212,7 @@ async function runAudit(client, flags) {
|
|
|
19566
19212
|
}
|
|
19567
19213
|
const duplicateCount = duplicates.reduce((sum, d) => sum + d.delete_ids.length, 0);
|
|
19568
19214
|
const hookHealth = auditHookHealth();
|
|
19569
|
-
|
|
19570
|
-
return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, hookOwnership, shards };
|
|
19215
|
+
return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, shards };
|
|
19571
19216
|
}
|
|
19572
19217
|
function indicator(value, warn) {
|
|
19573
19218
|
if (value === 0) return "\u{1F7E2}";
|
|
@@ -19646,15 +19291,6 @@ function formatReport(report, flags) {
|
|
|
19646
19291
|
lines.push(` ${p.count}x: ${p.pattern}`);
|
|
19647
19292
|
}
|
|
19648
19293
|
}
|
|
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
|
-
}
|
|
19658
19294
|
const sh = report.shards;
|
|
19659
19295
|
if (sh.total > 0) {
|
|
19660
19296
|
if (sh.unreadable === 0) {
|
|
@@ -19724,9 +19360,6 @@ function formatReport(report, flags) {
|
|
|
19724
19360
|
if (report.conflicts.superseded > 0) {
|
|
19725
19361
|
recs.push(`${fmtNum(report.conflicts.superseded)} superseded memories can be deactivated`);
|
|
19726
19362
|
}
|
|
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
|
-
}
|
|
19730
19363
|
if (recs.length > 0) {
|
|
19731
19364
|
lines.push("Recommendations:");
|
|
19732
19365
|
for (const r of recs) {
|
|
@@ -19860,8 +19493,8 @@ function splitAtSentences(text3, maxChunkSize) {
|
|
|
19860
19493
|
}
|
|
19861
19494
|
async function main(argv = process.argv.slice(2)) {
|
|
19862
19495
|
const flags = parseFlags(argv);
|
|
19863
|
-
|
|
19864
|
-
const client =
|
|
19496
|
+
await initStore();
|
|
19497
|
+
const client = getClient();
|
|
19865
19498
|
const report = await runAudit(client, flags);
|
|
19866
19499
|
console.log(formatReport(report, flags));
|
|
19867
19500
|
if (flags.fix || flags.dryRun) {
|
|
@@ -20142,31 +19775,43 @@ var ROSTER_LOCK_PATH = path34.join(EXE_AI_DIR, "roster-merge.lock");
|
|
|
20142
19775
|
var LOCK_STALE_MS = 3e4;
|
|
20143
19776
|
var _pgPromise = null;
|
|
20144
19777
|
var _pgFailed = false;
|
|
19778
|
+
function isTruthyEnv(value) {
|
|
19779
|
+
return /^(1|true|yes|on)$/i.test(value ?? "");
|
|
19780
|
+
}
|
|
20145
19781
|
function loadPgClient() {
|
|
20146
19782
|
if (_pgFailed) return null;
|
|
20147
|
-
const postgresUrl = process.env.DATABASE_URL;
|
|
20148
19783
|
const configPath = path34.join(EXE_AI_DIR, "config.json");
|
|
20149
19784
|
let cloudPostgresUrl;
|
|
19785
|
+
let configEnabled = false;
|
|
20150
19786
|
try {
|
|
20151
19787
|
if (existsSync29(configPath)) {
|
|
20152
19788
|
const cfg = JSON.parse(readFileSync22(configPath, "utf8"));
|
|
20153
19789
|
cloudPostgresUrl = cfg.cloud?.postgresUrl;
|
|
20154
|
-
|
|
20155
|
-
_pgFailed = true;
|
|
20156
|
-
return null;
|
|
20157
|
-
}
|
|
19790
|
+
configEnabled = cfg.cloud?.syncToPostgres === true;
|
|
20158
19791
|
}
|
|
20159
19792
|
} catch {
|
|
20160
19793
|
}
|
|
20161
|
-
const
|
|
19794
|
+
const envEnabled = isTruthyEnv(process.env.EXE_CLOUD_SYNC_TO_POSTGRES);
|
|
19795
|
+
if (!envEnabled && !configEnabled) {
|
|
19796
|
+
return null;
|
|
19797
|
+
}
|
|
19798
|
+
const url = process.env.DATABASE_URL || cloudPostgresUrl;
|
|
20162
19799
|
if (!url) {
|
|
20163
19800
|
_pgFailed = true;
|
|
20164
19801
|
return null;
|
|
20165
19802
|
}
|
|
20166
19803
|
if (!_pgPromise) {
|
|
20167
19804
|
_pgPromise = (async () => {
|
|
19805
|
+
if (!process.env.DATABASE_URL) process.env.DATABASE_URL = url;
|
|
20168
19806
|
const { createRequire: createRequire6 } = await import("module");
|
|
20169
19807
|
const { pathToFileURL: pathToFileURL6 } = await import("url");
|
|
19808
|
+
const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
|
|
19809
|
+
if (explicitPath) {
|
|
19810
|
+
const mod2 = await import(pathToFileURL6(explicitPath).href);
|
|
19811
|
+
const Ctor2 = mod2.PrismaClient ?? mod2.default?.PrismaClient;
|
|
19812
|
+
if (!Ctor2) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
19813
|
+
return new Ctor2();
|
|
19814
|
+
}
|
|
20170
19815
|
const exeDbRoot = process.env.EXE_DB_ROOT ?? path34.join(homedir6(), "exe-db");
|
|
20171
19816
|
const req = createRequire6(path34.join(exeDbRoot, "package.json"));
|
|
20172
19817
|
const entry = req.resolve("@prisma/client");
|
|
@@ -20363,6 +20008,15 @@ async function cloudSync(config2) {
|
|
|
20363
20008
|
} catch {
|
|
20364
20009
|
throw new Error("[cloud-sync] Database not initialized. Call initStore() before cloudSync().");
|
|
20365
20010
|
}
|
|
20011
|
+
try {
|
|
20012
|
+
const relink = await client.execute("SELECT value FROM sync_meta WHERE key = 'cloud_relink_required' LIMIT 1");
|
|
20013
|
+
if (String(relink.rows[0]?.value ?? "") === "1") {
|
|
20014
|
+
throw new Error("[cloud-sync] Paused after key rotation. Re-link/reupload cloud sync with the new recovery phrase before syncing.");
|
|
20015
|
+
}
|
|
20016
|
+
} catch (err) {
|
|
20017
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
20018
|
+
if (msg.includes("Paused after key rotation")) throw err;
|
|
20019
|
+
}
|
|
20366
20020
|
try {
|
|
20367
20021
|
const { getRawClient: getRawClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
20368
20022
|
await getRawClient2().execute("PRAGMA wal_checkpoint(PASSIVE)");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.65",
|
|
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",
|