Skip to content

feat: add labels command to list workspace labels - #43

Closed
seraph-pixelperfect wants to merge 1 commit into
feat/comment-listfrom
feat/labels-command
Closed

seraph-pixelperfect wants to merge 1 commit into
feat/comment-listfrom
feat/labels-command

Conversation

@seraph-pixelperfect

Copy link
Copy Markdown
Collaborator

Closes #22. Depends on #42.

What

linear-axi labels lists the workspace's issue labels through the root issueLabels connection — the same connection resolveLabelIds already queried workspace-wide — as TOON rows of name + color (raw HEX), with a count line, a definitive empty state, and hints pointing at issue create --label and issues --label. Last v0.2 item.

Stacked PR note

Stacked on #42 (stack: #37 → #38 → #39 → #40 → #41 → #42). Base is feat/comment-list, not main.

No CI checks appear on this PR — ci.yml only triggers on PRs targeting main. CI runs when retargeted to main after the stack merges; local gates below are the evidence.

Schema source

Fields verified against the generated documents in @linear/sdk v90.0.0 (npm pack @linear/sdk, inspecting dist/*.d.mts / dist/index.mjs), same method as the parent PRs:

  • IssueLabel (dist/index-zxW4m1xd.d.mts, line 10324): color: String — "The label's color as a HEX string (e.g., '#EB5757')" — non-nullable; name: String; a render-friendly description?: Maybe<String> also exists (see Ambiguities); team?: Maybe<Team> distinguishes team-scoped from workspace-level labels.
  • QueryIssueLabelsArgs: the root issueLabels connection takes after/filter/first/includeArchived/last/orderBy: PaginationOrderBy — full cursor pagination, same shape as projects/cycles/comments.
  • PaginationOrderBy (dist/index.mjs, line 3539): only createdAt | updatedAt — so orderBy: updatedAt is the recent-first ordering, consistent with issues/projects/cycles (no name sort exists).

Implementation

  • fetchLabels(apiKey, limit = 500) in src/linear.ts follows the established auto-pagination pattern (fetchProjects/fetchComments): pageInfo { hasNextPage endCursor }, 50/batch, same non-advancing-cursor/empty-page loop guards, hasMore in the result.
  • src/commands/labels.ts follows the projects/cycles template: LABELS_HELP const, no flags (unknown-flag rejection), count line, renderList, hints.
  • resolveLabelIds now reuses fetchLabels internally — deduplicated query string, and it fixes a latent gap where label resolution fetched a single unpaginated page and silently missed labels beyond the first 50. Matching stays case-insensitive in server order; no existing test asserted on the old document.
  • Wired into src/cli.ts (commands map, COMMAND_HELP, TOP_HELP now commands[9] with a linear-axi labels example) and src/skill.ts; skills/linear-axi/SKILL.md regenerated via pnpm run build:skill.

Demo (real output)

Before (base c6221ac):

$ linear-axi labels
error: "Unknown command: labels"
code: VALIDATION_ERROR
help[1]: Run `--help` to see available commands

After — stubbed-fetch render (no network):

$ linear-axi labels
count: 3
labels[3]{name,color}:
  bug,#EB5757
  feature,#4CB782
  chore,#95A2B3
help[2]:
  Run `linear-axi issues --label "<name>"` to list issues carrying a label
  Run `linear-axi issue create --label <name>` to add a label to a new issue

After — labels --key lin_api_fake reaches the Linear API layer (real request to api.linear.app; the fake key is rejected 401 and mapped by src/errors.ts):

$ linear-axi labels --key lin_api_fake
error: Linear auth required — set LINEAR_API_KEY or pass --key <key>
code: AUTH_REQUIRED

Top help:

commands[9]:
  (none)=dashboard, issues, issue, comment, teams, projects, cycles, labels, login, setup

Local gates (real output)

  • pnpm build — $ tsc, clean.
  • pnpm lint — $ eslint ., clean.
  • pnpm run build:skill -- --check — skills/linear-axi/SKILL.md is up to date.
  • pnpm test:
 Test Files  13 passed (13)
      Tests  134 passed (134)

(baseline on base branch: 124 tests in 12 files; +10 new in test/labels.test.ts: document shape incl. color + pagination args, name/color row rendering, truncation count line, empty workspace, two-page cursor-advanced pagination, unknown-flag rejection, hints, create-path label resolution through the reused query, help)

  • pnpm run format:check — RED pre-existing: the same 18 files as main (CI does not run it). New/edited-by-me files pass pnpm exec prettier --check (src/commands/labels.ts, test/labels.test.ts clean; src/linear.ts/src/cli.ts were already in the pre-existing flagged set and prettier's normalized delta on them is exactly this PR's additions).

CI quota caveat

If CI checks later appear and fail: GitHub Actions billing/spending-limit rejections look like check failures. Check gh run view <run-id> / the jobs API for a billing annotation, or an empty steps list with a ~3-4s duration. If quota-blocked, this PR relies on the local gate output above; it will not be retried against the quota.

Ambiguities flagged

  • Color rendering: rendered as the raw HEX string (e.g. #EB5757). No truecolor/ANSI swatch attempted — terminal color support varies (per task guidance). IssueLabel.color is a non-nullable String per the SDK.
  • Description field: IssueLabel.description (nullable String) exists and is render-friendly, but the issue spec says "name, color where exposed", so it is not selected/rendered. Easy follow-up column if wanted.
  • Ordering: orderBy: updatedAt (recent-first) for consistency with issues/projects/cycles; PaginationOrderBy offers no name sort, so no alphabetical ordering is possible server-side.
  • resolveLabelIds refactor: done — it reuses fetchLabels, preserving case-insensitive matching and server-order ids while fixing the >50-labels resolution gap; covered by a new create-path test. Reverted easily if reviewers prefer the old minimal query.
  • Fetch limit: fetchLabels defaults to 500 (10 pages) — generous for real workspaces while guarding a runaway cursor; hasMore surfaces as count: N (showing first N) when hit.

Identity note

Automated agent dispatch authenticated as seraph-pixelperfect; this PR is submitted for human review — not self-approved. Merge is a human decision.

`linear-axi labels` lists the workspace's issue labels through the root
`issueLabels` connection (the same connection resolveLabelIds already
queried workspace-wide), auto-paginated in 50-node batches with
orderBy: updatedAt (recent-first, matching issues/projects/cycles).
TOON rows render the label name and its color as the raw HEX string
("#EB5757"-style per the generated IssueLabel type in @linear/sdk —
rendered raw since terminal color support varies, no ANSI swatch), with
a count line, definitive empty state, and hints pointing at
`issue create --label` and `issues --label`.

resolveLabelIds now reuses fetchLabels, fixing a latent gap where label
resolution fetched a single unpaginated page and silently missed labels
beyond the first 50; matching stays case-insensitive in server order.

Closes #22
@ghostinprod-pixelperfect

Copy link
Copy Markdown
Collaborator

Superseded by merged rc/0.1 PR #51 (commit 694a564), which consolidated this read/discovery stack with validation and review fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants