From everywhere
Use when the user invokes /everywhere-setup, /everywhere-codex-setup, /everywhere-codex-uninstall, /session-save, /recall, /memory on, or /memory off. Also use when the user asks to search past sessions, access historical context across Claude Code or Codex CLI, save the current session to memory, or set up automatic Codex session capture.
npx claudepluginhub iamncj/everywhereThis skill uses the workspace's default tool permissions.
> *Your agent sessions, accessible everywhere.*
Guides Next.js Cache Components and Partial Prerendering (PPR): 'use cache' directives, cacheLife(), cacheTag(), revalidateTag() for caching, invalidation, static/dynamic optimization. Auto-activates on cacheComponents: true.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Share bugs, ideas, or general feedback.
Your agent sessions, accessible everywhere.
Everywhere persists Claude Code and Codex CLI sessions to ~/agent-memory/ synced to GitHub. For Claude, run /everywhere-setup to register Stop/SessionEnd hooks. For Codex, run /everywhere-codex-setup to install a launchd sweeper that polls ~/.codex/sessions/ every 5 minutes. Both feed the same memory repo; meta.yaml.agent distinguishes the source. Use the commands below for manual control and retrieval.
/everywhere-setupFirst-time setup. Run this once to initialize the memory repo and connect it to GitHub.
git --version
gh auth status
claude --version
gh auth status fails: tell the user to run gh auth login and re-invoke /everywhere-setup.git or claude are missing: tell the user to install them before continuing.Check whether ~/agent-memory/.git already exists:
test -d ~/agent-memory/.git && echo "exists" || echo "missing"
If missing, run:
mkdir -p ~/agent-memory && git -C ~/agent-memory init && git -C ~/agent-memory branch -m main
mkdir -p ~/agent-memory/.snapshots ~/agent-memory/global ~/agent-memory/projects
Then create the following files (skip if they already exist):
~/agent-memory/.gitignore:
.snapshots/
.DS_Store
~/agent-memory/INDEX.md:
# Everywhere — Global Memory Index
> Auto-maintained by Everywhere. Last updated by SessionEnd hook.
## Projects
~/agent-memory/global/cross-session-insights.md:
# Cross-Session Insights
> Patterns and learnings that span multiple projects or sessions.
Then make the initial commit:
git -C ~/agent-memory add -A
git -C ~/agent-memory commit -m "init: everywhere memory repo"
Check if the remote is already configured:
git -C ~/agent-memory remote get-url origin 2>/dev/null && echo "configured" || echo "missing"
If not configured:
gh repo create everywhere-memory --private --description "Everywhere session memory" 2>/dev/null || true
REMOTE_URL=$(gh repo view everywhere-memory --json sshUrl -q .sshUrl)
git -C ~/agent-memory remote add origin "$REMOTE_URL"
git -C ~/agent-memory push -u origin main
If gh repo create fails because the repo already exists, just get the URL and set the remote.
The plugin ships its own hooks/hooks.json registering Stop and SessionEnd as type: command + async: true. If the user has installed Everywhere via the plugin marketplace, they don't need to register hooks manually — enabling the plugin loads hooks.json automatically. Detect that case first:
python3 -c "
import json, sys
try:
with open('$HOME/.claude/plugins/installed_plugins.json') as f:
d = json.load(f)
plugins = d.get('plugins', {})
everywhere_keys = [k for k in plugins if k.startswith('everywhere@')]
if everywhere_keys:
print('plugin-installed:' + everywhere_keys[0])
else:
print('not-installed')
except FileNotFoundError:
print('not-installed')
"
If plugin-installed, tell the user: "Plugin already enabled — hooks load automatically from hooks/hooks.json. Just run /hooks to reload, or start a fresh session."
Otherwise (development install or not yet on a marketplace), register the hooks directly in ~/.claude/settings.json using absolute paths to this plugin's snapshot.py. Find the script first:
# 1. If the plugin lives under ~/.claude/plugins/cache/, prefer that path:
find ~/.claude/plugins/cache -path "*everywhere*/hooks/snapshot.py" 2>/dev/null | head -1
# 2. Otherwise, ask the user where they cloned the repo and use that hooks/snapshot.py path.
Read ~/.claude/settings.json (create if missing), merge the hook block below (preserving every other setting), and write back. Use absolute paths in the command field — ${CLAUDE_PLUGIN_ROOT} only resolves for plugins loaded via marketplace.
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "python3 \"<ABS_PATH>/hooks/snapshot.py\"",
"async": true,
"timeout": 120,
"statusMessage": "Everywhere: snapshotting session..."
}]
}],
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "python3 \"<ABS_PATH>/hooks/snapshot.py\"",
"async": true,
"timeout": 180,
"statusMessage": "Everywhere: finalizing session memory..."
}]
}]
}
}
Replace <ABS_PATH> with the actual plugin directory. Validate JSON after writing:
python3 -c "import json; json.load(open('$HOME/.claude/settings.json')); print('valid')"
Tell the user: "Hooks registered (type: command, async: true). They take effect on the next session or after running /hooks to reload."
Why this design: type: agent is documented as experimental. type: command runs a deterministic shell call to snapshot.py, which uses claude -p only for the summary-generation step. async: true makes the hook survive parent CC exit (so /exit and Ctrl-C reliably get a final snapshot).
Report:
~/agent-memory/gh repo view everywhere-memory --json url -q .url~/.claude/settings.json (Stop + SessionEnd, Haiku model, async)/session-save to trigger manually./everywhere-codex-setupOne-time setup for capturing Codex CLI sessions into the same memory repo. macOS only.
codex --version
test -d ~/agent-memory/.git && echo "ok" || echo "missing"
If codex is missing: tell the user to install Codex CLI first (brew install codex) and re-invoke.
If the memory repo is missing: tell the user to run /everywhere-setup first and exit.
find ~/.claude/plugins/cache -path "*everywhere*/hooks/snapshot.py" 2>/dev/null | head -1
If the search returns a path: that's <ABS_PLUGIN_ROOT> (the directory two levels above the matched file — i.e. drop the trailing /hooks/snapshot.py).
Else: ask the user where they cloned the plugin and use that path.
macOS Transparency, Consent, and Control (TCC) blocks launchd-spawned processes from reading paths inside ~/Documents/, ~/Desktop/, and ~/Downloads/ without explicit Full Disk Access. To avoid forcing the user through Privacy & Security settings, copy the Python scripts to ~/.everywhere/hooks/ (which is TCC-safe) and point the plist there.
PLUGIN=<ABS_PLUGIN_ROOT>
mkdir -p ~/.everywhere/hooks
cp "$PLUGIN/hooks/snapshot.py" "$PLUGIN/hooks/codex_sweep.py" \
"$PLUGIN/hooks/summarizer.py" "$PLUGIN/hooks/__init__.py" \
~/.everywhere/hooks/
Re-running /everywhere-codex-setup after a plugin update refreshes these copies.
Read <ABS_PLUGIN_ROOT>/hooks/codex-sweeper.plist.template. Replace __ABS_PLUGIN_ROOT__ with $HOME/.everywhere (the staging path from step 3) and __HOME__ with $HOME. Write the result to ~/Library/LaunchAgents/dev.everywhere.codex-sweeper.plist.
sed -e "s|__ABS_PLUGIN_ROOT__|$HOME/.everywhere|g" -e "s|__HOME__|$HOME|g" \
"$PLUGIN/hooks/codex-sweeper.plist.template" \
> ~/Library/LaunchAgents/dev.everywhere.codex-sweeper.plist
plutil ~/Library/LaunchAgents/dev.everywhere.codex-sweeper.plist
The plutil line validates the XML. If it fails, abort and report the error.
LABEL=dev.everywhere.codex-sweeper
launchctl bootout gui/$UID/$LABEL 2>/dev/null || true
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/$LABEL.plist
launchctl print gui/$UID/$LABEL | head -20
The bootout line is best-effort cleanup of any stale registration. bootstrap loads the plist. print should show the job is loaded.
launchctl kickstart gui/$UID/dev.everywhere.codex-sweeper
sleep 4
tail -20 ~/agent-memory/.snapshots/codex-sweep.log 2>/dev/null
tail -20 ~/agent-memory/.snapshots/codex-sweep.err 2>/dev/null
If codex-sweep.err shows command not found: codex or command not found: claude: the launchd PATH doesn't include the homebrew prefix. Check the plist's <key>EnvironmentVariables</key> block.
If codex-sweep.err shows Operation not permitted reading the script path: step 3 was skipped — the launchd job is pointing at a TCC-protected location instead of ~/.everywhere/hooks/. Re-run step 3 and step 4.
mkdir -p ~/.codex/skills/everywhere
cp $PLUGIN/skills/everywhere/SKILL.md ~/.codex/skills/everywhere/SKILL.md
This lets /recall, /memory on, etc. work from inside Codex too. Skip if the user prefers Claude-only invocation.
Tell the user:
~/.everywhere/hooks/ (re-run setup after plugin updates)~/Library/LaunchAgents/dev.everywhere.codex-sweeper.plist~/agent-memory/.snapshots/codex-sweep.log~/.codex/skills/everywhere/SKILL.md (if step 7 ran)notify setting was not modified./everywhere-codex-uninstallStop the Codex sweeper, remove the launchd plist, and clean up the staged hooks.
LABEL=dev.everywhere.codex-sweeper
launchctl bootout gui/$UID/$LABEL 2>/dev/null
rm -f ~/Library/LaunchAgents/$LABEL.plist
rm -rf ~/.everywhere
Then optionally remove the Codex-side skill:
rm -rf ~/.codex/skills/everywhere
The memory repo and existing session files are kept untouched. Tell the user that re-running /everywhere-codex-setup will resume sweeping with the existing cursor (no re-summarization of past sessions).
/session-saveManually trigger a full session save right now, following the same logic as the session-end.sh hook.
Detect which agent we're running in. If the environment variable CODEX_HOME is set, or ~/.codex/sessions/ exists and a recent rollout matches the current cwd, treat this as a Codex session. Otherwise, treat it as a Claude Code session.
Claude Code:
ls -t ~/.claude/projects/$(echo "$PWD" | sed 's|^/||; s|/|-|g')/*.jsonl 2>/dev/null | head -1
Codex CLI:
python3 - <<'PY'
import json, os, sys
from pathlib import Path
cwd = os.environ["PWD"]
root = Path.home() / ".codex" / "sessions"
candidates = sorted(root.rglob("rollout-*.jsonl"), key=lambda p: p.stat().st_mtime, reverse=True)
for p in candidates[:50]:
try:
with open(p) as f:
first = f.readline()
meta = json.loads(first)
if meta.get("type") == "session_meta" and meta.get("payload", {}).get("cwd") == cwd:
print(p)
sys.exit(0)
except Exception:
continue
sys.exit(1)
PY
If Codex case: shell out to the sweeper with the discovered path:
EVERYWHERE_DEBUG=1 python3 <ABS_PLUGIN_ROOT>/hooks/snapshot.py --codex-sweep
Then verify the latest finalized session for this project:
SLUG=$(python3 -c "import hashlib, os; p = os.path.abspath(os.environ['PWD']); print(f\"{os.path.basename(p) or 'unknown'}-{hashlib.sha256(p.encode()).hexdigest()[:8]}\")")
ls -t ~/agent-memory/projects/"$SLUG"/sessions/ | head -1
For the Claude case, continue with the original step-by-step logic below.
Read the first lines of the JSONL file to find a line with a cwd field:
project_path = the value of cwdproject_name = {basename}-{hash8} where basename is basename(project_path) and hash8 is the first 8 hex chars of sha256(abspath(project_path)) — disambiguates folders sharing a basenamesession_id = stem of the JSONL filename (filename without .jsonl)started_at = ISO 8601 timestamp from the first JSONL entry that has a timestamp fieldsession_id_short = first 6 characters of session_iddate_str = first 10 characters of started_at (e.g. 2026-04-29)Read the full JSONL. Collect messages:
user entries: message.content as a string (or join text blocks from a list)assistant entries: join text blocks from message.contentIf fewer than 3 user messages are found, tell the user the session is too short to save and exit.
Directory: ~/agent-memory/projects/{project_name}/sessions/{date_str}-{session_id_short}/
Create the directory. Write these files (overwrite if they exist):
meta.yaml: Quote all string values. Use snapshot_count: 1 if a prior meta.yaml exists for this session, else 0.
session_id: "{session_id}"
session_id_short: "{session_id_short}"
project_path: "{project_path}"
project_name: "{project_name}"
agent: claude-code
started_at: "{started_at}"
ended_at: "{current ISO 8601 timestamp}"
is_final: true
snapshot_count: {0 or 1}
tags: [{5-8 relevant tags as YAML inline sequence}]
summary.md: 3–5 sentences covering: what problem was solved, approach taken, outcome, anything left incomplete.
decisions.md: All technical decisions and conclusions. Group under sub-headings if more than 5.
artifacts.md:
## Files
- `path/to/file` — what was done
## Commands
- `command` — what it accomplished
## References
- PRs, issues, docs, or URLs mentioned
excerpts.md: The 3–5 most valuable Q&A exchanges, verbatim. Quote the user's message and assistant's response exactly — do not paraphrase.
File: ~/agent-memory/projects/{project_name}/PROJECT.md
Create with this template if it doesn't exist:
# {project_name}
**Path:** {project_path}
## Recent Sessions
<!-- Sessions listed below, newest first. Maintained by Everywhere. -->
## Project Overview
<!-- Updated manually or by /recall when patterns emerge -->
Prepend a new entry under ## Recent Sessions (after the comment line):
- [{date_str} — {first sentence of summary}](sessions/{date_str}-{session_id_short}/summary.md)
If there are more than 10 session entries, remove the oldest so only 10 remain.
File: ~/agent-memory/INDEX.md
Create if it doesn't exist:
# Everywhere — Global Memory Index
> Auto-maintained by Everywhere. Last updated by SessionEnd hook.
## Projects
If {project_name} is not already listed under ## Projects, append:
- [{project_name}](projects/{project_name}/PROJECT.md) — {project_path}
git -C ~/agent-memory add -A
git -C ~/agent-memory commit -m "session: {project_name} {session_id_short} - {first sentence of summary}"
git -C ~/agent-memory push origin main
If push fails (no remote or network error), commit locally and report the error — do not fail noisily.
Tell the user: "Session saved. Files written to ~/agent-memory/projects/{project_name}/sessions/{date_str}-{session_id_short}/ and pushed to GitHub."
/recall [query]Search the memory repo for sessions matching the query and return ranked results.
rg -l "{query}" ~/agent-memory/projects/ --glob="*.md" 2>/dev/null | head -20
rg "{query}" ~/agent-memory/projects/ --glob="meta.yaml" 2>/dev/null | head -20
Combine both result sets. Deduplicate by session directory. Prefer results where the match appeared in summary.md or meta.yaml tags over body matches in decisions.md or artifacts.md.
For the top 5 matching sessions, read their summary.md and meta.yaml (for date, project, and tags).
For the top 2 most relevant sessions, also read decisions.md and excerpts.md.
Present results ranked by relevance. For each match include:
meta.yaml started_at)summary.md showing why it matchedsummary.md for the user to explore furtherIf no results are found, say so and suggest broader search terms.
/memory onInject the global INDEX.md and the current project's PROJECT.md into context.
python3 -c "import hashlib, os; p = os.path.abspath(os.environ['PWD']); print(f\"{os.path.basename(p) or 'unknown'}-{hashlib.sha256(p.encode()).hexdigest()[:8]}\")"
Read ~/agent-memory/INDEX.md. If it doesn't exist, tell the user the memory repo hasn't been set up yet and suggest running /everywhere-setup.
Read ~/agent-memory/projects/{project_name}/PROJECT.md. If it doesn't exist, note that no sessions have been saved for this project yet.
Count the number of - [ entries under ## Recent Sessions in PROJECT.md (or 0 if the file doesn't exist).
Report: "Memory loaded. {N} sessions found for {project_name}. INDEX.md and PROJECT.md are now in context."
/memory offTell the user:
"Injected memory context cannot be removed from an active session — once read, it remains in context. To start fresh without prior memory context, begin a new Claude Code session and do not run
/memory on."
Do not proactively reference the previously loaded INDEX.md or PROJECT.md content for the remainder of the session unless the user explicitly asks about past sessions.