@askexenow/exe-os 0.9.62 → 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.
@@ -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(
@@ -12853,6 +12888,78 @@ var init_worker_gate = __esm({
12853
12888
  }
12854
12889
  });
12855
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
+
12856
12963
  // src/lib/db-backup.ts
12857
12964
  var db_backup_exports = {};
12858
12965
  __export(db_backup_exports, {
@@ -18685,8 +18792,6 @@ init_database();
18685
18792
  import { z as z56 } from "zod";
18686
18793
 
18687
18794
  // src/bin/exe-doctor.ts
18688
- init_store();
18689
- init_database();
18690
18795
  import os14 from "os";
18691
18796
 
18692
18797
  // src/lib/is-main.ts
@@ -18970,6 +19075,140 @@ async function detectConflicts(client, projectFilter, agentFilter2) {
18970
19075
  };
18971
19076
  }
18972
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
+
18973
19212
  // src/bin/exe-doctor.ts
18974
19213
  function parseFlags(argv) {
18975
19214
  const flags = { fix: false, dryRun: false, verbose: false, conflicts: false };
@@ -19168,6 +19407,121 @@ function auditHookHealth() {
19168
19407
  const topPatterns = [...patternCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([pattern, count]) => ({ pattern, count }));
19169
19408
  return { logExists: true, totalLines, errorsLastHour, topPatterns };
19170
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
+ }
19171
19525
  async function auditShards() {
19172
19526
  try {
19173
19527
  const { auditShardHealth: auditShardHealth2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
@@ -19212,7 +19566,8 @@ async function runAudit(client, flags) {
19212
19566
  }
19213
19567
  const duplicateCount = duplicates.reduce((sum, d) => sum + d.delete_ids.length, 0);
19214
19568
  const hookHealth = auditHookHealth();
19215
- return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, shards };
19569
+ const hookOwnership = auditHookOwnership();
19570
+ return { stats, nullVectors, duplicates, duplicateCount, bloated, fts, orphanedProjects, conflicts, hookHealth, hookOwnership, shards };
19216
19571
  }
19217
19572
  function indicator(value, warn) {
19218
19573
  if (value === 0) return "\u{1F7E2}";
@@ -19291,6 +19646,15 @@ function formatReport(report, flags) {
19291
19646
  lines.push(` ${p.count}x: ${p.pattern}`);
19292
19647
  }
19293
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
+ }
19294
19658
  const sh = report.shards;
19295
19659
  if (sh.total > 0) {
19296
19660
  if (sh.unreadable === 0) {
@@ -19360,6 +19724,9 @@ function formatReport(report, flags) {
19360
19724
  if (report.conflicts.superseded > 0) {
19361
19725
  recs.push(`${fmtNum(report.conflicts.superseded)} superseded memories can be deactivated`);
19362
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
+ }
19363
19730
  if (recs.length > 0) {
19364
19731
  lines.push("Recommendations:");
19365
19732
  for (const r of recs) {
@@ -19493,8 +19860,8 @@ function splitAtSentences(text3, maxChunkSize) {
19493
19860
  }
19494
19861
  async function main(argv = process.argv.slice(2)) {
19495
19862
  const flags = parseFlags(argv);
19496
- await initStore();
19497
- const client = getClient();
19863
+ const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
19864
+ const client = await fastDbInit2();
19498
19865
  const report = await runAudit(client, flags);
19499
19866
  console.log(formatReport(report, flags));
19500
19867
  if (flags.fix || flags.dryRun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.62",
3
+ "version": "0.9.63",
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",