ctx v0.6.0: The Integration Release¶

Two Commands to Persistent Memory¶
Jose Alekhinne / February 16, 2026
What Changed?
ctx is now a Claude Code plugin. Two commands, no build step:
Six hooks. Twenty-five skills. Installed.
For three releases, ctx required assembly:
- Clone the repo;
- Build the binary;
- Copy hook scripts into
.claude/hooks/; - Symlink skill files.
- Understand which shell scripts called which Go commands;
- Hope nothing broke when Claude Code updated its hook format.
v0.6.0 ends that era: ctx ships as a Claude Marketplace plugin:
Hooks and skills served directly from source, installed with a single command, updated by pulling the repo. The tool that gives AI persistent memory is now as easy to install as the AI itself.
But the plugin conversion was not just a packaging change: It was the
forcing function that rewrote every shell hook in Go, eliminated the
jq dependency, enabled go test coverage for hook logic, and made
distribution a solved problem.
When you fix how something ships, you end up fixing how it is built.
The Release Window
February 15–February 16, 2026
From the v0.3.0 tag to commit a3178bc:
- 109 commits.
- 334 files changed.
- Version jumped from 0.3.0 to 0.6.0 to signal the magnitude.
Before: Six Shell Scripts and a Prayer¶
v0.3.0 had six hook scripts. Each was a Bash file that shelled out to
ctx subcommands, parsed JSON with jq, and wired itself into Claude
Code's hook system via .claude/hooks/:
.claude/hooks/
├── check-context-size.sh
├── check-persistence.sh
├── check-journal.sh
├── post-commit.sh
├── block-non-path-ctx.sh
└── cleanup-tmp.sh
This worked, but it also meant:
- jq was a hard dependency: No
jq, no hooks. macOS ships without it. - No test coverage: Shell scripts were tested manually or not at all.
- Fragile deployment:
ctx inithad to scaffold.claude/hooks/and.claude/skills/with the right paths, permissions, and structure. - Version drift: Users who installed once never got hook updates
unless they re-ran
ctx init.
The shell scripts were the right choice for prototyping. They were the wrong choice for distribution.
After: One Plugin, Zero Shell Scripts¶
v0.6.0 replaces all six scripts with ctx system subcommands compiled
into the binary:
| Shell Script | Go Subcommand |
|---|---|
check-context-size.sh |
ctx system check-context-size |
check-persistence.sh |
ctx system check-persistence |
check-journal.sh |
ctx system check-journal |
post-commit.sh |
ctx system post-commit |
block-non-path-ctx.sh |
ctx system block-non-path-ctx |
cleanup-tmp.sh |
ctx system cleanup-tmp |
The plugin's hooks.json wires them to Claude Code events:
{
"PreToolUse": [
{"matcher": "Bash", "command": "ctx system block-non-path-ctx"},
{"matcher": ".*", "command": "ctx agent --budget 4000"}
],
"PostToolUse": [
{"matcher": "Bash", "command": "ctx system post-commit"}
],
"UserPromptSubmit": [
{"command": "ctx system check-context-size"},
{"command": "ctx system check-persistence"},
{"command": "ctx system check-journal"}
],
"SessionEnd": [
{"command": "ctx system cleanup-tmp"}
]
}
No jq. No shell scripts. No .claude/hooks/ directory to manage.
The hooks are Go functions with tests, compiled into the same binary you already have.
The Plugin Model¶
The ctx plugin lives at .claude-plugin/marketplace.json in the repo.
Claude Code's marketplace system handles discovery and installation:
Skills are served directly from internal/assets/claude/skills/; there
is no build step, no make plugin, no generated artifacts.
This means:
- Install is two commands: Not "clone, build, copy, configure."
- Updates are automatic: Pull the repo; the plugin reads from source.
- Skills and hooks are versioned together: No drift between what the CLI expects and what the plugin provides.
ctx initis tool-agnostic: It creates.context/and nothing else. No.claude/scaffolding, no assumptions about which AI tool you use.
That last point matters:
Before v0.6.0, ctx init tried to set up Claude Code integration as part of
initialization. That coupled the context system to a specific tool.
Now, ctx init gives you persistent context. The plugin gives you Claude Code
integration. They compose; they don't depend.
Beyond the Plugin: What Else Shipped¶
The plugin conversion dominated the release, but 109 commits covered more ground.
Obsidian Vault Export¶
Generates a full Obsidian vault from enriched journal entries: wikilinks, MOC (Map of Content) pages, and graph-optimized cross-linking. If you already use Obsidian for notes, your AI session history now lives alongside everything else.
Encrypted Scratchpad¶
AES-256-GCM encrypted storage for sensitive one-liners.
The encrypted blob commits to git; the key stays in .gitignore.
This is useful for connection strings, API keys, and other values that need to travel with the project without appearing in plaintext.
Security Hardening¶
Three medium-severity findings from a security audit are now closed:
| Finding | Fix |
|---|---|
Path traversal via --context-dir |
Boundary validation: operations cannot escape project root (M-1) |
Symlink following in .context/ |
Lstat() check before every file read/write (M-2) |
| Predictable temp file paths | User-specific temp directory under $XDG_RUNTIME_DIR (M-3) |
Plus a new /sanitize-permissions skill that audits
settings.local.json for overly broad Bash permissions.
Hooks That Know When to Be Quiet¶
A subtle but important fix: hooks now no-op before ctx init has run.
Previously, a fresh clone with no .context/ would trigger hook errors
on every prompt. Now, hooks detect the absence of a context directory
and exit silently. Similarly, ctx init treats a .context/ directory
containing only logs as uninitialized and skips the --overwrite prompt.
Small changes. Large reduction in friction for new users.
The Numbers¶
| Metric | v0.3.0 | v0.6.0 |
|---|---|---|
| Skills | 21 | 25 |
| Shell hook scripts | 6 | 0 |
| Go system subcommands | 0 | 6 |
| External dependencies (hooks) | jq, bash | none |
| Lines of Go | ~14,000 | ~37,000 |
| Plugin install commands | n/a | 2 |
| Security findings (open) | 3 | 0 |
ctx init creates .claude/ |
yes | no |
The line count tripled. Most of that is documentation site HTML, Obsidian export logic, and the scratchpad encryption module.
The core CLI grew modestly; the ecosystem around it grew substantially.
What Does v0.6.0 Mean for ctx?¶
v0.1.0asked: "Can we give AI persistent memory?"v0.2.0asked: "Can we make that memory accessible to humans too?"v0.3.0asked: "Can we make the quality self-enforcing?"
v0.6.0 asks: "Can someone else actually use this?"
A tool that requires cloning a repo, building from source, and manually wiring hooks into the right directories is a tool for its author.
A tool that installs with two commands from a marketplace is a tool for everyone.
The version jumped from 0.3.0 to 0.6.0 because the delta is not
incremental: The shell-to-Go rewrite, the plugin model, the security
hardening, and the tool-agnostic init: Together, they change what ctx
is: Not a different tool, but a tool that is finally ready to leave
the workshop.
What Comes Next¶
The plugin model opens the door to distribution patterns that were
not possible before. Marketplace discovery means new users find ctx
without reading a README. Plugin updates mean existing users get
improvements without rebuilding.
The next chapter is about what happens when persistent context is easy
to install: Adoption patterns, multi-project workflows, and whether
the .context/ convention can become infrastructure that other tools
build on.
But those are future posts.
This one is about the release that turned a developer tool into a distributable product: two commands, zero shell scripts, and a presence on the Claude Marketplace.
The Integration Release
v0.1.0 shipped features. v0.2.0 shipped archaeology.
v0.3.0 shipped discipline. v0.6.0 shipped the front door.
The most important code in this release is the code you never have to copy.
This post was drafted using /ctx-blog-changelog with access to the
full git history between v0.3.0 and v0.6.0, release notes, and the
plugin conversion PR. The meta continues.