feat(setup-repo): repo-aware summaries + GH_TOKEN setup, DRY token storage#310
Conversation
… storage Build on #308's GH_TOKEN support with the operator-UX improvements: * Open with two bulleted lists — what we know about the repo (name + local-checkout vs GitHub-remote, classified from the git URL) and what its setup entails (Claude credential always; GH_TOKEN for GitHub repos), each marked needed / already-configured / not-needed. * GH_TOKEN acquisition now combines both paths: reuse a GH_TOKEN already in the environment (#308's fast path) when present, else authenticate interactively via `gh auth login` + `gh auth token`. Offers to replace an existing GH_TOKEN, and guides the operator when `gh` isn't installed. * DRY the env-file write: generalize `store_oauth_token` into `store_env_token <VAR> <token> <file>`, the single comment-out/replace/append implementation both tokens share (retires the append-only `append_env_var`); `store_oauth_token` stays as a thin wrapper. * Turn the closing summary into a bullet-per-step list. * Fold in #309's hint wording (detach reassurance + actionable drop). The opening summary needs the repo's name, so the ShellRunner now also exports PANOPTICON_REPO_NAME (alongside #308's PANOPTICON_GIT_URL), passed through by the spawner from the repo record. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4ebdcd8 to
878e284
Compare
…sg cap The setup-repo UX changes grew the assembled shell command to ~18 KB. tmux sends a whole `new-session` command (pane shell command included) to its server over imsg, which caps a single message at MAX_IMSGSIZE (16 KiB) — so the spawn failed with `new-session ... returned non-zero exit status 1` before the script ever ran. Strip whole-line comments and blank lines from the assembled command at spawn time (they're pure bulk at runtime; the source files keep their comments). This brings setup-repo's command from ~18 KB to ~10 KB, well under the cap, and gives every shell workflow headroom. Only lines that are entirely a comment or blank are dropped — inline/trailing comments and code are untouched. Adds a tmux-free regression test asserting the assembled setup-repo command has no whole-line comments and stays under 16 KiB (the pytest CI job has no tmux, so the integration spawn test is skipped there — this guards it without one). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Keep only the reuse-a-GH_TOKEN-from-the-environment path: when the operator's env has a GH_TOKEN, offer to write it into the env-file (through the shared store_env_token, so an existing one is replaced); when it doesn't, guide them to add one by hand rather than minting one interactively. Removes collect_gh_token and the `gh auth login`/`gh auth token` flow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Begin the flow with a short intro stating the goal — collect persistent credentials (a Claude token, and a GH_TOKEN for GitHub repos) stored in the repo's env-file so Claude can use them inside task containers — and the reason: the agent runs on its own dedicated credentials instead of hijacking the operator's. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
tildesrc
left a comment
There was a problem hiding this comment.
Review — setup-repo onboarding, from the ICP's perspective
Reviewed from the lens of the target user: a terminal-native, review-first, security-conscious operator. The bones are strong — the upfront "This repo / To set up" status block, the detach hint that detects the actual prefix/detach keybinding (not a hardcoded C-b d), default-No on both replace prompts, and the careful store_env_token (comment-out history, atomic mv, chmod 600) are all exactly the trustworthy, legible behavior this audience rewards. Three things to fix before merge, plus copy.
Opening copy
The current opener reads as credential-harvesting: "collect persistent credentials" (this user flinches at "collect your credentials"), "persistent" raises an unanswered "persisted where?", and "hijacking yours" is alarmist and slightly inaccurate — the wrong register for calm infrastructure. It also narrates the system's goal rather than telling the user what happens and how to stay in control.
Suggested replacement:
Setting up '$repo_name'. Task containers use per-repo credentials from this repo's env-file — a Claude token, and a GH_TOKEN for GitHub repos — so the agent runs on its own tokens, not your personal session. You can skip this and set up your own secrets by editing $env_file yourself.
Other copy
- "collect" reads as harvesting throughout — "nothing collected," "Collect a new token anyway?" Swap for mint / set up / add (e.g. "Mint a new token anyway?", "…nothing set up.").
- The "use your own" path is clunky. To supply their own token the user must detach → drop the task → hand-edit → re-run, and the copy surfaces internal mechanics ("drop this task using 'x'"). This audience very likely already has a token; consider an inline "paste your own token" so BYO is a keystroke, not a cancel-and-restart.
- "so Claude can use them" hardcodes Claude — "so the agent can use them" ages better if CLI-agnosticism is on the roadmap.
- GH adoption says "the GH_TOKEN from your environment" without confirming which token (no last-4) — worth matching the masked-display consent model elsewhere.
Workflow — three to fix
-
GH adoption defaults to Yes (
[Y/n]). Copying a credential from an ephemeral env var into a persisted0600file is a heavier commitment than the env var was, and it contradicts the per-token default-No consent posture. Recommend flipping to[y/N]. (Defensible either way — it's the operator's own token — but default-No is the more consistent, respectful choice.) -
The Claude token isn't adopted from the environment the way GH is — and that can silently mis-report "configured" → a container that 401s.
claude_configuredis true wheneverCLAUDE_CODE_OAUTH_TOKEN/ANTHROPIC_API_KEYis set, and the shell runner inherits the host env (that's how the GH branch finds$GH_TOKEN). So a Claude token that lives only in the operator's shell env (not the repo's env-file) is reported "already configured" — but it's never written to the env-file, and the container gets--env-file, not the host env. Setup says "done," the agent can't authenticate. Fix: either adopt a host-env Claude token into the file (symmetric with GH, with consent), or make the "configured" check env-file-specific —env_file_has_varalready exists for exactly this. -
No inline "bring your own" for either token (see copy note) — the fast path for an already-authenticated operator is missing; the flow optimizes for mint-fresh.
Net: trustworthy engineering, right structure. The gaps are tone (harvesting language), one correctness edge (#2), and consent-default consistency (#1).
🤖 Automated review via Claude Code
…-file truth Address the self-review of the onboarding flow: Correctness * "Configured" is now checked against the env-file (env_file_has_var), not the sourced env. A Claude token that lives only in the operator's shell is no longer mis-reported as configured (the container gets --env-file, not the host env), which previously meant "done" but a container that 401s. Consent / control * Every adopt prompt defaults to No ([y/N]); flipped GH adoption off [Y/n]. * Adopting a token from the environment shows a masked tail (last 4) so the operator confirms which token — new mask_last4 helper. * Only offers to adopt a var that isn't already the env-file's own. Fast path for an already-authenticated operator * Each credential can be adopted from the environment or pasted inline; Claude falls back to `claude setup-token`. Symmetric Claude/GH via a shared store_token. No more detach → drop → hand-edit → re-run to bring your own. Copy * New opener: what happens + that you stay in control (per-repo tokens, "not your personal session", opt out by editing the env-file) — drops the "collect persistent credentials"/"hijacking" register. * "collect" → "mint / set up" throughout; agent-neutral wording. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Addressed the review (pushed): Workflow fixes
Copy
Only offers to adopt a var that isn't already the env-file's own, so replacing a configured token goes straight to paste/mint. |
Improves the operator UX of the setup-repo shell workflow (the host-side
claude setup-tokenflow). Started as adopting #309 and folds that in with four further improvements.What changed
gh auth login, then capture withgh auth tokenand write it into the repo's env-file. Gracefully guides the operator to addGH_TOKENmanually whenghisn't installed on the host. Local repos skip it entirely.store_oauth_tokenintostore_env_token <VAR> <token> <file>— the single implementation both the Claude token and GH_TOKEN write through (comment out the active line, drop the placeholder stub, append the new one).store_oauth_tokenstays as a thin wrapper.Plumbing
SetupReporuns withclone_repo = False, so the script has no checkout to inspect. To classify local vs GitHub,ShellRunner.spawnnow exportsPANOPTICON_REPO_NAME/PANOPTICON_REPO_GIT_URL, passed through by the spawner from the repo record. No model/DB change —Repo.git_urlalready exists.