Conversation
Pin to v0.0.0-20260305004813-bc5ad283b855 (bc5ad28, main HEAD after PR #1 merge). Provides output, credstore, pkce, and oauthcallback packages extracted from this repo.
Re-export exit codes, error codes, ExitCodeFor, NormalizeData, TruncationNotice, and TruncationNoticeWithTotal from the shared module. Type-alias Error for zero-cost compatibility with errors.As. ErrAuth and ErrForbiddenScope stay local (app-specific hint strings). Deletes ~330 lines of duplicated code including NormalizeData helpers, unmarshalPreservingNumbers, normalizeUnmarshaled, and the corresponding BenchmarkNormalizeUnmarshaled (now covered by shared module tests).
There was a problem hiding this comment.
Pull request overview
Migrates internal/output and internal/auth to consume the newly extracted shared module github.com/basecamp/cli, reducing duplicated code and keeping Basecamp CLI’s app-specific behavior where needed.
Changes:
- Add
github.com/basecamp/clidependency and re-export shared output error/codes/normalization helpers. - Replace the local keyring/file credential store with a typed wrapper around
credstore.Store. - Replace in-repo PKCE and callback-wait logic with shared
pkceandoauthcallbackutilities.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/output/errors.go | Type-aliases shared output.Error and re-exports shared error constructors + AsError, keeping app-specific auth/scope hints local. |
| internal/output/codes.go | Re-exports shared exit codes, error codes, and ExitCodeFor. |
| internal/output/envelope.go | Re-exports shared NormalizeData and truncation notice helpers; removes local implementations. |
| internal/output/envelope_benchmark_test.go | Removes benchmarks tied to deleted local normalization helpers. |
| internal/auth/keyring.go | Replaces local keyring + file fallback implementation with a typed wrapper over credstore.Store. |
| internal/auth/auth.go | Switches PKCE/state generation and OAuth callback waiting to shared pkce/oauthcallback. |
| internal/auth/auth_test.go | Updates tests to use the new store wrapper; removes tests for deleted local PKCE/key helpers and file-permission/atomic-write details. |
| go.mod | Adds github.com/basecamp/cli dependency. |
| go.sum | Adds checksums for github.com/basecamp/cli. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace keyring.go implementation (~230 lines of keyring probing, file I/O, atomic writes, Windows workarounds) with a typed wrapper around credstore.Store (~70 lines). Credentials struct and Store API unchanged. Replace PKCE helpers (generateCodeVerifier/Challenge/State) with pkce.GenerateVerifier/Challenge/State. Replace waitForCallback with inline listener creation + oauthcallback.WaitForCallback. Delete tests for removed unexported functions (TestGenerateCodeVerifier, TestGenerateCodeChallenge, TestGenerateState, TestKeyFunction). Update remaining tests to construct Store via newTestStore helper.
Replaces pseudo-version v0.0.0-20260305004813-bc5ad283b855. Same code (bc5ad28), proper semver tag.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
internal/auth/auth_test.go:35
- TestNewStore() calls NewStore() without disabling the keyring, so the test’s behavior can vary by environment and may touch the user/system keychain (or require desktop services like DBus). Consider setting BASECAMP_NO_KEYRING in this test (or using newTestStore) so unit tests are deterministic and avoid side effects.
func TestNewStore(t *testing.T) {
tmpDir := t.TempDir()
store := NewStore(tmpDir)
// Store should be created (may or may not use keyring depending on system)
require.NotNil(t, store, "NewStore returned nil")
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Mutable vars allow accidental reassignment from other packages in the module. Thin wrapper functions preserve immutability while delegating to the shared module.
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.
What
Consume
github.com/basecamp/cliv0.1.0 (merged in basecamp/cli#1) from basecamp-cli, validating the extraction and eliminating ~580 lines of duplicated code.Changes
github.com/basecamp/cli@v0.1.0internal/output— re-exports exit codes, error codes,ExitCodeFor,NormalizeData,TruncationNotice,TruncationNoticeWithTotalvia immutable wrapper functions. Type-aliasesErrorfor zero-costerrors.Ascompatibility. KeepsErrAuthandErrForbiddenScopelocal (app-specific hint strings).internal/auth— replaces keyring implementation (~230→70 lines) with a typed wrapper aroundcredstore.Store. Replaces PKCE helpers withpkce.GenerateVerifier/Challenge/State. ReplaceswaitForCallbackwith inline listener +oauthcallback.WaitForCallback(with 5-minute timeout preserved).What stays local
surface— fundamentally different approach (Go library walks cobra tree in-process vs. shell scripts invoke binary)profile— tightly integrated into basecamp-cli's config systemErrAuth/ErrForbiddenScope— app-specific hint stringsCredentialsstruct,Response/ErrorResponseenvelopes, presenter, TUI, renderer — app-specificVerification
make checkpasses (fmt, vet, lint, test, e2e, naming, surface, provenance, tidy)go-keyringremains a direct dependency (still imported bydoctor.goandmigrate.gofor keyring availability checks)go mod tidyis idempotent