V1 CLI ship polish by jeremy · Pull Request #160 · basecamp/basecamp-cli
added 6 commits
February 25, 2026 14:17Add --hints/--no-hints flags (default: on in dev builds, off in release). When disabled, breadcrumbs are stripped from output via WithoutBreadcrumbs(). Rename "Next:" label to "Hints:" across all output modes.
Remove ResolveProject() call that added ~200ms latency on every bare `basecamp` invocation. Project ID from config is sufficient; name resolution was nice-to-have but not worth a synchronous API roundtrip. Show active --profile name in summary when set.
Styled output now shows category headers with aligned command names, descriptions, and available actions. JSON/markdown still passes full structure through app.OK() for machine consumption.
Transform raw SDK structs into clean table columns: id, title (truncated to 60 chars), type (simplified: Chat::Lines::RichText → chat), project (from Bucket.Name), and created (relative time). Drops noisy columns like url, app_url, bookmark, visible_to_clients, raw timestamps.
Copilot AI review requested due to automatic review settings
February 25, 2026 22:18Checks GitHub for latest release, compares with current version. Detects Homebrew installations and runs brew upgrade automatically; otherwise directs to GitHub releases. Updates doctor hint to suggest `basecamp upgrade` when an update is available.
submitQuery() no longer silently skips when the user re-submits the same query (e.g., pressing Enter again to refresh results). The debounce path still deduplicates to avoid redundant in-flight requests during typing. Add height clamp to Search.View() to prevent the list from overflowing its allocated viewport and pushing chrome off-screen.
Only humanize search output for styled terminal display; --json/--agent get the full SDK SearchResult structs with all fields intact. Fall back to Subject when Title is empty (some Basecamp record types use Subject).
- upgrade.go: use cmd.OutOrStdout() instead of fmt.Println/os.Stdout - upgrade.go: extract versionChecker/homebrewChecker vars for testability - upgrade_test.go: add 4 tests covering dev build, current, available, writer - commands.go: accept io.Writer param, account for experimental prefix in alignment - search.go: use rune-based truncation for UTF-8 safety
Copilot AI review requested due to automatic review settings
February 25, 2026 22:31Pointer fields (*bool/*int) enable three-state semantics: nil = not set (fall through to version.IsDev()), explicit true/false = user preference. Load from config files and BASECAMP_HINTS/BASECAMP_STATS env vars, with standard layering: env > local > repo > global > system > defaults. Strict validation: env bools must be true/false/1/0 (invalid values ignored to preserve nil semantics); verbose range-checked to 0-2.
Change --hints/--stats defaults to false so Changed() can detect explicit flag usage. New resolvePreferences() in PersistentPreRunE checks: explicit flag > config value > version.IsDev() fallback. Negative flags (--no-stats, --no-hints) only suppress config resolution when their value is true, not merely when Changed.
Copilot AI review requested due to automatic review settings
February 26, 2026 16:34The OAuth server expects "full" for write access, not "write". The wizard was sending an invalid scope, causing auth to silently fall back to the default.
The config key is "account_id" not "account", so the suggested command was producing a config error.
len(v) counts bytes, not characters. Multi-byte UTF-8 strings (e.g. Japanese, emoji) could be sliced mid-rune, producing invalid output. Use utf8.RuneCountInString and []rune conversion.
Include Rename events so editors using temp-file+rename are detected. Re-add the resolved directory on re-arm so symlink repoints are tracked.
Replaces byte-slicing loop with the existing widget.Truncate() which handles multi-byte UTF-8 correctly.
Remove -no-fail from gosec so findings fail the build. Replace the deferred TODO with an actual dependency-review job that runs on PRs.
Add lint, test-e2e, and race detection to the release gate. Install golangci-lint and BATS (with cache) to support the expanded checks.
Drop the dogfooding banner from README, remove GOPRIVATE from go install instructions, and clean up goreleaser release notes and deferred comments.
Download checksums.txt and verify SHA256 before extracting the archive. When cosign is available, also verify the Sigstore signature against the GitHub Actions OIDC issuer. Shared tmpdir between download and verify.
Copilot AI review requested due to automatic review settings
February 27, 2026 18:55In mixed-tooling environments (e.g. Homebrew binary built with a different Go version), command -v may find the wrong golangci-lint first. Try GOBIN, then GOPATH/bin, then fall back to PATH to ensure the binary matching the active Go toolchain wins.
The golangci-lint-action was running lint by default then make lint ran it again. Set install-only: true so make lint is the single invocation. Add govulncheck as a release-path security check.
The error annotation logged but the step exited 0, making the regression invisible in the checks UI. The job already has continue-on-error: true so exit 1 turns the step red without blocking merge.
Add find_sha256_cmd helper that tries sha256sum before shasum for Linux compatibility. Tighten cosign identity from a regexp matching any workflow to an exact match on the release workflow at the specific tag ref.
Tag pushes don't trigger security.yml (it runs on push-to-main and PRs). Add workflow_call to security.yml and invoke it from release.yml so gitleaks, gosec, and trivy must pass before a release proceeds.
Copilot AI review requested due to automatic review settings
February 27, 2026 19:09CloseWatcher now sets w.themeWatcher = nil after closing, which makes repeated calls safe and prevents the ThemeChangedMsg handler from re-arming the watcher goroutine after shutdown.
The securego/gosec Docker action runs its own Go toolchain in a container that cannot inherit the host's git config, so it fails to resolve the private SDK module. Switch to go install + direct invocation so gosec uses the host's Go and git credentials. Mark dependency-review as continue-on-error since it requires GitHub Advanced Security which is not enabled on this repo.
Copilot AI review requested due to automatic review settings
February 27, 2026 19:27gosec now resolves private modules correctly (go install instead of Docker), which means it actually scans the full codebase and finds 100+ pre-existing findings (G304 file inclusion, G104 unhandled errors in TUI, G117 token fields). These are accepted patterns in a CLI tool. Use -no-fail so findings are reported via SARIF without blocking CI. dependency-review requires GitHub Advanced Security which is not enabled on this repo — mark continue-on-error so it does not block the security workflow.
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