Thank you for your interest in contributing to Polis! This document covers the development setup for each component and the conventions to follow.
Polis has four main components:
| Component | Language | Status | Description |
|---|---|---|---|
cli-go/ |
Go | Active | Go CLI — core packages imported by the webapp |
webapp/ |
Go | Active | Local web interface for managing a Polis site |
cli-bash/ |
Bash | Frozen (v0.56.0) | Original CLI — functional but receives no new features |
| Discovery Service | TypeScript | Active (closed for now) | Hono server for discovery coordination. Source not yet in this public repo; planned for open-source release. The DS API reference is the stable public contract. |
Key dependency rule: The Go CLI (cli-go/pkg/) owns all core packages. The webapp imports from the CLI, never the reverse.
Before submitting a bug report:
- Check existing issues to avoid duplicates
- Use the latest version
- Include in your report:
- Which component (Go CLI, webapp, bash CLI, discovery service)
- OS and version
- Steps to reproduce
- Expected vs actual behavior
- Relevant error messages
Feature requests are welcome! Please:
- Check existing issues for similar requests
- Describe the use case clearly
- Specify which component it affects
- Fork the repository
- Create a branch for your changes:
git checkout -b feature/your-feature-name
- Make your changes following the conventions below
- Test your changes (see component-specific sections)
- Commit with clear, descriptive messages
- Open a Pull Request with:
- Clear description of the changes
- Which component(s) are affected
- Reference to any related issues
- Go 1.21+
cd cli-go
# Build
go build ./...
# Run tests
go test ./...
# Build CLI binary
go build -o polis ./cmd/polisCore packages live in cli-go/pkg/ and are designed to be importable:
pkg/publish/— Post publishing logicpkg/comment/— Comment managementpkg/blessing/— Blessing workflowpkg/signing/— Ed25519 cryptographic signingpkg/render/— Markdown to HTML renderingpkg/template/— Mustache-like template enginepkg/discovery/— Discovery service HTTP clientpkg/metadata/— Public index (JSONL) management
See cli-go/README.md for the full package list and library usage examples.
Packages that write version strings into files must follow this pattern:
- Add
var Version = "dev"after imports - Add
func GetGenerator() string { return "polis-cli-go/" + Version } - Add
<pkg>.Version = Versionincmd/root.goExecute() - Use
GetGenerator()(not bareVersion) when writing to metadata files - Add a test verifying the written version matches
GetGenerator()
- Use
gofmt(enforced) - Follow existing patterns in the codebase
- Tests go in
*_test.gofiles alongside implementation - Use
t.TempDir()for test fixtures
- Go 1.21+
cd webapp
# Build webapp-only binary
go build -o polis-server ./cmd/server
# Build bundled binary (CLI + serve)
go build -o polis-full ./cmd/polis-full
# Run tests
go test ./...
# Quick iteration: build and run
go build -o polis-server ./cmd/server && ./polis-server- The webapp imports from
cli-go/pkg/, never the reverse - If you change packages in
cli-go/, rebuild both:cd cli-go && go build ./... && cd ../webapp && go build ./... - Add or update tests for every handler change
- Check bash CLI parity when modifying behavior that both CLIs share
See webapp/CLAUDE.md for detailed patterns, handler conventions, and frontend architecture.
internal/server/handlers.go— HTTP handlersinternal/server/server.go— Server struct and configurationinternal/server/routes.go— Route registrationinternal/webui/www/app.js— Frontend SPAinternal/webui/www/style.css— Styles
The bash CLI is feature-frozen at v0.56.0. Bug fixes are accepted but new features should be implemented in the Go CLI.
- Bash 4.0+, OpenSSH 8.0+, jq, curl, sha256sum/shasum
- ShellCheck (for linting)
cd cli-bash
# Lint
shellcheck bin/polis
# Run tests
./tests/run_tests.sh
# Run tests by category
./tests/run_tests.sh --category unit
./tests/run_tests.sh --skip-network- Quote variables:
"$variable"not$variable - Use
[[ ]]for conditionals - Use
$(command)not backticks - Functions:
snake_case; constants:UPPER_SNAKE_CASE - All commands must support
--jsonoutput mode
The DS source is not part of this public repo at this time, so contributions to the DS itself are not yet accepted via pull request. Issues, API-contract feedback, and proposed event-stream additions are very welcome — open an issue against this repo or follow the reporting channels below.
See the DS API reference and stream architecture doc for the stable public contract that the canonical deployment (and any future open-source release) honors.
- Ensure tests pass for affected components
- Update documentation if you've changed user-facing functionality
- Add entries to CHANGELOG.md for notable changes
- Keep PRs focused — one feature or fix per PR
- Be respectful and constructive in discussions
- Help others when you can
Thank you for contributing to Polis!