Skip to content

feat(setup-repo): repo-aware summaries + GH_TOKEN setup, DRY token storage#310

Merged
tildesrc merged 5 commits into
mainfrom
panopticon/setup-repo-dashboard-hints
Jul 14, 2026
Merged

feat(setup-repo): repo-aware summaries + GH_TOKEN setup, DRY token storage#310
tildesrc merged 5 commits into
mainfrom
panopticon/setup-repo-dashboard-hints

Conversation

@tildesrc

Copy link
Copy Markdown
Contributor

Improves the operator UX of the setup-repo shell workflow (the host-side claude setup-token flow). Started as adopting #309 and folds that in with four further improvements.

What changed

  • Opening summary. The flow now opens with two bulleted lists: what we know about the repo (name + source — local checkout vs GitHub remote, classified from the repo's git URL) and what its setup entails (Claude credential always; GH_TOKEN for GitHub repos), each marked needed / already-configured / not-needed.
  • GH_TOKEN setup (GitHub repos only). A new step mirroring the Claude-token step: interactive gh auth login, then capture with gh auth token and write it into the repo's env-file. Gracefully guides the operator to add GH_TOKEN manually when gh isn't installed on the host. Local repos skip it entirely.
  • DRY token storage. Generalized store_oauth_token into store_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_token stays as a thin wrapper.
  • Bulleted closing summary. The end-of-run summary is now a bullet per step and its outcome.
  • Hint wording (Update dashboard hints for task management #309). Folded in the detach-reassurance and actionable-drop wording (and fixed its "dashbaord" typo).

Plumbing

SetupRepo runs with clone_repo = False, so the script has no checkout to inspect. To classify local vs GitHub, ShellRunner.spawn now exports PANOPTICON_REPO_NAME / PANOPTICON_REPO_GIT_URL, passed through by the spawner from the repo record. No model/DB change — Repo.git_url already exists.

… 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>
@tildesrc
tildesrc force-pushed the panopticon/setup-repo-dashboard-hints branch from 4ebdcd8 to 878e284 Compare July 13, 2026 18:59
Panopticon Agent and others added 3 commits July 13, 2026 20:06
…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 tildesrc left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  1. GH adoption defaults to Yes ([Y/n]). Copying a credential from an ephemeral env var into a persisted 0600 file 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.)

  2. 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_configured is true whenever CLAUDE_CODE_OAUTH_TOKEN/ANTHROPIC_API_KEY is 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-specificenv_file_has_var already exists for exactly this.

  3. 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>
@tildesrc

Copy link
Copy Markdown
Contributor Author

Addressed the review (pushed):

Workflow fixes

  1. GH adoption now defaults to No ([y/N]) — consistent with the per-token consent posture.
  2. "Configured" is env-file-specific. claude_configured (and the summary) now check 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 — it correctly shows "needed" and gets adopted into the env-file (the container sees --env-file, not the host env).
  3. Inline BYO for both tokens. Each credential can be adopted from the environment or pasted inline; Claude still falls back to claude setup-token. No more detach → drop → hand-edit → re-run. Claude is now symmetric with GH (shared store_token).

Copy

  • New opener uses your suggested register — what happens + staying in control ("per-repo credentials", "not your personal session", opt out by editing the env-file); dropped "collect persistent credentials"/"hijacking".
  • "collect" → "mint / set up" throughout; agent-neutral wording where it was Claude-specific.
  • Adoption now shows a masked tail (last 4, via a new mask_last4) so you confirm which token.

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.

@tildesrc
tildesrc merged commit 3dc5fcb into main Jul 14, 2026
3 checks passed
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