Skip to content

feat: rewrite crux as a harness manager (v2.0)#32

Open
kaushalpaneri wants to merge 5 commits into
mainfrom
feat/v2-harness-manager
Open

feat: rewrite crux as a harness manager (v2.0)#32
kaushalpaneri wants to merge 5 commits into
mainfrom
feat/v2-harness-manager

Conversation

@kaushalpaneri
Copy link
Copy Markdown
Contributor

Summary

Rewrite crux from a per-MCP/per-skill manager (v1.x) into a harness manager (v2.0). A harness is a versioned bundle of agent configuration — CLAUDE.md, skills, MCPs, plugins, hooks — addressed by name@version. Activate one with crux use and Crux deploys symlinks under ~/.claude/ (or <cwd>/.claude/) into the registry.

Design doc: /Users/kaushal/Downloads/crux-v2-design.md (Part 1 — design, Part 2 — spec).
Plan: docs/superpowers/plans/2026-05-10-crux-v2-harness-manager.md.

What's in

  • Registry tree under ~/.crux/registry/{mcps,skills,plugins,harnesses}/.
  • Pointer file resolution: walk-up crux.toml → fallback ~/.crux/active.toml.
  • Symlink-based activation with conflict detection (refuses to clobber non-Crux files).
  • .mcp.json generation that wraps keychain MCPs with keychain-auth.sh and HTTP MCPs with http-bridge-auth.sh.
  • Versioning (crux new, crux bump) with append-only history log capped at 100 rows.
  • crux use - rolls back to the previous activation; crux use --none deactivates and removes managed symlinks.
  • crux migrate converts a v1 crux.json to harness@v1 + crux.toml pointer.

Architecture

src/crux_cli/
├── paths.py          v2 path helpers (registry_root, harnesses_root, …)
├── tomlio.py         minimal TOML reader/writer
├── pointer.py        parse_ref, resolve_active (cwd walk-up)
├── history.py        bounded TSV activation log
├── bundle.py         bundle.toml reader/writer
├── store.py          enumeration + lookup of primitives
├── harness_ops.py    new / bump
├── registry_ops.py   add MCP/skill/plugin; remove (with reference guard)
├── activation.py     plan_symlinks → apply_plan → emit_mcp_json
├── mcp_emit.py       .mcp.json builder with keychain/http launcher wiring
├── migrate_v1.py     v1 crux.json → v2 harness + pointer
├── setup.py          create registry tree, install skill + launchers
└── cli/commands/     setup_cmd, doctor_cmd, migrate_cmd, registry_cmd,
                      secret_cmd, harness_cmd, use_cmd

Removed modules: manifest.py, sync.py, projects.py, sandbox.py, setup_crux.py, auth.py, preflight.py, health.py, and the old cli/commands/{mcp,skill,project,task,version,doctor}.py.

Tests

  • 218 unit tests across the new modules.
  • 12 integration tests in tests/integration/test_cli_v2.py that drive python -m crux_cli in a subprocess and walk through realistic user workflows: fresh setup, versioning, directory vs user scope, use - rollback, --none deactivation, building a bundle from scratch, reference-guarded removal, migration, doctor, and refusal to clobber existing files.
  • Smoke-tested end-to-end (setup → new → use → active) outside the test suite to confirm real CLI behavior.

Test plan

  • All unit tests pass (pytest tests/unit/)
  • All integration tests pass (pytest tests/integration/)
  • Smoke test: setup, new, use, active end-to-end in /tmp works as expected
  • Ruff clean across src/ and tests/
  • CI passes on this PR

🤖 Generated with Claude Code

kaushalpaneri and others added 5 commits May 10, 2026 22:07
Add the foundation of crux v2: registry tree paths, TOML I/O, pointer
file resolution, append-only history log, bundle.toml reader/writer,
and primitive enumeration via store.

- paths.py: registry_root, mcps_root, skills_root, plugins_root,
  harnesses_root, active_pointer_path, history_path, claude_user_dir,
  claude_dir_for.
- tomlio.py: stdlib tomllib for reading; minimal writer for the small
  TOML dialect crux emits.
- pointer.py: parse_ref, read_pointer, write_pointer, resolve_active
  (cwd walk-up to user fallback).
- history.py: bounded TSV history log of activations.
- bundle.py: bundle.toml reader/writer with default sections.
- store.py: list/lookup primitives across the registry tree, including
  version-aware sorting.

Plan: docs/superpowers/plans/2026-05-10-crux-v2-harness-manager.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the modules that turn registry primitives into a deployed harness:

- activation.py: plan_symlinks, apply_plan with conflict detection,
  remove_managed_symlinks for clean re-activation, top-level activate().
- mcp_emit.py: emit .mcp.json from a bundle's MCP refs, wrapping
  keychain MCPs with keychain-auth.sh and HTTP MCPs with
  http-bridge-auth.sh.
- harness_ops.py: new_harness (v1) and bump (copy latest to next vN).
- registry_ops.py: add MCP (npm/uvx/github/local/http), skill
  (local/github), plugin (local, versioned); remove with reference
  guard.
- migrate_v1.py: migrate cwd's crux.json to harness@v1 plus crux.toml
  pointer, deleting the old file.
- setup.py: idempotent setup that creates the registry tree, writes
  config.toml, installs bundled crux skill and launchers.
- install.py: npm and uv install helpers used by registry_ops.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire all v2 commands together: setup_cmd, doctor_cmd, migrate_cmd,
registry_cmd, secret_cmd, harness_cmd (new/bump/list/show/edit),
use_cmd (use/active). Rewrite cli/main.py with the v2 parser. Map
exceptions to documented exit codes (1 usage, 2 not-found, 3 state/
conflict, 4 environment).

Added __main__.py so `python -m crux_cli ...` works for tests.

End-to-end coverage in tests/integration/test_cli_v2.py exercises the
ten primary user workflows: fresh setup, versioning, directory vs
user scope, `use -` rollback, `--none` deactivate, building a bundle
from scratch, blocked removal, migration with and without --name,
doctor, and refusal to clobber existing files.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Delete every v1 module replaced by the v2 implementation:

src/:
  manifest.py, sync.py, projects.py, sandbox.py, setup_crux.py,
  auth.py, preflight.py, health.py,
  cli/commands/{mcp,skill,project,task,version,doctor}.py

tests/:
  All v1 unit and integration tests, plus tests/fixtures/.

Trim crux_cli/paths.py to the v1 helpers actually still used at runtime
(secrets_path, config_path, tokens_path) plus the v2 helpers. Replace
tests/conftest.py and tests/integration/conftest.py with v2-shaped
fixtures.

Bump pyproject version to 2.0.0. Update ruff per-file-ignores to match
the v2 module set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the v1 quickstart and command reference with v2: harness as
the unit of composition, symlink-based activation, pointer files,
versioning with bump and use -, and the migrate command for v1
projects. Add a concepts section describing the four primitives.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant