Read a hill chart's progress updates

Merged
RO
13h ago
+1485-69

What

Read a hill chart's progress updates: every time someone moves dots on a hill chart, Basecamp records a progress update with the dots' positions and an optional note.

  • basecamp hillcharts updates (same as updates list): a todoset's progress updates, newest first. Flags: --todoset/-t, --in/--project, --limit/-n (default 50), --all, --page.
  • basecamp hillcharts updates show <id|url>: one update, with its dots (- 40/100 Design) and note. Takes an ID with --todoset, or a pasted web or API URL (held to a trusted host and the configured account, and checked against --in/--todoset when given). The listing URL gets a hint to use updates instead.
  • Human, --json and --md output through a new hill_chart_version presenter schema and a hill_dots field format. Breadcrumbs point to the update's comments and back to the listing, and keep --account/--profile when those weren't inherited.
  • show, track and untrack now share one todoset-resolution helper (resolveHillchartTodoset). Their behavior is unchanged.

The work is for Hill chart writes in the API. Moving dots and posting a note comes in a stacked draft PR, once the SDK has that operation.

SDK bump

The list and show operations shipped in basecamp-sdk v0.33.0 (go/v0.33.0, 57e8a94c, basecamp/basecamp-sdk#1061). No Dependabot or sdk-bump PR for that version was open when this branch was cut, so the bump is included here and the PR is based on main. If sdk-bump opens one later, close it in favor of this PR.

  • go.mod/go.sum to v0.33.0, internal/version/sdk-provenance.json updated.
  • MCP model synced from the v0.33.0 tag (scripts/sync-mcp-model.sh). Catalog counts go from 284 to 286 operations and from 62 to 63 link-paginated. The snapshot adds get_hill_chart_version and list_hill_chart_versions.
  • nix/package.nix vendorHash regenerated with make update-nix-hash.
  • API-COVERAGE.md gets a new "hill_charts (progress updates)" row; .surface is regenerated; the skill gets "hill chart progress" triggers.

Testing

  • make check passes locally on the head commit, with golangci-lint v2.11.1 as in CI.
  • Go: 20 new hillcharts updates tests (44 including subtests), covering pagination flags and their conflicts, the URL forms (web with fragment, API with and without .json, account-level API route), host/account/project/todoset mismatches refused before any request, --in checked through the todoset for the account-level URL, and breadcrumbs with an adopted vs. an inherited account. All 34 hillcharts tests pass, plus TestFormatFieldHillDots in the presenter.
  • BATS: e2e/hillcharts.bats 15/15, including 7 new tests.
  • Not run: the new smoke tests in e2e/smoke/smoke_hillcharts.bats (updates list, updates show) need a live account. I didn't run the commands against a live or local Basecamp either; the request and response shapes come from the SDK's v0.33.0 fixtures.

Review

A cross-family review of the branch found two issues, both fixed in 524b7193:

  1. Fixed. updates show rejected the account-level API URL (/{account}/todosets/{id}/hills/versions/{id}.json, the route the SDK itself requests) because the parser required a /buckets/{project} segment. The project segment is now optional. When --in is given with such a URL, the todoset's own bucket is checked instead. Tests cover the route with and without .json.
  2. Fixed. Breadcrumbs dropped an account given with --account, or adopted from a pasted URL, so a copied follow-up ran against the default account. Both commands now capture the follow-up scope before resolving the account, and append it to every breadcrumb.

Codex reviewed 524b7193 and found no issues. Copilot was requested on 524b7193 but hasn't reviewed: it hasn't reviewed any PR in bc3, basecamp-sdk or basecamp-cli since 16:02 UTC today. The first CI run's race shard 4 failed while listing tests, before any test ran, and passed on a rerun. Test listing succeeds locally.