Skip to content

Commit 216f8d8

Browse files
authored
Feat/container registry command (#44)
* feat(registry): add container registry command skeleton with vcr, vccr alias
1 parent 312698c commit 216f8d8

62 files changed

Lines changed: 20463 additions & 21 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/security.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ jobs:
4141
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.5.0
4242

4343
- name: Run gosec via golangci-lint
44-
run: golangci-lint run --no-config -E gosec ./...
44+
# --default=none + -E gosec scopes this step to gosec findings only.
45+
# Without --default=none, golangci-lint's "standard" linter set
46+
# (errcheck, govet, staticcheck, ...) also runs, which duplicates
47+
# `make lint` and bypasses the project's test-file exclusions in
48+
# .golangci.yaml — producing noise unrelated to security.
49+
run: golangci-lint run --no-config --default=none -E gosec ./...
4550

4651
gitleaks:
4752
name: Gitleaks (secret scanning)

AGENTS.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Read `CLAUDE.md` first. This file defines how you execute, not what the project is.
44

5+
Applies to every AI agent working in this repo. Primary targets are Claude Code (reads `CLAUDE.md`) and OpenAI Codex (reads this file). `CLAUDE.md` (project knowledge) + this file (execution contract) + `.golangci.yaml` (enforced style) form the complete brief. A `.cursor/rules/main.mdc` pointer exists for Cursor users but is not actively maintained.
6+
57
## Mandatory Read-First, Plan-First Workflow
68

79
Do NOT write code until you have completed all steps below. No exceptions.
@@ -44,7 +46,10 @@ Skipping these steps leads to pattern violations, broken dual-mode, and pricing
4446
## Done Checklist
4547

4648
- [ ] `make build` passes
47-
- [ ] `make test` passes
49+
- [ ] `make lint` passes with zero issues (do not rely on pre-commit to surface these)
50+
- [ ] `make test` passes (runs lint + unit tests)
4851
- [ ] `--help` renders correctly for changed commands
4952
- [ ] Interactive and non-interactive modes both work
5053
- [ ] No leftover debug code, TODOs, or commented-out blocks
54+
55+
If `make lint` reports issues, fix them *before* announcing completion. See `CLAUDE.md` § "Go House Style" for the patterns that prevent the common hits (http.NoBody, American spelling, reused constants, rangeValCopy, nilerr annotations, etc.).

CLAUDE.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Each command directory has its own `CLAUDE.md` (domain knowledge) and `README.md
3939
| `cmd/volume/` | CLAUDE.md, README.md | Volume lifecycle, trash, actions |
4040
| `cmd/sshkey/` | CLAUDE.md, README.md | SSH key management |
4141
| `cmd/startupscript/` | CLAUDE.md, README.md | Startup script management |
42+
| `cmd/registry/` | CLAUDE.md, README.md | Container registry (vccr.io): configure, show, login, ls, tags, push, copy — pre-release behind `VERDA_REGISTRY_ENABLED=1` |
4243
| `cmd/update/` | CLAUDE.md, README.md | CLI self-update |
4344
| `cmd/settings/` | CLAUDE.md, README.md | CLI settings management |
4445
| `cmd/availability/` || Instance availability by location |
@@ -67,6 +68,22 @@ Each command directory has its own `CLAUDE.md` (domain knowledge) and `README.md
6768

6869
## Conventions
6970

71+
### Go House Style — avoid avoidable lint hits
72+
73+
The repo lints with `golangci-lint` via `make lint` (included in `make test`). These are the patterns the linters enforce — write them correctly the first time instead of fixing them in a second pass:
74+
75+
- **HTTP bodies** — use `http.NoBody` for GET/DELETE/etc., never `nil`. Close with `defer func() { _ = resp.Body.Close() }()`, not bare `defer resp.Body.Close()` (errcheck).
76+
- **American English**`behavior`, `canceled`, `artifact`, `checkered`, `gray`. `misspell` runs with `locale: US` and rejects British spellings in code and comments.
77+
- **Reuse constants** — before writing a string literal that might repeat, grep for an existing one. Current package-level constants worth knowing: `defaultTag` (`"latest"`) in `cmd/registry/refname.go`, `progressJSON` (`"json"`) in `cmd/registry/push.go`, `untaggedLabel` (`"<untagged>"`) in `cmd/registry/format.go`. `goconst` fails on ≥3 occurrences.
78+
- **Strings over fmt.Sprintf**`"prefix " + s` beats `fmt.Sprintf("prefix %s", s)` when there's only one substitution (perfsprint).
79+
- **Range indexing for structs ≥96 B**`for i := range xs { x := &xs[i] }` avoids the per-iteration copy `for _, x := range xs` incurs (gocritic rangeValCopy). `ArtifactInfo`, `VMDescribeResult`, etc. all cross the threshold.
80+
- **Intentional `return nil` after error** — prompter cancellation returns an error that we deliberately swallow. Annotate with `return nil //nolint:nilerr // intentional: prompter cancel is a clean exit` so `nilerr` doesn't flag it and the reason survives.
81+
- **No blank line after `{`**`whitespace` linter flags it. Go straight into the first statement.
82+
- **Type inference over explicit declaration**`rt := http.DefaultTransport` over `var rt http.RoundTripper = http.DefaultTransport` (staticcheck ST1023).
83+
- **Complexity budgets**`gocyclo` trips at 20, `nestif` at 5. Extract helpers before you hit them; refactoring after the fact is more churn.
84+
85+
`.golangci.yaml` is the authoritative list — all of the above come from linters enabled there.
86+
7087
### Every API-calling command MUST:
7188

7289
1. **Timeout context**: `ctx, cancel := context.WithTimeout(cmd.Context(), f.Options().Timeout)`
@@ -125,9 +142,15 @@ make build # Must compile
125142
make test # Must pass (tests + lint)
126143
```
127144

145+
`make test` runs `golangci-lint`**never** report work as complete with lint failures outstanding. Fix them before the "done" message; don't defer to the pre-commit hook. See the "Go House Style" section above for the patterns that prevent the common hits.
146+
128147
If you modified a command, also verify:
129148
- `./bin/verda <command> --help` renders correctly
130149
- Interactive mode works (prompts appear)
131150
- Non-interactive mode works (flags only, no prompts)
132151
- `--agent -o json` mode works (structured output, no TUI)
133152
- `--debug` shows request/response payloads
153+
154+
## Other Agents
155+
156+
This repo targets Claude Code and OpenAI Codex. Claude auto-loads this file; Codex auto-loads `AGENTS.md` (execution contract). A `.cursor/rules/main.mdc` pointer exists for Cursor users but is not a primary target — if Cursor drops out of the stack, delete it rather than letting it drift.

go.mod

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,27 @@ require (
99
github.com/spf13/pflag v1.0.10
1010
github.com/spf13/viper v1.21.0
1111
github.com/verda-cloud/verdacloud-sdk-go v1.4.2
12-
github.com/verda-cloud/verdagostack v1.3.2
12+
github.com/verda-cloud/verdagostack v1.3.3
1313
go.yaml.in/yaml/v3 v3.0.4
1414
)
1515

1616
require (
17+
charm.land/bubbletea/v2 v2.0.2
1718
github.com/aws/aws-sdk-go-v2 v1.41.6
1819
github.com/aws/aws-sdk-go-v2/config v1.32.16
1920
github.com/aws/aws-sdk-go-v2/credentials v1.19.15
2021
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.15
2122
github.com/aws/aws-sdk-go-v2/service/s3 v1.99.1
2223
github.com/aws/smithy-go v1.25.0
2324
github.com/charmbracelet/x/term v0.2.2
25+
github.com/google/go-containerregistry v0.21.5
2426
github.com/mark3labs/mcp-go v0.47.0
2527
gopkg.in/ini.v1 v1.67.1
2628
)
2729

2830
require (
2931
charm.land/bubbles/v2 v2.1.0 // indirect
30-
charm.land/bubbletea/v2 v2.0.2 // indirect
32+
github.com/Microsoft/go-winio v0.6.2 // indirect
3133
github.com/atotto/clipboard v0.1.4 // indirect
3234
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.9 // indirect
3335
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.22 // indirect
@@ -42,6 +44,7 @@ require (
4244
github.com/aws/aws-sdk-go-v2/service/sso v1.30.16 // indirect
4345
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.20 // indirect
4446
github.com/aws/aws-sdk-go-v2/service/sts v1.42.0 // indirect
47+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4548
github.com/charmbracelet/colorprofile v0.4.2 // indirect
4649
github.com/charmbracelet/harmonica v0.2.0 // indirect
4750
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect
@@ -50,27 +53,52 @@ require (
5053
github.com/charmbracelet/x/windows v0.2.2 // indirect
5154
github.com/clipperhouse/displaywidth v0.11.0 // indirect
5255
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
56+
github.com/containerd/errdefs v1.0.0 // indirect
57+
github.com/containerd/errdefs/pkg v0.3.0 // indirect
58+
github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect
59+
github.com/distribution/reference v0.6.0 // indirect
60+
github.com/docker/cli v29.4.0+incompatible // indirect
61+
github.com/docker/docker-credential-helpers v0.9.3 // indirect
62+
github.com/docker/go-connections v0.6.0 // indirect
63+
github.com/docker/go-units v0.5.0 // indirect
64+
github.com/felixge/httpsnoop v1.0.4 // indirect
5365
github.com/fsnotify/fsnotify v1.9.0 // indirect
66+
github.com/go-logr/logr v1.4.3 // indirect
67+
github.com/go-logr/stdr v1.2.2 // indirect
5468
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
5569
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
5670
github.com/google/jsonschema-go v0.4.2 // indirect
5771
github.com/google/uuid v1.6.0 // indirect
5872
github.com/inconshreveable/mousetrap v1.1.0 // indirect
73+
github.com/klauspost/compress v1.18.5 // indirect
5974
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
6075
github.com/mattn/go-runewidth v0.0.21 // indirect
76+
github.com/mitchellh/go-homedir v1.1.0 // indirect
77+
github.com/moby/docker-image-spec v1.3.1 // indirect
78+
github.com/moby/moby/api v1.54.1 // indirect
79+
github.com/moby/moby/client v0.4.0 // indirect
6180
github.com/muesli/cancelreader v0.2.2 // indirect
81+
github.com/opencontainers/go-digest v1.0.0 // indirect
82+
github.com/opencontainers/image-spec v1.1.1 // indirect
6283
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
6384
github.com/rivo/uniseg v0.4.7 // indirect
6485
github.com/sagikazarmark/locafero v0.11.0 // indirect
86+
github.com/sirupsen/logrus v1.9.4 // indirect
6587
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
6688
github.com/spf13/afero v1.15.0 // indirect
6789
github.com/spf13/cast v1.10.0 // indirect
6890
github.com/subosito/gotenv v1.6.0 // indirect
91+
github.com/vbatts/tar-split v0.12.2 // indirect
6992
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
7093
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
94+
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
95+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
96+
go.opentelemetry.io/otel v1.43.0 // indirect
97+
go.opentelemetry.io/otel/metric v1.43.0 // indirect
98+
go.opentelemetry.io/otel/trace v1.43.0 // indirect
7199
go.uber.org/multierr v1.10.0 // indirect
72100
go.uber.org/zap v1.27.1 // indirect
73101
golang.org/x/sync v0.20.0 // indirect
74-
golang.org/x/sys v0.42.0 // indirect
102+
golang.org/x/sys v0.43.0 // indirect
75103
golang.org/x/text v0.35.0 // indirect
76104
)

0 commit comments

Comments
 (0)