Make user API keys first-class in me apikey#107
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR reshapes the me apikey CLI so personal access tokens (user keys) are the default, and agent keys are opt-in via --agent, aligning the CLI UX with the existing memberId-based server API and preventing same-day name collisions for unnamed PATs.
Changes:
- Reworks
me apikey create/listsyntax to be self-default (--selfremoved) and agent-targeted via--agent <agent>. - Adds randomized default key names (
cli-<date>-<rand>) and extends integration/e2e coverage for PAT behavior (create/list/authenticate). - Sweeps updated instructions across server/CLI messages, plugin metadata, and docs to reflect the new CLI shape.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/integration-test.ts | Updates integration test invocations to the new --agent flag shape. |
| packages/server/middleware/authenticate-space.ts | Updates legacy API key error guidance to point to me apikey create --agent <agent>. |
| packages/cli/commands/mcp.ts | Updates MCP CLI legacy-key guidance to the new --agent syntax. |
| packages/cli/commands/apikey.ts | Implements self-default create/list behavior and randomized default key names. |
| packages/cli/commands/agent.ts | Updates agent workflow hints to reference me apikey create --agent …. |
| packages/claude-plugin/README.md | Updates setup instructions to mint agent keys via --agent. |
| packages/claude-plugin/.claude-plugin/plugin.json | Updates plugin config text to reference me apikey create --agent <agent>. |
| e2e/cli.e2e.test.ts | Adds e2e test ensuring PAT default behavior and no same-day unnamed collisions. |
| docs/mcp-integration.md | Updates MCP prerequisites to document PAT vs agent-key creation. |
| docs/cli/me-opencode.md | Updates --api-key guidance to include PAT and --agent agent keys. |
| docs/cli/me-login.md | Updates login docs to describe PATs as headless alternative while sessions remain primary. |
| docs/cli/me-gemini.md | Updates --api-key guidance to include PAT and --agent agent keys. |
| docs/cli/me-codex.md | Updates --api-key guidance to include PAT and --agent agent keys. |
| docs/cli/me-claude.md | Updates headless install credential guidance for PATs and agent keys. |
| docs/cli/me-apikey.md | Rewrites me apikey reference docs for self-default + --agent shape and naming behavior. |
| AUTH_DESIGN.md | Updates auth design text to reflect PAT creation without --self. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
75
to
77
| clack.log.info( | ||
| "Add it to a space with 'me agent add', then mint a key with 'me apikey create'.", | ||
| `Add it to a space with 'me agent add', then mint a key with 'me apikey create --agent ${name}'.`, | ||
| ); |
Comment on lines
152
to
+155
| clack.log.success(`Added agent ${agent} to the space.`); | ||
| clack.log.info("Mint a key with 'me apikey create'."); | ||
| clack.log.info( | ||
| `Mint a key with 'me apikey create --agent ${agent}'.`, | ||
| ); |
Invert the command so a personal access token (PAT) is the default and agents opt in via `--agent`: me apikey create [name] [--agent <agent>] [--expires <ts>] me apikey list [--agent <agent>] - Drop `--self`; self is now the default. The old guard made `--self [name]` impossible, so PATs could never be named and two same-day unnamed PATs collided on `unique (member_id, name)`. - `name` is now the only positional (unambiguous). - Default name gains a random suffix (`cli-<date>-<rand>`) so repeated unnamed creates never collide. - `list` defaults to your own keys (was a required `<agent>` positional). Breaking, intentional, strict + silent: `me apikey create my-agent` mints a PAT named `my-agent`; agent provisioning moves to `--agent`. No server/protocol/DB/engine changes — the wire is already memberId-based. Sweeps agent-centric copy (`me apikey create <agent>` → `--agent`) across CLI/server messages, the claude-plugin, and docs. Refs TNT-145
5c17815 to
04a38bb
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: John Pruitt <jgpruitt@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: John Pruitt <jgpruitt@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
me apikey createwas designed for agents only. We later allowed users to mint personal access tokens (PATs) via--self, but the command structure was broken for that case:[agent] [name]with a guardif (opts.self && agent) → "Pass an agent or --self, not both.", so under--selfthe first positional parsed asagentand was rejected — you could never name a--selfkey. It always fell back tocli-<YYYY-MM-DD>.unique (member_id, name)→23505→A record with that name already exists.me apikey listrequired<agent>, so there was no way to list your own PATs.Reported by Matty:
me apikey create --selftwice (once per space) → second fails. (Keys are global per-principal, not per-space; the separate--space-per-MCP-server config gap is its own ticket.)Change
Invert the model so user keys are the default and agents opt in:
--self— self is now the default.nameis the only positional (unambiguous), so PATs can be named.cli-<date>-<rand>) so repeated unnamed creates never collide.listdefaults to your own keys.No server/protocol/DB/engine changes — the wire is already
memberId-based and treats user vs agent identically.Breaking change (intentional, strict + silent)
me apikey create my-agentnow mints a PAT namedmy-agent; agent provisioning moves tome apikey create --agent my-agent.me apikey list <agent>→me apikey list --agent <agent>(bare positional now errors).--agent?" hint.Agent-centric copy (
me apikey create <agent>→--agent <agent>) swept across CLI/server messages, the claude-plugin, and docs (incl. a rewrite ofdocs/cli/me-apikey.md).Verification
./bun run check— 648 pass, 0 fail.me apikey {create,list} -hconfirmed showing the self-first shape.7b): two unnamed PATs don't collide, a named PAT works,me apikey listshows your own keys, and a PAT authenticates as kindu. (The e2e suite self-skips withoutOPENAI_API_KEYlocally; runs in CI.)Closes TNT-145