Skip to content
Open
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 .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"name": "crosshead",
"source": "./plugins/claude-code",
"description": "Persistent memory across coding agents. Hooks connect this host to the locally installed Crosshead runtime, shared with Claude Code, Codex, Hermes, OpenCode and Pi.",
"version": "1.1.0"
"version": "1.2.0"
}
]
}
92 changes: 81 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,63 @@ Then start a session and run `/crosshead:setup` in Claude Code, or type
`$crosshead:setup` in Codex. Only you can start setup; the model does not run
it on its own. Until setup has run, each session starts with one line saying
Crosshead isn't set up; nothing else happens and the session is never blocked.
Setup asks for your consent, runs the installer below, and connects the host
with `crosshead quickstart --adapter claude-code|codex --hook-mode plugin`.
Codex runs plugin hooks only after you trust them in `/hooks`. The plugin
launcher needs a POSIX shell; Windows is not supported.
Setup asks where Crosshead should run and previews the directories, profiles,
and files before applying the setup. In Codex, review the new project hooks
in `/hooks`. The plugin launcher needs a POSIX shell.

The plugins are thin. They contain the lifecycle hooks, the setup skill and a
small launcher that runs the installed runtime's hook entrypoints. They do not
bundle, download or update the runtime, so one runtime, daemon and identity
stays shared by every host. See [host plugins](docs/HOST-PLUGINS.md).

### Other hosts and scripts: installer
### Choose where Crosshead runs

```bash
curl -fsSL https://crosshead.sh/install | bash
crosshead quickstart --api-base https://crosshead.sh --adapter claude-code --workspace-root .
crosshead quickstart
```

`--adapter` also takes `codex`, `pi`, `omp`, `hermes` and `opencode`. Without
the plugin, `crosshead install claude-code|codex` registers the hooks in
`.claude/settings.json` or `$CODEX_HOME/hooks.json` itself.
Quickstart recommends the current project. Add more directories, opt into all
projects, or choose manual commands only. Each directory can use Codex, Claude
Code, or both, with an existing or new profile. Project hooks use their selected
profile at startup and resume, including when the launcher skips `direnv`.

For scripts and agents, preview the same setup as JSON:

```sh
crosshead quickstart --scope project --workspace-root . --adapter both --profile work --dry-run --json
```

Use an existing profile name or pass `--api-base https://crosshead.sh` to create
one. Apply by removing `--dry-run`. After starting a session, use
`crosshead workspace check` to see the configured profile and observed startup
and resume. Run the same check in an unselected directory to inspect its scope.

```sh
crosshead workspace add --workspace-root ../other-project --adapter codex --profile work
crosshead workspace list
crosshead workspace remove --workspace-root ../other-project
```

A bare `crosshead quickstart` in a terminal opens the setup wizard. Existing
argument-based quickstart commands retain their legacy behavior; use an explicit
`--scope` to select project, all-project, or manual setup from scripts.

The first `workspace add` on a legacy installation previews the change from
user-wide coverage and asks before applying it. For noninteractive use, review
`--dry-run` and pass `--replace-user-hooks` to acknowledge that coverage change.

Project setup writes local hook settings for each selected host. Codex settings
are excluded locally through Git's info/exclude file. When a repository already
tracks its Codex hooks, Crosshead uses a directory-restricted user registration
and preserves the tracked file. Claude Code uses settings.local.json. Existing
user-wide Crosshead hook commands for this runtime are listed in the preview
when setup replaces them. The runtime skips old Crosshead plugin and hook
registrations after scoped setup. Review and restart host sessions after a
scope change. Source excerpts are off for new bindings unless you choose
`--source-excerpts on`. Checkpoints can still contain prompts and summaries.

Other hosts use `crosshead quickstart --adapter pi|omp|hermes|opencode`.

The installer downloads one release tarball, checks its SHA-256 against the
installer script, installs three npm dependencies (`@noble/curves`,
Expand Down Expand Up @@ -102,8 +139,9 @@ a fresh session after choosing either setting.
memory mode (`crosshead memory mode`).
- Hot-memory documents are signed by the local identity before upload and are
ignored on read if the signature, identity, or scope does not verify. Bounded
source-file excerpts are captured by default; set
`CROSSHEAD_CAPTURE_SOURCE_EVIDENCE=0` when that disclosure is not intended.
source-file capture follows each scoped binding's source excerpt choice. Legacy
installs capture excerpts by default and accept
`CROSSHEAD_CAPTURE_SOURCE_EVIDENCE=0` to opt out.
- Paid recall (warm and cold memory) is selected and assembled by the hosted
service. This client sends the turn's goal and workspace scope, but no hosted
response field is injected into an agent prompt. Only locally signature-
Expand All @@ -115,6 +153,38 @@ a fresh session after choosing either setting.
- `crosshead status`, `crosshead doctor` and `crosshead logs` show what the
runtime is doing. Local state lives in `~/.crosshead/state/`.

Set `CROSSHEAD_PROFILE` for explicit CLI commands. Legacy hooks retain their
installed profile.
`ONLYBOTS_PROFILE` is the legacy alias. Explicit CLI `--profile` takes precedence.
Scoped hooks use the profile selected during setup. Use
`crosshead memory mode off --profile <name>` to stop automatic memory hooks for
that profile, or `crosshead workspace remove` to detach a project.

Local-only checkpoints are stored per profile. A legacy flat store remains
readable for its sole existing local-only profile, whose identity is pinned
before creating another profile. If several profiles already shared an unowned
store, review its `state/local-hot-memory/*.json` files to establish ownership.
Scoped setup retains matching subdirectory and symlink history. Its preview
shows adoption of earlier unscoped checkpoints when one project is selected
for an existing profile. Eligible local history is copied into current workspace
partitions before a new session writes them. Once a scope is replaced, its flat
archive stays available for recovery and no longer participates in recall.
Later unscoped captures require an explicit workspace.

If workspace settings are damaged, `crosshead workspace list`, `workspace check`,
and `doctor` report the problem while automatic memory stays paused. Run:

```sh
crosshead workspace repair --dry-run
crosshead workspace repair
crosshead quickstart --scope project --adapter both --profile work
```

Repair preserves the exact damaged policy in a private adjacent backup and sets
manual scope. It keeps memory files and host settings intact. Review the new
setup before enabling automatic hooks again. `doctor` also reports missing
project directories without dropping the remaining runtime diagnostics.

`crosshead uninstall` removes the runtime. Uninstall the plugin
(`claude plugin uninstall crosshead@crosshead`, `codex plugin remove
crosshead@crosshead`) to remove its hooks; `crosshead uninstall claude-code`
Expand Down
23 changes: 15 additions & 8 deletions docs/HOST-PLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,21 @@ installer-written hooks keep working without duplicates.

The launcher is POSIX `sh`. Windows is not supported.

The setup skill explains what it is about to do, asks for consent, runs the
digest-checked installer, and then runs:
The setup skill asks where Crosshead should run, which profile to use and
whether to include source excerpts. It previews the selected configuration:

```sh
crosshead quickstart --api-base https://crosshead.sh --adapter claude-code --workspace-root . --hook-mode plugin
crosshead quickstart --api-base https://crosshead.sh --adapter codex --workspace-root . --hook-mode plugin
crosshead quickstart --scope project --adapter claude-code --workspace-root . --profile work --dry-run --json
crosshead quickstart --scope project --adapter codex --workspace-root . --profile work --dry-run --json
```

`--hook-mode plugin` writes the adapter configuration and wrappers but no host
hooks. Codex additionally requires you to trust the plugin hooks in `/hooks`;
a new plugin version needs a new review. The plugins have no MCP server and
ask for no credentials. The Codex marketplace entry still carries
Apply the preview without `--dry-run`. Add `--api-base` if you choose a new
profile. The scoped runtime dispatches from its project hooks. It skips
legacy and plugin hook invocations. In Codex, trust the new hooks in
`/hooks`, then start a fresh session. `crosshead workspace check` and
`crosshead doctor` distinguish configured hooks from observed startup and
resume. The plugins have no MCP server and ask for no credentials.
The Codex marketplace entry still carries
`policy.authentication: "ON_INSTALL"` because Codex requires both policy fields
on every entry and documents no other value.

Expand Down Expand Up @@ -100,6 +103,10 @@ or the npm package.

## Hook modes, migration and doctor

The following legacy modes apply to installations that have yet to choose
a workspace scope. Use `crosshead quickstart` to preview moving to project,
all-project, or manual scope.

`crosshead install claude-code|codex` takes `--hook-mode auto|plugin|settings`
(default `auto`, or the explicit mode of the previous install, so
`crosshead update` repeats it). Plugin mode is chosen only when the plugin is
Expand Down
2 changes: 1 addition & 1 deletion plugins/claude-code/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "crosshead",
"displayName": "Crosshead",
"version": "1.1.0",
"version": "1.2.0",
"description": "Persistent memory across coding agents. Hooks connect this host to the locally installed Crosshead runtime, shared with Claude Code, Codex, Hermes, OpenCode and Pi.",
"author": {
"name": "FriendMachine",
Expand Down
2 changes: 1 addition & 1 deletion plugins/claude-code/scripts/crosshead-hook
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ if [ "$host" = codex ]; then
CROSSHEAD_HOST_CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export CROSSHEAD_HOST_CODEX_HOME
fi
exec "$wrapper" "$event" --home "$home" --via plugin --plugin-version 1.1.0
exec "$wrapper" "$event" --home "$home" --via plugin --plugin-version 1.2.0
70 changes: 29 additions & 41 deletions plugins/claude-code/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,36 @@ disable-model-invocation: true

<!-- Generated by scripts/host-plugins.mjs; do not edit. -->

This plugin contains only hooks and this skill. The hooks run the Crosshead
runtime installed on this machine (`~/.crosshead` unless `CROSSHEAD_HOME` is
set). One runtime, daemon and identity is shared by Claude Code, Codex, Hermes,
OpenCode and Pi. Setup installs that runtime and connects it to Claude Code.

Run each command with your shell tool. Use `"${CROSSHEAD_HOME:-$HOME/.crosshead}/bin/crosshead"`
for `crosshead` if it is not on PATH.

1. Check the current state: `crosshead doctor`. If the runtime is installed and
the `claude_code_hooks` check is ok with `mode=plugin`, setup is already
done; report that and stop.
2. Explain the next two steps to the user and ask for explicit consent. Do not
continue without a clear yes.
- The installer is downloaded from https://crosshead.sh/install and run with
bash. It downloads one release tarball, checks its SHA-256 against the
digest pinned in the installer, installs three npm dependencies with install
scripts disabled, and writes wrappers to `~/.crosshead/bin`. Runtimes
never update themselves.
- Quickstart creates a local identity if there is none (its private key stays
in `~/.crosshead`), registers it with the hosted service at
https://crosshead.sh and starts the local daemon. An existing identity is
reused.
3. Install or update the runtime:
Crosshead shares one local runtime across projects and hosts. Start by asking
where the user wants automatic memory. Recommend the current project. Offer
additional directories, all projects, or manual commands only. Confirm the
profile for each directory; reuse an existing profile when the user selects
one. Explain that source excerpts can preserve exact workspace text and reach
the hosted service and later model prompts. Enable excerpts only on request.

1. Check `crosshead --help` and `crosshead workspace list --json`. If the CLI is
missing or its help lacks `--scope`, explain the install and ask for explicit
consent before running `curl -fsSL https://crosshead.sh/install | bash`.
The installer verifies the downloaded release digest and installs the
runtime. A new hosted profile uses a local key and authenticates to its
selected service. When Crosshead is installed, reuse its runtime home.
2. Preview the user's selection. Replace the example profile name with the
user's choice. Add `--api-base https://crosshead.sh` only if they want to
create a new hosted profile.

```sh
curl -fsSL https://crosshead.sh/install | bash
crosshead quickstart --scope project --adapter claude-code --workspace-root . --profile WORK --dry-run --json
```

4. Connect Claude Code:

```sh
crosshead quickstart --api-base https://crosshead.sh --adapter claude-code --workspace-root . --hook-mode plugin
```

`--hook-mode plugin` keeps quickstart from writing its own Claude Code hooks
(this plugin provides them). When the plugin is enabled for the user (the
default for a plugin install) it also removes Crosshead hooks an earlier
install wrote. Either way each event is captured once.
5. Verify with `crosshead doctor`. Expect `claude_code_hooks` to report `mode=plugin`.
Report any other failed check to the user verbatim; do not work around it.
6. Start a new Claude Code session (or run /reload-plugins) so the hooks load with the runtime in place.

Other hosts and scripts keep using `curl -fsSL https://crosshead.sh/install | bash`
followed by `crosshead quickstart --adapter <host>`. Remove Crosshead from
Claude Code by uninstalling this plugin; `crosshead uninstall` removes the runtime.
Use `--scope all` for user-wide hooks or `--scope manual` for manual use.
Show the paths, profiles, source excerpt choices and any replaced hooks.
Apply the confirmed command without `--dry-run`. For further directories
with existing profiles, preview and apply `crosshead workspace add`.
3. Open a fresh session in the selected project.
Run `crosshead workspace check --json`. Report the configured profile and
whether startup or resume has been observed. Check an unselected directory
when the user chose project scope.

Use `crosshead workspace remove` to detach a project. Keep machine-specific
hook entries local. Use an explicit `--profile` for memory commands when
working outside a configured project.
2 changes: 1 addition & 1 deletion plugins/codex/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "crosshead",
"version": "1.1.0",
"version": "1.2.0",
"description": "Persistent memory across coding agents. Hooks connect this host to the locally installed Crosshead runtime, shared with Claude Code, Codex, Hermes, OpenCode and Pi.",
"author": {
"name": "FriendMachine",
Expand Down
2 changes: 1 addition & 1 deletion plugins/codex/scripts/crosshead-hook
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ if [ "$host" = codex ]; then
CROSSHEAD_HOST_CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
export CROSSHEAD_HOST_CODEX_HOME
fi
exec "$wrapper" "$event" --home "$home" --via plugin --plugin-version 1.1.0
exec "$wrapper" "$event" --home "$home" --via plugin --plugin-version 1.2.0
73 changes: 29 additions & 44 deletions plugins/codex/skills/setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,36 @@ description: Install or update the Crosshead runtime and connect it to Codex. Ru

<!-- Generated by scripts/host-plugins.mjs; do not edit. -->

This plugin contains only hooks and this skill. The hooks run the Crosshead
runtime installed on this machine (`~/.crosshead` unless `CROSSHEAD_HOME` is
set). One runtime, daemon and identity is shared by Claude Code, Codex, Hermes,
OpenCode and Pi. Setup installs that runtime and connects it to Codex.

Run each command with your shell tool. Use `"${CROSSHEAD_HOME:-$HOME/.crosshead}/bin/crosshead"`
for `crosshead` if it is not on PATH.

1. Check the current state: `crosshead doctor`. If the runtime is installed and
the `codex_hooks` check is ok with `mode=plugin`, setup is already
done; report that and stop.
2. Explain the next two steps to the user and ask for explicit consent. Do not
continue without a clear yes.
- The installer is downloaded from https://crosshead.sh/install and run with
bash. It downloads one release tarball, checks its SHA-256 against the
digest pinned in the installer, installs three npm dependencies with install
scripts disabled, and writes wrappers to `~/.crosshead/bin`. Runtimes
never update themselves.
- Quickstart creates a local identity if there is none (its private key stays
in `~/.crosshead`), registers it with the hosted service at
https://crosshead.sh and starts the local daemon. An existing identity is
reused.
3. Install or update the runtime:
Crosshead shares one local runtime across projects and hosts. Start by asking
where the user wants automatic memory. Recommend the current project. Offer
additional directories, all projects, or manual commands only. Confirm the
profile for each directory; reuse an existing profile when the user selects
one. Explain that source excerpts can preserve exact workspace text and reach
the hosted service and later model prompts. Enable excerpts only on request.

1. Check `crosshead --help` and `crosshead workspace list --json`. If the CLI is
missing or its help lacks `--scope`, explain the install and ask for explicit
consent before running `curl -fsSL https://crosshead.sh/install | bash`.
The installer verifies the downloaded release digest and installs the
runtime. A new hosted profile uses a local key and authenticates to its
selected service. When Crosshead is installed, reuse its runtime home.
2. Preview the user's selection. Replace the example profile name with the
user's choice. Add `--api-base https://crosshead.sh` only if they want to
create a new hosted profile.

```sh
curl -fsSL https://crosshead.sh/install | bash
crosshead quickstart --scope project --adapter codex --workspace-root . --profile WORK --dry-run --json
```

4. Connect Codex:

```sh
crosshead quickstart --api-base https://crosshead.sh --adapter codex --workspace-root . --hook-mode plugin
```

`--hook-mode plugin` keeps quickstart from writing its own Codex hooks
(this plugin provides them). When the plugin is enabled for the user (the
default for a plugin install) it also removes Crosshead hooks an earlier
install wrote. Either way each event is captured once.
5. Verify with `crosshead doctor`. Expect `codex_hooks` to report `mode=plugin`.
Until Codex has run the plugin hooks, that check warns that no plugin hook
invocation has been seen; the next step resolves it.
Report any other failed check to the user verbatim; do not work around it.
6. Codex runs plugin hooks only after you trust them. Ask the user to open `/hooks`, review the Crosshead hooks and trust them. A changed plugin version needs a new review. Until Codex has run them, quickstart keeps any Crosshead hooks an earlier install wrote; rerun `crosshead install codex` after the first session to remove those.
7. Start a new Codex session so the hooks load with the runtime in place.

Other hosts and scripts keep using `curl -fsSL https://crosshead.sh/install | bash`
followed by `crosshead quickstart --adapter <host>`. Remove Crosshead from
Codex by uninstalling this plugin; `crosshead uninstall` removes the runtime.
Use `--scope all` for user-wide hooks or `--scope manual` for manual use.
Show the paths, profiles, source excerpt choices and any replaced hooks.
Apply the confirmed command without `--dry-run`. For further directories
with existing profiles, preview and apply `crosshead workspace add`.
3. Open a fresh session in the selected project and review the project’s hooks in `/hooks`.
Run `crosshead workspace check --json`. Report the configured profile and
whether startup or resume has been observed. Check an unselected directory
when the user chose project scope.

Use `crosshead workspace remove` to detach a project. Keep machine-specific
hook entries local. Use an explicit `--profile` for memory commands when
working outside a configured project.
Loading
Loading