Skip to content

Add label workflows to the CLI and TUI - #207

Merged
robzolkos merged 4 commits into
mainfrom
feature/labels-cli-tui
Aug 20, 2026
Merged

Add label workflows to the CLI and TUI#207
robzolkos merged 4 commits into
mainfrom
feature/labels-cli-tui

Conversation

@robzolkos

@robzolkos robzolkos commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add HEY label workflows to both the CLI and the Mail TUI, using the same Labels terminology as the web UI while retaining the server and SDK's internal folder resource names.

  • add hey labels and hey label <id> with cursor pagination, limits, complete traversal, and structured/styled output
  • add hey label add|create|remove for existing labels, new labels, individual removal, and removing every label
  • append labels to Mail navigation and add n/p label pagination
  • add a height-aware g label picker for adding, creating, and removing labels
  • pin the released hey-sdk/go@v0.6.1 pagination API

Behavior

Mail
├── HEY boxes
└── Labels
    ├── open labeled threads
    ├── n / p: next or previous page
    └── g: manage labels
        ├── add an existing label
        ├── create and add a label
        ├── remove one label
        └── remove every label

CLI commands:

hey labels
hey label <label-id> [--limit N | --all | --page CURSOR]
hey label add <thread-id>... --to <label-id>
hey label create <name> <thread-id>...
hey label remove <thread-id>... --from <label-id|all>

Label reads expose posting IDs, derived topic IDs, next_page, and total_count. Mutations validate positive, unique thread IDs before making requests.

Scope and compatibility

  • Uses existing typed HEY JSON operations; no server API change or HTML scraping.
  • Discovers labels through /my/navigation.json and reads them through the SDK Folders() service.
  • Preserves hey-sdk and wire-level folder names such as /folders and folder_id as implementation details.
  • Labels remain separate from box move destinations and cannot capture HEY box shortcuts, icons, or colliding IDs.
  • Label discovery and page loads reject stale responses, preserve known labels on transient failures, and support retry.
  • Markdown output now sanitizes terminal control characters and escapes table layout characters for all commands.
  • No migrations, feature flags, configuration, or deployment ordering are required. Rollback is a revert of this PR.

Validation

GOWORK=off make check
PASS

GOWORK=off make race-test
PASS

GOWORK=off make coverage
73.021% (5,700 / 7,806 statements), floor 70.8%

GOWORK=off make build
PASS

cd tests/smoke && GOWORK=off go test -count=1 -v -run '^TestLabel'
PASS

git diff --check
PASS

Unit coverage includes CLI request contracts, validation-before-request behavior, pagination, styled/Markdown sanitization, TUI navigation and picker workflows, retry and stale-response handling, pagination key scoping, and box/label identity collisions. Independent and Copilot reviews identified actionable CLI, TUI, output-contract, and smoke-cleanup edge cases. This head resolves every finding and both suggestions suppressed by Copilot’s follow-up review; all review threads are resolved, and focused re-review found no remaining P0/P1/P2 issues.

Reviewer focus

  1. internal/cmd/label.go and internal/folders/navigation.go: command contracts, opaque pagination cursors, and label discovery.
  2. internal/tui/mail.go and internal/tui/folders.go: source lifecycle, n/p scoping, stale-response guards, and label picker behavior.
  3. internal/output/writer.go: shared Markdown sanitization and escaping.

Traceability

This PR must not be merged without explicit approval.


Summary by cubic

Adds Labels to the CLI and Mail TUI so users can list and manage labels without the web app. Previously labels were unavailable; now Mail shows labels after HEY boxes, supports per‑label n/p pagination, and a height‑aware g picker to add, create, or remove labels. Markdown output now sanitizes terminal controls, escapes table pipes while preserving backslashes, and renders newlines as
.

  • CLI: hey labels; hey label <id> with cursor pagination (--limit, --all, --page); hey label add|create|remove with positive, unique thread ID validation.
  • TUI: discovers labels via /my/navigation.json; reads label pages with SDK Folders().GetPage; g manages add/create/remove; n/p paginates per label; guards reject stale navigation, keep known labels on transient failures; preserves boxes alongside labels on ID/name collisions; move picker excludes labels from destinations.
  • Implementation notes: label file/unfile via Postings().File/Unfile; create via Postings().CreateFolder; “folders” remain an internal term. Fixes hey box thread ID display to prefer topic ID and fall back to posting ID. Pins github.com/basecamp/hey-sdk/go to v0.6.1. Help, .surface, README, skills/hey, API coverage, and tests (unit and smoke) updated. No server changes, migrations, or flags; rollback is a revert.

Reviewer focus

  • CLI: internal/cmd/label.go for command contracts, validation, pagination; curated help in internal/cmd/help.go.
  • TUI: internal/folders/navigation.go for label discovery; internal/tui/mail.go and internal/tui/folders.go for per‑label pagination, picker behavior, and stale‑response guards; internal/tui/move.go and internal/tui/nav.go for excluding labels from move destinations and preserving boxes when IDs/names collide.
  • Output: internal/output/writer.go Markdown sanitization and escaping.

Written for commit 824032f. Summary will update on new commits.

Review in cubic

Copilot AI balanced review requested due to automatic review settings August 20, 2026 15:41
@robzolkos
robzolkos requested a review from a team as a code owner August 20, 2026 15:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds label workflows across the CLI and Mail TUI using HEY’s typed folder APIs.

Changes:

  • Adds label listing, pagination, creation, assignment, and removal commands.
  • Adds TUI label navigation, pagination, and management picker.
  • Updates output sanitization, documentation, tests, and SDK dependency.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.surface Registers the label command surface.
API-COVERAGE.md Documents covered label endpoints.
README.md Documents CLI and TUI label workflows.
go.mod Pins HEY SDK v0.6.1.
go.sum Updates SDK checksums.
skills/hey/SKILL.md Adds label guidance and triggers.
tests/smoke/labels_test.go Adds label read and validation smoke tests.
internal/cmd/drafts_test.go Generalizes formatted-command test helpers.
internal/cmd/help.go Adds labels to curated help.
internal/cmd/help_test.go Updates help expectations.
internal/cmd/label.go Implements label CLI commands.
internal/cmd/label_test.go Tests label commands and pagination.
internal/cmd/root.go Registers label commands.
internal/folders/navigation.go Discovers labels from navigation.
internal/folders/navigation_test.go Tests label discovery.
internal/models/box.go Adds folder metadata to postings.
internal/output/writer.go Sanitizes Markdown cells.
internal/output/writer_test.go Tests Markdown sanitization.
internal/tui/folders.go Implements the label picker.
internal/tui/mail.go Integrates labels into Mail.
internal/tui/mail_test.go Tests label TUI workflows.
internal/tui/move.go Excludes labels from move destinations.
internal/tui/nav.go Adds collision-safe label navigation.
internal/tui/tui.go Handles background Mail loading.
internal/tui/tui_test.go Tests inactive loading and collisions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/tui/move.go Outdated
Comment thread internal/tui/tui.go
Comment thread internal/cmd/label.go
Comment thread tests/smoke/labels_test.go
@robzolkos
robzolkos requested a balanced review from Copilot August 20, 2026 16:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 28 changed files in this pull request and generated no new comments.

Suppressed comments (2)

internal/output/writer.go:362

  • A value that already contains \| is transformed into \\|: Markdown consumes the first pair as a literal backslash, leaving the pipe to split the table cell. Escape backslashes before escaping pipes so arbitrary values cannot still change the table layout.
	value = strings.ReplaceAll(value, "|", `\|`)

tests/smoke/labels_test.go:44

  • This compares a decoded label name with raw HTML, so a valid name such as Travel & Expenses appears as Travel &amp; Expenses and fails the smoke test. Compare against decoded page text (the existing browserPageText helper) or unescape the HTML before asserting.
	html := fetchHTML(t, baseURL+"/folders")
	if !strings.Contains(html, folder.Name) {
		t.Errorf("folder page does not contain %q", folder.Name)

@github-actions

Copy link
Copy Markdown

Sensitive Change Detection (shadow mode)

This PR modifies control-plane files:

  • .github/workflows/ci.yml
  • .github/workflows/test.yml

Shadow mode — this check is informational only. When activated, changes to these paths will require approval from a maintainer.

@robzolkos
robzolkos force-pushed the feature/labels-cli-tui branch from ce6aa07 to 469f539 Compare August 20, 2026 16:40
@robzolkos
robzolkos enabled auto-merge (squash) August 20, 2026 16:45
@robzolkos
robzolkos disabled auto-merge August 20, 2026 16:45
@robzolkos
robzolkos force-pushed the feature/labels-cli-tui branch from 469f539 to 824032f Compare August 20, 2026 16:56
@robzolkos
robzolkos merged commit 77bf8c4 into main Aug 20, 2026
21 checks passed
@robzolkos
robzolkos deleted the feature/labels-cli-tui branch August 20, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants