Skip to content

Latest commit

 

History

History
103 lines (67 loc) · 7.13 KB

File metadata and controls

103 lines (67 loc) · 7.13 KB

Contributing to superhuman

Thanks for your interest. This is a Claude Code plugin that runs a team of agents to make autonomous open-source contributions. Contributions of all sizes are welcome — bug fixes, new safety rails, better reviewers, docs.

Ground rules

  • Be kind and assume good faith. See our Code of Conduct.
  • Keep the safety model intact. This plugin pushes real code to real repos. Any change that weakens a safety rail (single-author commit rule, force-with-lease, CI allowlist, prompt-injection halt, reputation cooldown) needs an explicit rationale and will get extra scrutiny.
  • Lossless refactors. Several past releases (e.g. v0.5.0 bash extraction) had "lose no behavior" as a hard constraint. If you're refactoring, prove the behavior is preserved with tests.

Repo layout

superhuman/
├── .claude-plugin/   # plugin.json + marketplace.json manifests
├── agents/           # subagent prompts (the behavioral logic) + SHARED_STATE.md
├── commands/         # slash commands (/contribute, /repo-finder, /preferences, …)
├── scripts/          # shell extracted from agent prompts, organised by agent
│   ├── lib/          # shared helpers: state.sh, preferences.sh, mistakes.sh, flake.sh, delim.sh
│   ├── repo-finder/  # build_queries.sh — compiles preferences.md into search queries
│   ├── profiler/  scorer/  orchestrator/  builder/
├── schemas/          # JSON Schema (draft 2020-12) for every shared-state file
├── tests/scripts/    # bash unit tests for scripts/ (one per script/schema)
└── docs/             # design specs and plans for notable changes

Where logic lives

Behavior is split deliberately:

  • Agent prompts (agents/*.md) hold the reasoning, decisions, and safety prose. Things a model needs to judge stay here.
  • Scripts (scripts/*.sh) hold the deterministic shell — JSON reads/writes, state transitions, gates. Things a computer should execute the same way every time live here.
  • User config (~/.superhuman/preferences.md) holds what the user wants. Everything else under ~/.superhuman/ is machine-written state the plugin owns; this one file is theirs, and only /preferences writes it on their behalf.

When you find yourself writing more than a couple of lines of bash/jq inside an agent prompt, extract it to scripts/ and call it from the prompt. That keeps prompts short (cheaper to load per phase) and makes the logic testable.

Development setup

You need gh, git, jq, and python3 on your PATH (see README → Prerequisites). No build step — it's prompts and shell.

To work on the plugin live, install it from your local checkout:

/plugin marketplace add /absolute/path/to/your/superhuman/checkout
/plugin install superhuman@superhuman
/reload-plugins

Tests

Every script in scripts/ has a matching test in tests/scripts/. They're plain bash — no framework. Each one sets set -euo pipefail and exits non-zero on failure, writing only to mktemp dirs (never your real ~/.superhuman/).

Run the full suite:

for t in tests/scripts/test_*.sh; do bash "$t" || echo "FAIL: $t"; done

Run one:

bash tests/scripts/test_state.sh

A green suite is required before opening a PR. If you add or change a script, add or update its test. If you change a shared-state file's shape, update both its schemas/*.schema.json and the tests/scripts/test_schema_*.sh fixture — they drift easily (the v0.5.1 mode telemetry field is a cautionary tale).

Pull request checklist

  • All tests pass (for t in tests/scripts/test_*.sh; do bash "$t" || echo FAIL $t; done).
  • New/changed scripts have tests.
  • Changed shared-state shapes update schema and test fixture together.
  • No safety rail weakened without explicit justification in the PR body.
  • Add your notes under ## [Unreleased] in CHANGELOG.md. A patch release is cut automatically when your PR merges (see Versioning & releases) — you do not need to bump the manifests for a patch. For a minor/major release, bump version yourself in all three manifests (.claude-plugin/plugin.json, .claude-plugin/marketplace.json, .codex-plugin/plugin.json — they must match) and the merge releases that version as-is.
  • Notable design decisions captured under docs/ when warranted.

Versioning & releases

Versions follow semver. The three manifests — .claude-plugin/plugin.json, .claude-plugin/marketplace.json, and .codex-plugin/plugin.jsonmust carry the same version; a mismatch is a release bug (it happened in v0.4.1→v0.5.0).

Releases are automatic. Every push to main runs .github/workflows/release.yml:

  • If the current version is already tagged (the normal case for a merge), it bumps the patch across all three manifests, promotes the ## [Unreleased] CHANGELOG section into a dated ## [X.Y.Z] section, commits that back to main (chore(release): vX.Y.Z), then tags and publishes the GitHub Release.
  • If the merge already introduced a new version (you bumped the manifests for a minor/major), it releases that version as-is instead of patching past it.

So: put your notes under ## [Unreleased] and they become the next release's notes. The version-writing and CHANGELOG promotion live in scripts/release/prepare_release.sh (tested by tests/scripts/test_prepare_release.sh); the workflow only decides the target version and does the git/tag/release plumbing.

Branch protection & the release token

main is protected: PRs merge only when the suite (ubuntu-latest) / suite (macos-latest) checks pass and every review conversation (CodeRabbit included) is resolved. A failing check or an unresolved review comment blocks the merge.

Because protection also blocks the release bot's push, the release workflow authenticates its bump-commit push with a RELEASE_TOKEN secret — a fine-grained PAT owned by a repo admin, scoped Contents: write. Protection is set with enforce_admins=false, so an admin token bypasses the required checks for that one automated push. Without the secret the release step fails loudly rather than silently skipping a release. (Pushes made by a PAT re-trigger workflows, so the chore(release): commit is filtered by the if: guard in release.yml to avoid a bump loop.)

Reporting bugs & requesting features

Open a GitHub issue. For anything security- or safety-sensitive, follow SECURITY.md instead of filing a public issue.

Code of Conduct

Be respectful, inclusive, and constructive. Harassment, discrimination, and personal attacks are not tolerated. Maintainers may remove comments, commits, and contributions that violate this, and may block repeat offenders. Report concerns to the maintainer listed in SECURITY.md.

License

By contributing, you agree that your contributions are licensed under the MIT License.