ADHD-friendly AI responses for Claude Code, Codex, and Cursor: answer first, numbered steps, no filler, calibrated to how you personally process text.
Built for people with ADHD, and for anyone who wants a direct answer over padded prose.
It changes response shape β never what the assistant tells you to do, and never its coding behavior.
/plugin marketplace add thgMatajs/squirrel-mode/plugin install squirrel@squirrel-modeβ the install summary tells you whether the plugin is already active (Plugin is now active.) or needs/reload-pluginsfirst (Run /reload-plugins to activate.).- Start a new session. The base rules load as an output style with
force-for-plugin: trueβ no/configstep β and a new session is the one thing this repo can promise makes that happen.
Testing a local checkout instead of the marketplace: claude --plugin-dir /path/to/squirrel-mode.
First message, fresh install: with no profile yet, squirrel-mode suggests /squirrel:init
once, in one line, then waits β it never starts the interview on its own.
Checking it's active: run /config β squirrel-mode should show as the current output style.
If it doesn't, run /clear or start a new session; the style loads at session start, not
mid-conversation, so editing rules first is the wrong place to look.
Keeping it updated: auto-update is off by default for third-party marketplaces like this
one, so an install stays on whatever version it first fetched. Turn it on once: /plugin, then the
Marketplaces tab, then squirrel-mode, then Enable auto-update. Claude Code checks after
session start and tells you to run /reload-plugins when a newer version lands; the session you
are in keeps the version it launched with. To update by hand instead, run claude plugin update squirrel@squirrel-mode and restart, or /plugin marketplace update squirrel-mode to refresh only
the catalog. This is worth doing rather than tracking a version number yourself: v0.4.0 closed a
path-traversal in the hook that auto-approves checkpoint writes, and an install left on v0.3.2
keeps that hole with nothing to signal it is there. A --plugin-dir checkout needs none of this β
it reads the directory live, so it is always whatever you last saved.
Uninstalling: see Privacy and what it writes below.
Run Codex at least once first β it creates ~/.codex on first run, and the installer needs that
directory to exist. Then clone this repository; the installer reads its sources from a checkout.
git clone https://github.com/thgMatajs/squirrel-mode
cd squirrel-mode
targets/codex/install.sh # dry run - shows what would change
targets/codex/install.sh --yes # actually installAdds a delimited block to ~/.codex/AGENTS.md and four skills under ~/.agents/skills/. Dry-run
by default, POSIX sh, never touches a project repository. targets/codex/install.sh --uninstall
reverses it, on the same dry-run-by-default terms. Full detail, and what Codex loses
compared to Claude Code, in docs/OTHER-TOOLS.md.
Open Cursor at least once first β it creates ~/.cursor on first run, and the installer needs that
directory to exist. Then clone this repository; the installer reads its sources from a checkout.
git clone https://github.com/thgMatajs/squirrel-mode
cd squirrel-mode
targets/cursor/install.sh # dry run
targets/cursor/install.sh --yes # actually installAdds ~/.cursor/rules/squirrel-mode.mdc (the always-on base rules) and two Cursor Agent Skills at
~/.cursor/skills/squirrel-digest/SKILL.md and ~/.cursor/skills/squirrel-plan/SKILL.md, invoked as
/squirrel-digest and /squirrel-plan in every project on the machine.
targets/cursor/install.sh --uninstall removes all three again, on the same dry-run-by-default
terms. Cursor's project-scoped /digest and /plan commands are a separate mechanism and still have
to be copied into a project's own .cursor/commands/ if you want them there too β
docs/OTHER-TOOLS.md has the two file paths.
| Command | What it does |
|---|---|
/squirrel:init |
Runs the seven-question calibration interview and writes your profile. |
/squirrel:tune |
Changes one profile field without repeating the interview. |
/squirrel:digest |
Restructures a rambling ticket, email, pasted note, file, or Jira issue into a fixed TL;DR, Next action, Breakdown, Priority, and Open questions / blockers brief; --for-reply adds a copy-paste reply. |
/squirrel:plan |
Converges a messy idea dump into a scoped plan with one first action and a parking lot for tangents. |
/squirrel:pickup |
Shows recent wins, what you were doing, the next action, and open decisions from this project's checkpoint, then stops. |
/squirrel:off |
Turns the base rules off for the rest of the current session. |
/squirrel:on |
Turns them back on in the current session. |
/squirrel:rules |
Pulls the base rules into the current conversation by hand. A recovery path only β see below. |
/squirrel:stash |
Records one durable memory β a correction, a decision, a bug and its fix β in your cross-project hoard. Costs one permission prompt: the memory write itself is auto-approved, but the date command that stamps it is a Bash call, and this plugin registers no hook that runs on one. |
/squirrel:dig |
Searches that hoard and shows ranked titles, then fetches only the one you open; --all also searches superseded memories. Costs one permission prompt for the search and a second for that same date stamp when you open a memory β both Bash calls, for the same reason. |
All ten exist on Claude Code. Codex gets digest, plan, init, and tune. Cursor gets
digest and plan only β see the parity table below for why. On Cursor they are /squirrel-digest
and /squirrel-plan: Cursor has no command namespace, so the prefix is part of the name.
/squirrel:rules is a recovery path, not part of the normal flow. The base rules are already in
the system prompt on every turn, carried by the forced output style
(ADR-0001) β so there is normally nothing to load. This
command exists for the case where that style has been turned off and you want the rules back in one
conversation without turning it on again. Typed while the style is still active, it loads a second
copy of the same ~12 KB of rules and tells Claude nothing it did not already have. It never fires on
its own: disable-model-invocation: true stops Claude from reaching for it, so it runs only when you
type it.
| Target | Always-on rules | Commands | Auto profile injection | Auto checkpoints | Hoard |
|---|---|---|---|---|---|
| Claude Code | output style, force-for-plugin |
10 namespaced skills | SessionStart hook |
PreToolUse hook |
stash + dig |
| Codex | ~/.codex/AGENTS.md global layer |
4 in ~/.agents/skills/<name>/SKILL.md |
instructed file read only, best-effort | no | no |
| Cursor | ~/.cursor/rules/*.mdc, alwaysApply: true |
2 in ~/.cursor/skills/squirrel-<name>/SKILL.md, machine-wide, explicit invocation only |
no | no | no |
The hoard's own files are plain markdown under ~/.squirrel/, so any target can read them; what
Codex and Cursor lack is the two commands, which is what this phase ships and only for Claude Code.
Porting them is not a copy: both name the Write and Read tools explicitly because those are what
Claude Code's auto-approval covers, and a Codex or Cursor variant has neither that tool nor that
auto-approval, so those sentences have to be rewritten rather than carried across.
Codex and Cursor have no lifecycle hooks, so neither gets automatic checkpoints, session-scoped
off/on, or profile reinjection after a tune β a change elsewhere can leave their view stale until
their own cadence re-reads the file. Claude Code isolates concurrent sessions (one checkpoint file
per session, token-bound off/on) and reinjects an updated profile on the next prompt; see
ADR-0006. Neither Codex nor Cursor can run the
calibration interview at all, so the question of the model starting it unprompted does not arise
there. Codex has no disable-model-invocation equivalent of any kind; Cursor's Agent Skills do
support it, and squirrel-mode sets it on both skills it installs, so /squirrel-digest and
/squirrel-plan never fire on their own. All three targets read the same
~/.squirrel/profile.md, so one calibration run β /squirrel:init in Claude Code, or asking Codex
in plain language to run squirrel init β calibrates every target on that machine. Full breakdown β
which commands port and why, what each target loses β in
docs/OTHER-TOOLS.md.
10 of the 16 base rules trace to a specific research finding, verified against its own source and tagged by the population it was actually measured in. The other 6 rules are stated design decisions β product and ergonomic choices, not empirical claims β named as such in docs/RESEARCH.md, which is also the full evidence base and citation policy.
Four of the findings:
- Working memory holds only a handful of items at once and drops old ones when new information
arrives.
general working memoryβ numbered steps, one concept per paragraph, a capped list length. - Adolescents and young adults with ADHD show a sharper drop in working-memory accuracy as
demands increase than neurotypical peers do.
ADHDβ never more than one decision offered per answer by default β tunable viaoptions_per_answer. - Software engineers with ADHD report losing track of what they were doing after an interruption.
ADHDβ automatic checkpoints and/squirrel:pickupmake resuming cost seconds instead of a full reconstruction. - Separately, higher ADHD-symptom scores in a non-clinical sample were associated with stronger
recall of negative material than positive.
ADHDβ the Done log opens with recent wins first, on purpose, rather than leaving that to happen on its own.
Nothing here restates a finding beyond what its own citation actually supports β see docs/RESEARCH.md's "Corrections" section for what got cut when a citation didn't hold up.
No network calls. No telemetry. Every script squirrel-mode ships is plain POSIX sh or Markdown.
The Claude Code plugin's runtime writes to exactly one place β ~/.squirrel/ β and, inside it, to
exactly six kinds of file:
profile.mdβ your calibration, written by/squirrel:initand edited by/squirrel:tune.checkpoints/<slug>/<session-id>.mdβ one checkpoint file per session (ADR-0006).off/PENDING.<token>,off/CLEAR.<token>, andoff/<session-id>β the sentinels/squirrel:offand/squirrel:onleave for the next prompt's hook to claim, and the flag a claimedPENDINGbecomes. The hook consumes each sentinel as it claims it; claiming aCLEARremoves the flag too.profile-seen/<session-id>β an empty marker whose timestamp is all that matters: it is how a session knows whether it has already been shown the currentprofile.md, and it is what makes a/squirrel:tunein one session reach the others.prune-cursorβ one line naming the last project directory the checkpoint sweep below looked at, so the next session start resumes where it stopped instead of always restarting at the same place. Nothing reads it but the sweep, and losing it costs nothing.hoard/global/<id>.md,hoard/projects/<slug>/<id>.mdβ durable memories. One file per memory./squirrel:stashwrites them,/squirrel:digreads them, and both also edit memories that already exist, which is the part of this that is easiest to miss. Opening a memory through/squirrel:digadds 1 to itsusesand sets itslast_usedto now, so a memory you keep consulting holds its rank and one nobody opens sinks on its own. Only your opening one counts; appearing in a result list does not. And when a fact changes,/squirrel:stashwrites the new memory and then setsstatus: supersededandsuperseded_by:on the old one. Neither path ever rewrites a title or a body, and neither deletes anything: the superseded version stays on disk and is still findable with/squirrel:dig --all. A memory goes toprojects/<slug>/only when this session injected a checkpoint path that qualifies; otherwise it goes toglobal/, and/squirrel:stashsays which in its one-line confirmation. These are the only files squirrel-mode writes that are meant to outlive the project they were written in.
Installs from before this location moved have their data at an older path instead β see the note at the end of this section; squirrel-mode detects that and tells you, once per session, rather than moving it for you.
Your profile.md is quoted back into the model's context, and one class of line is marked when it
is. squirrel-mode appends its own lines after that quoted text β the checkpoint path, the hoard
search command, the session off-token β and a line of yours that COULD otherwise begin exactly the
way one of those does gets [profile] put in front of it before the model sees it, so it cannot be
read as squirrel-mode's own (ADR-0008). Nothing is deleted
and nothing is reworded: the marker exists only in the injected copy, and the file on disk stays
byte for byte what /squirrel:init and /squirrel:tune wrote.
It also deletes, on its own, at session start. The prunes all run in scripts/load-profile.sh,
and only there β never on an ordinary message:
- Off/on sentinels older than 7 days, and
profile-seenmarkers older than 7 days. Both are per-session scraps that are worthless once their session ends; 7 days is a deliberately generous cushion so no realistically long-lived session loses its own live one. - Checkpoint files, on a much narrower rule, because losing one loses work you cannot get back: a file is deleted only if it is both older than 30 days and not among the 10 most recently modified checkpoints for that project. However long a project lies untouched, its ten newest checkpoints always survive. At most 100 candidates are examined per session start, so a huge directory cannot stall the hook.
- The same checkpoint rule, applied to every project rather than only the one you are opening.
Otherwise a project you stop working on keeps every checkpoint it ever had, forever, and
~/.squirrel/checkpoints/grows without bound across abandoned projects. The count that matters is always within one project: ten newest per project, never ten newest overall, so a rarely touched project never loses its memory because a busy one has newer files. This sweep is deliberately bounded β it looks at no more than 100 project directories and spends no more than 200 filesystem probes per session start (measured worst case on a Mac: under a second, against tens of milliseconds for an ordinary machine), and it resumes where it left off next time rather than starting over, so every project is reached within a few sessions without any one session start doing all the work. - Project directories under
checkpoints/that are completely empty, which is the other half of the same growth: one directory per project you ever opened, kept forever. Only genuinely empty directories are removed, and never one that still holds a checkpoint.
Memories are never pruned. Nothing under hoard/ is deleted by squirrel-mode, on any schedule,
at any age. Losing a memory loses something that cannot be reconstructed, and a memory that has lost
its relevance already stops appearing in results by its own score β which is reversible, and deletion
is not.
Search reads every memory file on each run, with no index. Measured on the author's machine, a
query costs about 44 ms at 500 memories, 79 ms at 1000, and 155 ms at 2000. Re-measured
independently on that machine, those totals hold β 42, 81 and 159 ms β but the split this paragraph
used to publish does not. At the 2000-memory size the awk pass over every file's frontmatter is
about half of the run, not the 71% the old 110-of-155 figure implied; most of the rest is the shell
enumerating the files and checking them one stat at a time.
That half is the whole of what survived re-measurement, and a finer breakdown has been withdrawn
rather than corrected. A per-phase split used to be published here. It was taken against a fixture
whose path length was never written down, and path length is exactly the parameter
scripts/hoard-search.sh already records as moving its own timings by a large factor β the same 2000
files cost 14.67 s under paths of 176 bytes and 24.08 s under paths of 292. Without that number
stated, nobody else can reproduce a split, so none is claimed. And even the half is a fact about one
machine's toolchain rather than about the design: swapping in a different awk on the same fixture
moves it far enough in both directions to change whether that pass is most of a search or a minority
of it. docs/specs/2026-08-13-hoard-design.md Β§5.1 carries
the method, and says which figures it stands behind and which it withdrew.
The cost of a search did not start out this low. The same query cost 12.08 s at 2000 until the list of
files handed to awk stopped being assembled one file at a time: appending a file to that list
rebuilds the whole list, so building it cost O(nΒ²) rather than O(n). Assembling each layer's files in
one step instead took that phase from 12.05 s to 42 ms and left the results byte-identical. Three
sizes on one machine say where the cost sits at those sizes, not how far it goes; if search ever
starts to feel slow, these are the numbers to compare against.
Nothing else in ~/.squirrel/ is ever deleted by squirrel-mode, and profile.md never is.
The Codex and Cursor installers are a separate, one-time step: they write to the per-target
directories already listed above (~/.codex/AGENTS.md, ~/.agents/skills/, ~/.cursor/rules/,
~/.cursor/skills/).
Nothing, on any target, is ever written inside a project repository.
/plugin uninstall squirrel@squirrel-mode removes the Claude Code plugin.
Uninstalling β or reinstalling β leaves ~/.squirrel/ alone: your profile and checkpoints
survive independently of the plugin's install state
(ADR-0003). That is a statement about install
state, not about the session-start pruning above, which keeps running for as long as the plugin is
installed.
One exception to the normal permission flow: a PreToolUse hook auto-approves the plugin's own
reads and writes inside ~/.squirrel/checkpoints/ β both the read a checkpoint interaction
starts with (/squirrel:pickup, and rule 14's own update path checking what is already logged) and
the write that follows it β so neither one is meant to interrupt the task to ask for permission.
Each is still a tool call like any other and shows up in the transcript the same way every other
tool call does β what's skipped is the permission prompt and any commentary about it in the
response, not the read or write itself.
That guarantee is exactly as wide as the hook's matcher, and every instruction that touches a
checkpoint now names a tool the matcher covers. The matcher is Write|Edit|Read: three exact tool
names, not a pattern that also catches things containing them. A checkpoint read or write made with
one of those three skips the prompt. hooks/hooks.json registers this plugin's PreToolUse hook for
those three names and nothing else, so no hook of this plugin's is ever invoked for a Bash call and
none of them can auto-approve one β a checkpoint written with a heredoc instead goes through the
normal permission flow, a prompt, in an interactive session.
That is this plugin's own configuration, and not a limit of Claude Code. A PreToolUse hook may
match Bash and may answer permissionDecision: "allow"; squirrel-mode declines to register one,
because auto-approving Bash means approving a tool whose argument is an arbitrary command string,
while everything that makes this hook defensible rests on normalising one field,
tool_input.file_path, against one directory this plugin owns
(ADR-0002). Every prompt count on this page follows from
that choice rather than from something Claude Code makes impossible.
/squirrel:pickup names the Read tool explicitly; the base
rule that keeps a checkpoint current names the Read and Write tools and rules out a shell command
in as many words. Neither is worded tool-agnostically any more.
That is an instruction, not enforcement, and the difference is worth stating. The matcher decides
which tool calls are auto-approved, never which tool gets called: nothing in the harness stops a model
from reaching for a Bash heredoc against the checkpoint anyway, and this plugin has registered no
hook that would run on it if it did. What has been watched live is the tool-agnostic wording, not this one β /squirrel:init,
/squirrel:tune, /squirrel:off and /squirrel:on still say "write" or "create" without naming a
tool, and a live run recorded the model reaching for a Bash heredoc first there, then retrying with
Write and saying so in one line (docs/ACCEPTANCE.md, Live-sweep finding 3 β observed on those
four, never on the checkpoint rule itself). Should a checkpoint write ever go that way, the cost is
the same as it was there: one permission prompt and one extra line of report, not a lost checkpoint.
The auto-approval decides about the path as a name, at the moment the hook is asked, and it
refuses two shapes rather than approving them. The first is a symlink: a symlink at
checkpoints/ itself, or anywhere below it, is never auto-approved β that write falls back to the
normal permission prompt instead of being silently redirected through the symlink.
The second is a hard link, and it is the reason the sentence above says name rather than resolves
inside that directory, which is how this paragraph used to put it. An existing file inside
checkpoints/ that some other name also points at is never auto-approved either β for any tool,
Read included β even though nothing about its own path leads anywhere else.
ln ~/.ssh/id_rsa ~/.squirrel/checkpoints/proj/x.md gives a private key a second name inside the
directory, and until that refusal landed a read of that name returned the key and a write overwrote
it, both without a prompt. What is tested is the file's link count, only where the answer would
otherwise already be allow, and the test needs find on PATH: with find missing, that one
refusal does not run and the hard link is auto-approved again
(ADR-0008 records that limit).
The same auto-approval covers ~/.squirrel/hoard/, on the same terms and through the same layers
(ADR-0008) β the same .. rejection, the same length cap,
the same prefix check, the same symlink walk, applied to whichever of the two directories the path
resolved into. A symlink at hoard/ itself, or anywhere below it, falls back to the normal
permission prompt exactly as one at checkpoints/ does. Two things are stricter for the hoard, and
both add refusals rather than removing any: a file sitting directly inside hoard/ rather than one
level down is refused auto-approval for every tool, Read included, and a Write or Edit whose
text looks like it carries a credential is refused too β that write falls back to the normal
permission prompt and you decide, rather than going through without one.
What that auto-approval does not buy, stated as a number rather than left to be discovered. It
covers the file operations and nothing else, and both hoard commands need one thing that is not a
file operation: a UTC timestamp, built by running date -u +%Y%m%dT%H%M%SZ. That is a Bash call,
and the matcher above holds for it unchanged β Write|Edit|Read does not name Bash, so this
plugin's hook never runs on it β so it goes through the normal permission flow. Both counts below are
therefore facts about how squirrel-mode is configured, not about what Claude Code permits: they would
change if this plugin registered a different hook, which the paragraph above says why it does not. In
an interactive session the true cost is
one prompt for a /squirrel:stash (the memory write is auto-approved; the stamp is not) and
two for a /squirrel:dig you open a memory from β one for the search script, which is also a
Bash call, and one for the stamp the uses/last_used edit needs. The read and the edit
themselves are auto-approved. What ADR-0008 buys is that the writes are silent, not that the
commands are.
That credential check matches unambiguous shapes only β private-key headers, a handful of provider
token prefixes, and one key = <long opaque string> rule β and it is not a complete secret
scanner. It also has the opposite failure: any memory whose text merely mentions one of those
prefixes, including a memory about this feature, will ask for permission it did not need. That
costs one prompt and never a refusal to write, which is the trade it was tuned for. ADR-0008 states
exactly what it does and does not catch, including what stops working when grep is missing.
The auto-approval requires jq to be installed and on PATH. A regex cannot safely parse nested
JSON, so on a machine without jq the hook never guesses β every checkpoint and hoard read and
write falls back to the normal permission prompt instead. This is a deliberate, graceful fallback,
not a crash; jq is already a hard prerequisite for this project's own test suite.
The base rules that trigger these writes also cap them at one checkpoint write per turn. Those two directories are the whole of what is auto-approved; full rationale in ADR-0002 and ADR-0008.
squirrel-mode replaces your Claude Code output style while it's enabled. keep-coding-instructions: true keeps its coding behavior untouched, but Explanatory or Learning mode is overridden for as
long as the plugin is on.
/squirrel:off suspends the base rules for one session. /plugin disable squirrel@squirrel-mode,
then a new session, removes them from the system prompt entirely β the hard off. /reload-plugins
alone is not a substitute for that, but not for the reason this paragraph used to give. Claude Code's
plugins reference does name output-styles/ among the components /reload-plugins picks up β so the
old claim that its reload list never mentions output styles was wrong. What that sentence covers is
reloading a component's content; it says nothing about deactivating a style already applied to the
running session, and this repo has not tested whether it does. A new session is the trigger that can
actually be promised here, which is why it is the one documented above. (/plugin disable opens the
plugin panel and leaves it open; press Esc before typing the next command.)
/squirrel:off and /squirrel:on take effect starting with your next message, not the one you
just sent: both write a sentinel that a hook claims on the next prompt, not immediately.
Each sentinel is named with an opaque session token injected at session start, so two Claude Code sessions in the same project directory do not steal each other's off/on request. The claiming hook matches that token to the session id it receives β not whichever session happens to prompt first (ADR-0005 Amendment P2, ADR-0006).
/squirrel:on only clears this session's own suppression flag. After /squirrel:tune, Claude Code
reinjects the updated profile into other open Claude sessions on their next prompt; Codex and Cursor
do not get that reinjection (docs/OTHER-TOOLS.md).
On the data directory having moved. Versions before this one kept this data inside Claude
Code's own config directory, on the theory that a plugin hook could auto-approve writes there the
same way it does anywhere else. It cannot: Claude Code treats that directory as a protected path,
and that check runs before any hook's allow is even considered, so the exact promise this section
makes β a checkpoint update that never stops to ask β could never actually hold at the old location.
~/.squirrel/ sits outside it, and the same auto-approval mechanism works there for real; see
ADR-0002's and
ADR-0003's S11 amendments for the exact old path,
the experiment that found the problem, and the reasoning behind the move. If your old data is still
there, squirrel-mode notices and tells you once per session; it never moves it for you.
No background process, no activity monitoring, no nudges or timers β deliberately out of scope, not a missing feature. For that heavier category:
- Tether
ADHDβ an academic prototype combining activity monitoring, retrieval-augmented generation, and gamification for developers with ADHD. - ravila4/claude-adhd-skills β nudge- and timer-based skills for Claude Code.
MIT β see LICENSE.