fix(grant): resolve repo by name via the singular `repo` field (COR-699) · Entire

fix(grant): resolve repo by name via the singular repo field (COR-699)

9fe0c77→main·

toothbrush·2w ago·2 files·+9 added/-6 removed

The control plane returns a name-filtered repo list under the singular repo field (like org/project), not the plural repos array — repos is only populated for an unfiltered page. resolveRepoRef read repos, so grant repo {list,add,remove} <name> --project <p> always 404'd with "no repo named" even when the repo existed. The fixture mocked the plural array too, hiding it; it now mirrors the real server's singular field.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

0a7fba82dafbView transcript

[?
Improve Grant CLI Verb Syntax and HandlingClaude Code·Opus 4.8[1m]·1 step](/content/gh/entireio/cli/session/fbd23c93-1510-47c9-9201-6c325b4f3251#timeline-0a7fba82dafb/index.html)

Changes

2

171 unmodified lines

172
173
174
175
176
177
178
175
176
177
178
179
180
181

171 unmodified lines

// resolveRepoRef turns a repo reference into its ULID. A ULID passes through.
// A name requires a project scope (projectRef, itself a name or ULID) because
// repo names are unique only within a project: the repo is resolved via the
// server's case-insensitive by-name lookup, scoped to that project. A
// name-filtered query returns the single match in the response's `repo`
// field (empty when there's no match) — the `repos` array is only populated
// for unfiltered list pages.
// server's case-insensitive by-name lookup, scoped to that project. Like the
// org/project endpoints, a name-filtered list returns the single match under the
// response's singular `repo` field (the plural `repos` is only populated for an
// unfiltered page) — reading `repos` here was the COR-699 bug.
func resolveRepoRef(ctx context.Context, c *coreapi.Client, ref, projectRef string) (string, error) {
    if looksLikeULID(ref) {
        return ref, nil

Mcmd/entire/cli/resolveref.go+4/-4

203 unmodified lines

204
205
206
207
208
207
208
209
210
211
212
213
214

203 unmodified lines

var gotName string
    c, calls := resolveTestClient(t, func(w http.ResponseWriter, r *http.Request) {
        gotName = r.URL.Query().Get("name");
        // A name-filtered query returns the match in the singular `repo`
        // field, not the `repos` page array — mirror the real server.
        // A name-filtered list returns the single match under the singular
        // `repo` field (like org/project) — NOT the plural `repos` array,
        // which is only populated for an unfiltered page. Reading `repos`
        // here was the COR-699 bug, so the fixture must mirror the real
        // server's singular field to keep that regression covered.
        if err := writeJSON(w, &coreapi.ListProjectReposOutputBody{Repo: coreapi.NewOptRepo(coreapi.Repo{ID: ulidRepoWeb, Name: "web"})}); err != nil {
            t.Errorf("encode repo: %v", err)
        }
    }

Mcmd/entire/cli/resolveref_test.go+5/-2