Thanks for your interest in contributing to clictl. This guide covers the basics.
git clone https://github.com/clictl/cli.git
cd cli
make build
make testRequires Go 1.23+.
Good first contributions:
- Bug fixes with a failing test
- New protocol support (GraphQL, gRPC, WebSocket)
- Improvements to error messages
- Documentation fixes
Before starting large changes:
Open an issue first to discuss the approach. This saves time for everyone.
- Fork the repo
- Create a branch from
main - Make your changes
- Run
make testandgo vet ./... - Commit with a clear message
- Open a pull request
- Standard
gofmtformatting (enforced by CI) - Explicit
if err != nilerror handling, no panics in production paths - Context (
ctx) as the first argument in network/long-running functions - Error wrapping:
fmt.Errorf("doing X: %w", err) - All exported types and functions must have godoc comments
Every new feature or bug fix should include tests.
make test # run all tests
go test ./internal/... # run specific package tests- Test files live next to source:
foo.go->foo_test.go - Use
t.TempDir()for file-based tests - Use
t.Setenv()for environment variables - Use
httptest.NewServerfor HTTP client tests
Keep them short and descriptive. Use the imperative mood.
fix: handle missing API key error gracefully
feat: add GraphQL protocol support
docs: update CLI reference for memory commands
test: add exec command parameter validation tests
- One feature or fix per PR
- Include tests for new behavior
- Update docs if you change commands, flags, or config
- Keep the diff focused. Don't refactor unrelated code in the same PR.
cmd/clictl/ Entry point
internal/
command/ Cobra CLI commands
config/ Config loading, auth resolution
executor/ Protocol-specific execution (HTTP)
httpcache/ RFC 7234 response cache
mcp/ MCP stdio server
models/ Data structures
registry/ API client, cache, index, spec resolution
updater/ Auto-update, version check, registry sync
When publishing skills to a toolbox, you can sign them for provenance verification. Signed skills allow workspaces to enforce that only trusted publishers' skills are installed.
- Generate a keypair (one-time setup):
clictl skill keygen --output ~/.clictl/signing-keyThis creates ~/.clictl/signing-key (private) and ~/.clictl/signing-key.pub (public). Register the public key with the registry via your workspace settings.
- Generate the manifest with hashes:
clictl skill manifest ./my-skill/This outputs the source.files array with SHA256 hashes for each file.
- Sign the skill:
clictl skill sign ./my-skill/ --key ~/.clictl/signing-keyThis computes a signature over all files and their hashes, then outputs the source.signature value to include in your spec.
- Publish the spec with the signature field included.
You can test how skill isolation behaves without publishing to a toolbox:
- Install a local skill with isolation fields:
# Create a test spec with requires_tools, permissions.filesystem, and bash_allow
clictl install ./test-spec.yaml --target ./test-project- Verify the generated SKILL.md contains the expected isolation metadata:
cat ./test-project/.claude/skills/test-tool/SKILL.mdCheck that allowed-tools in the frontmatter matches requires_tools, filesystem scope comments are present, and bash-allow comments match bash_allow patterns.
-
Test tool restriction by invoking the skill in your agent and verifying that tools outside
allowed-toolsare not available. -
Test filesystem scope by confirming the skill cannot read or write outside the declared paths.
-
Test bash allowlisting by confirming that commands not matching any
bash_allowpattern are rejected.
Open an issue on GitHub. For security issues, see SECURITY.md.