@cleocode/core 2026.3.72 → 2026.3.73

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.
Files changed (48) hide show
  1. package/dist/hooks/handlers/agent-hooks.d.ts +48 -0
  2. package/dist/hooks/handlers/agent-hooks.d.ts.map +1 -0
  3. package/dist/hooks/handlers/context-hooks.d.ts +53 -0
  4. package/dist/hooks/handlers/context-hooks.d.ts.map +1 -0
  5. package/dist/hooks/handlers/error-hooks.d.ts +4 -4
  6. package/dist/hooks/handlers/error-hooks.d.ts.map +1 -1
  7. package/dist/hooks/handlers/file-hooks.d.ts +3 -3
  8. package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
  9. package/dist/hooks/handlers/index.d.ts +8 -1
  10. package/dist/hooks/handlers/index.d.ts.map +1 -1
  11. package/dist/hooks/handlers/mcp-hooks.d.ts +29 -7
  12. package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
  13. package/dist/hooks/handlers/session-hooks.d.ts +5 -5
  14. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  15. package/dist/hooks/handlers/task-hooks.d.ts +5 -5
  16. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  17. package/dist/hooks/handlers/work-capture-hooks.d.ts +7 -7
  18. package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -1
  19. package/dist/hooks/payload-schemas.d.ts +177 -11
  20. package/dist/hooks/payload-schemas.d.ts.map +1 -1
  21. package/dist/hooks/provider-hooks.d.ts +33 -7
  22. package/dist/hooks/provider-hooks.d.ts.map +1 -1
  23. package/dist/hooks/registry.d.ts +26 -6
  24. package/dist/hooks/registry.d.ts.map +1 -1
  25. package/dist/hooks/types.d.ts +132 -38
  26. package/dist/hooks/types.d.ts.map +1 -1
  27. package/dist/index.js +335 -59
  28. package/dist/index.js.map +4 -4
  29. package/dist/sessions/snapshot.d.ts.map +1 -1
  30. package/package.json +6 -6
  31. package/src/hooks/handlers/__tests__/hook-automation-e2e.test.ts +634 -0
  32. package/src/hooks/handlers/agent-hooks.ts +148 -0
  33. package/src/hooks/handlers/context-hooks.ts +156 -0
  34. package/src/hooks/handlers/error-hooks.ts +8 -5
  35. package/src/hooks/handlers/file-hooks.ts +6 -4
  36. package/src/hooks/handlers/index.ts +12 -1
  37. package/src/hooks/handlers/mcp-hooks.ts +74 -9
  38. package/src/hooks/handlers/session-hooks.ts +7 -7
  39. package/src/hooks/handlers/task-hooks.ts +7 -7
  40. package/src/hooks/handlers/work-capture-hooks.ts +12 -12
  41. package/src/hooks/payload-schemas.ts +96 -26
  42. package/src/hooks/provider-hooks.ts +50 -9
  43. package/src/hooks/registry.ts +86 -23
  44. package/src/hooks/types.ts +175 -39
  45. package/src/sessions/index.ts +4 -4
  46. package/src/sessions/snapshot.ts +4 -2
  47. package/src/store/json.ts +2 -2
  48. package/src/task-work/index.ts +4 -4
package/dist/index.js CHANGED
@@ -732,22 +732,42 @@ __export(registry_exports, {
732
732
  HookRegistry: () => HookRegistry,
733
733
  hooks: () => hooks
734
734
  });
735
- var DEFAULT_HOOK_CONFIG, HookRegistry, hooks;
735
+ var LEGACY_EVENT_MAP, DEFAULT_HOOK_CONFIG, HookRegistry, hooks;
736
736
  var init_registry = __esm({
737
737
  "packages/core/src/hooks/registry.ts"() {
738
738
  "use strict";
739
739
  init_logger();
740
+ LEGACY_EVENT_MAP = {
741
+ onSessionStart: "SessionStart",
742
+ onSessionEnd: "SessionEnd",
743
+ onToolStart: "PreToolUse",
744
+ onToolComplete: "PostToolUse",
745
+ onFileChange: "Notification",
746
+ onError: "PostToolUseFailure",
747
+ onPromptSubmit: "PromptSubmit",
748
+ onResponseComplete: "ResponseComplete"
749
+ };
740
750
  DEFAULT_HOOK_CONFIG = {
741
751
  enabled: true,
742
752
  events: {
743
- onSessionStart: true,
744
- onSessionEnd: true,
745
- onToolStart: true,
746
- onToolComplete: true,
747
- onFileChange: true,
748
- onError: true,
749
- onPromptSubmit: true,
750
- onResponseComplete: true,
753
+ // CAAMP canonical events (16)
754
+ SessionStart: true,
755
+ SessionEnd: true,
756
+ PromptSubmit: true,
757
+ ResponseComplete: true,
758
+ PreToolUse: true,
759
+ PostToolUse: true,
760
+ PostToolUseFailure: true,
761
+ PermissionRequest: true,
762
+ SubagentStart: true,
763
+ SubagentStop: true,
764
+ PreModel: true,
765
+ PostModel: true,
766
+ PreCompact: true,
767
+ PostCompact: true,
768
+ Notification: true,
769
+ ConfigChange: true,
770
+ // CLEO internal coordination events (5)
751
771
  onWorkAvailable: true,
752
772
  onAgentSpawn: true,
753
773
  onAgentComplete: true,
@@ -758,12 +778,33 @@ var init_registry = __esm({
758
778
  HookRegistry = class {
759
779
  handlers = /* @__PURE__ */ new Map();
760
780
  config = DEFAULT_HOOK_CONFIG;
781
+ /**
782
+ * Resolve a potentially-legacy event name to its canonical equivalent.
783
+ *
784
+ * If the event name matches a known legacy `on`-prefix name, it is
785
+ * remapped and a deprecation warning is logged. Unknown names pass through
786
+ * unchanged so callers using the new canonical names are unaffected.
787
+ */
788
+ resolveEvent(event) {
789
+ const canonical = LEGACY_EVENT_MAP[event];
790
+ if (canonical) {
791
+ getLogger("hooks").warn(
792
+ { legacyEvent: event, canonicalEvent: canonical },
793
+ `[DEPRECATED] Hook event '${event}' has been renamed to '${canonical}'. Update your handler registration.`
794
+ );
795
+ return canonical;
796
+ }
797
+ return event;
798
+ }
761
799
  /**
762
800
  * Register a hook handler for a specific event.
763
801
  *
764
802
  * Handlers are sorted by priority (highest first) and executed
765
803
  * in parallel when the event is dispatched.
766
804
  *
805
+ * Backward compatibility: legacy `on`-prefix event names are automatically
806
+ * remapped to their canonical equivalents.
807
+ *
767
808
  * @param registration - The hook registration containing event, handler, priority, and ID
768
809
  * @returns A function to unregister the handler
769
810
  *
@@ -771,7 +812,7 @@ var init_registry = __esm({
771
812
  * ```typescript
772
813
  * const unregister = hooks.register({
773
814
  * id: 'my-handler',
774
- * event: 'onSessionStart',
815
+ * event: 'SessionStart',
775
816
  * handler: async (root, payload) => { console.log('Session started'); },
776
817
  * priority: 100
777
818
  * });
@@ -780,12 +821,14 @@ var init_registry = __esm({
780
821
  * ```
781
822
  */
782
823
  register(registration) {
783
- const list = this.handlers.get(registration.event) || [];
784
- list.push(registration);
824
+ const resolvedEvent = this.resolveEvent(registration.event);
825
+ const resolvedRegistration = { ...registration, event: resolvedEvent };
826
+ const list = this.handlers.get(resolvedEvent) || [];
827
+ list.push(resolvedRegistration);
785
828
  list.sort((a, b) => b.priority - a.priority);
786
- this.handlers.set(registration.event, list);
829
+ this.handlers.set(resolvedEvent, list);
787
830
  return () => {
788
- const handlers = this.handlers.get(registration.event);
831
+ const handlers = this.handlers.get(resolvedEvent);
789
832
  if (handlers) {
790
833
  const idx = handlers.findIndex((h) => h.id === registration.id);
791
834
  if (idx !== -1) handlers.splice(idx, 1);
@@ -799,14 +842,17 @@ var init_registry = __esm({
799
842
  * execution. Errors in individual handlers are logged but do not block
800
843
  * other handlers or propagate to the caller.
801
844
  *
802
- * @param event - The CAAMP hook event to dispatch
845
+ * Backward compatibility: legacy `on`-prefix event names are automatically
846
+ * remapped to their canonical equivalents.
847
+ *
848
+ * @param event - The CAAMP canonical hook event to dispatch
803
849
  * @param projectRoot - The project root directory path
804
850
  * @param payload - The event payload (typed by event)
805
851
  * @returns Promise that resolves when all handlers have completed
806
852
  *
807
853
  * @example
808
854
  * ```typescript
809
- * await hooks.dispatch('onSessionStart', '/project', {
855
+ * await hooks.dispatch('SessionStart', '/project', {
810
856
  * timestamp: new Date().toISOString(),
811
857
  * sessionId: 'sess-123',
812
858
  * name: 'My Session',
@@ -816,15 +862,19 @@ var init_registry = __esm({
816
862
  */
817
863
  async dispatch(event, projectRoot, payload) {
818
864
  if (!this.config.enabled) return;
819
- if (!this.config.events[event]) return;
820
- const handlers = this.handlers.get(event);
865
+ const resolvedEvent = this.resolveEvent(event);
866
+ if (!this.config.events[resolvedEvent]) return;
867
+ const handlers = this.handlers.get(resolvedEvent);
821
868
  if (!handlers || handlers.length === 0) return;
822
869
  await Promise.allSettled(
823
870
  handlers.map(async (reg) => {
824
871
  try {
825
872
  await reg.handler(projectRoot, payload);
826
873
  } catch (error40) {
827
- getLogger("hooks").warn({ err: error40, hookId: reg.id, event }, "Hook handler failed");
874
+ getLogger("hooks").warn(
875
+ { err: error40, hookId: reg.id, event: resolvedEvent },
876
+ "Hook handler failed"
877
+ );
828
878
  }
829
879
  })
830
880
  );
@@ -833,12 +883,14 @@ var init_registry = __esm({
833
883
  * Check if a specific event is currently enabled.
834
884
  *
835
885
  * Both the global enabled flag and the per-event flag must be true.
886
+ * Automatically resolves legacy `on`-prefix event names.
836
887
  *
837
888
  * @param event - The CAAMP hook event to check
838
889
  * @returns True if the event is enabled
839
890
  */
840
891
  isEnabled(event) {
841
- return this.config.enabled && this.config.events[event];
892
+ const resolvedEvent = this.resolveEvent(event);
893
+ return this.config.enabled && this.config.events[resolvedEvent];
842
894
  }
843
895
  /**
844
896
  * Update the hook system configuration.
@@ -850,7 +902,7 @@ var init_registry = __esm({
850
902
  * @example
851
903
  * ```typescript
852
904
  * hooks.setConfig({ enabled: false }); // Disable all hooks
853
- * hooks.setConfig({ events: { onError: false } }); // Disable specific event
905
+ * hooks.setConfig({ events: { PostToolUseFailure: false } }); // Disable specific event
854
906
  * ```
855
907
  */
856
908
  setConfig(config2) {
@@ -868,12 +920,14 @@ var init_registry = __esm({
868
920
  * List all registered handlers for a specific event.
869
921
  *
870
922
  * Returns handlers in priority order (highest first).
923
+ * Automatically resolves legacy `on`-prefix event names.
871
924
  *
872
925
  * @param event - The CAAMP hook event
873
926
  * @returns Array of hook registrations
874
927
  */
875
928
  listHandlers(event) {
876
- return [...this.handlers.get(event) || []];
929
+ const resolvedEvent = this.resolveEvent(event);
930
+ return [...this.handlers.get(resolvedEvent) || []];
877
931
  }
878
932
  };
879
933
  hooks = new HookRegistry();
@@ -13584,7 +13638,7 @@ async function saveJson(filePath, data, options) {
13584
13638
  }
13585
13639
  await atomicWriteJson(filePath, data, { indent: options?.indent });
13586
13640
  Promise.resolve().then(() => (init_registry(), registry_exports)).then(
13587
- ({ hooks: h }) => h.dispatch("onFileChange", process.cwd(), {
13641
+ ({ hooks: h }) => h.dispatch("Notification", process.cwd(), {
13588
13642
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
13589
13643
  filePath,
13590
13644
  changeType: "write"
@@ -18379,13 +18433,13 @@ var init_session_hooks = __esm({
18379
18433
  init_memory_bridge_refresh();
18380
18434
  hooks.register({
18381
18435
  id: "brain-session-start",
18382
- event: "onSessionStart",
18436
+ event: "SessionStart",
18383
18437
  handler: handleSessionStart,
18384
18438
  priority: 100
18385
18439
  });
18386
18440
  hooks.register({
18387
18441
  id: "brain-session-end",
18388
- event: "onSessionEnd",
18442
+ event: "SessionEnd",
18389
18443
  handler: handleSessionEnd,
18390
18444
  priority: 100
18391
18445
  });
@@ -18432,13 +18486,13 @@ var init_task_hooks = __esm({
18432
18486
  init_memory_bridge_refresh();
18433
18487
  hooks.register({
18434
18488
  id: "brain-tool-start",
18435
- event: "onToolStart",
18489
+ event: "PreToolUse",
18436
18490
  handler: handleToolStart,
18437
18491
  priority: 100
18438
18492
  });
18439
18493
  hooks.register({
18440
18494
  id: "brain-tool-complete",
18441
- event: "onToolComplete",
18495
+ event: "PostToolUse",
18442
18496
  handler: handleToolComplete,
18443
18497
  priority: 100
18444
18498
  });
@@ -18468,7 +18522,7 @@ var init_error_hooks = __esm({
18468
18522
  init_registry();
18469
18523
  hooks.register({
18470
18524
  id: "brain-error",
18471
- event: "onError",
18525
+ event: "PostToolUseFailure",
18472
18526
  handler: handleError,
18473
18527
  priority: 100
18474
18528
  });
@@ -18499,6 +18553,7 @@ async function isFileCaptureEnabled(projectRoot) {
18499
18553
  }
18500
18554
  }
18501
18555
  async function handleFileChange(projectRoot, payload) {
18556
+ if (!payload.filePath || !payload.changeType) return;
18502
18557
  if (!await isFileCaptureEnabled(projectRoot)) return;
18503
18558
  const now = Date.now();
18504
18559
  const lastWrite = recentWrites.get(payload.filePath);
@@ -18545,7 +18600,7 @@ var init_file_hooks = __esm({
18545
18600
  ];
18546
18601
  hooks.register({
18547
18602
  id: "brain-file-change",
18548
- event: "onFileChange",
18603
+ event: "Notification",
18549
18604
  handler: handleFileChange,
18550
18605
  priority: 100
18551
18606
  });
@@ -18599,22 +18654,51 @@ async function handleResponseComplete(projectRoot, payload) {
18599
18654
  if (!isMissingBrainSchemaError4(err)) throw err;
18600
18655
  }
18601
18656
  }
18657
+ async function handleSystemNotification(projectRoot, payload) {
18658
+ if (payload.filePath || payload.changeType) return;
18659
+ if (!payload.message) return;
18660
+ try {
18661
+ const { loadConfig: loadConfig3 } = await Promise.resolve().then(() => (init_config(), config_exports));
18662
+ const config2 = await loadConfig3(projectRoot);
18663
+ if (!config2.brain?.autoCapture) return;
18664
+ } catch {
18665
+ return;
18666
+ }
18667
+ const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
18668
+ try {
18669
+ await observeBrain2(projectRoot, {
18670
+ text: `System notification: ${payload.message}`,
18671
+ title: `Notification: ${payload.message.slice(0, 60)}`,
18672
+ type: "discovery",
18673
+ sourceSessionId: payload.sessionId,
18674
+ sourceType: "agent"
18675
+ });
18676
+ } catch (err) {
18677
+ if (!isMissingBrainSchemaError4(err)) throw err;
18678
+ }
18679
+ }
18602
18680
  var init_mcp_hooks = __esm({
18603
18681
  "packages/core/src/hooks/handlers/mcp-hooks.ts"() {
18604
18682
  "use strict";
18605
18683
  init_registry();
18606
18684
  hooks.register({
18607
18685
  id: "brain-prompt-submit",
18608
- event: "onPromptSubmit",
18686
+ event: "PromptSubmit",
18609
18687
  handler: handlePromptSubmit,
18610
18688
  priority: 100
18611
18689
  });
18612
18690
  hooks.register({
18613
18691
  id: "brain-response-complete",
18614
- event: "onResponseComplete",
18692
+ event: "ResponseComplete",
18615
18693
  handler: handleResponseComplete,
18616
18694
  priority: 100
18617
18695
  });
18696
+ hooks.register({
18697
+ id: "brain-system-notification",
18698
+ event: "Notification",
18699
+ handler: handleSystemNotification,
18700
+ priority: 90
18701
+ });
18618
18702
  }
18619
18703
  });
18620
18704
 
@@ -18691,19 +18775,158 @@ var init_work_capture_hooks = __esm({
18691
18775
  ]);
18692
18776
  hooks.register({
18693
18777
  id: "work-capture-prompt-submit",
18694
- event: "onPromptSubmit",
18778
+ event: "PromptSubmit",
18695
18779
  handler: handleWorkPromptSubmit,
18696
18780
  priority: 90
18697
18781
  });
18698
18782
  hooks.register({
18699
18783
  id: "work-capture-response-complete",
18700
- event: "onResponseComplete",
18784
+ event: "ResponseComplete",
18701
18785
  handler: handleWorkResponseComplete,
18702
18786
  priority: 90
18703
18787
  });
18704
18788
  }
18705
18789
  });
18706
18790
 
18791
+ // packages/core/src/hooks/handlers/agent-hooks.ts
18792
+ function isMissingBrainSchemaError6(err) {
18793
+ if (!(err instanceof Error)) return false;
18794
+ const message = String(err.message || "").toLowerCase();
18795
+ return message.includes("no such table") && message.includes("brain_");
18796
+ }
18797
+ async function isAutoCaptureEnabled(projectRoot) {
18798
+ try {
18799
+ const { loadConfig: loadConfig3 } = await Promise.resolve().then(() => (init_config(), config_exports));
18800
+ const config2 = await loadConfig3(projectRoot);
18801
+ return config2.brain?.autoCapture ?? false;
18802
+ } catch {
18803
+ return false;
18804
+ }
18805
+ }
18806
+ async function handleSubagentStart(projectRoot, payload) {
18807
+ if (!await isAutoCaptureEnabled(projectRoot)) return;
18808
+ const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
18809
+ const rolePart = payload.role ? ` role=${payload.role}` : "";
18810
+ const taskPart = payload.taskId ? ` task=${payload.taskId}` : "";
18811
+ try {
18812
+ await observeBrain2(projectRoot, {
18813
+ text: `Subagent spawned: ${payload.agentId}${rolePart}${taskPart}`,
18814
+ title: `Subagent start: ${payload.agentId}`,
18815
+ type: "discovery",
18816
+ sourceSessionId: payload.sessionId,
18817
+ sourceType: "agent"
18818
+ });
18819
+ } catch (err) {
18820
+ if (!isMissingBrainSchemaError6(err)) throw err;
18821
+ }
18822
+ }
18823
+ async function handleSubagentStop(projectRoot, payload) {
18824
+ if (!await isAutoCaptureEnabled(projectRoot)) return;
18825
+ const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
18826
+ const statusPart = payload.status ? ` status=${payload.status}` : "";
18827
+ const taskPart = payload.taskId ? ` task=${payload.taskId}` : "";
18828
+ const summaryPart = payload.summary ? `
18829
+ Summary: ${payload.summary}` : "";
18830
+ try {
18831
+ await observeBrain2(projectRoot, {
18832
+ text: `Subagent completed: ${payload.agentId}${statusPart}${taskPart}${summaryPart}`,
18833
+ title: `Subagent stop: ${payload.agentId}`,
18834
+ type: "change",
18835
+ sourceSessionId: payload.sessionId,
18836
+ sourceType: "agent"
18837
+ });
18838
+ } catch (err) {
18839
+ if (!isMissingBrainSchemaError6(err)) throw err;
18840
+ }
18841
+ }
18842
+ var init_agent_hooks = __esm({
18843
+ "packages/core/src/hooks/handlers/agent-hooks.ts"() {
18844
+ "use strict";
18845
+ init_registry();
18846
+ hooks.register({
18847
+ id: "brain-subagent-start",
18848
+ event: "SubagentStart",
18849
+ handler: handleSubagentStart,
18850
+ priority: 100
18851
+ });
18852
+ hooks.register({
18853
+ id: "brain-subagent-stop",
18854
+ event: "SubagentStop",
18855
+ handler: handleSubagentStop,
18856
+ priority: 100
18857
+ });
18858
+ }
18859
+ });
18860
+
18861
+ // packages/core/src/hooks/handlers/context-hooks.ts
18862
+ function isMissingBrainSchemaError7(err) {
18863
+ if (!(err instanceof Error)) return false;
18864
+ const message = String(err.message || "").toLowerCase();
18865
+ return message.includes("no such table") && message.includes("brain_");
18866
+ }
18867
+ async function isAutoCaptureEnabled2(projectRoot) {
18868
+ try {
18869
+ const { loadConfig: loadConfig3 } = await Promise.resolve().then(() => (init_config(), config_exports));
18870
+ const config2 = await loadConfig3(projectRoot);
18871
+ return config2.brain?.autoCapture ?? false;
18872
+ } catch {
18873
+ return false;
18874
+ }
18875
+ }
18876
+ async function handlePreCompact(projectRoot, payload) {
18877
+ if (!await isAutoCaptureEnabled2(projectRoot)) return;
18878
+ const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
18879
+ const tokensPart = payload.tokensBefore != null ? ` (~${payload.tokensBefore.toLocaleString()} tokens)` : "";
18880
+ const reasonPart = payload.reason ? ` Reason: ${payload.reason}` : "";
18881
+ try {
18882
+ await observeBrain2(projectRoot, {
18883
+ text: `Context compaction about to begin${tokensPart}.${reasonPart}`,
18884
+ title: "Pre-compaction context snapshot",
18885
+ type: "discovery",
18886
+ sourceSessionId: payload.sessionId,
18887
+ sourceType: "agent"
18888
+ });
18889
+ } catch (err) {
18890
+ if (!isMissingBrainSchemaError7(err)) throw err;
18891
+ }
18892
+ }
18893
+ async function handlePostCompact(projectRoot, payload) {
18894
+ if (!await isAutoCaptureEnabled2(projectRoot)) return;
18895
+ const { observeBrain: observeBrain2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
18896
+ const statusPart = payload.success ? "succeeded" : "failed";
18897
+ const beforePart = payload.tokensBefore != null ? ` before=${payload.tokensBefore.toLocaleString()}` : "";
18898
+ const afterPart = payload.tokensAfter != null ? ` after=${payload.tokensAfter.toLocaleString()}` : "";
18899
+ try {
18900
+ await observeBrain2(projectRoot, {
18901
+ text: `Context compaction ${statusPart}${beforePart}${afterPart}`,
18902
+ title: "Post-compaction record",
18903
+ type: "change",
18904
+ sourceSessionId: payload.sessionId,
18905
+ sourceType: "agent"
18906
+ });
18907
+ } catch (err) {
18908
+ if (!isMissingBrainSchemaError7(err)) throw err;
18909
+ }
18910
+ }
18911
+ var init_context_hooks = __esm({
18912
+ "packages/core/src/hooks/handlers/context-hooks.ts"() {
18913
+ "use strict";
18914
+ init_registry();
18915
+ hooks.register({
18916
+ id: "brain-pre-compact",
18917
+ event: "PreCompact",
18918
+ handler: handlePreCompact,
18919
+ priority: 100
18920
+ });
18921
+ hooks.register({
18922
+ id: "brain-post-compact",
18923
+ event: "PostCompact",
18924
+ handler: handlePostCompact,
18925
+ priority: 100
18926
+ });
18927
+ }
18928
+ });
18929
+
18707
18930
  // packages/core/src/hooks/handlers/index.ts
18708
18931
  var init_handlers = __esm({
18709
18932
  "packages/core/src/hooks/handlers/index.ts"() {
@@ -18714,6 +18937,10 @@ var init_handlers = __esm({
18714
18937
  init_file_hooks();
18715
18938
  init_mcp_hooks();
18716
18939
  init_work_capture_hooks();
18940
+ init_agent_hooks();
18941
+ init_context_hooks();
18942
+ init_agent_hooks();
18943
+ init_context_hooks();
18717
18944
  init_error_hooks();
18718
18945
  init_file_hooks();
18719
18946
  init_mcp_hooks();
@@ -20564,7 +20791,7 @@ async function startSession(options, cwd, accessor) {
20564
20791
  });
20565
20792
  }
20566
20793
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
20567
- hooks2.dispatch("onSessionStart", cwd ?? process.cwd(), {
20794
+ hooks2.dispatch("SessionStart", cwd ?? process.cwd(), {
20568
20795
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
20569
20796
  sessionId: session.id,
20570
20797
  name: options.name,
@@ -20602,7 +20829,7 @@ async function endSession(options = {}, cwd, accessor) {
20602
20829
  session.endedAt = (/* @__PURE__ */ new Date()).toISOString();
20603
20830
  const duration3 = Math.floor((Date.now() - new Date(session.startedAt).getTime()) / 1e3);
20604
20831
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
20605
- hooks2.dispatch("onSessionEnd", cwd ?? process.cwd(), {
20832
+ hooks2.dispatch("SessionEnd", cwd ?? process.cwd(), {
20606
20833
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
20607
20834
  sessionId: session.id,
20608
20835
  duration: duration3,
@@ -28502,10 +28729,15 @@ __export(hooks_exports, {
28502
28729
  OnWorkAvailablePayloadSchema: () => OnWorkAvailablePayloadSchema,
28503
28730
  handleError: () => handleError,
28504
28731
  handleFileChange: () => handleFileChange,
28732
+ handlePostCompact: () => handlePostCompact,
28733
+ handlePreCompact: () => handlePreCompact,
28505
28734
  handlePromptSubmit: () => handlePromptSubmit,
28506
28735
  handleResponseComplete: () => handleResponseComplete,
28507
28736
  handleSessionEnd: () => handleSessionEnd,
28508
28737
  handleSessionStart: () => handleSessionStart,
28738
+ handleSubagentStart: () => handleSubagentStart,
28739
+ handleSubagentStop: () => handleSubagentStop,
28740
+ handleSystemNotification: () => handleSystemNotification,
28509
28741
  handleToolComplete: () => handleToolComplete,
28510
28742
  handleToolStart: () => handleToolStart,
28511
28743
  handleWorkPromptSubmit: () => handleWorkPromptSubmit,
@@ -39662,33 +39894,42 @@ var HookPayloadSchema = external_exports.object({
39662
39894
  providerId: external_exports.string().optional(),
39663
39895
  metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
39664
39896
  });
39665
- var OnSessionStartPayloadSchema = HookPayloadSchema.extend({
39897
+ var SessionStartPayloadSchema = HookPayloadSchema.extend({
39666
39898
  sessionId: external_exports.string(),
39667
39899
  name: external_exports.string(),
39668
39900
  scope: external_exports.string(),
39669
39901
  agent: external_exports.string().optional()
39670
39902
  });
39671
- var OnSessionEndPayloadSchema = HookPayloadSchema.extend({
39903
+ var OnSessionStartPayloadSchema = SessionStartPayloadSchema;
39904
+ var SessionEndPayloadSchema = HookPayloadSchema.extend({
39672
39905
  sessionId: external_exports.string(),
39673
39906
  duration: external_exports.number(),
39674
39907
  tasksCompleted: external_exports.array(external_exports.string())
39675
39908
  });
39676
- var OnToolStartPayloadSchema = HookPayloadSchema.extend({
39909
+ var OnSessionEndPayloadSchema = SessionEndPayloadSchema;
39910
+ var PreToolUsePayloadSchema = HookPayloadSchema.extend({
39677
39911
  taskId: external_exports.string(),
39678
39912
  taskTitle: external_exports.string(),
39679
- previousTask: external_exports.string().optional()
39913
+ previousTask: external_exports.string().optional(),
39914
+ toolName: external_exports.string().optional(),
39915
+ toolInput: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
39680
39916
  });
39681
- var OnToolCompletePayloadSchema = HookPayloadSchema.extend({
39917
+ var OnToolStartPayloadSchema = PreToolUsePayloadSchema;
39918
+ var PostToolUsePayloadSchema = HookPayloadSchema.extend({
39682
39919
  taskId: external_exports.string(),
39683
39920
  taskTitle: external_exports.string(),
39684
- status: external_exports.enum(["done", "archived", "cancelled"])
39921
+ status: external_exports.enum(["done", "archived", "cancelled"]),
39922
+ toolResult: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
39685
39923
  });
39686
- var OnFileChangePayloadSchema = HookPayloadSchema.extend({
39687
- filePath: external_exports.string(),
39688
- changeType: external_exports.enum(["write", "create", "delete"]),
39689
- sizeBytes: external_exports.number().optional()
39924
+ var OnToolCompletePayloadSchema = PostToolUsePayloadSchema;
39925
+ var NotificationPayloadSchema = HookPayloadSchema.extend({
39926
+ filePath: external_exports.string().optional(),
39927
+ changeType: external_exports.enum(["write", "create", "delete"]).optional(),
39928
+ sizeBytes: external_exports.number().optional(),
39929
+ message: external_exports.string().optional()
39690
39930
  });
39691
- var OnErrorPayloadSchema = HookPayloadSchema.extend({
39931
+ var OnFileChangePayloadSchema = NotificationPayloadSchema;
39932
+ var PostToolUseFailurePayloadSchema = HookPayloadSchema.extend({
39692
39933
  errorCode: external_exports.union([external_exports.number(), external_exports.string()]),
39693
39934
  message: external_exports.string(),
39694
39935
  domain: external_exports.string().optional(),
@@ -39696,13 +39937,15 @@ var OnErrorPayloadSchema = HookPayloadSchema.extend({
39696
39937
  gateway: external_exports.string().optional(),
39697
39938
  stack: external_exports.string().optional()
39698
39939
  });
39699
- var OnPromptSubmitPayloadSchema = HookPayloadSchema.extend({
39940
+ var OnErrorPayloadSchema = PostToolUseFailurePayloadSchema;
39941
+ var PromptSubmitPayloadSchema = HookPayloadSchema.extend({
39700
39942
  gateway: external_exports.string(),
39701
39943
  domain: external_exports.string(),
39702
39944
  operation: external_exports.string(),
39703
39945
  source: external_exports.string().optional()
39704
39946
  });
39705
- var OnResponseCompletePayloadSchema = HookPayloadSchema.extend({
39947
+ var OnPromptSubmitPayloadSchema = PromptSubmitPayloadSchema;
39948
+ var ResponseCompletePayloadSchema = HookPayloadSchema.extend({
39706
39949
  gateway: external_exports.string(),
39707
39950
  domain: external_exports.string(),
39708
39951
  operation: external_exports.string(),
@@ -39710,6 +39953,32 @@ var OnResponseCompletePayloadSchema = HookPayloadSchema.extend({
39710
39953
  durationMs: external_exports.number().optional(),
39711
39954
  errorCode: external_exports.string().optional()
39712
39955
  });
39956
+ var OnResponseCompletePayloadSchema = ResponseCompletePayloadSchema;
39957
+ var SubagentStartPayloadSchema = HookPayloadSchema.extend({
39958
+ agentId: external_exports.string(),
39959
+ role: external_exports.string().optional(),
39960
+ taskId: external_exports.string().optional()
39961
+ });
39962
+ var SubagentStopPayloadSchema = HookPayloadSchema.extend({
39963
+ agentId: external_exports.string(),
39964
+ status: external_exports.enum(["complete", "partial", "blocked", "failed"]).optional(),
39965
+ taskId: external_exports.string().optional(),
39966
+ summary: external_exports.string().optional()
39967
+ });
39968
+ var PreCompactPayloadSchema = HookPayloadSchema.extend({
39969
+ tokensBefore: external_exports.number().optional(),
39970
+ reason: external_exports.string().optional()
39971
+ });
39972
+ var PostCompactPayloadSchema = HookPayloadSchema.extend({
39973
+ tokensBefore: external_exports.number().optional(),
39974
+ tokensAfter: external_exports.number().optional(),
39975
+ success: external_exports.boolean()
39976
+ });
39977
+ var ConfigChangePayloadSchema = HookPayloadSchema.extend({
39978
+ key: external_exports.string(),
39979
+ previousValue: external_exports.unknown().optional(),
39980
+ newValue: external_exports.unknown().optional()
39981
+ });
39713
39982
  var OnWorkAvailablePayloadSchema = HookPayloadSchema.extend({
39714
39983
  taskIds: external_exports.array(external_exports.string()),
39715
39984
  epicId: external_exports.string().optional(),
@@ -39741,14 +40010,21 @@ var OnPatrolPayloadSchema = HookPayloadSchema.extend({
39741
40010
  scope: external_exports.string().optional()
39742
40011
  });
39743
40012
  var EVENT_SCHEMA_MAP = {
39744
- onSessionStart: OnSessionStartPayloadSchema,
39745
- onSessionEnd: OnSessionEndPayloadSchema,
39746
- onToolStart: OnToolStartPayloadSchema,
39747
- onToolComplete: OnToolCompletePayloadSchema,
39748
- onFileChange: OnFileChangePayloadSchema,
39749
- onError: OnErrorPayloadSchema,
39750
- onPromptSubmit: OnPromptSubmitPayloadSchema,
39751
- onResponseComplete: OnResponseCompletePayloadSchema,
40013
+ // CAAMP canonical events (16)
40014
+ SessionStart: SessionStartPayloadSchema,
40015
+ SessionEnd: SessionEndPayloadSchema,
40016
+ PreToolUse: PreToolUsePayloadSchema,
40017
+ PostToolUse: PostToolUsePayloadSchema,
40018
+ Notification: NotificationPayloadSchema,
40019
+ PostToolUseFailure: PostToolUseFailurePayloadSchema,
40020
+ PromptSubmit: PromptSubmitPayloadSchema,
40021
+ ResponseComplete: ResponseCompletePayloadSchema,
40022
+ SubagentStart: SubagentStartPayloadSchema,
40023
+ SubagentStop: SubagentStopPayloadSchema,
40024
+ PreCompact: PreCompactPayloadSchema,
40025
+ PostCompact: PostCompactPayloadSchema,
40026
+ ConfigChange: ConfigChangePayloadSchema,
40027
+ // CLEO internal coordination events (5)
39752
40028
  onWorkAvailable: OnWorkAvailablePayloadSchema,
39753
40029
  onAgentSpawn: OnAgentSpawnPayloadSchema,
39754
40030
  onAgentComplete: OnAgentCompletePayloadSchema,
@@ -60620,7 +60896,7 @@ async function startTask(taskId, cwd, accessor) {
60620
60896
  accessor
60621
60897
  );
60622
60898
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
60623
- hooks2.dispatch("onToolStart", cwd ?? process.cwd(), {
60899
+ hooks2.dispatch("PreToolUse", cwd ?? process.cwd(), {
60624
60900
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
60625
60901
  taskId,
60626
60902
  taskTitle: task.title
@@ -60646,7 +60922,7 @@ async function stopTask(cwd, accessor) {
60646
60922
  const now = (/* @__PURE__ */ new Date()).toISOString();
60647
60923
  if (taskId && task) {
60648
60924
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
60649
- hooks2.dispatch("onToolComplete", cwd ?? process.cwd(), {
60925
+ hooks2.dispatch("PostToolUse", cwd ?? process.cwd(), {
60650
60926
  timestamp: now,
60651
60927
  taskId,
60652
60928
  taskTitle: task.title,
@@ -65364,7 +65640,7 @@ async function restoreSession(projectRoot, snapshot, options = {}, accessor) {
65364
65640
  await acc.upsertSingleSession(restoredSession);
65365
65641
  try {
65366
65642
  const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
65367
- await hooks2.dispatch("onSessionStart", projectRoot, {
65643
+ await hooks2.dispatch("SessionStart", projectRoot, {
65368
65644
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
65369
65645
  sessionId: restoredSession.id,
65370
65646
  name: restoredSession.name,