Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/brains/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "brains",
"description": "Your memory layer: Gmail, Calendar, Drive, and prior Claude conversations as queryable pages, with reflexive recall, hook-driven turn-by-turn capture and inbox delivery, and boards/automations/workflows on top.",
"version": "2.8.1",
"version": "2.8.2",
"author": {
"name": "brains (ssvlabs)"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/brains/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "brains",
"version": "2.8.1",
"version": "2.8.2",
"description": "Your personal memory layer for Codex: query Gmail, Calendar, Drive, and prior conversations, then build boards, automations, and workflows.",
"author": {
"name": "brains (ssvlabs)",
Expand Down
2 changes: 1 addition & 1 deletion plugins/brains/hooks/claude-hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume|clear|compact",
"matcher": "startup|resume|clear|compact|fork",
"hooks": [
{
"type": "command",
Expand Down
11 changes: 10 additions & 1 deletion tests/plugin-contract/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ type HookGroup = {
const CLAUDE_HOOK_EVENTS: Record<string, HookGroup[]> = {
SessionStart: [
{
matcher: "startup|resume|clear|compact",
matcher: "startup|resume|clear|compact|fork",
hooks: [
{
type: "command",
Expand Down Expand Up @@ -986,6 +986,15 @@ for (const [label, source, expected] of [
// would reject adding them but would report it as a set mismatch; these say why.
assert(!codexEvents.includes("PostToolUseFailure"), "Codex does not support PostToolUseFailure");
assert(!codexEvents.includes("SessionEnd"), "Codex does not support SessionEnd");
// Not a claim about Codex at runtime — a CONFIGURATION pin recording why the two SessionStart
// matchers above differ, so the asymmetry reads as deliberate rather than as drift. Codex declares
// four SessionStart sources and no `fork` (codex-rs/hooks/src/events/session_start.rs); a forked
// Codex thread arrives as `startup` or `resume` depending on the fork path, and both are already
// matched. `fork` is Claude vocabulary only.
assert(
!(codexHooks.hooks.SessionStart[0].matcher ?? "").split("|").includes("fork"),
"Codex declares no fork SessionStart source — a forked Codex thread arrives as startup or resume, so `fork` here would pin a value Codex never emits",
);

for (const command of [...hookScripts(claudeHooks), ...hookScripts(codexHooks)]) {
const match = command.match(/hooks\/(brains-[a-z-]+\.sh)/);
Expand Down
Loading