Repository navigation
Carry --profile in suggested follow-up commands - #945
Conversation
Three cases fail: a profile chosen with --profile is dropped from the suggested follow-up, so a fresh shell runs it under the default profile.
followUpScope replaces hasPersistentAccount, replyAccountArg and templateCommandContextArgs. It names --profile when the profile came from the flag, and --account when the account would not resolve again in a fresh process. A profile from default_profile or BASECAMP_PROFILE is left out, as an account from config or env already was. Template follow-ups used to name every active profile. They now follow the same rule as the rest.
There was a problem hiding this comment.
🟡 Changes recommended
Template follow-ups lose interactively selected profiles, causing repeated prompts or failures in noninteractive use.
1 open issue
What changed in this PR
This PR centralizes follow-up command scope handling so suggested Basecamp CLI commands retain an explicit --profile alongside process-local account selections.
Changes:
- Adds a shared helper for profile and account flags.
- Applies it to template, spotlight, and comment follow-ups.
- Updates tests for profile propagation, account provenance, and shell quoting.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
| File | Description |
|---|---|
internal/commands/templates.go |
Uses shared scope handling for template follow-ups. |
internal/commands/templates_test.go |
Sets explicit profile flags in follow-up tests. |
internal/commands/spotlight.go |
Carries scope into spotlight follow-ups. |
internal/commands/spotlight_test.go |
Tests profile and account propagation. |
internal/commands/helpers.go |
Introduces the shared follow-up scope helper. |
internal/commands/comment.go |
Uses shared scope handling for comment breadcrumbs. |
internal/commands/comment_test.go |
Tests inherited and process-local scope behavior. |
Review effort: Balanced
A profile picked from the interactive picker never set the --profile flag, so follow-ups left it out. Pasted into a shell, they asked for a profile again, or failed when not interactive. Template follow-ups had named the active profile before, so they regressed. Follow-ups now name the active profile however it was chosen. That also keeps them right in a shell that exports another BASECAMP_PROFILE, at the cost of a redundant flag when the profile came from default_profile or the environment. Users without profiles see no change.
|
Codex review of 7f8c97e (gpt-6.1-sol, run locally; it has no GitHub threads). It raised the same picker-profile regression as the Copilot thread above, and 43ac084 fixes it. Codex also noted that the PR had rewritten the template tests to set The PR body briefly showed #946's description, because two drafts shared one scratch file. It now has this PR's own description, and it says |
|
Codex review of 43ac084 (gpt-6.1-sol, run locally). It found no regressions in this PR across the seven migrated call sites. It raised one finding that predates this PR, which I'm declining:
|

Fixes #943.
What
Suggested follow-up commands now name the active profile with
--profile, however this run chose it. With production as the default profile:One helper,
followUpScopeininternal/commands/helpers.go, decides what a follow-up must name so that a fresh process acts on the same profile and account:--profile <name>whenever a profile is active, from--profile,BASECAMP_PROFILE,default_profile, the only configured profile, or the interactive picker. The name is shell-quoted.--account <id>when the account came from--account, from a URL, or from the account picker, the same rule as before. An account set in the named profile is not repeated.BASECAMP_ACCOUNT_ID. Users without profiles see no change.It replaces
hasPersistentAccount,replyAccountArgand the templates-onlytemplateCommandContextArgs. The callers incomments show,comments thread,spotlight,unspotlightandtemplates library/copy/copy-statususe it. Template follow-ups already named the active profile, so they do not change.Why
A follow-up copied into a new shell ran under that shell's profile, which can be a different host or account. If recording 456 exists there,
unspotlight 456acts on the wrong item.Naming the profile only when it came from
--profilewas not enough. A profile picked from the interactive picker is not picked again. The pasted command asks again, or fails with "multiple profiles configured but none selected" when not interactive. A shell can also export a differentBASECAMP_PROFILEfrom the one that ran the command. The cost of the rule is a redundant--profilewhen the profile came fromdefault_profileor the environment.Breadcrumbs that do not use this helper still carry neither flag. This PR does not change them.
Testing
TestFollowUpNamesTheProfileHoweverItWasChosenininternal/clirunsspotlight 456 --hints --jsonthrough the root command against a local server. It covers no profiles,default_profile,BASECAMP_PROFILEand--profile, and checks both the follow-up and the account the request reached.TestSpotlightFollowUpCarriesTheProfileAndAccountcovers a profile active without--profile(the picker case), an account from the URL with and without a profile, and--accountunder a profile.TestFollowUpScopeNamesWhatAFreshProcessLackscovers each account source with and without an active profile, and shell quoting. The template tests are back to theirmainversion, which sets the active profile without the flag.app.Flags.Profileagain, every case with a profile active and no flag fails: 2 of 4 root cases, 3 of 5 spotlight cases, the 3 profile assertions in the helper test, and all 4 template tests. The remaining cases give the same answer under both rules.mainspotlight 456(default_profileproduction)unspotlight 456unspotlight 456unspotlight 456 --profile production--profile staging spotlight 456unspotlight 456… --profile staging… --profile stagingBASECAMP_PROFILE=staging spotlight 456unspotlight 456unspotlight 456… --profile stagingspotlight 456unspotlight 456unspotlight 456… --profile staging--profile bare spotlight <URL in account 33333>… --account 33333… --profile bare --account 33333… --profile bare --account 33333--profile staging spotlight 456 --account 44444… --account 44444… --profile staging --account 44444… --profile staging --account 44444bin/cipasses