Skip to content

Commit 8b5bc2e

Browse files
authored
Polish: dual-vocabulary CLI — app terms for humans, API terms for agents (#222)
* Polish: remove internal API terms from catalog descriptions Replace "recording" with user-facing terms in the command catalog: assign → "Assign someone to an item", react → "React with an emoji", recordings → "Browse content by type across projects", show → "Show any item by ID", events → "View change history", timesheet actions → "item" instead of "recording". * Polish: reframe recordings.go user-visible text Replace "recording" with "item" or "content" in all help text, flag descriptions, breadcrumbs, summaries, and error messages. Agent notes updated to drop leading "Recordings" reference. * Polish: purge "recording" from show, events, subscriptions Replace "recording" with "item" in user-visible strings across show.go, events.go, and subscriptions.go. Update Use strings from <recording_id|url> to <id|url>. Update e2e assertion. * Polish: purge "recording" from comment, boost, and root error handling Replace "recording" with "item" in flag descriptions, help text, breadcrumbs, and error messages. Update react shortcut to "React with an emoji". Update e2e assertion for --on error. * Polish: rename timesheet recording → item, keep alias Rename the "recording" subcommand to "item" with "recording" as an alias for backward compat. Update all user-visible text and breadcrumbs to use "item" instead of "recording". * Polish: replace "bucket" with "project" in user-facing text Update search breadcrumb and reports --group-by to use "project" instead of "bucket". "bucket" remains accepted for backward compat and is normalized to the API value before the SDK call. * Polish: normalize vault/folder terminology in files.go Replace "vault" with "folder" in user-visible error messages and help text. Simplify Long description to remove API jargon. * Polish: fix "recording types" → "content types" in todos agent notes * Polish: address review feedback and fix CLI surface check - Fix 3 missed "recording" → "item" replacements in boost.go - Map API "bucket" back to "project" in reports assigned summary - Include command aliases in --help --agent output so surface snapshot tracks backward-compatible names (fixes CI surface check) * Polish: address second round of review feedback - Use strings.TrimSuffix for safer alias path construction in agent help - Replace remaining "vault" with "folder" in files.go subcommand help text - Replace "recordings" with "items" in comment.go batch error messages * Polish: fix last missed "recordings" in comment.go error message
1 parent bfd9cb8 commit 8b5bc2e

File tree

17 files changed

+214
-199
lines changed

17 files changed

+214
-199
lines changed

.surface

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ CMD basecamp templates update
211211
CMD basecamp timeline
212212
CMD basecamp timesheet
213213
CMD basecamp timesheet project
214-
CMD basecamp timesheet recording
214+
CMD basecamp timesheet item
215215
CMD basecamp timesheet report
216216
CMD basecamp todo
217217
CMD basecamp todolistgroups
@@ -4660,30 +4660,30 @@ FLAG basecamp timesheet project --styled type=bool
46604660
FLAG basecamp timesheet project --to type=string
46614661
FLAG basecamp timesheet project --todolist type=string
46624662
FLAG basecamp timesheet project --verbose type=count
4663-
FLAG basecamp timesheet recording --account type=string
4664-
FLAG basecamp timesheet recording --agent type=bool
4665-
FLAG basecamp timesheet recording --cache-dir type=string
4666-
FLAG basecamp timesheet recording --count type=bool
4667-
FLAG basecamp timesheet recording --end type=string
4668-
FLAG basecamp timesheet recording --from type=string
4669-
FLAG basecamp timesheet recording --hints type=bool
4670-
FLAG basecamp timesheet recording --ids-only type=bool
4671-
FLAG basecamp timesheet recording --in type=string
4672-
FLAG basecamp timesheet recording --json type=bool
4673-
FLAG basecamp timesheet recording --markdown type=bool
4674-
FLAG basecamp timesheet recording --md type=bool
4675-
FLAG basecamp timesheet recording --no-hints type=bool
4676-
FLAG basecamp timesheet recording --no-stats type=bool
4677-
FLAG basecamp timesheet recording --person type=string
4678-
FLAG basecamp timesheet recording --profile type=string
4679-
FLAG basecamp timesheet recording --project type=string
4680-
FLAG basecamp timesheet recording --quiet type=bool
4681-
FLAG basecamp timesheet recording --start type=string
4682-
FLAG basecamp timesheet recording --stats type=bool
4683-
FLAG basecamp timesheet recording --styled type=bool
4684-
FLAG basecamp timesheet recording --to type=string
4685-
FLAG basecamp timesheet recording --todolist type=string
4686-
FLAG basecamp timesheet recording --verbose type=count
4663+
FLAG basecamp timesheet item --account type=string
4664+
FLAG basecamp timesheet item --agent type=bool
4665+
FLAG basecamp timesheet item --cache-dir type=string
4666+
FLAG basecamp timesheet item --count type=bool
4667+
FLAG basecamp timesheet item --end type=string
4668+
FLAG basecamp timesheet item --from type=string
4669+
FLAG basecamp timesheet item --hints type=bool
4670+
FLAG basecamp timesheet item --ids-only type=bool
4671+
FLAG basecamp timesheet item --in type=string
4672+
FLAG basecamp timesheet item --json type=bool
4673+
FLAG basecamp timesheet item --markdown type=bool
4674+
FLAG basecamp timesheet item --md type=bool
4675+
FLAG basecamp timesheet item --no-hints type=bool
4676+
FLAG basecamp timesheet item --no-stats type=bool
4677+
FLAG basecamp timesheet item --person type=string
4678+
FLAG basecamp timesheet item --profile type=string
4679+
FLAG basecamp timesheet item --project type=string
4680+
FLAG basecamp timesheet item --quiet type=bool
4681+
FLAG basecamp timesheet item --start type=string
4682+
FLAG basecamp timesheet item --stats type=bool
4683+
FLAG basecamp timesheet item --styled type=bool
4684+
FLAG basecamp timesheet item --to type=string
4685+
FLAG basecamp timesheet item --todolist type=string
4686+
FLAG basecamp timesheet item --verbose type=count
46874687
FLAG basecamp timesheet report --account type=string
46884688
FLAG basecamp timesheet report --agent type=bool
46894689
FLAG basecamp timesheet report --cache-dir type=string
@@ -6362,7 +6362,7 @@ SUB basecamp templates update
63626362
SUB basecamp timeline
63636363
SUB basecamp timesheet
63646364
SUB basecamp timesheet project
6365-
SUB basecamp timesheet recording
6365+
SUB basecamp timesheet item
63666366
SUB basecamp timesheet report
63676367
SUB basecamp todo
63686368
SUB basecamp todolistgroups

e2e/errors.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ load test_helper
4848

4949
run basecamp comment "test" --on
5050
assert_failure
51-
assert_output_contains "--on requires a recording ID"
51+
assert_output_contains "--on requires an ID"
5252
}
5353

5454
@test "cards --column without value shows error" {

e2e/events.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ load test_helper
2424
run basecamp events --help
2525
assert_success
2626
assert_output_contains "basecamp events"
27-
assert_output_contains "recording_id"
27+
assert_output_contains "id|url"
2828
assert_output_contains "audit"
2929
}

e2e/timesheet.bats

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ load test_helper
7777
assert_output_contains "basecamp timesheet"
7878
assert_output_contains "report"
7979
assert_output_contains "project"
80-
assert_output_contains "recording"
80+
assert_output_contains "item"
8181
}
8282

8383

internal/cli/root.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ func transformCobraError(err error) error {
454454
flag := after
455455
// Special cases for flags with custom error messages
456456
if flag == "--on" {
457-
return output.ErrUsage("--on requires a recording ID")
457+
return output.ErrUsage("--on requires an ID")
458458
}
459459
return output.ErrUsage(flag + " requires a value")
460460
}
@@ -501,7 +501,7 @@ func transformCobraError(err error) error {
501501
case "to":
502502
return output.ErrUsage("Position required")
503503
case "on":
504-
return output.ErrUsage("Recording ID required")
504+
return output.ErrUsage("ID required")
505505
default:
506506
return output.ErrUsage(flag + " required")
507507
}
@@ -587,14 +587,21 @@ func emitAgentHelp(cmd *cobra.Command) {
587587
}
588588
}
589589

590-
// Subcommands
590+
// Subcommands (include aliases so the CLI surface snapshot tracks them)
591591
for _, sub := range cmd.Commands() {
592592
if sub.IsAvailableCommand() || sub.Name() == "help" {
593593
info.Subcommands = append(info.Subcommands, agentSubcommand{
594594
Name: sub.Name(),
595595
Short: sub.Short,
596596
Path: sub.CommandPath(),
597597
})
598+
for _, alias := range sub.Aliases {
599+
info.Subcommands = append(info.Subcommands, agentSubcommand{
600+
Name: alias,
601+
Short: sub.Short,
602+
Path: strings.TrimSuffix(sub.CommandPath(), sub.Name()) + alias,
603+
})
604+
}
598605
}
599606
}
600607

internal/commands/boost.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ func NewBoostsCmd() *cobra.Command {
1818
Use: "boost [action]",
1919
Aliases: []string{"boosts"},
2020
Short: "Manage boosts (reactions)",
21-
Long: `Manage boosts (emoji reactions) on recordings.
21+
Long: `Manage boosts (emoji reactions) on items.
2222
23-
Use 'basecamp boost list <recording-id>' to see boosts on a recording.
23+
Use 'basecamp boost list <id>' to see boosts on an item.
2424
Use 'basecamp boost show <boost-id>' to view a specific boost.
25-
Use 'basecamp boost create <recording-id> "emoji"' to boost a recording.
25+
Use 'basecamp boost create <id> "emoji"' to boost an item.
2626
Use 'basecamp boost delete <boost-id>' to remove a boost.`,
2727
Annotations: map[string]string{"agent_notes": "Boost content is typically an emoji but can be text\nbasecamp react is a shortcut for boost create"},
2828
Args: cobra.MinimumNArgs(0),
@@ -48,15 +48,15 @@ func newBoostListCmd(project *string) *cobra.Command {
4848
var eventID string
4949

5050
cmd := &cobra.Command{
51-
Use: "list <recording-id|url>",
52-
Short: "List boosts on a recording",
53-
Long: `List boosts on a recording.
51+
Use: "list <id|url>",
52+
Short: "List boosts on an item",
53+
Long: `List boosts on an item.
5454
55-
You can pass either a recording ID or a Basecamp URL:
55+
You can pass either an ID or a Basecamp URL:
5656
basecamp boost list 789 --project my-project
5757
basecamp boost list https://3.basecamp.com/123/buckets/456/todos/789
5858
59-
Use --event to list boosts on a specific event within the recording.`,
59+
Use --event to list boosts on a specific event within the item.`,
6060
Args: cobra.ExactArgs(1),
6161
RunE: func(cmd *cobra.Command, args []string) error {
6262
app := appctx.FromContext(cmd.Context())
@@ -99,7 +99,7 @@ func runBoostList(cmd *cobra.Command, app *appctx.App, recording, project, event
9999

100100
recordingIDInt, err := strconv.ParseInt(recordingID, 10, 64)
101101
if err != nil {
102-
return output.ErrUsage("Invalid recording ID")
102+
return output.ErrUsage("Invalid ID")
103103
}
104104

105105
if eventID != "" {
@@ -140,7 +140,7 @@ func runBoostList(cmd *cobra.Command, app *appctx.App, recording, project, event
140140
output.Breadcrumb{
141141
Action: "create",
142142
Cmd: fmt.Sprintf("basecamp boost create %s \"emoji\" --project %s", recordingID, resolvedProjectID),
143-
Description: "Boost this recording",
143+
Description: "Boost this item",
144144
},
145145
),
146146
)
@@ -224,15 +224,15 @@ func newBoostCreateCmd(project *string) *cobra.Command {
224224
var eventID string
225225

226226
cmd := &cobra.Command{
227-
Use: "create <recording-id|url> <content>",
228-
Short: "Boost a recording",
229-
Long: `Boost a recording with an emoji reaction.
227+
Use: "create <id|url> <content>",
228+
Short: "Boost an item",
229+
Long: `Boost an item with an emoji reaction.
230230
231-
You can pass either a recording ID or a Basecamp URL:
231+
You can pass either an ID or a Basecamp URL:
232232
basecamp boost create 789 "🎉" --project my-project
233233
basecamp boost create https://3.basecamp.com/123/buckets/456/todos/789 "👍"
234234
235-
Use --event to boost a specific event within the recording.`,
235+
Use --event to boost a specific event within the item.`,
236236
Args: cobra.ExactArgs(2),
237237
RunE: func(cmd *cobra.Command, args []string) error {
238238
app := appctx.FromContext(cmd.Context())
@@ -275,7 +275,7 @@ func runBoostCreate(cmd *cobra.Command, app *appctx.App, recording, project, con
275275

276276
recordingIDInt, err := strconv.ParseInt(recordingID, 10, 64)
277277
if err != nil {
278-
return output.ErrUsage("Invalid recording ID")
278+
return output.ErrUsage("Invalid ID")
279279
}
280280

281281
if eventID != "" {
@@ -331,7 +331,7 @@ func newBoostDeleteCmd() *cobra.Command {
331331
cmd := &cobra.Command{
332332
Use: "delete <boost-id|url>",
333333
Short: "Delete a boost",
334-
Long: `Delete a boost from a recording.
334+
Long: `Delete a boost.
335335
336336
You can pass either a boost ID or a Basecamp URL:
337337
basecamp boost delete 789
@@ -365,7 +365,7 @@ You can pass either a boost ID or a Basecamp URL:
365365
output.WithBreadcrumbs(
366366
output.Breadcrumb{
367367
Action: "list",
368-
Cmd: "basecamp boost list <recording-id> --project <project>",
368+
Cmd: "basecamp boost list <id> --project <project>",
369369
Description: "View boosts",
370370
},
371371
),
@@ -383,10 +383,10 @@ func NewBoostShortcutCmd() *cobra.Command {
383383

384384
cmd := &cobra.Command{
385385
Use: "react <content>",
386-
Short: "Boost a recording",
387-
Long: `Boost a recording with an emoji reaction (shortcut for boost create).
386+
Short: "React with an emoji",
387+
Long: `React to an item with an emoji (shortcut for boost create).
388388
389-
Content as positional argument, --on for the recording:
389+
Content as positional argument, --on for the item:
390390
basecamp react "🎉" --on 789 --project my-project
391391
basecamp react "👍" --on https://3.basecamp.com/123/buckets/456/todos/789`,
392392
Args: cobra.ExactArgs(1),
@@ -406,8 +406,8 @@ Content as positional argument, --on for the recording:
406406
},
407407
}
408408

409-
cmd.Flags().StringVarP(&recording, "on", "r", "", "Recording ID or URL to boost")
410-
cmd.Flags().StringVar(&recording, "recording", "", "Recording ID or URL (alias for --on)")
409+
cmd.Flags().StringVarP(&recording, "on", "r", "", "ID or URL to react to")
410+
cmd.Flags().StringVar(&recording, "recording", "", "ID or URL (alias for --on)")
411411
cmd.Flags().StringVar(&eventID, "event", "", "Event ID (for event-specific boosts)")
412412
cmd.Flags().StringVarP(&project, "project", "p", "", "Project ID or name")
413413
cmd.Flags().StringVar(&project, "in", "", "Project ID (alias for --project)")

internal/commands/commands.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ func CommandCategories() []CommandCategory {
5252
{Name: "message", Category: "shortcut", Description: "Post a message"},
5353
{Name: "card", Category: "shortcut", Description: "Create a card"},
5454
{Name: "comment", Category: "shortcut", Description: "Add a comment"},
55-
{Name: "assign", Category: "shortcut", Description: "Assign a recording"},
55+
{Name: "assign", Category: "shortcut", Description: "Assign someone to an item"},
5656
{Name: "unassign", Category: "shortcut", Description: "Remove assignment"},
57-
{Name: "react", Category: "shortcut", Description: "Boost a recording"},
57+
{Name: "react", Category: "shortcut", Description: "React with an emoji"},
5858
},
5959
},
6060
{
@@ -70,7 +70,7 @@ func CommandCategories() []CommandCategory {
7070
Name: "Scheduling & Time",
7171
Commands: []CommandInfo{
7272
{Name: "schedule", Category: "scheduling", Description: "Manage schedule entries", Actions: []string{"show", "entries", "create", "update"}},
73-
{Name: "timesheet", Category: "scheduling", Description: "Manage time tracking", Actions: []string{"report", "project", "recording"}},
73+
{Name: "timesheet", Category: "scheduling", Description: "Manage time tracking", Actions: []string{"report", "project", "item"}},
7474
{Name: "checkins", Category: "scheduling", Description: "View automatic check-ins", Actions: []string{"questions", "question", "answers", "answer"}},
7575
{Name: "timeline", Category: "scheduling", Description: "View activity timelines", Actions: []string{}},
7676
{Name: "reports", Category: "scheduling", Description: "View reports", Actions: []string{"assignable", "assigned", "overdue", "schedule"}},
@@ -100,9 +100,9 @@ func CommandCategories() []CommandCategory {
100100
Name: "Search & Browse",
101101
Commands: []CommandInfo{
102102
{Name: "search", Category: "search", Description: "Search across projects"},
103-
{Name: "recordings", Category: "search", Description: "Browse recordings by type/status", Actions: []string{"list", "trash", "archive", "restore", "visibility"}},
104-
{Name: "show", Category: "search", Description: "Show any recording by ID"},
105-
{Name: "events", Category: "search", Description: "View recording change history"},
103+
{Name: "recordings", Category: "search", Description: "Browse content by type across projects", Actions: []string{"list", "trash", "archive", "restore", "visibility"}},
104+
{Name: "show", Category: "search", Description: "Show any item by ID"},
105+
{Name: "events", Category: "search", Description: "View change history"},
106106
{Name: "url", Category: "search", Description: "Parse Basecamp URLs"},
107107
},
108108
},

0 commit comments

Comments
 (0)