# fix(repo): resolve `mirror get` clone URLs via that cluster's core

`5a02cce`→[main](/content/gh/entireio/cli/commits/main/index.html)·  toothbrush·1w ago·3 files·+166 added/-8 removed

`entire repo mirror get entire://<cluster>/gh/<owner>/<repo>` listed mirrors on the active context's core, so a clone URL for a cluster in a different federation failed with "no mirror matching" until the user manually switched contexts with `entire auth use`. The clone URL already names its cluster; dial the core fronting it — discovered from the cluster's /.well-known/entire-cluster.json and authenticated with the matching local context — the same routing `mirror create`/`remove` (PR #1475) and `repo clone --cluster` (PR #1529) already use. A ULID ref carries no cluster coordinate and stays on the active context.

Adds runCoreObjectForCluster (mirroring runCoreListForCluster) and a clusterCoreClient test seam alongside activeCoreClient so the routing decision is pinned by command-level tests without live discovery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

## Changes

3

- cmd/entire/cli

- Mcorecmd.go+25/-3
  - Mrepo_mirror.go+32/-5
  - Mrepo_mirror_test.go+109

``` 
214 unmodified lines

``` 
// field/value list (default) or raw JSON (--json), reusing the same column definition as the matching list view.
func runCoreObject[T any](cmd *cobra.Command, headers []string, row func(T) []string, fn func(ctx context.Context, c *coreapi.Client) (*T, error)) error {
    return runCore(cmd, func(ctx context.Context, c *coreapi.Client) error {
        return runCore(cmd, renderCoreObject(cmd, headers, row, fn))
    })
}

// runCoreObjectForCluster is runCoreObject for a resource-provider command (see runCoreForCluster): identical field/JSON rendering, but dialing the core that fronts clusterHost rather than the active context.
func runCoreObjectForCluster[T any](cmd *cobra.Command, clusterHost string, headers []string, row func(T) []string, fn func(ctx context.Context, c *coreapi.Client) (*T, error)) error {
    return runCoreForCluster(cmd, clusterHost, renderCoreObject(cmd, headers, row, fn))
}

// renderCoreObject builds the run-function shared by runCoreObject and runCoreObjectForCluster: fetch via fn, then render as a field/value list (default) or raw JSON (--json). Kept separate from the client-selection so the two object variants differ only in which core they dial (mirroring renderCoreList).
func renderCoreObject[T any](cmd *cobra.Command, headers []string, row func(T) []string, fn func(ctx context.Context, c *coreapi.Client) (*T, error)) func(context.Context, *coreapi.Client) error {
    return func(ctx context.Context, c *coreapi.Client) error {
        item, err := fn(ctx, c)
        if err != nil {
            return err
        }
        return printFields(cmd.OutOrStdout(), headers, row(*item))
    }
}
// tableStyles holds the foreground styles for the human table/field views,
// without standing up the auth/context/TLS stack.
var activeCoreClient = func(context.Context) (*coreapi.Client, error) { return coreapi.New() }

// clusterCoreClient builds the control-plane client for cluster-addressed commands (see runCoreForCluster). Same test seam as activeCoreClient — production wiring is coreapi.NewForCluster, which does live /.well-known discovery that command-level tests must not reach.
var clusterCoreClient func(ctx context.Context, clusterHost string) (*coreapi.Client, error) = coreapi.NewForCluster

// runCore is the shared base for every active-context control-plane command: it owns the preamble only — silence usage, build the client, map API errors — and leaves all rendering to fn. The delete/revoke verbs call it
// cluster_host". See coreapi.NewForCluster.
func runCoreForCluster(cmd *cobra.Command, clusterHost string, fn func(ctx context.Context, c *coreapi.Client) error) error {
    return runCoreClient(cmd, func(ctx context.Context) (*coreapi.Client, error) {
        return coreapi.NewForCluster(ctx, clusterHost)
    }, fn)
}
```
Mcmd/entire/cli/corecmd.go+25/-3

```
422 unmodified lines

```  
Short: "Show a mirror by ULID or clone URL",
Long: "Show a mirror. <mirror> is either a mirror ULID or an entire:// clone " +
"URL\n(entire://<cluster>/gh/<owner>/<repo>) — the form `mirror list` " +
"prints and `git clone` accepts.",
Example: "  entire repo mirror get 01KS6KFJR2XS6PZ188MVYE07AN\n" +
"  entire repo mirror get entire://aws-us-east-2.entire.io/gh/octocat/hello-world",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
    return runCoreObject(cmd, mirrorColumns, mirrorRow, func(ctx context.Context, c *coreapi.Client) (*coreapi.Mirror, error) {
        mirrorID, err := resolveMirrorRef(ctx, c, args[0])
        ref := args[0]
        show := func(ctx context.Context, c *coreapi.Client) (*coreapi.Mirror, error) {
            mirrorID, err := resolveMirrorRef(ctx, c, ref)
            if err != nil {
                return nil, err
            }
            return c.GetMirror(ctx, coreapi.GetMirrorParams{MirrorId: mirrorID})
        }
    }
    // A ULID carries no cluster coordinate, so it can only be looked up
    // on the active context's core. A clone URL names its cluster — dial
    // the core fronting that cluster (discovered from its well-known and
    // authenticated with the matching local context, the same path
    // create/remove use), so the lookup works when the mirror lives in a
    // federation other than the active login instead of failing with
    // "no mirror matching".
    if looksLikeULID(ref) {
        return runCoreObject(cmd, mirrorColumns, mirrorRow, show)
    }
    clusterHost, _, _, _, err := parseMirrorCloneURL(ref)
    if err != nil {
        cmd.SilenceUsage = true
        return badMirrorRefErr(err)
    }
    return runCoreObjectForCluster(cmd, clusterHost, mirrorColumns, mirrorRow, show)
},
}
}

```
Mcmd/entire/cli/repo_mirror.go+32/-5

```664 unmodified lines

```  
// TestRepoMirrorGet_Routing pins which core `mirror get <ref>` dials. A clone
// URL names its cluster, so it must be resolved on the core fronting that
// cluster (clusterCoreClient), not the active context — the original bug:
// `mirror get entire://<cluster>/…` for a cluster in a federation other than
// the active login failed with "no mirror matching" until the user switched
// contexts. A ULID carries no cluster coordinate and stays on the active
// context; an unparseable ref must error before dialing anything.
func TestRepoMirrorGet_Routing(t *testing.T) {
    const mirrorULID = "0123456789ABCDEFGHJKMNPQRS"
    const clusterHost = "eukanuba.partial.to"
    const cloneURL = "entire://" + clusterHost + "/gh/entirehq/librarian"

// mirrorServer answers both the list (clone-URL resolution) and the
// GetMirror-by-ULID calls for the librarian mirror.
    mirrorServer := func(t *testing.T) *httptest.Server {
        t.Helper()
        srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Header().Set("Content-Type", "application/json")
            switch r.URL.Path {
            case mirrorsAPIPath:
                assert.NoError(t, printJSON(w, &coreapi.ListMirrorsOutputBody{Mirrors: []coreapi.Mirror{
                    {MirrorId: mirrorULID, Owner: "entirehq", Repo: "librarian", ClusterHost: clusterHost},
                }}))
            case mirrorsAPIPath + "/" + mirrorULID:
                assert.NoError(t, printJSON(w, &coreapi.Mirror{
                    MirrorId: mirrorULID, Owner: "entirehq", Repo: "librarian", ClusterHost: clusterHost,
                    IsPrivate: coreapi.NewOptBool(true),
                }))
            default:
                t.Errorf("unexpected request path %q", r.URL.Path)
                w.WriteHeader(http.StatusNotFound)
            }
        }))
        t.Cleanup(srv.Close)
        return srv
    }
    seamActive := func(t *testing.T, fn func(context.Context) (*coreapi.Client, error)) {
        t.Helper()
        prev := activeCoreClient
        activeCoreClient = fn
        t.Cleanup(func() { activeCoreClient = prev })
    }
    seamCluster := func(t *testing.T, fn func(context.Context, string) (*coreapi.Client, error)) {
        t.Helper()
        prev := clusterCoreClient
        clusterCoreClient = fn
        t.Cleanup(func() { clusterCoreClient = prev })
    }
    runGet := func(t *testing.T, ref string) (string, error) {
        t.Helper()
        cmd := newRepoCmd()
        var out, errW bytes.Buffer
        cmd.SetOut(&out)
        cmd.SetErr(&errW)
        cmd.SetArgs([]string{"mirror", "get", ref})
        err := cmd.ExecuteContext(t.Context())
        return out.String(), err
    }

t.Run("clone URL dials the cluster's core, not the active context", func(t *testing.T) {
    srv := mirrorServer(t)
    seamActive(t, func(context.Context) (*coreapi.Client, error) {
        t.Error("clone-URL get dialed the active context's core")
        return nil, errors.New("wrong core")
    })
    var gotHost string
    seamCluster(t, func(_ context.Context, host string) (*coreapi.Client, error) {
        gotHost = host
        return coreapi.NewWithBearer(srv.URL, "tok")
    })
    out, err := runGet(t, cloneURL)
    require.NoError(t, err)
    require.Equal(t, clusterHost, gotHost, "must resolve on the clone URL's cluster")
    require.Contains(t, out, "entirehq/librarian")
    require.Contains(t, out, cloneURL)
})

t.Run("ULID dials the active context", func(t *testing.T) {
    srv := mirrorServer(t)
    seamActive(t, func(context.Context) (*coreapi.Client, error) {
        return coreapi.NewWithBearer(srv.URL, "tok")
    })
    seamCluster(t, func(_ context.Context, host string) (*coreapi.Client, error) {
        t.Errorf("ULID get dialed cluster core %q; a ULID has no cluster coordinate", host)
        return nil, errors.New("wrong core")
    })
    out, err := runGet(t, mirrorULID)
    require.NoError(t, err)
    require.Contains(t, out, "entirehq/librarian")
})

t.Run("unparseable ref errors before dialing any core", func(t *testing.T) {
    seamActive(t, func(context.Context) (*coreapi.Client, error) {
        t.Error("unparseable ref dialed the active context's core")
        return nil, errors.New("no dial expected")
    })
    seamCluster(t, func(context.Context, string) (*coreapi.Client, error) {
        t.Error("unparseable ref dialed a cluster core")
        return nil, errors.New("no dial expected")
    })
    _, err := runGet(t, "not-a-url")
    require.Error(t, err)
    require.ErrorContains(t, err, "pass a mirror ULID or a clone URL")
})
}

func TestMirrorRow(t *testing.T) {
t.Parallel()
tests := []struct {
...
