ksrc is a Go CLI for searching and reading Kotlin/Java dependency sources resolved from Gradle projects.
It resolves dependencies via Gradle, ensures -sources.jar artifacts exist in Gradle caches, then uses rg for search and zip reads for cat/open.
The tool is designed for scriptable/agent workflows: stable output, file-id chaining, and zero mutation of the target project.
Primary docs to keep aligned with code:
README.mddocs/cli-api.mddocs/decisions.mdskills/ksrc/SKILL.md
- Run the local quality gate used in CI before pushing:
./scripts/ci-format.sh
go vet ./...
go test ./...- Rebuild local CLI binary after code changes:
KSRC_VERSION="$(tr -d ' \n' < VERSION)"
go build -ldflags "-X github.com/respawn-app/ksrc/internal/cli.Version=${KSRC_VERSION}" -o ./bin/ksrc ./cmd/ksrc- Run a fast functional smoke check against the sample project:
./bin/ksrc search LocalDate --module org.jetbrains.kotlinx:kotlinx-datetime --project ./sample- For release-related changes, follow
docs/release-workflow.mdand usescripts/update-brew-tap.shinstead of manual formula edits.
- Add a regression test for every bug fix.
- Add unit tests for every new feature.
- Keep tests in the package being changed (
internal/<pkg>/*_test.go) and prefer deterministic fakes/stubs over networked/real-project dependencies.
Test layers used in this repo:
- Default test suite (
go test ./...): unit tests plus lightweight integration tests usingtestdata/fixture/gradlewfake wrapper and temporary jars. - Real Gradle integration suite: gated by
KSRC_INTEGRATION=1ininternal/cli/integration_gradle_test.go; usestestdata/integrationandsample. - MCP integration test:
internal/mcpserver/integration_test.gobuilds and launchesksrc mcpand exercises tool calls.
Useful test commands:
go test ./...
go test ./internal/cli -run Integration
KSRC_INTEGRATION=1 go test ./internal/cli -run IntegrationWithRealGradle
go test -cover ./...cmd/ksrc/main.go: CLI entrypoint.internal/cli/: Cobra command wiring, flags, output formatting, hints.internal/resolution/: orchestration layer from CLI to Gradle/cache resolution.internal/gradle/: init script generation, Gradle invocation, traversal (root -> buildSrc -> included builds).internal/resolve/: cache scanning, coordinate/file-id parsing, filtering/version selection.internal/search/:rgexecution strategy (--search-zipwhen supported, extract fallback), output parsing.internal/cat/: zip file reads and--linesrange parsing.internal/mcpserver/: stdio MCP server and tool handlers.internal/executil/: command execution abstraction used for testability.testdata/fixture/: fake Gradle wrapper test fixture.testdata/integration/: real Gradle integration fixture.sample/: KMP/Android sample used for smoke coverage.docs/: API spec, decisions, release workflow.scripts/: CI format check, install script, brew tap update automation.
- Build output version is injected from
VERSIONvia ldflags; without that, CLI reportsdev. - Keep
./bin/ksrccurrent if your local shell/tooling points to it.
- Keep command wiring thin in
internal/cli; add behavior in domain packages (resolution,gradle,resolve,search,cat,mcpserver). - Preserve zero-mutation behavior for target Gradle projects; only temporary files are allowed.
- Resolution behavior is intentional and documented in
docs/decisions.md. - Gradle invocation failures fall back to cache-only resolution with warnings; this is part of UX contract.
- Search output and file-id contract are API surfaces; keep formats stable and parseable:
- Search:
<file-id> <line>:<col>:<match> - File-id:
group:artifact:version!/path/inside/jar.ext
- Search:
- MCP tools are plaintext-first; keep tool outputs in
contentand avoid introducing structured payload dependencies.
- Follow
gofmtstrictly (./scripts/ci-format.shis authoritative). - Keep CLI stdout machine-parseable; send diagnostics/warnings/verbose lines to stderr.
- Reuse
executil.Runnerinstead of directos/execin logic that needs test coverage. - Keep changes cohesive and package-local; avoid leaking command concerns into resolution/search internals.
- When flags/output/API surface changes, update all affected docs and skill files in the same change.
- Follow the commit style used by changelog automation: scoped/typed subject lines such as
cli: ...,mcp: ...,docs: ...,release: ...,fix: ....
Always keep this file up-to-date when you change project behavior, workflows, flags, outputs, release process, or architecture; remove stale facts promptly, and do not add temporary notes, generic boilerplate, or frequently changing product details.