Skip to content

Commit ea8c427

Browse files
committed
Add lineup list command and bump SDK to 827a46dd
Adds `basecamp lineup list` to fetch all markers for an account. Bumps the SDK to pick up ListLineupMarkers and the simplified CloneTool Create signature (title parameter moved into Create, removing the separate Update round-trip).
1 parent badd1fa commit ea8c427

11 files changed

Lines changed: 113 additions & 28 deletions

File tree

.surface

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ CMD basecamp help
149149
CMD basecamp lineup
150150
CMD basecamp lineup create
151151
CMD basecamp lineup delete
152+
CMD basecamp lineup list
152153
CMD basecamp lineup update
153154
CMD basecamp login
154155
CMD basecamp logout
@@ -3606,6 +3607,26 @@ FLAG basecamp lineup delete --stats type=bool
36063607
FLAG basecamp lineup delete --styled type=bool
36073608
FLAG basecamp lineup delete --todolist type=string
36083609
FLAG basecamp lineup delete --verbose type=count
3610+
FLAG basecamp lineup list --account type=string
3611+
FLAG basecamp lineup list --agent type=bool
3612+
FLAG basecamp lineup list --cache-dir type=string
3613+
FLAG basecamp lineup list --count type=bool
3614+
FLAG basecamp lineup list --hints type=bool
3615+
FLAG basecamp lineup list --ids-only type=bool
3616+
FLAG basecamp lineup list --in type=string
3617+
FLAG basecamp lineup list --jq type=string
3618+
FLAG basecamp lineup list --json type=bool
3619+
FLAG basecamp lineup list --markdown type=bool
3620+
FLAG basecamp lineup list --md type=bool
3621+
FLAG basecamp lineup list --no-hints type=bool
3622+
FLAG basecamp lineup list --no-stats type=bool
3623+
FLAG basecamp lineup list --profile type=string
3624+
FLAG basecamp lineup list --project type=string
3625+
FLAG basecamp lineup list --quiet type=bool
3626+
FLAG basecamp lineup list --stats type=bool
3627+
FLAG basecamp lineup list --styled type=bool
3628+
FLAG basecamp lineup list --todolist type=string
3629+
FLAG basecamp lineup list --verbose type=count
36093630
FLAG basecamp lineup update --account type=string
36103631
FLAG basecamp lineup update --agent type=bool
36113632
FLAG basecamp lineup update --cache-dir type=string
@@ -7326,6 +7347,7 @@ SUB basecamp help
73267347
SUB basecamp lineup
73277348
SUB basecamp lineup create
73287349
SUB basecamp lineup delete
7350+
SUB basecamp lineup list
73297351
SUB basecamp lineup update
73307352
SUB basecamp login
73317353
SUB basecamp logout

API-COVERAGE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ Coverage of Basecamp 3 API endpoints. Source: [bc3-api/sections](https://github.
66

77
| Status | Sections | Endpoints |
88
|--------|----------|-----------|
9-
| ✅ Implemented | 37 | 136 |
9+
| ✅ Implemented | 37 | 137 |
1010
| ⏭️ Out of scope | 4 | 12 |
11-
| **Total (docs)** | **41** | **148** |
11+
| **Total (docs)** | **41** | **149** |
1212

13-
**100% coverage of in-scope API** (136/136 endpoints)
13+
**100% coverage of in-scope API** (137/137 endpoints)
1414

1515
Out-of-scope sections are excluded from parity totals and scripts: chatbots (different auth), legacy Clientside (deprecated)
1616

17-
**SDK version:** v0.4.0 — uniform pagination (Limit/Page) on all List methods; `types.FlexibleTime` and `types.FlexInt` for wire format handling.
17+
**SDK version:** v0.6.0 — uniform pagination (Limit/Page) on all List methods; `types.FlexibleTime` and `types.FlexInt` for wire format handling.
1818

1919
## Coverage by Section
2020

@@ -77,7 +77,7 @@ Out-of-scope sections are excluded from parity totals and scripts: chatbots (dif
7777
| **Chatbots** |
7878
| chatbots | 10 | - | ⏭️ | skip | Requires chatbot key, not OAuth (see notes) |
7979
| **Lineup** |
80-
| lineup_markers | 3 | `lineup` || - | create, update, delete markers |
80+
| lineup_markers | 4 | `lineup` || - | list, create, update, delete markers |
8181
| **Reference Only** |
8282
| basecamps | 0 | - | - | - | Documentation reference, no endpoints |
8383
| rich_text | 0 | - | - | - | Documentation reference, no endpoints |

e2e/smoke/.qa-allowlist

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ test_timesheet_item_returns_timesheet_item_detail # timesheets not enabled — s
2222

2323
# Lineup API may not exist on all environments
2424
test_lineup_create_creates_a_lineup_marker # API not available on some servers — smoke
25+
test_lineup_list_returns_markers # API not available on some servers — smoke
26+
test_lineup_update_updates_a_lineup_marker # depends on lineup create — smoke
27+
test_lineup_delete_removes_a_lineup_marker # depends on lineup create — smoke
2528

2629
# SDK bug: TodolistOrGroup0 union type expects wrapped JSON, API returns flat
2730
test_todolists_show_returns_todolist_detail # SDK deserialization mismatch — smoke

e2e/smoke/smoke_lifecycle.bats

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,6 @@ load smoke_helper
128128
mark_out_of_scope "Bulk completion — destructive, no undo"
129129
}
130130

131-
# --- Structurally untestable (API returns 204 No Content, no ID to chain) ---
132-
133-
@test "lineup update is out of scope" {
134-
mark_out_of_scope "API returns 204 No Content — no ID to chain"
135-
}
136-
137-
@test "lineup delete is out of scope" {
138-
mark_out_of_scope "API returns 204 No Content — no ID to chain"
139-
}
140-
141131
# --- Code-path equivalence: docs group shares implementation with files ---
142132

143133
@test "docs archive is out of scope" {

e2e/smoke/smoke_lineup.bats

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
#!/usr/bin/env bats
2-
# smoke_lineup.bats - Level 1: Lineup create
3-
#
4-
# Note: lineup update/delete are OOS — the API returns 204 No Content
5-
# (no ID in response), making them structurally untestable without a
6-
# fragile list-after-create workaround. See smoke_lifecycle.bats.
2+
# smoke_lineup.bats - Level 1: Lineup CRUD lifecycle
73

84
load smoke_helper
95

@@ -15,8 +11,50 @@ setup_file() {
1511
@test "lineup create creates a lineup marker" {
1612
local future_date
1713
future_date=$(date -v+7d +%Y-%m-%d 2>/dev/null || date -d "+7 days" +%Y-%m-%d)
18-
run_smoke basecamp lineup create "Smoke lineup $(date +%s)" "$future_date" --json
14+
local marker_name="Smoke lineup $(date +%s)"
15+
run_smoke basecamp lineup create "$marker_name" "$future_date" --json
1916
# Lineup API may not exist on all environments (404 → validation error)
2017
[[ "$status" -ne 0 ]] && mark_unverifiable "Lineup API not available"
2118
assert_json_value '.ok' 'true'
19+
echo "$marker_name" > "$BATS_FILE_TMPDIR/marker_name"
20+
}
21+
22+
@test "lineup list returns markers" {
23+
run_smoke basecamp lineup list --json
24+
[[ "$status" -ne 0 ]] && mark_unverifiable "Lineup API not available"
25+
assert_json_value '.ok' 'true'
26+
}
27+
28+
@test "lineup update updates a lineup marker" {
29+
local name_file="$BATS_FILE_TMPDIR/marker_name"
30+
[[ ! -f "$name_file" ]] && mark_unverifiable "No marker created by earlier test"
31+
local marker_name
32+
marker_name=$(cat "$name_file")
33+
run_smoke basecamp lineup list --json
34+
[[ "$status" -ne 0 ]] && mark_unverifiable "Lineup API not available"
35+
assert_json_value '.ok' 'true'
36+
local marker_id
37+
marker_id=$(echo "$output" | jq -r --arg name "$marker_name" '[.data[] | select(.name == $name)][0].id // empty')
38+
[[ -z "$marker_id" ]] && mark_unverifiable "No markers found to update"
39+
local updated_name="Updated $marker_name"
40+
run_smoke basecamp lineup update "$marker_id" "$updated_name" --json
41+
assert_success
42+
assert_json_value '.ok' 'true'
43+
echo "$updated_name" > "$BATS_FILE_TMPDIR/marker_name"
44+
}
45+
46+
@test "lineup delete removes a lineup marker" {
47+
local name_file="$BATS_FILE_TMPDIR/marker_name"
48+
[[ ! -f "$name_file" ]] && mark_unverifiable "No marker created by earlier test"
49+
local marker_name
50+
marker_name=$(cat "$name_file")
51+
run_smoke basecamp lineup list --json
52+
[[ "$status" -ne 0 ]] && mark_unverifiable "Lineup API not available"
53+
assert_json_value '.ok' 'true'
54+
local marker_id
55+
marker_id=$(echo "$output" | jq -r --arg name "$marker_name" '[.data[] | select(.name == $name)][0].id // empty')
56+
[[ -z "$marker_id" ]] && mark_unverifiable "No markers found to delete"
57+
run_smoke basecamp lineup delete "$marker_id" --json
58+
assert_success
59+
assert_json_value '.ok' 'true'
2260
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
charm.land/bubbles/v2 v2.0.0
77
charm.land/bubbletea/v2 v2.0.2
88
charm.land/lipgloss/v2 v2.0.2
9-
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260318221909-49475983b9c8
9+
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260319050216-1c33ce43c305
1010
github.com/basecamp/cli v0.1.1
1111
github.com/charmbracelet/bubbles v1.0.0
1212
github.com/charmbracelet/glamour v1.0.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ
2525
github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w=
2626
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
2727
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
28-
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260318221909-49475983b9c8 h1:WsLan1O+1GWBSQEn+dTd63roBunjojffjaoKnQ4g33U=
29-
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260318221909-49475983b9c8/go.mod h1:g05DM58QkUm4/mvBAvRiugPw+F4trliuGkRGg8y+Th4=
28+
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260319050216-1c33ce43c305 h1:NuMRr9mXUhSZAxxxLLfOAhiCTeYDlt/h7HaoarRLGjk=
29+
github.com/basecamp/basecamp-sdk/go v0.6.1-0.20260319050216-1c33ce43c305/go.mod h1:g05DM58QkUm4/mvBAvRiugPw+F4trliuGkRGg8y+Th4=
3030
github.com/basecamp/cli v0.1.1 h1:FAF3M09xo1m7gJJXf38glCkT50ZUuvz+31f+c3R3zcc=
3131
github.com/basecamp/cli v0.1.1/go.mod h1:NTHe+keCTGI2qM5sMXdkUN0QgU3zGbwnBxcmg8vD5QU=
3232
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=

internal/commands/commands.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func CommandCategories() []CommandCategory {
8585
{Name: "people", Category: "organization", Description: "Manage people and access", Actions: []string{"list", "show", "pingable", "add", "remove"}},
8686
{Name: "templates", Category: "organization", Description: "Manage project templates", Actions: []string{"list", "show", "create", "update", "delete", "construct"}},
8787
{Name: "webhooks", Category: "organization", Description: "Manage webhooks", Actions: []string{"list", "show", "create", "update", "delete"}},
88-
{Name: "lineup", Category: "organization", Description: "Manage lineup markers", Actions: []string{"create", "update", "delete"}},
88+
{Name: "lineup", Category: "organization", Description: "Manage lineup markers", Actions: []string{"list", "create", "update", "delete"}},
8989
},
9090
},
9191
{

internal/commands/lineup.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ They apply to the entire Basecamp account.`,
2929
}
3030

3131
cmd.AddCommand(
32+
newLineupListCmd(),
3233
newLineupCreateCmd(),
3334
newLineupUpdateCmd(),
3435
newLineupDeleteCmd(),
@@ -37,6 +38,36 @@ They apply to the entire Basecamp account.`,
3738
return cmd
3839
}
3940

41+
func newLineupListCmd() *cobra.Command {
42+
return &cobra.Command{
43+
Use: "list",
44+
Short: "List lineup markers",
45+
RunE: func(cmd *cobra.Command, args []string) error {
46+
app := appctx.FromContext(cmd.Context())
47+
48+
if err := ensureAccount(cmd, app); err != nil {
49+
return err
50+
}
51+
52+
result, err := app.Account().Lineup().ListMarkers(cmd.Context())
53+
if err != nil {
54+
return convertSDKError(err)
55+
}
56+
57+
return app.OK(result.Markers,
58+
output.WithSummary(fmt.Sprintf("%d lineup markers", len(result.Markers))),
59+
output.WithBreadcrumbs(
60+
output.Breadcrumb{
61+
Action: "create",
62+
Cmd: "basecamp lineup create <name> <date>",
63+
Description: "Create new marker",
64+
},
65+
),
66+
)
67+
},
68+
}
69+
}
70+
4071
func newLineupCreateCmd() *cobra.Command {
4172
cmd := &cobra.Command{
4273
Use: "create <name> <date>",

internal/version/sdk-provenance.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"sdk": {
33
"module": "github.com/basecamp/basecamp-sdk/go",
4-
"version": "v0.6.1-0.20260318221909-49475983b9c8",
5-
"revision": "49475983b9c8",
6-
"updated_at": "2026-03-18T22:19:09Z"
4+
"version": "v0.6.1-0.20260319050216-1c33ce43c305",
5+
"revision": "1c33ce43c305",
6+
"updated_at": "2026-03-19T05:02:16Z"
77
},
88
"api": {
99
"repo": "basecamp/bc3",

0 commit comments

Comments
 (0)