@askexenow/exe-os 0.9.59 → 0.9.60

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 CHANGED
@@ -31309,11 +31309,11 @@ export const ExeOsPlugin = async ({ project, directory }) => {
31309
31309
  permission_mode: "dangerously-skip-permissions",
31310
31310
  };
31311
31311
 
31312
- // Fire-and-forget ingestion (spawns detached worker internally)
31313
- fireHook("ingest.js", payload);
31314
-
31315
- // Error recall \u2014 blocking, returns context if error detected
31316
- const result = await runHook("error-recall.js", payload, 5000);
31312
+ // Combined hook: runs memory ingestion + error recall in the same
31313
+ // orchestrator used by Claude Code and Codex. This prevents duplicate
31314
+ // PostToolUse pipelines and keeps error-recall output formatting in one
31315
+ // place.
31316
+ const result = await runHook("post-tool-combined.js", payload, 10000);
31317
31317
  if (result?.hookSpecificOutput?.additionalContext) {
31318
31318
  return result.hookSpecificOutput.additionalContext;
31319
31319
  }
@@ -31432,6 +31432,13 @@ function verifyOpenCodeHooks(homeDir = os19.homedir()) {
31432
31432
  return false;
31433
31433
  }
31434
31434
  if (!existsSync32(pluginPath)) return false;
31435
+ try {
31436
+ const plugin = readFileSync28(pluginPath, "utf-8");
31437
+ if (!plugin.includes("post-tool-combined.js")) return false;
31438
+ if (plugin.includes('fireHook("ingest.js"') || plugin.includes('runHook("error-recall.js"')) return false;
31439
+ } catch {
31440
+ return false;
31441
+ }
31435
31442
  return true;
31436
31443
  }
31437
31444
  async function runOpenCodeInstaller(homeDir) {
@@ -31559,6 +31566,18 @@ async function mergeCodexHooks(packageRoot, homeDir = os20.homedir()) {
31559
31566
  ];
31560
31567
  let added = 0;
31561
31568
  let skipped = 0;
31569
+ const legacyPostToolMarkers = [
31570
+ "dist/hooks/ingest.js",
31571
+ "dist/hooks/error-recall.js",
31572
+ "dist/hooks/ingest-worker.js"
31573
+ ];
31574
+ const postToolGroups = hooksJson.hooks["PostToolUse"];
31575
+ if (Array.isArray(postToolGroups)) {
31576
+ hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
31577
+ ...g,
31578
+ hooks: g.hooks.filter((h) => !legacyPostToolMarkers.some((marker) => h.command.includes(marker)))
31579
+ })).filter((g) => g.hooks.length > 0);
31580
+ }
31562
31581
  for (const { event, group, marker } of hooksToRegister) {
31563
31582
  if (!hooksJson.hooks[event]) {
31564
31583
  hooksJson.hooks[event] = [];
@@ -31598,6 +31617,15 @@ function verifyCodexHooks(homeDir = os20.homedir()) {
31598
31617
  return false;
31599
31618
  }
31600
31619
  }
31620
+ const postToolCommands = (hooksJson.hooks.PostToolUse ?? []).flatMap((g) => g.hooks.map((h) => h.command));
31621
+ if (!postToolCommands.some((cmd) => cmd.includes("dist/hooks/post-tool-combined.js"))) {
31622
+ return false;
31623
+ }
31624
+ if (postToolCommands.some(
31625
+ (cmd) => cmd.includes("dist/hooks/ingest.js") || cmd.includes("dist/hooks/error-recall.js") || cmd.includes("dist/hooks/ingest-worker.js")
31626
+ )) {
31627
+ return false;
31628
+ }
31601
31629
  return true;
31602
31630
  } catch {
31603
31631
  return false;
@@ -3823,6 +3823,18 @@ async function mergeCodexHooks(packageRoot, homeDir = os10.homedir()) {
3823
3823
  ];
3824
3824
  let added = 0;
3825
3825
  let skipped = 0;
3826
+ const legacyPostToolMarkers = [
3827
+ "dist/hooks/ingest.js",
3828
+ "dist/hooks/error-recall.js",
3829
+ "dist/hooks/ingest-worker.js"
3830
+ ];
3831
+ const postToolGroups = hooksJson.hooks["PostToolUse"];
3832
+ if (Array.isArray(postToolGroups)) {
3833
+ hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
3834
+ ...g,
3835
+ hooks: g.hooks.filter((h) => !legacyPostToolMarkers.some((marker) => h.command.includes(marker)))
3836
+ })).filter((g) => g.hooks.length > 0);
3837
+ }
3826
3838
  for (const { event, group, marker } of hooksToRegister) {
3827
3839
  if (!hooksJson.hooks[event]) {
3828
3840
  hooksJson.hooks[event] = [];
@@ -3862,6 +3874,15 @@ function verifyCodexHooks(homeDir = os10.homedir()) {
3862
3874
  return false;
3863
3875
  }
3864
3876
  }
3877
+ const postToolCommands = (hooksJson.hooks.PostToolUse ?? []).flatMap((g) => g.hooks.map((h) => h.command));
3878
+ if (!postToolCommands.some((cmd) => cmd.includes("dist/hooks/post-tool-combined.js"))) {
3879
+ return false;
3880
+ }
3881
+ if (postToolCommands.some(
3882
+ (cmd) => cmd.includes("dist/hooks/ingest.js") || cmd.includes("dist/hooks/error-recall.js") || cmd.includes("dist/hooks/ingest-worker.js")
3883
+ )) {
3884
+ return false;
3885
+ }
3865
3886
  return true;
3866
3887
  } catch {
3867
3888
  return false;
@@ -3840,11 +3840,11 @@ export const ExeOsPlugin = async ({ project, directory }) => {
3840
3840
  permission_mode: "dangerously-skip-permissions",
3841
3841
  };
3842
3842
 
3843
- // Fire-and-forget ingestion (spawns detached worker internally)
3844
- fireHook("ingest.js", payload);
3845
-
3846
- // Error recall \u2014 blocking, returns context if error detected
3847
- const result = await runHook("error-recall.js", payload, 5000);
3843
+ // Combined hook: runs memory ingestion + error recall in the same
3844
+ // orchestrator used by Claude Code and Codex. This prevents duplicate
3845
+ // PostToolUse pipelines and keeps error-recall output formatting in one
3846
+ // place.
3847
+ const result = await runHook("post-tool-combined.js", payload, 10000);
3848
3848
  if (result?.hookSpecificOutput?.additionalContext) {
3849
3849
  return result.hookSpecificOutput.additionalContext;
3850
3850
  }
@@ -3963,6 +3963,13 @@ function verifyOpenCodeHooks(homeDir = os10.homedir()) {
3963
3963
  return false;
3964
3964
  }
3965
3965
  if (!existsSync12(pluginPath)) return false;
3966
+ try {
3967
+ const plugin = readFileSync8(pluginPath, "utf-8");
3968
+ if (!plugin.includes("post-tool-combined.js")) return false;
3969
+ if (plugin.includes('fireHook("ingest.js"') || plugin.includes('runHook("error-recall.js"')) return false;
3970
+ } catch {
3971
+ return false;
3972
+ }
3966
3973
  return true;
3967
3974
  }
3968
3975
  async function runOpenCodeInstaller(homeDir) {
@@ -1665,6 +1665,18 @@ async function mergeCodexHooks(packageRoot, homeDir = os6.homedir()) {
1665
1665
  ];
1666
1666
  let added = 0;
1667
1667
  let skipped = 0;
1668
+ const legacyPostToolMarkers = [
1669
+ "dist/hooks/ingest.js",
1670
+ "dist/hooks/error-recall.js",
1671
+ "dist/hooks/ingest-worker.js"
1672
+ ];
1673
+ const postToolGroups = hooksJson.hooks["PostToolUse"];
1674
+ if (Array.isArray(postToolGroups)) {
1675
+ hooksJson.hooks["PostToolUse"] = postToolGroups.map((g) => ({
1676
+ ...g,
1677
+ hooks: g.hooks.filter((h) => !legacyPostToolMarkers.some((marker) => h.command.includes(marker)))
1678
+ })).filter((g) => g.hooks.length > 0);
1679
+ }
1668
1680
  for (const { event, group, marker } of hooksToRegister) {
1669
1681
  if (!hooksJson.hooks[event]) {
1670
1682
  hooksJson.hooks[event] = [];
@@ -1704,6 +1716,15 @@ function verifyCodexHooks(homeDir = os6.homedir()) {
1704
1716
  return false;
1705
1717
  }
1706
1718
  }
1719
+ const postToolCommands = (hooksJson.hooks.PostToolUse ?? []).flatMap((g) => g.hooks.map((h) => h.command));
1720
+ if (!postToolCommands.some((cmd) => cmd.includes("dist/hooks/post-tool-combined.js"))) {
1721
+ return false;
1722
+ }
1723
+ if (postToolCommands.some(
1724
+ (cmd) => cmd.includes("dist/hooks/ingest.js") || cmd.includes("dist/hooks/error-recall.js") || cmd.includes("dist/hooks/ingest-worker.js")
1725
+ )) {
1726
+ return false;
1727
+ }
1707
1728
  return true;
1708
1729
  } catch {
1709
1730
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.59",
3
+ "version": "0.9.60",
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",