4.2 KiB
4.2 KiB
Conventions
Rules that govern this repo. Anything that becomes load-bearing belongs here, in conventions.md, never in a section appended to another doc.
Repository layout
cmd/ one subdir per shippable binary; package main only
setup/ bootstrap installer entry (go run ./setup); not shipped
internal/ every other package; never imported outside this module
internal/installer/ the one install/update implementation (shared by setup + `sherlock update`)
docs/ one topic per file (see "Docs" below)
VERSION release version source of truth (see versioning.md)
README.md TOC only
No top-level pkg/ until we have an external consumer.
Go
- Module path:
gitea.alexandru.macocian.me/amacocian/sherlock. - Target Go toolchain:
go 1.25(pinned viago.mod'sgodirective; CI installs the matching minor). - One
package mainpercmd/<binary>/. No multiple-main-files trickery. - Every other package has a top-of-file
Package <name> ...doc comment (in the leading.gosource file; we drop standalonedoc.gofiles once a real source file exists). - Third-party deps are added with a one-line justification. The current set:
github.com/zalando/go-keyring— OS keyring for token persistence.github.com/BurntSushi/toml— parse the operator config (config.toml).github.com/coreos/go-oidc/v3— OIDC discovery + ID-token verification against Authentik.golang.org/x/oauth2— auth-code + PKCE + refresh against Authentik's token endpoint.golang.org/x/mod—semverfor version comparison in self-update.github.com/grafana/mcp-grafana+github.com/mark3labs/mcp-go— upstream Grafana MCP tool set, served in-process bycmd/grafana-mcp.github.com/modelcontextprotocol/go-sdk— MCP server SDK for the gitea/gssh MCPs.github.com/coder/websocket— gssh exec WebSocket client.
Docs
README.mdis TOC only. One-line description + a bulleted index ofdocs/*.md.- One topic per file under
docs/. Never append a new section to an existing doc to cover a new concern; createdocs/<new-topic>.mdand link it fromREADME.md. - Cross-link aggressively: every doc should link to the other docs whose concerns it touches.
- Mermaid diagrams over images or ASCII art. Diagrams live next to the prose that explains them.
Naming
- Binaries are kebab-case (
gitea-mcp,gssh-mcp). - Built-in agent profiles match the agent's canonical CLI name (
copilot,claude,aider). - Service registry files match the service's canonical name (
gitea.toml,grafana.toml). - Env vars are
<SERVICE>_TOKEN(e.g.GITEA_TOKEN,GSSH_TOKEN).
Extensibility invariants
- Agent extensibility: adding a new agent CLI is a Go file under
internal/agent/registering itself viainit(). See agents.md. The TOML-overlay design was tried and dropped — per-CLI quirks (auth subcommands, flag schemas, MCP config shapes) deserve a real code home. - Service extensibility: adding a new downstream service is a TOML drop-in under
~/.config/sherlock/services.d/+ (optionally) a newcmd/<service>-mcp/binary. Sherlock's own code does not learn about individual services.
Commits
- Conventional-ish:
area: short imperative(e.g.authn: persist client_id in TokenSet,docs: add gssh-integration). - One logical change per commit. CI must pass on every commit on
main.
CI
.gitea/workflows/release.yamlis the single pipeline. On every push + PR it runsgofmt,go vet,errcheck,staticcheck,go test -race, andgo build.- On push to
mainonly, and only after every gate above passes, a final step reads the rootVERSIONfile and pushes the tagvVERSIONif it doesn't already exist. A tag is never created on a red build. Cutting a release is a one-line edit toVERSION. See versioning.md. - Sherlock is operator-installed via
install.sh(which clones +go installs) and self-updates viasherlock update. No host-deploy pipeline.
Security
- No secrets in this repo, ever. Not in tests, not in fixtures, not in comments.
- The operator's Authentik tokens and (Phase 2+) per-service tokens live in the OS keyring. See storage.md.