@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.
- package/dist/hooks/handlers/agent-hooks.d.ts +48 -0
- package/dist/hooks/handlers/agent-hooks.d.ts.map +1 -0
- package/dist/hooks/handlers/context-hooks.d.ts +53 -0
- package/dist/hooks/handlers/context-hooks.d.ts.map +1 -0
- package/dist/hooks/handlers/error-hooks.d.ts +4 -4
- package/dist/hooks/handlers/error-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/file-hooks.d.ts +3 -3
- package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/index.d.ts +8 -1
- package/dist/hooks/handlers/index.d.ts.map +1 -1
- package/dist/hooks/handlers/mcp-hooks.d.ts +29 -7
- package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.d.ts +5 -5
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/task-hooks.d.ts +5 -5
- package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/work-capture-hooks.d.ts +7 -7
- package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -1
- package/dist/hooks/payload-schemas.d.ts +177 -11
- package/dist/hooks/payload-schemas.d.ts.map +1 -1
- package/dist/hooks/provider-hooks.d.ts +33 -7
- package/dist/hooks/provider-hooks.d.ts.map +1 -1
- package/dist/hooks/registry.d.ts +26 -6
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/types.d.ts +132 -38
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.js +335 -59
- package/dist/index.js.map +4 -4
- package/dist/sessions/snapshot.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.ts +634 -0
- package/src/hooks/handlers/agent-hooks.ts +148 -0
- package/src/hooks/handlers/context-hooks.ts +156 -0
- package/src/hooks/handlers/error-hooks.ts +8 -5
- package/src/hooks/handlers/file-hooks.ts +6 -4
- package/src/hooks/handlers/index.ts +12 -1
- package/src/hooks/handlers/mcp-hooks.ts +74 -9
- package/src/hooks/handlers/session-hooks.ts +7 -7
- package/src/hooks/handlers/task-hooks.ts +7 -7
- package/src/hooks/handlers/work-capture-hooks.ts +12 -12
- package/src/hooks/payload-schemas.ts +96 -26
- package/src/hooks/provider-hooks.ts +50 -9
- package/src/hooks/registry.ts +86 -23
- package/src/hooks/types.ts +175 -39
- package/src/sessions/index.ts +4 -4
- package/src/sessions/snapshot.ts +4 -2
- package/src/store/json.ts +2 -2
- 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
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
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: '
|
|
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
|
|
784
|
-
|
|
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(
|
|
829
|
+
this.handlers.set(resolvedEvent, list);
|
|
787
830
|
return () => {
|
|
788
|
-
const handlers = this.handlers.get(
|
|
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
|
-
*
|
|
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('
|
|
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
|
-
|
|
820
|
-
|
|
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(
|
|
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
|
-
|
|
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: {
|
|
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
|
-
|
|
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("
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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("
|
|
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("
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
39687
|
-
|
|
39688
|
-
|
|
39689
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
39745
|
-
|
|
39746
|
-
|
|
39747
|
-
|
|
39748
|
-
|
|
39749
|
-
|
|
39750
|
-
|
|
39751
|
-
|
|
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("
|
|
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("
|
|
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("
|
|
65643
|
+
await hooks2.dispatch("SessionStart", projectRoot, {
|
|
65368
65644
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
65369
65645
|
sessionId: restoredSession.id,
|
|
65370
65646
|
name: restoredSession.name,
|