Skip to content

feat(cli): T8 — global --project flag#4

Merged
hbrombeer merged 1 commit intomainfrom
feat/cli-project-flag
Apr 26, 2026
Merged

feat(cli): T8 — global --project flag#4
hbrombeer merged 1 commit intomainfrom
feat/cli-project-flag

Conversation

@hbrombeer
Copy link
Copy Markdown
Member

Summary

T8 of the Multi-Project model. CLI gains a global `--project ` flag (and `GROUNDS_PROJECT` env var fallback) that threads `projectId` into every forge call. Empty value falls back to forge's default-project resolution, so single-project users see no behaviour change.

Changes

  • `internal/api/client.go` — `Client.ProjectID`, `WithProject` clone helper, `scopedPath` that idempotently appends `?projectId=` (URL-escaped, no double-append).
  • `cluster.go` — `ClusterDelete` builds its request inline; switched to `scopedPath` too.
  • `cmd/grounds/commands/root.go` — `PersistentFlags().String("project", ...)` so every subcommand inherits.
  • `cluster/` + `push/` subcommands — read `--project` (cobra) / `GROUNDS_PROJECT` (env) and stamp it on `Client.ProjectID`.

Tests

  • Table cases for `scopedPath`: empty → no-op, plain → `?projectId=`, query already present → `&projectId=`, special chars → URL-escaped, idempotent when `projectId=` already in path.
  • Wire-level: `Client.ProjectID = "p-test"` + `GetCluster` → server sees `/v1/cluster?projectId=p-test`.
  • `WithProject` clones rather than mutating the receiver.

Spec

`grounds-platform/docs/specs/2026-04-26-multi-project-model.md` §10 T8

Test plan

  • `go build ./...`
  • `go test ./...` — all packages green
  • CI green
  • Manual: `grounds cluster status` (no flag) hits default project; `grounds cluster status --project ` switches scope

🤖 Generated with Claude Code

Phase 6.1 T8 of the Multi-Project model. CLI gains a global
\`--project <id>\` flag (also GROUNDS_PROJECT env var); when set,
every forge call carries it as \`?projectId=...\` so multi-project
users can target a specific project from the terminal. Empty value
falls back to forge's default-project resolution (the user's
auto-created Personal project), so single-project users see no
behaviour change.

- internal/api/client.go: Client gains a ProjectID field + WithProject
  clone helper. doRequest threads the id through scopedPath() which
  appends the query string (idempotent, URL-escapes, doesn't double-
  append if path already carries projectId).
- ClusterDelete builds its request inline; updated to also call
  scopedPath.
- cmd/grounds/commands/root.go: cobra persistent flag declared at the
  root so all subcommands inherit it.
- cmd/grounds/commands/cluster + push: read --project / GROUNDS_PROJECT
  before constructing the API client and stamp it onto Client.ProjectID.

Tests cover the path-mutation table cases + the wire-level
propagation through doRequest + the WithProject clone semantics.
@hbrombeer hbrombeer merged commit dfd42ad into main Apr 26, 2026
5 checks passed
@hbrombeer hbrombeer deleted the feat/cli-project-flag branch April 26, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant