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
4 changes: 2 additions & 2 deletions .claude/plugins/onebrain/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "onebrain",
"version": "3.4.11",
"version": "3.4.12",
"description": "OneBrain — Your AI Thinking Partner",
"author": {
"name": "OneBrain Contributors"
},
"license": "MIT OR Apache-2.0",
"requires": {
"cli": ">=3.4.18"
"cli": ">=3.4.25"
}
}
4 changes: 2 additions & 2 deletions .claude/plugins/onebrain/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "onebrain",
"version": "3.4.11",
"version": "3.4.12",
"description": "OneBrain — Your AI Thinking Partner",
"namespace": "onebrain",
"skills": "./skills/",
Expand All @@ -11,6 +11,6 @@
"tagline": "Your AI Thinking Partner"
},
"requires": {
"cli": ">=3.4.18"
"cli": ">=3.4.25"
}
}
40 changes: 23 additions & 17 deletions .claude/plugins/onebrain/INSTRUCTIONS.md

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions .claude/plugins/onebrain/hooks/check-cli-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
# OneBrain plugin v3 — SessionStart enforcement hook.
#
# Refuses to load the session when the `onebrain` CLI is absent or older
# than v3.1.0. Pairs with `requires.cli` in plugin.json — that field is
# metadata for tooling; this hook is the runtime enforcement. The floor is
# v3.1.0 because this plugin emits v3.1 nested commands (`session init`,
# `search reindex`, …) + the `--json` hook contract that v3.0.x can't parse.
# than v3.4.25. Pairs with `requires.cli` in plugin.json — that field is
# metadata for tooling; this hook is the runtime enforcement. The floor
# includes the cache-independent Codex hook runner and bounded startup task
# listing introduced in CLI v3.4.25.
#
# Comparison strategy: extract the bare MAJOR.MINOR.PATCH from
# `onebrain --version` (drops any prerelease suffix like -alpha.9) and
# sort against 3.1.0 with `sort -V`. v2.x Bun users and v3.0.x users are
# blocked with a clear update path.
# Comparison strategy: parse a SemVer MAJOR.MINOR.PATCH with an optional
# prerelease suffix. Compare the numeric core component-wise; a prerelease
# at the exact floor (for example 3.4.25-alpha.1) is below the required
# 3.4.25 release and is blocked. Older CLI users are blocked with a clear
# update path.
#
# Output contract: emit a JSON SessionStart payload with `decision: block`
# and a `reason` that lists the install / update paths for each platform.
# Exit 0 either way — the JSON `decision` is what Claude Code reads.

set -u

MIN_VERSION="3.1.0"
MIN_VERSION="3.4.25"

block_message() {
# Single-string JSON message; embedded newlines stay as literal "\n" in
Expand All @@ -37,11 +38,12 @@ if ! command -v onebrain >/dev/null 2>&1; then
exit 0
fi

# Extract the bare semver triple from `onebrain --version` output
# (handles `onebrain 3.0.0`, `onebrain 3.0.0-alpha.9`, or any leading text).
CURRENT_VERSION=$(onebrain --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
# Extract SemVer from `onebrain --version` output (handles `onebrain 3.0.0`,
# `onebrain 3.0.0-alpha.9`, build metadata, or leading text).
CURRENT_VERSION_RAW=$(onebrain --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?' | head -1)
CURRENT_VERSION=${CURRENT_VERSION_RAW%%[-+]*}

if [ -z "${CURRENT_VERSION}" ]; then
if [ -z "${CURRENT_VERSION_RAW}" ]; then
block_message "OneBrain plugin v3.x could not parse the \`onebrain --version\` output. Verify the CLI is on PATH and at least v${MIN_VERSION} — run \`onebrain --version\` manually to debug."
exit 0
fi
Expand All @@ -63,8 +65,8 @@ version_gte() {
return 0
}

if ! version_gte "${CURRENT_VERSION}" "${MIN_VERSION}"; then
block_message "OneBrain plugin v3.x requires CLI >= ${MIN_VERSION}, but found v${CURRENT_VERSION}.\n\nUpdate in place:\n onebrain update\n\nOr reinstall:\n • macOS: brew tap onebrain-ai/onebrain && brew upgrade onebrain (or brew install onebrain-ai/onebrain/onebrain)\n • Linux/Windows: download from https://github.com/onebrain-ai/onebrain-cli/releases/latest\n\nThen restart this session."
if ! version_gte "${CURRENT_VERSION}" "${MIN_VERSION}" || { [ "${CURRENT_VERSION}" = "${MIN_VERSION}" ] && [[ "${CURRENT_VERSION_RAW}" == "${MIN_VERSION}-"* ]]; }; then
block_message "OneBrain plugin v3.x requires CLI >= ${MIN_VERSION}, but found v${CURRENT_VERSION_RAW}.\n\nUpdate in place:\n onebrain update\n\nOr reinstall:\n • macOS: brew tap onebrain-ai/onebrain && brew upgrade onebrain (or brew install onebrain-ai/onebrain/onebrain)\n • Linux/Windows: download from https://github.com/onebrain-ai/onebrain-cli/releases/latest\n\nThen restart this session."
exit 0
fi

Expand Down
126 changes: 0 additions & 126 deletions .claude/plugins/onebrain/hooks/codex-hook.py

This file was deleted.

18 changes: 6 additions & 12 deletions .claude/plugins/onebrain/hooks/codex-hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"hooks": [
{
"type": "command",
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/codex-hook.py\" session-start",
"commandWindows": "py \"%CLAUDE_PLUGIN_ROOT%\\hooks\\codex-hook.py\" session-start",
"command": "onebrain hook || echo '{\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"OneBrain lifecycle hooks are inactive: the onebrain CLI is missing or older than 3.4.25. Run onebrain update, then start a new session.\"}}'",
"commandWindows": "onebrain hook || echo {\"hookSpecificOutput\":{\"hookEventName\":\"SessionStart\",\"additionalContext\":\"OneBrain lifecycle hooks are inactive: the onebrain CLI is missing or older than 3.4.25. Run onebrain update, then start a new session.\"}}",
"timeout": 10
}
]
Expand All @@ -19,8 +19,8 @@
"hooks": [
{
"type": "command",
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/codex-hook.py\" lex",
"commandWindows": "py \"%CLAUDE_PLUGIN_ROOT%\\hooks\\codex-hook.py\" lex",
"command": "onebrain hook || echo '{}'",
"commandWindows": "onebrain hook || echo {}",
"timeout": 10
}
]
Expand All @@ -31,14 +31,8 @@
"hooks": [
{
"type": "command",
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/codex-hook.py\" checkpoint",
"commandWindows": "py \"%CLAUDE_PLUGIN_ROOT%\\hooks\\codex-hook.py\" checkpoint",
"timeout": 10
},
{
"type": "command",
"command": "python3 \"${CLAUDE_PLUGIN_ROOT}/hooks/codex-hook.py\" pending",
"commandWindows": "py \"%CLAUDE_PLUGIN_ROOT%\\hooks\\codex-hook.py\" pending",
"command": "onebrain hook || echo '{}'",
"commandWindows": "onebrain hook || echo {}",
"timeout": 10
}
]
Expand Down
11 changes: 10 additions & 1 deletion .claude/plugins/onebrain/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"description": "OneBrain plugin v3 — SessionStart hook that refuses to load against an incompatible OneBrain CLI (< v3.0.0), pairs with `requires.cli` in plugin.json. PreToolUse hooks: (1) gates repeat Read calls on vault .md docs already sent this session (token-optimization Ledger Gate, CLI v3.4.10+, design §5b) — off by default (onebrain.yml `token_optimization.read_hook: off`), always fail-open, see INSTRUCTIONS.md \"Vault-read Ledger Gate (PreToolUse Hook)\"; (2) gates vault-content Grep calls that skip the search cascade's MCP-first step (Track C #221) — always on, always fail-open, see skills/startup/SEARCH.md \"The Cascade\".",
"description": "OneBrain plugin v3 — SessionStart lifecycle uses the shared `onebrain hook` bridge plus a version check that refuses to load against an incompatible OneBrain CLI (< v3.4.25), pairing with `requires.cli` in plugin.json. PreToolUse hooks: (1) gates repeat Read calls on vault .md docs already sent this session (token-optimization Ledger Gate, CLI v3.4.10+, design §5b) — off by default (onebrain.yml `token_optimization.read_hook: off`), always fail-open, see INSTRUCTIONS.md \"Vault-read Ledger Gate (PreToolUse Hook)\"; (2) gates vault-content Grep calls that skip the search cascade's MCP-first step (Track C #221) — always on, always fail-open, see skills/startup/SEARCH.md \"The Cascade\".",
"hooks": {
"SessionStart": [
{
Expand All @@ -10,6 +10,15 @@
"timeout": 10
}
]
},
{
"hooks": [
{
"type": "command",
"command": "onebrain hook || echo '{}'",
"timeout": 10
}
]
}
],
"PreToolUse": [
Expand Down
6 changes: 5 additions & 1 deletion .claude/plugins/onebrain/skills/pause/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ Review the current conversation since the last pause file of `active_slug` (or s

1. Today's date as `YYYY-MM-DD`.
2. Ensure directory exists: `mkdir -p [logs_folder]/pause/`
3. Get `session_token` from agent context (run `onebrain session init` to recover if missing). **If `session init` fails or returns no token:** abort the write. Do NOT proceed to Step 5. Output: `⚠️ Could not determine session token. Snapshot not saved — try again or run /doctor.`
3. Get `session_token` from agent context.
- **Claude:** if missing, recover it with the resolve-only verb — run `ONEBRAIN_HOOK_SESSION_ID="$CLAUDE_CODE_SESSION_ID" "{resolved executable}" session token --json` and read `session_token` from its JSON. Use `session token`, not `session init`, here: this is mid-session recovery, and `session init` deletes the Stop-hook cadence state file whenever it runs mid-session, while `session token` touches no state files. `ONEBRAIN_HOOK_SESSION_ID` is the resolver's top-priority layer and applies the same sha256[..16] derivation the Stop hook applies to `CLAUDE_CODE_SESSION_ID`, so the recovered value provably equals the token the Stop hook incremented.
- **Codex and Gemini:** SessionStart injects the token; if missing, do **not** run `session init` to mint a replacement — a terminal- or process-derived token could merge another chat's snapshots.

**If no token is available after applying the rule above:** abort the write. Do NOT proceed to Step 5. Output: `⚠️ Could not determine session token. Snapshot not saved — try again or run /doctor.`
4. Write to `[logs_folder]/pause/YYYY-MM-DD-{active_slug}-pause-{next_nn}.md`:

```yaml
Expand Down
10 changes: 7 additions & 3 deletions .claude/plugins/onebrain/skills/startup/AUTO-SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ Run silently (no output) if ALL of these are true:
3. The session had 3 or more user↔assistant exchanges

If conditions are met:
- Use `session_token` from context if already loaded (set by `onebrain session init` at startup); if absent, run `onebrain session init --json` and use the `SESSION_TOKEN` value. Glob checkpoint files (post-v2.4.0: checkpoints live in flat `[logs_folder]/checkpoint/` regardless of date): `[logs_folder]/checkpoint/YYYY-MM-DD-{session_token}-checkpoint-*.md`. Also yesterday's (handles cross-midnight sessions): compute yesterday's date (accounting for month/year rollover) and glob `[logs_folder]/checkpoint/YYYY-MM-DD_PREV-{session_token}-checkpoint-*.md`. **Read every file in the glob result** and fully incorporate all of their content into the session summary (not just as background context). Any checkpoint file that exists is unmerged by definition — there is no `merged:` filter. Every checkpoint must appear in the summary before it is deleted.
- Use `session_token` from context if already loaded (set by `"{resolved executable}" session init` at startup).
- **Codex and Gemini:** SessionStart injects a token derived from the complete hook `session_id`; it is the chat identity for this auto-summary. If that injected token is absent, abort auto-summary silently (checkpoint files stay in place — /wrapup recovers them at the next session start) rather than falling back to a terminal- or process-derived token, since that could merge another chat's checkpoints.
- **Claude:** if absent, recover it with the resolve-only verb — run `ONEBRAIN_HOOK_SESSION_ID="$CLAUDE_CODE_SESSION_ID" "{resolved executable}" session token --json` and use the `session_token` value. Use `session token`, not `session init`, for this mid-session recovery: `session init` deletes the Stop-hook cadence state file whenever it runs mid-session, while `session token` is resolve-only and touches no state files. `ONEBRAIN_HOOK_SESSION_ID` is the resolver's top-priority layer and applies the same sha256[..16] derivation the Stop hook applies to `CLAUDE_CODE_SESSION_ID`, so the recovered value provably equals the token the Stop hook incremented.

Glob checkpoint files (post-v2.4.0: checkpoints live in flat `[logs_folder]/checkpoint/` regardless of date): `[logs_folder]/checkpoint/YYYY-MM-DD-{session_token}-checkpoint-*.md`. Also yesterday's (handles cross-midnight sessions): compute yesterday's date (accounting for month/year rollover) and glob `[logs_folder]/checkpoint/YYYY-MM-DD_PREV-{session_token}-checkpoint-*.md`. **Read every file in the glob result** and fully incorporate all of their content into the session summary (not just as background context). Any checkpoint file that exists is unmerged by definition — there is no `merged:` filter. Every checkpoint must appear in the summary before it is deleted.
- Determine NN: count existing `[logs_folder]/session/YYYY/MM/YYYY-MM-DD-session-*.md` files for today; NN = count + 1, zero-padded to 2 digits (01, 02, …). **Verify** `YYYY-MM-DD-session-NN.md` does not already exist before writing; if it does, increment NN until a free slot is found.

- **Auto-finalize active pause thread (if any) — runs before the session log write.** Read `[logs_folder]/pause/_active.md`. If absent or empty, skip this step. If a slug is present, apply the three skip conditions from `skills/pause/SKILL.md` → Auto-Finalize section (canonical source — keep in sync):
Expand Down Expand Up @@ -41,9 +45,9 @@ If conditions are met:
- Dedup: strip `📅 YYYY-MM-DD` suffix from candidate and existing `- [ ]`/`- [x]` lines before comparing; skip if same text already exists (open or completed).
- Insert at first available point: after last `- [ ]` in `## Action Items` section (or after the `## Action Items` heading if the section exists but is empty) → or before `## Open Questions` → or before `## Related` → or at end of file.
- Write the file once. On write error, skip all tasks for this file silently and continue to the next target file.
- After confirming the session log was written, reset the checkpoint hook counter to prevent spurious post-summary checkpoints:
- After confirming the session log was written, reset the checkpoint hook counter to prevent spurious post-summary checkpoints, passing the resolved `session_token` from above (never a re-minted one):
```bash
onebrain checkpoint reset
"{resolved executable}" checkpoint reset --session-token {session_token}
```
- Delete the checkpoint files from the glob above. Guard: only delete AFTER confirming the session log file was successfully written and is non-empty. Never delete before or during the write. If an individual delete fails, skip it silently — stale checkpoints are cleaned up later by /doctor or by the next /wrapup. Do not delete checkpoint files outside this session's glob result.
- If a genuinely useful long-term insight emerged, write it to a new `memory/` file using /learn conventions: filename `[agent_folder]/memory/kebab-case-topic.md`, frontmatter `tags: [agent-memory], type: behavioral, source: auto-summary, status: active, conf: medium, verified: today, updated: today, created: today, topics: [2–4 keywords]`. Add a row to MEMORY-INDEX.md and increment `total_active`. **Do not write to MEMORY.md.**
Expand Down
Loading
Loading