Devkit is a CLI application written in Go. It is designed to:
- Initialize projects and generate project scaffolding.
- Provide and apply reusable code templates.
- Download, install, or prepare device-related dependencies.
- Create, update, and configure files required by projects or local development environments.
All implementations should be designed for CLI use. Commands must be clear, behavior must be predictable, errors must be actionable, and cross-platform compatibility should be considered.
- Keep the root-level
Makefileas the single entry point for local formatting, tests, verification, builds, and releases. Do not add bothMakefileandmakefile. - Keep local checks reproducible with the commands defined in
Makefile; avoid adding a command that depends on an undocumented global executable when a project-managed or CI-managed alternative is available. - Keep CI responsibilities in
.github/workflows/ci.ymland release responsibilities in.github/workflows/release.yml. - The release workflow uses the open-source GoReleaser distribution. Run
go mod verifyas an explicit workflow step rather than using GoReleaser Pro-only global hooks. - Use
prek.tomlonly as the Git hook integration. The pre-commit hook should invokemake check; do not duplicate project checks or lint rules insideprek. - Keep
make lintas the single local entry point for Go formatting and golangci-lint, and keepmake checkas the complete local quality gate that includesmake lint. - Keep
scripts/install.shaligned with the archive names and supported targets in.goreleaser.yaml; verify downloaded archives withchecksums.txtbefore installation. - Treat
devkit,dist/, andcoverage.outas generated outputs; do not commit them.
- This is a Go project. New code must follow official Go conventions and be formatted with
gofmt. - Prefer the Go standard library. Evaluate third-party packages only when the standard library cannot reasonably satisfy the requirement.
- Avoid reinventing existing solutions. When a mature implementation already exists for a general-purpose feature, use a reliable package instead of building a custom replacement.
- Do not introduce a large package, a complex dependency tree, or a high maintenance burden for a small feature. The benefit of a dependency must clearly outweigh its cost.
- Keep implementations simple, maintain clear module boundaries, and provide useful error messages for user-visible failures.
- Keep executable entry points under
cmd/<binary>small. They should wire dependencies, execute the application, report terminal errors, and avoid containing command business logic. - Assemble the Devkit root command in
internal/app. - Put each top-level user-facing CLI command in its own package under
internal/commands. Use a clear package suffix such asinitcmdwhen the command name conflicts with a Go keyword or would otherwise be ambiguous. - Keep sub-flows that only belong to one command inside that command package. Extract a separate internal package only when logic or data is genuinely shared or forms an independent domain boundary.
- Keep reusable runtime version types, embedded version data, and loading logic in
internal/runtime. Treatinternal/runtime/data/versions.jsonas checked-in data, not user configuration. - Keep maintenance executables, such as the runtime snapshot updater, as separate binaries under
cmdrather than exposing them as user-facing Devkit commands. - Keep tests beside the package they verify. Test command packages directly, and keep a small assembly test for the root command.
Conduct thorough research before introducing any third-party Go package. Do not select a package based on assumptions or a single metric.
Research must consider at least:
- GitHub stars, usage, import counts, and general community adoption.
- Recent commits and releases, issue and pull request responsiveness, and maintainer activity.
- Compatibility with the Go version used by this project and its primary target platforms.
- API stability, documentation quality, license, dependency tree size, and known security risks.
- Newer, lighter, or more actively maintained alternatives that provide similar functionality.
Selection principles:
- Prefer widely adopted packages with strong usage, high GitHub stars, good documentation, and active maintenance.
- High usage and star counts are not sufficient on their own. Do not select a package solely because of its historical popularity if it is unmaintained, outdated, or superseded by a modern alternative.
- When candidates have similar maturity, prefer the package with more recent development, regular releases, and compatibility with modern Go tooling.
- Briefly document the evaluated candidates, selection rationale, important tradeoffs, and links to the official documentation or source repository.
The user must run every go get command manually. Agents and automated tools must never run go get themselves.
When a task requires a new third-party dependency:
- Complete the requirement analysis, package research, and package selection first.
- Stop immediately when the dependency needs to be installed. Do not run
go get, and do not bypass this process by manually editinggo.modorgo.sum. - Tell the user the exact command to run, such as
go get example.com/module@version. - Provide links to the selected package's official documentation and source repository, together with a short explanation of the selection rationale.
- Wait for the user to confirm that the command has been completed.
- Continue implementing code that depends on the package and perform subsequent verification only after receiving confirmation.
If a task does not require a new dependency, implementation may continue without triggering this approval process.