Skip to content

feat: wire --fields opt-in extra fields into commands - #41

Closed
seraph-pixelperfect wants to merge 1 commit into
feat/cycle-supportfrom
feat/fields-wiring
Closed

seraph-pixelperfect wants to merge 1 commit into
feat/cycle-supportfrom
feat/fields-wiring

Conversation

@seraph-pixelperfect

Copy link
Copy Markdown
Collaborator

Closes #23. Depends on #40.

parseFields in src/fields.ts was built and unit-tested (#20) but wired into no command. This PR adds the opt-in --fields <a,b,c> flag to issues and issue view: per-command available field maps select extra GraphQL scalar keys that are appended to the selection set and to the rendered TOON schema. Default documents and default output are byte-identical without the flag.

What changed

  • src/linear.ts — new withExtraFields(base, extraKeys) helper appends opt-in keys to a base selection, returning the base string unchanged when no extras are requested; fetchIssues/fetchIssue gain an optional extraFields param (extras apply to the searchIssues document too, since fetchIssues also serves --search). LinearIssue documents the new optional fields.
  • src/commands/issues.ts — ISSUE_LIST_EXTRA_FIELDS map (url, estimate, dueDate, createdAt), --fields parsed via parseFields, extras passed to fetchIssues and appended to listSchema as extra columns. Added to KNOWN_FLAGS and ISSUES_HELP.
  • src/commands/issue.ts — VIEW_EXTRA_FIELDS map (dueDate, estimate, archivedAt, branchName), same wiring in viewIssue (extra detail rows). Added to VIEW_FLAGS and ISSUE_HELP.
  • src/skill.ts + regen skills/linear-axi/SKILL.md — new tip documenting --fields.
  • test/fields-wiring.test.ts — 13 new tests (network-free, stubbed fetch, asserting on the captured GraphQL document, variables, and rendered output).

Field maps and schema source

Each map offers only fields not already in that command's default output, all scalars on Linear's Issue type — verified against the generated documents in @linear/sdk v90.0.0 (npm pack @linear/sdk, Issue type in dist/index-zxW4m1xd.d.mts):

Command Flag names GraphQL key / type
issues url url: String
issues estimate estimate: Float (nullable)
issues dueDate dueDate: TimelessDate (serialized YYYY-MM-DD, nullable)
issues createdAt createdAt: DateTime (rendered as relative time, like updated)
issue view dueDate / estimate same as above
issue view archivedAt archivedAt: DateTime (nullable; rendered as relative time, archived)
issue view branchName branchName: String

Note: the issue mentions subIssueCount as a possible view field — it does not exist on Issue in @linear/sdk v90.0.0 (only children: IssueConnection / subIssueSortOrder), so it was not mapped. url/createdAt are intentionally absent from the view map (already in ISSUE_DETAIL_FIELDS); priority is intentionally absent from the issues map (already in ISSUE_LIST_FIELDS, and not a column add candidate without duplicating the selection).

Demo (real output, stubbed fetch — no network)

Default vs --fields url — the acceptance example, plus multi-field and the loud unknown-field failure:

$ linear-axi issues                       # default, unchanged
count: 1
issues[1]{identifier,title,state,team,updated}:
  LIN-1,Ship the thing,started,LIN,22h ago
help[2]:
  Run `linear-axi issue view <IDENTIFIER>` for details
  Run `linear-axi issue create --title "..." --team <KEY>` to add one

$ linear-axi issues --fields url          # acceptance: url column added
count: 1
issues[1]{identifier,title,state,team,updated,url}:
  LIN-1,Ship the thing,started,LIN,22h ago,"https://linear.app/lini/issue/LIN-1/ship-the-thing"
help[2]:
  ...

$ linear-axi issues --fields url,estimate
count: 1
issues[1]{identifier,title,state,team,updated,url,estimate}:
  LIN-1,Ship the thing,started,LIN,22h ago,"https://linear.app/lini/issue/LIN-1/ship-the-thing",3
help[2]:
  ...

$ linear-axi issues --fields bogus
error: "Unknown field(s): bogus. Available: createdAt, dueDate, estimate, url"
code: VALIDATION_ERROR
(exit 2, no network request issued)

$ linear-axi issue view LIN-1 --fields dueDate,estimate
issue:
  identifier: LIN-1
  title: Ship the thing
  state: Started
  state_type: started
  priority: 2
  assignee: Ada Lovelace
  team: LIN
  labels: bug
  url: "https://linear.app/lini/issue/LIN-1/ship-the-thing"
  created: 18d ago
  updated: 22h ago
  dueDate: 2026-09-01
  estimate: 3
description:
Long description body
help[2]:
  ...

Extra columns append after the default columns in the list CSV header; extra fields append after the default rows in detail view.

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
 RUN  v3.2.7 (CUDA) /Users/seraph/workspace/linear-axi-wt/fields-wiring

 ✓ test/format.test.ts (6 tests) 2ms
 ✓ test/toon.test.ts (7 tests) 3ms
 ✓ test/errors.test.ts (7 tests) 3ms
 ✓ test/args.test.ts (7 tests) 3ms
 ✓ test/fields.test.ts (4 tests) 2ms
 ✓ test/config.test.ts (12 tests) 7ms
 ✓ test/issues-search.test.ts (8 tests) 5ms
 ✓ test/projects.test.ts (15 tests) 6ms
 ✓ test/issues-pagination.test.ts (12 tests) 7ms
 ✓ test/cycles.test.ts (19 tests) 8ms
 ✓ test/fields-wiring.test.ts (13 tests) 6ms

 Test Files  11 passed (11)
      Tests  110 passed (110)
   Duration  377ms

Baseline on the parent branch was 97 tests in 10 files; +13 new tests, no existing test weakened. pnpm run format:check remains RED pre-existing (19 files incl. this PR's touched tracked files, which were already flagged before this branch); the new test/fields-wiring.test.ts passes prettier --check and no previously-clean file is newly flagged.

Stacked PR note

Stacked on #40 (stack: #37 → #38 → #39 → #40). No CI checks appear — ci.yml only triggers on PRs targeting main. CI runs when retargeted to main after the stack merges; local gates below are the evidence. Not retargeting.

CI quota-block caveat: if checks appear and fail with billing/spending-limit rejections, that looks like a check failure — check gh run view <run-id> or the jobs API for a billing annotation (or empty steps with ~3-4s duration). If quota-blocked, rely on the local gate output above; do not retry.

Ambiguities flagged

  • Field sets per command are my choice; the issue only fixes issues --fields url. I mapped 4 list fields (url, estimate, dueDate, createdAt) and 4 view fields (dueDate, estimate, archivedAt, branchName) — all schema-verified scalars absent from each command's defaults. subIssueCount from the issue discussion does not exist on Issue in the current SDK.
  • Rendering: timestamps (createdAt, archivedAt) render as relative times consistent with existing created/updated columns; dueDate renders raw YYYY-MM-DD (TimelessDate is already compact); estimate renders the raw number (null when unset). In the list, extras append as trailing CSV columns; in detail, as trailing key rows.
  • Blank --fields value (e.g. --fields= or empty names) selects nothing and keeps default output — this is parseFields' tested, pre-existing behavior (splits/filters blanks), preserved rather than made a hard error, unlike value-requiring filters like --search.

Identity note

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

parseFields (src/fields.ts) was built and unit-tested but wired into no
command. Add the opt-in --fields <a,b,c> flag to `issues` and `issue view`
(#23): per-command available field maps select extra GraphQL scalar keys
that are appended to the selection set and the rendered TOON schema.

- issues: url, estimate, dueDate, createdAt (extra columns)
- issue view: dueDate, estimate, archivedAt, branchName (extra rows)
- Field shapes verified against the generated Issue type in
  @linear/sdk v90.0.0; only fields absent from each command's default
  output are offered, so defaults stay byte-identical without the flag
- fetchIssues/fetchIssue gain an optional extraFields param; a new
  withExtraFields helper appends keys, returning the base string
  unchanged when no extras are requested. Extras apply to the
  searchIssues document too
- Unknown names fail loud (AxiError VALIDATION_ERROR) with the valid set
  listed, before any network request; blank values select nothing
- Help (ISSUES_HELP/ISSUE_HELP), KNOWN_FLAGS/VIEW_FLAGS, and SKILL.md
  updated; new test/fields-wiring.test.ts (13 tests) covers document +
  output wiring, filter/search composition, unknown-field failure, and
  default-schema invariance
@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